Putting ${} variables into custom extension dialing

I’m trying to set up a scenario where I:
Have an existing SIP call.
When this caller presses a particular choice on an IVR, I want to route that call out a SIP trunk (which is a custom extension).

When I create a custom extension using FreePBX 2.4.0, I can put things like:
SIP/1234@OtherSipBox

into my “Device Options->This device uses custom technology. dial” rule with no problem.

However, the SIP box on the other end of this trunk really wants to gather its DID from the extension dialed. Therefore, I want my “Device Options->This device uses custom technology. dial” rule to look like:
SIP/${EXTEN}@OtherSipTrunk
or
SIP/${DIALEDPEERNAME}@OtherSipTrunk

or similar scenarios, where I could put in the typical Asterisk dialplan variable and have it resolved and dialed. When I put this into my extension, test it, and dial the appropriate condition in the IVR, Asterisk properly sends the call down the trunk, but seems to literally dial the ${} macro variable name. It seems FreePBX is quoting it and passing it to Asterisk?

Asterisk says:
– Executing [s@macro-dial:7] Dial(“SIP/172.16.3.75-08217f48”, “SIP/7${SIP_HEADER(TO)}@OtherSipTrunk||tr”) in new stack
– Called 7${SIP_HEADER(TO)}@OtherSipTrunk
– Got SIP response 400 “Bad Request - ‘Malformed/Missing URL’” back from 172.16.3.75
– SIP/VoIPGW-08275850 is circuit-busy
== Everyone is busy/congested at this time (1:0/1/0)
In this scenario, 172.16.3.75 is getting a request to dial a non-number and it doesn’t know how to do that.

Is there a quick trick to make FreePBX/Asterisk let me put dialplan variables directly into my dial rule, or do I have to do that with a custom context? Or perhaps I can do it with a custom trunk?

I did some more poking around, and I discovered that in my
/etc/asterisk/extensions_additional.conf (generated by FreePBX)

there is an internal variable called FROM_DID.

I also discovered that if I hack up
/var/lib/asterisk/agi-bin/dialparties.agi (generated by FreePBX)

I can do something hacky, like:

$SIPSIPSIP = get_var( $AGI, “SIP_HEADER(TO)” );
$SIPSTRIP = substr( $SIPSIPSIP, strpos($SIPSIPSIP,’:’)+1,3);
debug(“SIPSIPSIP”,1);
debug(${SIPSIPSIP},1);
debug(“SIPSTRIP”,1);
debug(${SIPSTRIP},1);

And this will give me EXACTLY what I want, which is my DNID info on the SIP call in my system, and then I could hack up the return value for $ds at the end of
/var/lib/asterisk/agi-bin/dialparties.agi

Of course, if you want your changes to /var/lib/asterisk/agi-bin/dialparties.agi to survive a reload of FreePBX, you’ll instead need to put those changes elsewhere, or change the file to read only.

So now that I know the hacky work-around, my question still stands about whether there’s a legal way to put dialplan variables into the FreePBX custom extensions front-end. The answer seems to be a resounding no after I read through the code that’s processing it. Any opinions?

I managed to get FreePBX to do what I wanted.
Question 1) Is there a better way to do what I’m doing?
Question 2) Does anybody want this code, or is this a feature other FreePBX users might want?

Previously, custom extensions could only be defined to static destinations, aka: SIP/1234@SipTrunk1
This code permits using ${} values predefined elsewhere within Asterisk.
In my particular instance, I’m using SIP, and I wasn’t successful getting DNIS except to do my own hack. If somebody has a better way, PLEASE speak up. I made a new variable called HODNIS for this purpose and populate with just the bits I want.

My changes allow SIP/7${HODNIS}@SipTrunk1 to get dynamically remapped to the DID, dialed digits, DNIS, whatever you want to call it, which map to the particular call. For example, SIP/7236@SipTrunk1. In my situation, I have more than 100 unique DNIS settings inbound to my call center, and I need to push back out what I got in. It’s not practical to make more than 100 separate rules.

