Need to playback() a file as soon as the call is ANSWERED.
Page 1 of 2

Author:  cygar [ Mon Jan 28, 2008 2:23 pm ]
Post subject:  Need to playback() a file as soon as the call is ANSWERED.


Even if I can see this is the dev a2billing list I am doing a couple of modifications to a2billing that I need and maybe you can help me out on this.

What I need to solve is this: When receiving a call from some already known ( and listed in a MySQL table ) I need , after the call is completed, to playback() an audio message to the called party "B".

So far I have already modifified Class.A2Billing.php and after getting the CALLERID I make a select query to match it to the table. So far so good.

Now, I need to find out how to play that audio just to the called party after the call has been performed:

I found in Class.RateEngine.php the function rate_engine_performcall() that looks to me that is the function that sends the Dial().

$myres = $agi->exec("Dial $dialstr");
//exec('Dial', trim("$type/$identifier|$timeout|$options|$url", '|'));
$A2B -> write_log("DIAL $dialstr");
if ($A2B -> agiconfig['record_call'] == 1){
// Monitor(wav,kiki,m)
$myres = $agi->exec("STOPMONITOR");
$A2B -> write_log("EXEC StopMonitor (".$A2B->uniqueid."-".$A2B->cardnumber.")");

// My modification.

$lala='si'; // I just force $lala='si' to test it
if($lala == 'si'){
$A2B->write_log("I wanna play pacific.gsm from rate_engine_performcall()! as soon as the call is answered ");
$agi-> stream_file($prompt, '#');

I can see the write_log() being written BUT the audio is not played when I need it. My question is.... how can I play an audio meanwhile the call is connected? It looks to me that it's a blocking function and it does not allow me to play() an audio until the call is finished.

If you can help me with this or just point me out where should I look or any help will be highly appreciated. I will upload the src code of my modifications in case of someone needs to make something similar.


Author:  asiby [ Mon Jan 28, 2008 4:28 pm ]
Post subject: 

Ship should be verify simple. I believe that it can be done with very little change in the php code.

Here is how I believe you can do it.

Look closely at the dial command parameters . On of them is G as in Goto

G(context^exten^pri): If the call is answered, transfer both parties to the specified context and extension. The calling party is transferred to priority x, and the called party to priority x+1. This allows the dialplan to distinguish between the calling and called legs of the call (new in v1.2).

You can create the appropriate context in extensions.conf and give it a try. Let's suppose that the context is:

exten => s,1,Noop(do something for the caller here. e.g. Play a sound)
exten => s,n,Noop(do something for the called party here. e.g. Play a sound file)

Then, in a2billing.conf, modify the dialcommand_param option.

dialcommand_param = "|60|HRgrL(%timeout%:61000:30000)G(nice_prompt^s^1)"

You will find more information about the Dial command on here

Author:  cygar [ Mon Jan 28, 2008 7:17 pm ]
Post subject: 

Thanks a lot for that. That will help me a lot.

But as I said, I am doing a couple of SELECT to a new table I created in order to match those CALLERIDs , since I need to do that PlayBack() to the called party ONLY when the call is being originated from any of the CallerIDs that are listed on my table.

The select and the match is being done in a2billing.php with success, how could I pass a value to the dialplan ( to implement what you told me ) if I do my matching through a2billing.php ?

Thanks !

Author:  asiby [ Tue Jan 29, 2008 4:11 pm ]
Post subject: 

Hello Cygar,

Please, you have to dismiss my last statements. I stumbled upon another option of the Dial command that does exactly what you are trying to achieve. It is the "A" option.

A(x): Play an announcement (x.gsm) to the called party.

No need to create a special extension in extensions.conf

I asked how to prevent the announcement from being play if the user is not found in your custom table. Depending on how your current code is and where it is located in A2Billing, you can use a variable for the A(x) announcement sound file name. You will then need to set that variable to the name of a silent sound file (example: "silence/1") if the calledid is not found or to the real announcement file (example: annoucement) if the callerid is found.

So basically, an announcement will be always played but not always heard.


Author:  krzykat [ Tue Jan 29, 2008 6:22 pm ]
Post subject: 

Hate to say it, but I still have a 1.2.3 box out there that I haven't been able to upgrade to yellowjacket yet. Could I use this command to play a voice file on callbacks such as "Your call is being connected" instead of the dead air that the default 1.2.3 does ?

Author:  asiby [ Tue Jan 29, 2008 6:49 pm ]
Post subject: 

Possible. But I think that the announcement will be played to the called party only. The caller will not here anything. cygar can give some feedback about that.

Author:  cygar [ Thu Jan 31, 2008 1:37 pm ]
Post subject: 

Hello !
Finally my modification is working properly ! :)

I will try to explain the reason why I needed this, basically it's because of a regulation in my country that tells you "every call originated from jail has to warn the called party that is coming from prision".

So what I did was create a new table:

mysql> describe Anis;
| Field | Type | Null | Key | Default | Extra |
| ani | varchar(100) | | PRI | | |
| tipo | varchar(50) | YES | | NULL | |
| recargo | varchar(10) | YES | | NULL | |

That will help me in the future for other stuff, in this case ani is the callerid from all the jails, "tipo" would be "type" in this case "carcel" [ jail in spanish ], and "recargo" would be charge [I will use it then for other purpose ].

Then what I did as asiby recommend me was to use the A(audio_file) in the Dial inside of /etc/asterisk/a2billing.conf:


Then in Class.A2Billing.php inside of the function callingcard_ivr_authenticate() I added the following code:

$carcel = 'silence/1';
$this->escarcel = $carcel;
$ani = $this->CallerID;
$QUERYMAT = "SELECT ani FROM Anis where ani='".$ani."' AND tipo='carcel'";
if ($this->agiconfig['debug']>=1) $agi->verbose($QUERYMAT);
$matresult = $this->instance_table -> SQLExec ($this->DBHandle, $QUERYMAT);
if ($this->agiconfig['debug']>=1) $agi->verbose($result);

if($matresult != 0){ // viene de una carcel
$carcel = 'warn_jail_audio';
$this->write_log("WARNING: $ani is coming from prision!!!");


I defined the var $escarcel in the Class A2Billing to be able to read it from Class.RateEngine.php where I added this code:

// Added by Matias Rollan to replace %carcel% in /etc/asterisk/a2billing.conf to either the warn_jail_audio or just a silence
$pepe = $A2B->escarcel;
$A2B -> write_log("MATIAS PEPE: escarcel $pepe");
$dialparams = str_replace("%carcel%", $pepe, $dialparams);

I hope this all helps, if you are interested in the code I will post it in:

Matias Rollan

Author:  krzykat [ Thu Jan 31, 2008 2:37 pm ]
Post subject: 

Cool. Always like the followups on successful items.

Author:  areski [ Thu Jan 31, 2008 6:53 pm ]
Post subject: 

Hola Matias,
just wondering, you could not simply achieve this by using the additional parameter in trunk.
By creating a call-plan for the persons in prison that will outbound calls with the notification message you are willing to play !?

Rgds, Areski

Author:  cygar [ Thu Jan 31, 2008 7:01 pm ]
Post subject: 

Hola Areski!

Mh... I don't find a way . You mean passing the A(sound_file) to the "additional parameter" for the dial() function ?

I don't know what calling cards are going to be used from prission.

I just knows the CallerIDs ( ANIs ) from jail. I don't find a way of how to make the relationship between all those ANIs with different card numbers ( that I don't know ) if they are going to be used from inside of jail or not.

The modification is working properly even if my code is a little ugly :)

