Author Topic: [SOLVED] External Module Communication  (Read 5972 times)

Matt R.

  • Newbie
  • *
  • Posts: 4
    • View Profile
[SOLVED] External Module Communication
« on: September 28, 2017, 09:16:41 PM »
I would like to make an application that handles calls similar to an IVR but with some extra audio processing. I am having the hardest time getting external module communication to work.

This basic example from scripts/echo.sh shows the output of %%<message:<ID>:true:\n being written to stdout. It works perfectly fine, echoing the message on stderr (visible in Yate logs) and accepts a call.

Code: [Select]
#!/bin/sh

read -r REPLY
echo "$REPLY" | sed 's/^[^:]*:\([^:]*\):.*$/%%<message:\1:true:/;'
echo "$REPLY" | sed 's/^[^:]*:\([^:]*\):.*$/%%<message:\1:true:/;' >&2

(sleep 1; cat) <&3 >&4

I would like to do the same thing in C, although skip piping audio from FD3 to FD4 for simplicity's' sake.

Code: [Select]
#include <stdio.h>
#include <string.h>
#include <unistd.h>

char commandBuf[4096];
char messageID[256];

int main(void) {

if( fgets(commandBuf, 4096, stdin) == NULL ) {
fprintf(stderr, "No command received.\n" );
return 1;
}

fprintf( stderr, "COMMAND %s\n", commandBuf); // Debug the command, logs correctly to Yate log

char* tokens = strdup(commandBuf);
char* curToken;
int curTokenIdx = 0;
while( (curToken = strsep(&tokens, ":")) != NULL ) {
fprintf(stderr, "TOKEN: %s\n", curToken ); // Tokens are correctly separated and logged

if(curTokenIdx == 1) break; // Stop when we've reached the ID

curTokenIdx++;
}

fprintf(stdout, "%%%%<message:%s:true:\n", curToken); // Send the message command to Yate
fprintf(stderr, "%%%%<message:%s:true:\n", curToken); // Log what we sent

sleep(20);
return 0;
}

As far as I can tell this should work. The debug messages all indicate that the %%<message:<ID>:true: command was sent to Yate. However, I'm getting the following logs:

Code: [Select]
Sep 28 22:34:12 yate[9443]: 2017-09-28_22:34:12.933304 <extmodule:WARN> Message 0x7fca8803fdc0 'call.execute' did not return in 10000 msec [0x7fca7c0f5500]
Sep 28 22:34:12 yate[9443]: 2017-09-28_22:34:12.933413 <WARN> ExtMod 'testmodule' did not handle call message

What is causing this? My program, as far as I can tell, is outputting the exact same output as the shell script, which works just fine.

Thanks for your help.
« Last Edit: October 03, 2017, 12:21:18 PM by Matt R. »

Monica Tepelus

  • Administrator
  • Full Member
  • *****
  • Posts: 198
    • View Profile
Re: External Module Communication
« Reply #1 on: September 29, 2017, 01:21:57 AM »
You did not acknowledge the message.  Acknowledging is separate. It doesn't matter if you handled the message or not.

Matt R.

  • Newbie
  • *
  • Posts: 4
    • View Profile
Re: External Module Communication
« Reply #2 on: September 29, 2017, 05:34:56 AM »
Hi Monica,

Can you please explain what you mean and indicate the difference between the shell script and the C code?

As I understand it, this line in the shell script acknowledges the message by replying to the server over stdout.

Code: [Select]
echo "$REPLY" | sed 's/^[^:]*:\([^:]*\):.*$/%%<message:\1:true:/;'
How is this line in my C code different?

Code: [Select]
fprintf(stdout, "%%%%<message:%s:true:\n", curToken);

Monica Tepelus

  • Administrator
  • Full Member
  • *****
  • Posts: 198
    • View Profile
Re: External Module Communication
« Reply #3 on: September 29, 2017, 06:50:48 AM »
If you wish to build an IVR start from one on the IVR examples from scripts/ directory. PHP is similar to C in syntax and you should be able to read them.

In your code I think you are missing an :. Try:

 fprintf(stdout, "%%%%<message:%s:true::\n", curToken);

This is an example from a script more complex .sh global script that handles a single message:
 http://yate.null.ro/websvn/filedetails.php?repname=yatebts&path=%2Ftrunk%2Fnipc%2Fauth%2Fnipc_auth.sh

        if [ -n "$resp" ]; then
      echo "%%<message:$id:true:::$resp"
       else
      echo "%%<message:$id:false::"

Matt R.

  • Newbie
  • *
  • Posts: 4
    • View Profile
Re: External Module Communication
« Reply #4 on: September 29, 2017, 07:52:04 AM »
I have read the PHP scripts, specifically libyate.php which includes the following function call for this scenario: _yate_print("%%<message:$id:$handled:$name:$retval$params\n");. I'm interested in working out this very basic communication issue before moving forward and implementing any of the library functions available in the PHP scripts.

Adding extra :s did not help.

When executing both the original shell script (echo.sh) and the C code I've posted, I can successfully log to stderr the exact same output (except ID obviously). I'm interested in understanding why this is not working from my C code when written to stdout. I am writing a newline at the end of the message, as specified by the docs. Could this be some kind of encoding issue? This example is so simple we should be able to deduce the problem without resorting to a library.

echo.sh stderr log:

Code: [Select]
%%<message:0x7fca99a4a9d0.1560637037:true:
C code stderr log:

Code: [Select]
%%<message:0x7fca99a4a9d0.1511079866:true:

Matt R.

  • Newbie
  • *
  • Posts: 4
    • View Profile
Re: External Module Communication
« Reply #5 on: October 03, 2017, 12:20:51 PM »
Solved!

This is so stupid. I assumed that including a newline in fprintf would flush, but it doesn't. Adding a fflush(stdout) fixed it.

Programming.