Author Topic: Problems with call.answered ( Windows - Global Script )  (Read 13337 times)

jamie

  • Newbie
  • *
  • Posts: 38
    • View Profile
Problems with call.answered ( Windows - Global Script )
« on: January 19, 2015, 12:01:01 PM »
Me again ...


Using PHP, I have a simple script to ... 1) answer the call, 2) send call.answered and 3) play a prompt

Yate::Install( "call.route" );
Yate::Install( "call.answered"   );

$ev->retval = "wave/play/C:/Program Files/Yate/share/sounds/test.wav";
$ev->params['targetid'] = $ev->params["id"];
$ev->handled = true;
$ev->Acknowledge();   

$m = new Yate("call.answered");
$m->params["id"] = $ev->params["id"];
$m->params["targetid"] = $ev->params["id"];
$m->Dispatch();       
   
But for some reason i can't understand why I never see the  incoming - call.answered event.


However if i do the following in JavaScript routing, the incoming - call.answered event arrives fine.
       
var m = new Message('call.answered');
m['id'] = msg['id'];
m['targetid'] = msg['id'];
m.enqueue();


any help and dummies guide would be much appreciated,
Thank you
Jamie
« Last Edit: January 20, 2015, 07:18:44 PM by jamie »

Monica Tepelus

  • Administrator
  • Full Member
  • *****
  • Posts: 198
    • View Profile
Re: Problems with call.answered
« Reply #1 on: January 20, 2015, 04:32:09 AM »
Hi,

Since you didn't paste the full code I can't be sure you called things in the correct order.  The first thing I note is that you don't need to install 'call.answered' since you are sending it from the script.

Also, there is a basic example in share/scripts/playrec.php in yate's sources that starts exactly as you need so check it out.

jamie

  • Newbie
  • *
  • Posts: 38
    • View Profile
Re: Problems with call.answered ( Windows - Global Script )
« Reply #2 on: January 20, 2015, 07:17:52 PM »

Hi Monica,

Thanks for the reply & sorry for not posting all the code.

I've actually been using the sample scripts for help, but unfortunately as far as i understand, Windows can't use the external script routing method.

Example:

^NNN$=external/nodata/playrec.php

... so I've been attempting to use global scripts instead, but with inspiration from the sample scripts.


as you suggested i went back to the playrec.php script and extracted what I think is the relavent parts to get me going.


Pasted below is what was created:


Code: [Select]
// Start YATE
Yate::Init(true, "localhost", 5039, "");

$eventCtr = 0;

Yate::Debug(true);
Yate::Output(true);


Yate::Install("call.route", 80 );
Yate::Install("call.execute", 70  );  // Added because we dont get the call.execute event without it

Yate::Install("chan.notify"  );


$ourcallid = "";
$chl_id    = "";




/* The main loop. We pick events and handle them */

for (;;) {


$ev=Yate::GetEvent();

// To help see all events
if ( $ev && $ev->name != 'engine.timer' && $ev->type !== 'installed' && $ev->type !== 'watched'   )
{
Yate::Debug( '   E -------------------> ' . $ev->type . ' -> ' . $ev->name );
};




/* If Yate disconnected us then exit cleanly */
if ($ev === false)
break;
/* Empty events are normal in non-blocking operation.
   This is an opportunity to do idle tasks and check timers */
if ($ev === true) {

Yate::Output("PHP event: empty");
continue;
}


// Handling Functions


/* If we reached here we should have a valid object */
switch ($ev->type) {

case "incoming":




if ( $ev && $ev->name == "call.route"  )
{


if ( $ev->getValue("called") == '600' ) {

Yate::Debug( 'Route Called ' . $ev->getValue("called") );

$chl_id = NULL;
$ourcallid   = "playtest/" . uniqid(rand(),1);

// Not sure about this, it's all I can do to get it to start.

//$ev->retval = "tone/noise";
$ev->retval = "dumb/";
$ev->handled = true;
$ev->Acknowledge();   
$ev = false;


}


}





if ( $ev && $ev->name == "call.execute"  )
{

Yate::Debug( 'Execute ' . $ev->params["id"] );

$chl_id = $ev->params["id"];

$ev->params["targetid"] = $ourcallid;
$ev->handled = true;
// we must ACK this message before dispatching a call.answered
$ev->Acknowledge();
// we already ACKed this message
$ev = false;


        $m = new Yate("call.answered");
$m->params["id"] = $ourcallid;
$m->params["targetid"] = $chl_id;
$m->Dispatch();



$m = new Yate("chan.attach");
$m->params["source"] = "wave/play/C:/Program Files/Yate/share/sounds/test.wav";
$m->Dispatch();


// Resulted in the error
//<WARN> Wave source 'C:/Program Files/Yate/share/sounds/test.wav' attach request with no data channel!




}







if ( $ev  )
{
$ev->Acknowledge();
};


break;
case "answer":
Yate::Output("PHP Answered -: " . $ev->name . " time: " . microtime(true) );

break;
case "installed":
Yate::Output("PHP Installed: " . $ev->name . " time: " . microtime(true) );
break;
case "uninstalled":
Yate::Output("PHP Uninstalled: " . $ev->name . " time: " . microtime(true) );
break;
case "setlocal":
Yate::Output("PHP Parameter: ". $ev->name . "=" . $ev->retval . ($ev->handled ? " (OK)" : " (error)")  . " time: " . microtime(true)  );
break;
default:
( $ev->type != 'empty' ? Yate::Output("PHP Event: " . $ev->type . " time: " . microtime(true) ) : NULL );




}
}