I edited WEBROOT/admin/modules/core/agi-bin/dialparties.agi, inserting the following at line 620, just before the export of the value $ds, aka dialstring.

            # begin David and Justin modifications
            $CUSTSIPTOHEADER = get_var( $AGI, "SIP_HEADER(TO)" );
            #CUSTSIPTOHEADER looks like <sip:[email protected]>
            if ( $isSipCall = strpos($CUSTSIPTOHEADER,"sip") ) {
                    $tmpDidString=${CUSTSIPTOHEADER};
                    # get position of @
                    $lastDidPosition=strpos($tmpDidString,'@');
                    # strip off @ and everything after
                    $tmpDidString=substr($tmpDidString,0,$lastDidPosition);
                    # strip off the beginning '<sip:'
                    $tmpDidString=substr($tmpDidString,5);
                    debug("tmpDidString is",1);
                    debug(${tmpDidString},1);
                    $AGI->set_variable('HODNIS',$tmpDidString);
            }

            if ( $isAstVariable = strpos($ds,'${') ) {
                    #Parse out Variables
                    $lastAstVariable=0;
                    $tmpAstVariable=$ds;
                    while($isAstVariable = strpos($tmpAstVariable,'${',$lastAstVariable)) {
                            # Find the end of the variable
                            $tmpAstVariable=substr($tmpAstVariable,$isAstVariable+2);
                            $lastAstVariable=strpos($tmpAstVariable,'}');
                            $AstVariable=substr($tmpAstVariable,0,$lastAstVariable);
                            $AsteriskVars[]=$AstVariable;
                    }
                    # Get Variables and run SR
                    foreach ($AsteriskVars as $AstVar) {
                            $AstVarValue = get_var($AGI,$AstVar);
                            debug("Asterisk Var $AstVar => $AstVarValue",3);
                    }
                    # Finally, build the string
                    debug("original ds was",1);
                    debug(${ds},1);
                    $intBeginSub=strpos($ds,'${');
                    $intEndSub=strpos($ds,'}');
                    debug("intBeginSub",1);
                    debug(${intBeginSub},1);
                    debug("intEndSub",1);
                    debug(${intEndSub},1);
                    $tempDs=substr($ds,0,$intBeginSub);
                    debug(${tempDs},1);
                    foreach ($AsteriskVars as $AstVar) {
                            $AstVarValue = get_var($AGI,$AstVar);
                            $tempDs=$tempDs . $AstVarValue;
                            debug(${tempDs},1);
                    }
                    #add back rest of extension string
                    $tempDs=$tempDs . substr($ds,$intEndSub+1,strlen($ds));
                    debug(${tempDs},1);
                    $ds=${tempDs};
            }
          # end David and Justin changes

Thanks to FreePBX for providing a tool that got me 95% of what I needed, and hopefully this will help somebody else!

1 Like

The forum auto-sanitized some comments that help people understand what the code is doing.
The SIP TO header is formatted as:
less-than (open tag), the word sip, the colon character, the digits dialed, the at symbol, the ip address of the destination, greater-than (close tag). This was explicitly written in a sanitized comment earlier in the code.

Hi,

Did you find a better way to do this other than the hack into dialparties.agi?

I need to do something similar for an OOH323 connection to an Avaya Modular Messaging system. I have the H323 trunks running & I can dial the MM directly. However, I want to be able to forward calls to it & carry the original dialled number. I set up a custom extension using a custom dial string:

OOH323/${SOMEVARIABLE}@IP_ADDRESS_OF_MM

I need the ‘SomeVariable’ to contain the original dialled extension number that is being forwarded & have tried several of the available system ones - DNID, DIALLEDPEERNUMBER, EXTEN etc but it always leaves a blank. If I put in a physical number, it works fine, but it will not always be the same number, so that doesn’t help.

I saw your post & tried to insert your code into the dialedparties.agi, but I think the file has changed since you wrote this. I could not find an export of the $ds variable around 620, so I put the code near the end, just before the final $ds sanity check. However, that does not seem to work when I use the ${HODNIS} variable in my custom extension.

System - Fresh install of Free PBX 2.5.1 on Centos 5.3 in VMware WS 6.5