Saludos !

Matias Rollan

Author:  areski [ Thu Jan 31, 2008 9:20 pm ]
Post subject: 

Ok senior, entiendo bien !!!

As you said the code is not neat and it cannot be included until it gets to a good and logical structure... anyway we will think about something for the next version!

Cheers, Areski

Author:  cygar [ Wed Apr 02, 2008 3:04 pm ]
Post subject:  New modification using the new table Anis structure

Hello this is just to let you know (maybe is useful for someone) that I had to do the following:

- I had to record into the monitor some calls that were originated from some specific CallerIDs.

So I used the Anis table I had created for the jail stuff using the "tipo" (type) field with "grabar" (record) value on it.

And add the following code into Class.A2Billing.php below the code I had written for the previous patch:

$QUERY = "SELECT ani FROM Anis where ani='".$ani."' AND tipo='grabar'";

if ($this->agiconfig['debug']>=1) $agi->verbose($QUERY);
$result = $this->instance_table -> SQLExec ($this->DBHandle, $QUERY);
if ($this->agiconfig['debug']>=1) $agi->verbose($result);
$this->write_log("$QUERY = $result ");

if($result != 0){ // we have to record the call
$respuesta = $agi->exec("MONITOR wav"."|".$ani."-".$this->uniqueid."|mb");
$this->write_log("Recording the file $ani $this->uniqueid.wav....");

So now I can record the calls originated from any specific CallerIDs just doing an SQL INSERT into the Anis table with the specific CallerID and tipo="grabar".

Just wanted to share this with you.


Matias Rollan
<[email protected]>

Author:  cygar [ Mon Jan 26, 2009 7:19 pm ]
Post subject:  Play audio to the caller once connect has been established

Hello !

I am writing in the same thread that I opened nearly one year ago because what I have to do is very similar and based on the code I have written over a2billing for this same purpose.

This time based on the CallerID ( ANI ) I need to play a sound to the caller right after the call has been established and the callee has already picked up the phone.

I am using the same table Anis that I created for the jail patch but now with a different "tipo" field , not carcel but 'TonoA' .

Every call that is answered by A2Billing is checked in that databases to see if it matchs the CallerID. So far so good, this is working for me with the code below in Class.A2Billing.php inside of the function callingcard_ivr_authenticate() :

        $Q = "SELECT ani FROM Anis where ani='".$ani."' AND tipo='TonoA'";
         if ($this->agiconfig['debug']>=1) $agi->verbose($Q);
         $resultadoa = $this->instance_table -> SQLExec($this->DBHandle, $Q);
         if ($this->agiconfig['debug']>=1) $agi->verbose($result);
         $this->write_log("The query result for TonoA {$Q}:  is $resultadoa");

         if($resultadoa != 0){
            $this->write_log("Play()ing TonoA....");
            $agi->exec('Playback', 'welcome');


So far so good BUT I am playing the audio before the call is established. I understand that this modification should not be in the ivr_authentication function since this is a previous step for the call to be established ( here is where the PIN number is validated, etc,etc ) but I would like to know if you guys find it somewhere in the code will be more suitable without too much code modification.

Also, as you can read in this thread I solved the original problem with an idea Asiby gave me of adding the A() parameter to the Dial() in a2billing.conf.

This would solve my problem if there's a parameter for Dial() that only plays the audio to the caller leg and not the callee leg as with A() parameter.

Any recommedantions would be appreciated!

Matias Rollan
[email protected] || [email protected]

Author:  asiby [ Tue Jan 27, 2009 8:59 pm ]
Post subject: 

I am not aware of such command. But I do know that if you use the normal playback command, the caller will here it. That is how a2billing is playing the account balance, and other prompts. Why are you trying to play the audio after establishing the call? If the audio is for the caller, is it really that important to play it after establishing the connection? If you really need to do that and nothing else, then use the G() option that I gave you earlier. That will send the caller party and called party to a certain context as soon as the line will be answered and you will be able to do whatever you want. The only thing is that I don't know if A2Billing will be able to keep track of the billing.


Author:  cygar [ Thu Jan 29, 2009 2:04 pm ]
Post subject:  Dial() being a blocking function?

Hi !

I started the modification this way since I didn't want ot change the Dial() again going to different contexts as Asiby recommends in the previous thread.

I implemented it the way below my writing but I am still having a problem.

It looks like when the Connect ( I am sorry if I speak more an H323 languange than a SIP but I am still more used to H323 than SIP) after the Dial() is done, the function is blocking... and I can not play the audio.

The way I wrote it its not playing the audio BUT if I try to play the audio the same way I do it in Class.RateEngine a couple of lines before the dial ( in the Alerting... or RINGing ) it works well.

My problem is that I need to play that audio JUST when the call has been answered. Any recommendation on how to play an audio in this Dial() function that looks to be blocking ?

In Class.A2Billing
// Patch to play an A Tono when matching the following CallerIDs
$Q = "SELECT ani FROM Anis where ani='".$ani."' AND tipo='TonoA'";
if ($this->agiconfig['debug']>=1) $agi->verbose($Q);
$resultadoa = $this->instance_table -> SQLExec ($this->DBHandle, $Q);
if ($this->agiconfig['debug']>=1) $agi->verbose($result);

if($resultadoa != 0){
  $this->write_log("Play()ing TonoA.");
  // This var $esTonoA is used to be read from Class.RateEngine

In ClassRateEngine :


//# Ooh, something actually happend!
if ($this->dialstatus  == "BUSY") {
  $agi-> stream_file('prepaid-isbusy', '#');
} elseif ($this->dialstatus == "NOANSWER") {
   $agi-> stream_file('prepaid-noanswer', '#');
} elseif ($this->dialstatus == "CANCEL") {
} elseif ($this->dialstatus == "ANSWER") {
    // Patch TonoA not working after the Dial() it looks like its blocking
    if($mattonoa == 'si'){
       $A2B->write_log("Playing TonoA , var mattonoa =$mattonoa");
       $agi-> stream_file('welcome', '#');
     // Till here... Its not playing the welcome.gsm sound file
if ($A2B->agiconfig['debug']>=1)
   $agi->verbose("-> dialstatus : ".$this->dialstatus.", answered time is ".$this->answeredtime." \n");


Matias Rollan

Page 1 of 2 All times are UTC
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group