Yate::Output("PHP: bye!");



However, this kept giving me an error:

<WARN> Wave source 'C:/Program Files/Yate/share/sounds/test.wav' attach request with no data channel!

      
So .... I did a bit of Googling and found a previous question that was almost the same query as mine.

http://permalink.gmane.org/gmane.comp.telephony.yate/6182


Here, you suggested replacing chan.attach with a chan.masquerade and chan.attach, for example:

Code: [Select]
$m = new Yate("chan.masquerade");
$m->params["message"] = "chan.attach";
$m->params["source"] = "wave/play/C:/Program Files/Yate/share/sounds/test.wav";
$m->params["id"] = $peerid;
$m->params["notify"] = $chl_id;




( This was initially inserted in place of the chan.attach code above )

But sadly I couldn't get this to work as $peerid of the other channel wasn't available to catch yet. ie it's wasn't in 'call.execute'



So, what i came up with was the following: ( this replaces the $ev->type 'incoming' above )

Which works, but I'm not so happy with chan.connected being the best way to detect when a call is 'answered' and ready to play prompts etc etc !

Sorry, for the long post, but please could you help point me in the right direction ?
Thank you!


Code: [Select]


if ( $ev && $ev->name == "chan.connected" && $ev->params["module"] == 'sip'  )
{

$peer_id = $ev->params["peerid"];

$m = new Yate("chan.masquerade");
$m->params["message"] = "chan.attach";
//$m = new Yate("chan.attach");
$m->params["source"] = "wave/play/C:/Program Files/Yate/share/sounds/test.wav";
$m->params["id"] = $peer_id;
$m->params["notify"] = $ourcallid;
$m->Dispatch();
}



if ( $ev && $ev->name == "call.route"  )
{


if ( $ev->getValue("called") == '600' ) {

Yate::Debug( 'Route Called ' . $ev->getValue("called") );

$chl_id = NULL;
$ourcallid   = $ev->params["id"];

// Not sure about this, it's all I can do to get it to start.

$ev->retval = "tone/noise";
//$ev->retval = "dumb/";
$ev->handled = true;
$ev->Acknowledge();   
$ev = false;


   

}


}





if ( $ev && $ev->name == "call.execute"  )
{

Yate::Debug( 'Execute ' . $ev->params["id"] );


        $m = new Yate("call.answered");
$m->params["id"] = $chl_id;
$m->params["targetid"] = $chl_id;
$m->Dispatch();




}




Monica Tepelus

  • Administrator
  • Full Member
  • *****
  • Posts: 198
    • View Profile
Re: Problems with call.answered ( Windows - Global Script )
« Reply #3 on: January 26, 2015, 02:53:49 AM »
Hi Jamie,

Yes, the logic is different and more complex when trying to implement ivrs in a global script.
In Yate you can't have an unpaired channel for very long. So I suggest you route your call to a dumbchannel (http://docs.yate.ro/wiki/Dumbchan). You then send and receive messages on behalf on that dumbchan from your global script. In general when sending messages on behalf of someone else you use chan.masquerade (http://docs.yate.ro/wiki/Chan.masquerade).

Internally you will have the same flow of messages but you will interact differently with them. We don't have php examples with dumbchannel but you can follow the YAYPM ones where dumbchan is used (http://docs.yate.ro/wiki/index.php?search=yaypm&go=Go&title=Special%3ASearch)

Good luck :)

jamie

  • Newbie
  • *
  • Posts: 38
    • View Profile
Re: Problems with call.answered ( Windows - Global Script )
« Reply #4 on: February 01, 2015, 12:53:40 PM »

Thanks Monica !