Hello Everyone! I’m excited to say I got my hands on an unofficial “SigMa Cookbook” from a buddy of mine at Avaya. This was put together by some engineers at Sipera. This was passed around within Avaya and maybe some customers, but I don’t think it was officially released.
These recipes were put together in 2010 and 2011 for “generic release 4.0.4 Q102 or later”. I do not think there’s official support for this. It was an internal document and was always sent with various warnings about “your mileage will vary”. So you have been warned! If you find any errors and clean up some of these, please let me know and I’ll fix them here.
I have formatted it as HTML for easy searching. I do not know if the engineers want me to include their names. If any of you are from Avaya or Sipera and want attribution for these recipes, please let me know and I’m happy to do it!
And also let me know if you have any good examples we should add. There’s not much of a user community for these SBCs so let’s help each other!
Example 1: P-Asserted-Identity (PAI) Header Manipulation
Use Case:
The P-Asserted-Identity header field can be used to present the identity of the originator of a request within a trusted network. Since the “From” header field is populated by the originating User-Agent it may not contain the actual identity. It usually is established by means of authentication between the originating User-Agent and its outgoing proxy. The outgoing proxy then adds a P-Asserted-Identity header field to assert the identity of the originator to other proxies.
- If there is no P-Asserted-Identity header field present, a proxy MAY add one containing at most one SIP or SIPS URI, and at most one tel URL.
- If the proxy received the message from an element that it does NOT trust and if there is a P-Asserted-Identity header present, the proxy MUST replace the SIP URI or remove it.
Script:
within session "ALL" { /* Looks into all the messages Message should be a request (act on request) and the messages coming towards the Uc-Sec should be considered, i.e. the destination of the message should be Uc-Sec ({0ed28e3470e974017c124b0897303dd14e34b5245564abb28916e7d48d9b07c0}DIRECTION="INBOUND"). The actions are invoked as soon as the message comes from the wire ({0ed28e3470e974017c124b0897303dd14e34b5245564abb28916e7d48d9b07c0}ENTRY_POINT="AFTER_NETWORK") */ act on request where {0ed28e3470e974017c124b0897303dd14e34b5245564abb28916e7d48d9b07c0}DIRECTION="INBOUND" and {0ed28e3470e974017c124b0897303dd14e34b5245564abb28916e7d48d9b07c0}ENTRY_POINT="AFTER_NETWORK" { /* Checks if the first P-Asserted-Identity header is present/exists in the message. Each header is represented as {0ed28e3470e974017c124b0897303dd14e34b5245564abb28916e7d48d9b07c0}HEADERS["<Header-name>"][<Header position>]. For headers such as From and Contact, the Header Position is always 1. For headers like Via and P-Asserted-Identity, the positions can range from 1 to n */ if(exists({0ed28e3470e974017c124b0897303dd14e34b5245564abb28916e7d48d9b07c0}HEADERS["p-asserted-identity"][1])) then { remove({0ed28e3470e974017c124b0897303dd14e34b5245564abb28916e7d48d9b07c0}HEADERS["p-asserted-identity"][1]); //Remove the header } else { /* If the P-Asserted-Identity header is not found in the message Add a SIP and a telephone URI. */ {0ed28e3470e974017c124b0897303dd14e34b5245564abb28916e7d48d9b07c0}HEADERS["p-asserted-identity"][1] = "12345<sip:12345@192.168.150.150>"; {0ed28e3470e974017c124b0897303dd14e34b5245564abb28916e7d48d9b07c0}HEADERS["p-asserted-identity"][2] = "tel:+14085554000"; } } }
Additional Description:
The script looks into each message that comes in (since the script acts on all sessions) and checks if
- It is a request message
- The message is inbound towards the Uc-Sec
If both the above conditions are successful, as soon as the message comes from the wire, (and after the basic sanity checks and DoS checks are performed on the message), the action is performed. The script checks to see if a “P-Asserted-Identity” header exists. If it does, it removes it, else it adds the header.
Limitations:
If you would like to remove all the P-Asserted-Identity headers, it is assumed that you know the maximum number of headers that would be present in the messages. You do not need to know the exact number of headers that come in because if you perform an operation on a header that does not exist, it is simply ignored.
Note:
If {0ed28e3470e974017c124b0897303dd14e34b5245564abb28916e7d48d9b07c0}HEADERS[“<Header-Name>”][<Header Position>] is already present, then the operation
{0ed28e3470e974017c124b0897303dd14e34b5245564abb28916e7d48d9b07c0}HEADERS["<Header-Name>"][<Header Position>] = <Val>
will modify the header. If it is not present in the message,
{0ed28e3470e974017c124b0897303dd14e34b5245564abb28916e7d48d9b07c0}HEADERS["<Header-Name>"][<Header Position>] = <Val>
will add the header to the message.
Example 2: Addition of a media attribute in SDP
Use Case:
It might be required to add/modify SDP attributes or connection parameters for interoperability.
Script:
within session "INVITE" { /* Looks into messages in the INVITE session only (It includes all messages in the INVITE dialog) */ act on request where {0ed28e3470e974017c124b0897303dd14e34b5245564abb28916e7d48d9b07c0}DIRECTION="INBOUND" and {0ed28e3470e974017c124b0897303dd14e34b5245564abb28916e7d48d9b07c0}ENTRY_POINT="AFTER_NETWORK" { /* The "m=" field in SDP contains information about the type of media session. It includes the format-list parameter for specifying the codecs. Assuming that the message comes in with 2 codecs, we add a third codec as 101 */ {0ed28e3470e974017c124b0897303dd14e34b5245564abb28916e7d48d9b07c0}SDP[1]["s"]["m"][1].FORMATS[3]="101"; /* The "a=" field contains attributes to provide more information on the codecs. Assuming that the message does not have any fmtp attribute, we add the first one as 101 0-16 */ {0ed28e3470e974017c124b0897303dd14e34b5245564abb28916e7d48d9b07c0}SDP[1]["s"]["m"][1].ATTRIBUTES["fmtp"][1]="101 0-16"; } }
Additional Description:
The script looks into all the messages of the “INVITE” session. A session is defined as a SIP dialog and has the same lifetime as that of a dialog. A new format-type and an attribute is added corresponding to fmtp.
Limitations:
We would need to know the number of codecs (number of formats in format-list parameter and attributes), or we would end up replacing an existing format-type.
Example 3: Changing Privacy Header Value
Use Case:
Restricting Calling Party Presentation.
Script:
within session "ALL" { act on message where {0ed28e3470e974017c124b0897303dd14e34b5245564abb28916e7d48d9b07c0}DIRECTION="INBOUND" and {0ed28e3470e974017c124b0897303dd14e34b5245564abb28916e7d48d9b07c0}ENTRY_POINT="AFTER_NETWORK" { /* Checks if the privacy header value matches with the regular expression given (e.g. "none"). If it matches, then the privacy header value is changed to "id" */ if({0ed28e3470e974017c124b0897303dd14e34b5245564abb28916e7d48d9b07c0}HEADERS["Privacy"][1] = "none") then { {0ed28e3470e974017c124b0897303dd14e34b5245564abb28916e7d48d9b07c0}HEADERS["Privacy"][1] = "id"; } } }
Example 4 – Replace “From” header for a set of users
Use Case:
In an organization, there could be several phones used by the employees and each of them might have a unique “From URI” associated with them. It may be required that all calls going out from the organization have the same “From URI”. For this purpose, the following script can be used.
Script:
within session "INVITE" { /* For users whose Uri begins with the prefix 10, when the message comes towards the Uc-Sec, the Uri is changed to “9000”<sip:9000@domain>. So, when the receiver answers the call, the From is 9000. */ act on request where {0ed28e3470e974017c124b0897303dd14e34b5245564abb28916e7d48d9b07c0}DIRECTION="INBOUND" and {0ed28e3470e974017c124b0897303dd14e34b5245564abb28916e7d48d9b07c0}ENTRY_POINT="AFTER_NETWORK" { /* A Uri can be represented as "<diplay_name>"<scheme>:<user>@<host>:<port>, eg: "roger"<sip:roger@rogerthephoneguy.com:5060>. URI.USER extracts the user portion of the URI. regex_match tries to match the string against the regular expression. It is of the form <string>.regex_match("<regular expression>"). In this example, it is checked if the USER portion in the "From" Header starts with the prefix 10 */ if({0ed28e3470e974017c124b0897303dd14e34b5245564abb28916e7d48d9b07c0}HEADERS["From"][1].URI.USER.regex_match("^10")) then { /* The uri and display name of the actual user is stored in temporary variables */ {0ed28e3470e974017c124b0897303dd14e34b5245564abb28916e7d48d9b07c0}OriginalFromUri = {0ed28e3470e974017c124b0897303dd14e34b5245564abb28916e7d48d9b07c0}HEADERS["From"][1].URI.USER; {0ed28e3470e974017c124b0897303dd14e34b5245564abb28916e7d48d9b07c0}OriginalFromName = {0ed28e3470e974017c124b0897303dd14e34b5245564abb28916e7d48d9b07c0}HEADERS["From"][1].DISPLAY_NAME; /* The display name and uri is changed to the new values. */ {0ed28e3470e974017c124b0897303dd14e34b5245564abb28916e7d48d9b07c0}HEADERS["From"][1].DISPLAY_NAME = "9000"; {0ed28e3470e974017c124b0897303dd14e34b5245564abb28916e7d48d9b07c0}HEADERS["From"][1].URI.USER = "9000"; } } /* When the response comes back, we need to change the URI USER and DISPLAY NAME to the actual user. So,before the message is sent out to the wire from the Uc-Sec, it is checked if the URI.USER is 9000. If yes, then change it back to the original user's details. Message should be a response (act on response) and the messages going out from the Uc-Sec should be considered ({0ed28e3470e974017c124b0897303dd14e34b5245564abb28916e7d48d9b07c0}DIRECTION="INBOUND"). The actions are invoked before the message goes out ({0ed28e3470e974017c124b0897303dd14e34b5245564abb28916e7d48d9b07c0}ENTRY_POINT="BEFORE_NETWORK") */ act on response where {0ed28e3470e974017c124b0897303dd14e34b5245564abb28916e7d48d9b07c0}DIRECTION="OUTBOUND" and {0ed28e3470e974017c124b0897303dd14e34b5245564abb28916e7d48d9b07c0}ENTRY_POINT="BEFORE_NETWORK" { /* Check if the user portion of the From URI is 9000 */ if({0ed28e3470e974017c124b0897303dd14e34b5245564abb28916e7d48d9b07c0}HEADERS["From"][1].URI.USER = "9000") then { /* Change the URI.USER and display name to the original user’s details, which are saved in the temporary variables */ {0ed28e3470e974017c124b0897303dd14e34b5245564abb28916e7d48d9b07c0}HEADERS["From"][1].URI.USER = {0ed28e3470e974017c124b0897303dd14e34b5245564abb28916e7d48d9b07c0}OriginalFromUri; {0ed28e3470e974017c124b0897303dd14e34b5245564abb28916e7d48d9b07c0}HEADERS["From"][1].DISPLAY_NAME = {0ed28e3470e974017c124b0897303dd14e34b5245564abb28916e7d48d9b07c0}OriginalFromName; } } }
Additional Description:
The above example shows how to modify a message (request) on its way out and also modify a message (response) when it comes in.
Limitations:
The example illustrates the use of regex_match. The regular expression provided within the parentheses, i.e. regex_match(<regular expression>), can be any valid Perl regular expression. However, the “$” symbol (which typically anchors the match to the end of the pattern) cannot be used in the regular expression.
Example 5: Editing the “Allow” Header
Use Case:
The Allow header is used to indicate the methods supported by the user agent, e.g. “Allow: INVITE, ACK, BYE, INFO, OPTIONS, CANCEL”. The OPTIONS method is used to query a user agent or server about its capabilities and discover its current availability. The response to the request lists the capabilities of the user agent or server. This may not be desired (probably due to security reasons). In this case, the Uc-Sec can strip the OPTIONS method from the Allow header before sending out the message.
Script:
within session "INVITE" { /* Look for INVITE messages only. This is specified with the extra condition {0ed28e3470e974017c124b0897303dd14e34b5245564abb28916e7d48d9b07c0}METHOD="INVITE" in the where clause */ act on request where {0ed28e3470e974017c124b0897303dd14e34b5245564abb28916e7d48d9b07c0}DIRECTION="INBOUND" and {0ed28e3470e974017c124b0897303dd14e34b5245564abb28916e7d48d9b07c0}ENTRY_POINT="AFTER_NETWORK" and {0ed28e3470e974017c124b0897303dd14e34b5245564abb28916e7d48d9b07c0}METHOD="INVITE" { /* There could be (1) multiple methods in Allow or (2) OPTIONS could be the only method in Allow. If there are multiple methods in Allow, OPTIONS could be (1) in the beginning (2) in the middle, or (3) the end */ /* If OPTIONS is in the middle/end in Allow, it would be of the form Allow:<Methods>,OPTIONS,<More methods> or Allow:<Methods>,OPTIONS. So, we try to match Allow against the regex ",OPTIONS" */ /* Note from RogerThePhoneGuy - this example had ,OPTIONS in the comment but comma [space] OPTIONS in the regex below. You might want to check traces to see if there's a space between the comma and the word OPTIONS and make sure you match it in this script! */ if({0ed28e3470e974017c124b0897303dd14e34b5245564abb28916e7d48d9b07c0}HEADERS["Allow"][1].regex_match(",OPTIONS")) then { /* <string1>regex_replace("<regex1>","<string2>") looks for regex1(regular expression) in string1 and replaces it with string2(plain string). Here we replace ",OPTIONS" with an empty string, indirectly removing ",OPTIONS" */ {0ed28e3470e974017c124b0897303dd14e34b5245564abb28916e7d48d9b07c0}HEADERS["Allow"][1].regex_replace(",OPTIONS",""); /* Note from Roger: The original example had a space between the comma and the word OPTIONS but I think that is incorrect so I removed it for this example. I do not have an SBC at the moment though - please check your traces! /* } else { /* Nested if-else */ /* If OPTIONS is in the beginning in Allow, it would be of the form Allow: OPTIONS,<More methods>. So, we try to match Allow against the regex "OPTIONS," */ if({0ed28e3470e974017c124b0897303dd14e34b5245564abb28916e7d48d9b07c0}HEADERS["Allow"][1].regex_match(" OPTIONS,")) then { /* We replace OPTIONS, with an empty string, indirectly removing " OPTIONS," */ {0ed28e3470e974017c124b0897303dd14e34b5245564abb28916e7d48d9b07c0}HEADERS["Allow"][1].regex_replace(" OPTIONS,", ""); } else { /* If OPTIONS is the only method in Allow, it would be of the form Allow: OPTIONS. So, we try to match Allow against the regex " OPTIONS" */ if({0ed28e3470e974017c124b0897303dd14e34b5245564abb28916e7d48d9b07c0}HEADERS["Allow"][1].regex_match(" OPTIONS")) then { /* Since OPTIONS is the only method in Allow, we remove the entire header */ /* remove({0ed28e3470e974017c124b0897303dd14e34b5245564abb28916e7d48d9b07c0}HEADERS["<Header-name>"][<Posn>] removes the header specified in <Header-name> in Position <Posn>. Here we remove the Allow header */ remove({0ed28e3470e974017c124b0897303dd14e34b5245564abb28916e7d48d9b07c0}HEADERS["Allow"][1]); } } } } }
Additional Description:
The above script can come in handy while operating on headers such as Allow, Supported, Content-Type etc, whose values can’t be extracted individually as compared to headers like “From”, “To”, or “Contact”.
Limitations:
The regular expression in regex_replace can’t have the $ symbol.
Example 6: Prefix Stripping
Use Case:
Phone numbers may come in with a prefix. Sometimes this needs to be stripped off before the call is routed. This is useful in scenarios where a call transfer is made and the number to which the call has to be transferred is entered with a prefix.
Script:
within session "INVITE" { /* Look for REFER messages only. This is specified with the extra condition {0ed28e3470e974017c124b0897303dd14e34b5245564abb28916e7d48d9b07c0}METHOD="REFER" in the where clause */ act on request where {0ed28e3470e974017c124b0897303dd14e34b5245564abb28916e7d48d9b07c0}DIRECTION="INBOUND" and {0ed28e3470e974017c124b0897303dd14e34b5245564abb28916e7d48d9b07c0}ENTRY_POINT="AFTER_NETWORK" and {0ed28e3470e974017c124b0897303dd14e34b5245564abb28916e7d48d9b07c0}METHOD="REFER" { /* The User portion of the URI in the Refer-To header is checked to see if it starts with the prefix 011. If it does, then it is replaced with an empty string. If URI.USER does not match the regex, then the action is ignored and the message is left intact. */ {0ed28e3470e974017c124b0897303dd14e34b5245564abb28916e7d48d9b07c0}HEADERS["Refer-To"][1].URI.USER.regex_replace("^011",""); } }
Additional Description:
The messages which have the “Refer-To” method are checked if the URI contains a prefix. If so, it is stripped before sending it out.
Limitations:
The regular expression in regex_replace can’t have the $ symbol.
Example 7: Diversion Header Addition and phone context removal
Use Case:
The user may want the option to add a diversion header or manipulate the extension field or change the URI parameters in the header. This example also illustrates combining two functions such as addition of a diversion header only to the INVITE and the removal of phone-context from all outbound messages.
Script:
within session "ALL" //Looks into all the messages { act on message where {0ed28e3470e974017c124b0897303dd14e34b5245564abb28916e7d48d9b07c0}DIRECTION="OUTBOUND" and {0ed28e3470e974017c124b0897303dd14e34b5245564abb28916e7d48d9b07c0}ENTRY_POINT="POST_ROUTING" { /* Any message that is outbound from the UC-Sec is checked */ /* Remove phone-context from Request Line */ remove({0ed28e3470e974017c124b0897303dd14e34b5245564abb28916e7d48d9b07c0}HEADERS["Request_Line"][1].PARAMS["phone-context"]); /* Remove phone-context from the From header */ remove({0ed28e3470e974017c124b0897303dd14e34b5245564abb28916e7d48d9b07c0}HEADERS["From"][1].PARAMS["phone-context"]); /* Remove phone-context from the To header */ remove({0ed28e3470e974017c124b0897303dd14e34b5245564abb28916e7d48d9b07c0}HEADERS["To"][1].PARAMS["phone-context"]); if ({0ed28e3470e974017c124b0897303dd14e34b5245564abb28916e7d48d9b07c0}INITIAL_REQUEST = "true") then { /* Add a diversion header */ {0ed28e3470e974017c124b0897303dd14e34b5245564abb28916e7d48d9b07c0}HEADERS["Diversion"][1] = "sip:3145552375@rogerthephoneguy.com"; } } }
Example 8: Redirection
Use Case:
The user may require to populate the From header in the outbound INVITE message with the contents of the Diversion header in the incoming INVITE.
Script:
within session "ALL" { act on message where {0ed28e3470e974017c124b0897303dd14e34b5245564abb28916e7d48d9b07c0}DIRECTION="OUTBOUND" and {0ed28e3470e974017c124b0897303dd14e34b5245564abb28916e7d48d9b07c0}ENTRY_POINT="POST_ROUTING" and {0ed28e3470e974017c124b0897303dd14e34b5245564abb28916e7d48d9b07c0}METHOD="INVITE" { /* Store the contents of diversion header URI */ {0ed28e3470e974017c124b0897303dd14e34b5245564abb28916e7d48d9b07c0}Div = {0ed28e3470e974017c124b0897303dd14e34b5245564abb28916e7d48d9b07c0}HEADERS["Diversion"][1].URI; /* Replace the contents of From header with stored value */ {0ed28e3470e974017c124b0897303dd14e34b5245564abb28916e7d48d9b07c0}HEADERS["From"][1].URI = {0ed28e3470e974017c124b0897303dd14e34b5245564abb28916e7d48d9b07c0}Div; } }
Example 9: Invite XML Body Manipulation
Use Case:
The user may require manipulation of the contents of the xml body present in the INVITE message.
Script:
within session "INVITE" { act on request where {0ed28e3470e974017c124b0897303dd14e34b5245564abb28916e7d48d9b07c0}DIRECTION="OUTBOUND" and {0ed28e3470e974017c124b0897303dd14e34b5245564abb28916e7d48d9b07c0}ENTRY_POINT="POST_ROUTING" { /* Check the body for the regex value */ if({0ed28e3470e974017c124b0897303dd14e34b5245564abb28916e7d48d9b07c0}BODY[1].regex_match("sip:2911@192.168.3.150")) then { /* Replace the matching string with sip:anonymous@anonymous.com */ {0ed28e3470e974017c124b0897303dd14e34b5245564abb28916e7d48d9b07c0}BODY[1].regex_replace("sip:2911@192.168.3.150","sip:anonymous@anonymous.com"); } } }
Example 10: Switching From and To tags
Use Case:
The user may require to switch tags on the From and To in a particular message. The following example illustrates tag switching in the 200 OK message.
Script:
within session "REGISTER" { act on response where {0ed28e3470e974017c124b0897303dd14e34b5245564abb28916e7d48d9b07c0}DIRECTION="INBOUND" and {0ed28e3470e974017c124b0897303dd14e34b5245564abb28916e7d48d9b07c0}ENTRY_POINT="AFTER_NETWORK" and {0ed28e3470e974017c124b0897303dd14e34b5245564abb28916e7d48d9b07c0}RESP_CODE="200" { {0ed28e3470e974017c124b0897303dd14e34b5245564abb28916e7d48d9b07c0}from = {0ed28e3470e974017c124b0897303dd14e34b5245564abb28916e7d48d9b07c0}HEADERS["From"][1].PARAMS["tag"]; {0ed28e3470e974017c124b0897303dd14e34b5245564abb28916e7d48d9b07c0}HEADERS["From"][1].PARAMS["tag"] = {0ed28e3470e974017c124b0897303dd14e34b5245564abb28916e7d48d9b07c0}HEADERS["To"][1].PARAMS["tag"]; {0ed28e3470e974017c124b0897303dd14e34b5245564abb28916e7d48d9b07c0}HEADERS["To"][1].PARAMS["tag"] = {0ed28e3470e974017c124b0897303dd14e34b5245564abb28916e7d48d9b07c0}from; } }
Note from Roger: Does anyone know why you’d want to swap the from and to? This was the 10th example in the doc but I cannot think of why this would be useful.
Hi Rogger,
You have done a great work, wish you all the best for your future.
I’m looking for queue timmer/ Min-SE timer sigma script for Avaya SBCE for incoming and out going calls with service provider sip trunk.
Can you help me in this.
Thanks & Regards,
Hey Farhan – Sorry I’m so late responding. Did you get this working?
Hi!
Thanks for a great website! I also find it difficult to get some help with SIGMA-scripts, there are som examples built in SBC, but it often end up with lots of googleing.
I have a situation where with mobile extension. Normally a call looks like this:
The user, we can call her Sally, belonging to company A is doing a call to ramdom guy via her cellphone. The operator routes that traffice to the custumers siptrunk and from now n its my resposibility :-).
The call is going to Avaya SBC -> session Manager -> CM. CM matches the off-pbx of Sallys cellphone to her extension in CM and then CM is route the call via SM – SBC and out to that random guy. The random guy sees in his display the Sallys company nr.
Sometimes, more and more often nowadays the user want to show their mobilenumber instead of companynumber and thats a problem that I want to solve.
Sallys first call leg, that one that is going in to SBC comes with a prefix before her from nr. So my thinking is to copy that cellphonenumber to a new field in SBC, just so its stored. Lets call that field XMEX
Then in CM put the off-pbx in a different location -> different ARS -> and in routepattern add a prefix, lets say *82.
When SBC see that a call has *82 in from, it replaces *82 with the values that it stored in XMEX
But I´m not a guru in regular expression so thats why I contact you 🙂 How will my sigmascripts look like in both the incoming part and the outgoing part?
Have a nice weekend!
Regards Tobias Davidsson
Hi Tobias- sorry for the delay getting back to you.
Is Sally ever at her desk? You could simply change the callerid of her extension to match her cell phone in public unknown numbering.
If the call comes into the SBC with a prefix, how is the CM matching it to her extension? You could remove the “1” in the off-station mapping and put it in the dialed string. This will “break” that matching so it will just use her mobile number.
Hi Roger,
This is great info so thank you ! I have a question though, I am very new to this so trying to understand where these sigma scripts get placed. Is it in Server Configuration under advanced tab or under device specific settings, end point flows. We are having trouble sending a toll free number in the public Numbering and dialing an outbound toll free. We have AT&T SIP trunks. I would like to put a sigma script in to resolve that but not sure which location it should go in.
Ugh! I know what you mean! Actually, we fixed this issue on a Cisco site by adding a “Diversion” header to every call. When AT&T would normally reject it, the diversion header can be used to provide a billing telephone number and AT&T will still allow the call. Did you want me to find that doc and post about it?
Roger
Greetings, Roger. Great information here. I am wondering if it is possible to use the SBC to add a prefix to the From header. The carrier sends the call with the From header as a 10-digit number, but we need to add a +1 prefix. Normally I would do this via the Session Manager, but the client is utilizing a 3rd-party call filtering provider. The inbound call comes in to the SBC from the carrier, gets sent over to the 3rd party as the first next-hop in the SIP server route. If it’s a number that needs to be filtered, it gets dropped. If it’s a good number, it gets sent back to the SBC and the SBC tries the priority 2 next-hop. The 3rd-party provider is expecting the calls to come in with a +1 prefix. Is there a way to add this in the SBC?
Sorry for the delay. Did you get this working? It seems pretty straightforward. I’m happy to share the script here if you’d like others to benefit from your work.
Thanks!
Roger
Roger,
For those looking for a bit more insight into SigMa Scripting, the following white paper might be helpful:
Google for “Super Sigma Scripting”,
or download it for free (no strings attached) from this URL:
https://www.convergeone.com/avaya-super-sigma-scripting
Roger, your contributions to understanding Avaya products are impressive and highly respected. Thank you, very, very, very, much.
Thank you John!
Hi, i have a question regarding Sigma script and below is my query.
We’re using an ELIN server in ASM. This server tracks SIP devices as they move around the environment and assigns an ELIN from a pool of numbers to the phones.
ELIN – Emergency Response Location – is a telephone number tied to a physical address. The 911 operators look this number up to locate the caller’s location / address during emergency calls
When a SIP user calls 911, ASM inserts this ELIN number into the AP-Loc header.
Then:
1. If the call routes via CM / ISDN PRI, the AP-Loc header is converted into the Calling Party Number automatically.
2. If the call routes via SIP Trunk / ASBCE, the AP-Loc header is sent to the carrier and Calling Party Number is not changed.
This AP-Loc: elin=xxxxxxxxxx number will change based on a user’s location. What I’m trying to achieve here is to make the ASBCE act like the call over CM / ISDN PRI and copy the 10-Digit number contained in the AP-Loc header and make that the Calling Party Number.
This header is only sent for emergency calls.
##########################################################################################
within session “INVITE”
{
act on request where %DIRECTION=”OUTBOUND” and %ENTRY_POINT=”POST_ROUTING”
{
%HEADERS[“From”][1] = %HEADERS[“AP-Loc”][1];
}
}
##########################################################################################
but this is not working as expected, any thoughts would be appreciated.
Hi Abdul! I guess I would start with “is this script getting called?” and try to set a debug header within it, like %HEADERS[“debug-message”][1] = “Roger was here”;
Are you positive you are getting an AP-Loc header? You could try to set it to a known header like %HEADERS[“debug-message”][1] = %HEADERS[“From”][1]
You could also try to set a variable first, and then set the header from that, like
%aploc = %HEADERS[“AP-Loc”][1]
%HEADERS[“From”][1] = %aploc
I wish SigMa had better debugging. There’s a log function, but I never figured out where that is written. Good luck! When you figure it out, please post the solution here so we can all celebrate your success.
Roger
Hi Roger, Thanks for your reply, i will try your suggestion and let you know the outcome of it. Also, i am not sure about the log’s function, but i will dig into it and sure, will share it.
Is it necessary to learn regex and any basic programming knowledge to play with sigma scripting as i was curious to know, as i am bad in programming.
Also, can you please explain a little bit more about log function, such that it will easy to get the required info about it.
I found two admin guides in my archives that discuss SigMa. I think both chapters are the same actually. Here are the links:
http://rogerthephoneguy.com/wp-content/uploads/2021/06/Administering_Avaya_SBC_08-064063.pdf
http://rogerthephoneguy.com/wp-content/uploads/2021/06/E-SBC_Admin_Guide_010-5424-405v100.pdf
I remember reading about logging somewhere, but I was never able to actually find the file that it was logged to. So I would just create a “debug-roger” header and use TraceSM to find it in the SIP messages.
Regex is great, but you can just pick it up as needed. In the examples, there are plenty of “search/replace” regexes. Just remember that you can pretty much do anything. If you want to delete everything after a >, or if you want to remove quotation marks, or if you want to replace carriage returns with carriage return/line feed, you can do it all with regexes and all you have to do is type your wish into Google and you’ll get plenty of examples. It’s too bad you’re learning regex for this antique SBC though. There are much more fun projects to work on.
Thank you, Roger.
Hi Roger,
Below is the script that we used and achieved the expected result.
###########
within session “INVITE”
{
act on request where %DIRECTION=”OUTBOUND” and %ENTRY_POINT=”POST_ROUTING”
{
%aploc = %HEADERS[“AP-Loc”][1];
%HEADERS[“From”][1].URI.USER = %aploc;
%HEADERS[“From”][1].regex_replace(“elin=”, “\+1”);
%HEADERS[“P-Asserted-Identity”][1].URI.USER = %aploc;
%HEADERS[“P-Asserted-Identity”][1].regex_replace(“elin=”, “\+1”);
}
}
Thought to share it with you.
Hi Roger,
Below is the script that we used and achieved the expected result.
###########
within session “INVITE”
{
act on request where %DIRECTION=”OUTBOUND” and %ENTRY_POINT=”POST_ROUTING”
{
%aploc = %HEADERS[“AP-Loc”][1];
%HEADERS[“From”][1].URI.USER = %aploc;
%HEADERS[“From”][1].regex_replace(“elin=”, “\+1”);
%HEADERS[“P-Asserted-Identity”][1].URI.USER = %aploc;
%HEADERS[“P-Asserted-Identity”][1].regex_replace(“elin=”, “\+1”);
}
}
Thought to share it with you.
Hey great job!
Pingback: Super Sigma Scripting | Roger the Phone Guy
Hi Roger,
Looking for a way to allow all header information ‘identity header’ ‘STIR/SHAKEN/ info to come into the SBC if not already enabled.
Also, want to ‘mirror’ that info to a 3rd party. Is this done on Signaling Manipulation? How so? I would like to pass all header info or at minimum IDH, OLI, and verstat, and/or full P-Asserted-Identity info along.
PS, you can share the cookbook to me, it’s okay. lol
Thanks in advance.
The STIR/SHAKEN headers should come through like all other SIP headers. But I haven’t personally seen it yet (I’m working with Cisco CUBEs now).
As for passing the signaling to another destination – I don’t know if this is done with SigMa, but it should be possible through signal forking. I think all SBCs can fork the signaling. And I’m happy to send you the cookbook. Send me an email at roger@rogerthephoneguy.com and I’ll send it to you.
Roger
Hi Roger,
Great explanation!
Would like to check if we are able to design a script that handles both incoming and outgoing message?
For example:
//session for masking details for outbound call
within session “All”
{
act on message where %DIRECTION=”OUTBOUND”and %ENTRY_POINT=”POST_ROUTING”
{
//remove Display Name header parameter
remove(%HEADERS[“From”][1].DISPLAY_NAME);
remove(%HEADERS[“Contact”][1].DISPLAY_NAME);
remove(%HEADERS[“Remote-Party-ID”][1]);
remove(%HEADERS[“P-Asserted-Identity”][1]);
remove(%HEADERS[“Server”][1]);
}
}
//session for removing Display Name that being sent by provider part of From header
within session “INVITE”
{
act on request where %DIRECTION=”INBOUND” and %ENTRY_POINT=”AFTER_NETWORK”
{
remove(%HEADERS[“From”][1].DISPLAY_NAME); //remove Display Name header parameter
}
}
Finally checking these comments. Alas – my Avaya network is gone. I can no longer help.