cancel
Showing results for 
Search instead for 
Did you mean: 
cancel
8195
Views
5
Helpful
10
Replies

SIP Normalization Script to Add Diversion Header Based on Calling Number

nickwarfield
Level 4
Level 4

Hello,

I'm new to the normalization scripting but I wrote a script to add a diversion header to an outgoing call based on the calling number. 

This is a short version of the script:

--get contents of To header

--if contents of To header is not 911, get contents of From header

--if From header is 202555XXXX, add diversion header of 2025551212, repeat for all number ranges

--if From header does not match any of our configured number ranges, add diversion header of 2125551212

M = {}

--change to trace.enable() to have trace output in SDI

--trace.disable() 

trace.enable()

--specify diversion headers for each office

local addDiversionOffice1 = "<sip:2025551212@10.10.10.10>"

local addDiversionOffice2 = "<sip:3125551212@10.10.10.10>"

local addDiversionOffice2 = "<sip:310555121210.10.10.10>"

local addDiversionDefault = "<sip:2125551212@10.10.10.10>"

--default diversion header catch-all header if no matches

function M.outbound_INVITE(msg)

--specifies this function only for outbound invites

  local calledNumber = msg:getHeader ("To")

  --get To header to determine called number

  local emergencyCall = string.find (calledNumber, "sip:911@")

  --search for 911 in called number

  if emergencyCall == nil

     then

  local callingNumber = msg:getHeader ("From")

  --get From header to determine calling number

  --begin searching from header for calling number from each number range

        local callingNumberOffice1 = string.find (callingNumber, "sip:202555%d%d%d%d")

        local callingNumberOffice2 = string.find (callingNumber, "sip:312555%d%d%d%d")

        local callingNumberOffice3 = string.find (callingNumber, "sip:310555%d%d%d%d")

  --begin applying diversion header based on calling number

  if(callingNumberOffice1)

     then

  msg:removeHeader ("Diversion")

  --removing diversion header in case it already exists

     msg:addHeader("Diversion", addDiversionOffice1)

  --adding new diversion header back to call

        elseif(callingNumberOffice2)

     then

  msg:removeHeader ("Diversion")

     msg:addHeader("Diversion", addDiversionOffice2)

  elseif(callingNumberOffice3)

     then

  msg:removeHeader ("Diversion")

     msg:addHeader("Diversion", addDiversionOffice3)

  else --apply default diversion header

  msg:removeHeader ("Diversion")

  msg:addHeader ("Diversion", addDiversionDefault)

  end

  end

end

return M

The problem is that with the full script, there are 50 different offices and 50 different if/then statements. 

Does anyone know of a way to make this simpler or more efficient? 

I see this lua-users wiki: Switch Statement page gives some info on how to do it with a lookup table, but I can't figure out how they corresponds to what i'm trying to do. 

Any help please? 

Thanks

1 Accepted Solution

Accepted Solutions

dstaudt
Cisco Employee
Cisco Employee

Not a Lua expert by any means, but it appears the trick would be to parse out the DN from the From header, and use it with a lookup table.  Something like:

lookup = {

    ["202555"] = "<sip:2025551212@10.10.10.10>",

    ["302555"] = "<sip:3025551212@10.10.10.10>",

    ["402555"] = "<sip:4025551212@10.10.10.10>"

  }

testFromString = '"Joe" <sip:3025551234@5.5.5.45>;tag=001795f9d7d300080dd06ac1-fdc37874'

dummy,userStart = string.find(testFromString, "sip:")

areaExchange = string.sub(testFromString, userStart+1, userStart+6)

print(areaExchange)

diversion = lookup[areaExchange]

print(diversion)

which gives:

302555

<sip:3025551212@10.10.10.10>


View solution in original post

10 Replies 10

dstaudt
Cisco Employee
Cisco Employee

Not a Lua expert by any means, but it appears the trick would be to parse out the DN from the From header, and use it with a lookup table.  Something like:

lookup = {

    ["202555"] = "<sip:2025551212@10.10.10.10>",

    ["302555"] = "<sip:3025551212@10.10.10.10>",

    ["402555"] = "<sip:4025551212@10.10.10.10>"

  }

testFromString = '"Joe" <sip:3025551234@5.5.5.45>;tag=001795f9d7d300080dd06ac1-fdc37874'

dummy,userStart = string.find(testFromString, "sip:")

areaExchange = string.sub(testFromString, userStart+1, userStart+6)

print(areaExchange)

diversion = lookup[areaExchange]

print(diversion)

which gives:

302555

<sip:3025551212@10.10.10.10>


Thanks!  that was a big help!

This is what I have after the info you gave me:

M = {}

--change to trace.enable() to have trace output in SDI

--trace.disable() 

trace.enable()

local addDiversionDefault = "<sip:4105551212@10.10.10.10>"

lookup = { 

    ["410555"] = "<sip:4105551212@10.10.10.10>", 

    ["202555"] = "<sip:2025551212@10.10.10.10>", 

    ["212555"] = "<sip:2125551212@10.10.10.10>" 

  } 

function M.outbound_INVITE(msg)

--specifies function only for outbound invites

  local calledNumber = msg:getHeader ("To")

  --get To header to determine called number

  local emergencyCall = string.find (calledNumber, "sip:911@")

  --search for 911 in called number

  if emergencyCall == nil

     then

  local callingNumber = msg:getHeader ("From")

        dummy,userStart = string.find(callingNumber, "sip:") 

        areaExchange = string.sub(callingNumber, userStart+1, userStart+6) 

  --parsing area code and exchange from calling number

  diversion = lookup[areaExchange] 

  --looking up diversion header based on area code and exchange

  msg:removeHeader ("Diversion")

  --removing diversion header in case it already exists

     msg:addHeader("Diversion", diversion)

     --adding new diversion header back to call

  if diversion == nil

     then msg:addHeader ("Diversion", addDiversionDefault)

  end

  end

end

return M

It seems to work from what I've tested.  I really appreciate your help.  Do you see anything that could be done better or might cause any issues?

Thanks!

So does this only apply to 911 calls? or will this work for any number?

I believe the logic is looking for 911 calls, and then 'not' changing anything if it is a 911 call. So, it's only making changes if the sip:911@ is 'nil'.

Mark

So what if i always wanted to set a diversion header based o nthe calling number? And what if the range of number varies, so i cant count on area code and exchange or i have to use more digits to detemine my diversion header.

See below for examples i know ill have to change the "userstart +6" but to what?

and how would i remove the check for 911?

is htere a limit on the number of search items?

  1. M = {} 
  2.  
  3.  
  4. --change to trace.enable() to have trace output in SDI 
  5. --trace.disable()   
  6. trace.enable() 
  7.  
  8.  
  9. local addDiversionDefault = "<sip:4105551212@10.10.10.10>"  
  10.  
  11.  
  12. lookup = {   
  13.     ["410"] = "<sip:4105551212@10.10.10.10>",   
  14.     ["202555"] = "<sip:2025551212@10.10.10.10>",   
  15.     ["21255512"] = "<sip:2125551212@10.10.10.10>"   
  16.   }   
  17.  
  18.  
  19. function M.outbound_INVITE(msg)  
  20. --specifies function only for outbound invites 
  21.   local calledNumber = msg:getHeader ("To")  
  22.   --get To header to determine called number 
  23.   local emergencyCall = string.find (calledNumber, "sip:911@")  
  24.   --search for 911 in called number 
  25.   if emergencyCall == nil 
  26.      then 
  27.   local callingNumber = msg:getHeader ("From")  
  28.         dummy,userStart = string.find(callingNumber, "sip:")   
  29.         areaExchange = string.sub(callingNumber, userStart+1, userStart+6)   
  30.   --parsing area code and exchange from calling number 
  31.   diversion = lookup[areaExchange]   
  32.   --looking up diversion header based on area code and exchange  
  33.   msg:removeHeader ("Diversion")  
  34.   --removing diversion header in case it already exists 
  35.      msg:addHeader("Diversion", diversion) 
  36.      --adding new diversion header back to call 
  37.   if diversion == nil 
  38.      then msg:addHeader ("Diversion", addDiversionDefault) 
  39.   end 
  40.   end 
  41. end 
  42. return M 

Hi James,

I had an email exchange with John V. about this. Can you chat with him? I can help you out, but I need a better idea what you're trying to accomplish.

Mark

jfladouceur
Level 4
Level 4

Hi,

I have the requirement to add a diversion header to messages directed towards Exchange CAS and UM servers.   We have a scenario where users call the VM pilot (CAS) from a device that does not have VM and they continue to get ringback from exchange after they enter their VM box number to identify themselves.  The DTMF is valid.  TAC has advised that the system does not understand how to direct the call as their is no Diversion header.

Specifically :

"CUCM would not insert a Diversion header on this situations. Diversion header would be inserted if the party that is transferring the call has a DN assigned, SIP integration does not have this capability. To insert a Diversion header, we would have to do it using Normalization"


I think the SIP trunk from Exchange must not have a number assigned and so this fails.   


Can someone provide the framework for adding a diversion header so the call will complete?

The specific log sequence is:


11463721.001 |13:50:09.653 |AppInfo  |SIPTcp - wait_SdlSPISignal: Outgoing SIP TCP message to 10.167.128.202 on port 5067 index 146254

[2197798,NET]

SIP/2.0 202 Accepted

Via: SIP/2.0/TCP 10.167.128.202:5067;branch=z9hG4bK1781c77a

From: <sip:70001@10.167.128.102>;tag=fafd7cbaf2;epid=13CC005D1A

To: "Blue Berry" <sip:9920400@hoc-lab-cdc.ca>;tag=844637~4166cdbc-a7d7-4923-9018-926776b31eb2-39132798

Date: Wed, 12 Apr 2017 17:50:09 GMT

Call-ID: 6f407f80-8ee168c4-68a57-d06aa0a@10.170.6.13<mailto:6f407f80-8ee168c4-68a57-d06aa0a@10.170.6.13>

Server: Cisco-CUCM10.5

CSeq: 1 REFER

Contact: <sip:9920400@10.170.6.13:5060;transport=tcp>

Content-Length: 0

11463802.001 |13:50:09.733 |AppInfo  |SIPD(48) - getKeyBasedOnCiAndBranch: AddressingElement branch is 0 and ci is 39132801  mapKey is 39132801

11463802.002 |13:50:09.733 |AppInfo  |SIPD(48) - getCdpcPidGivenKey: Did not find Cdpc Pid for mapKey 39132801

11463802.003 |13:50:09.733 |AppInfo  |resetLocalDtmfCaps: mLocalDtmfCaps.oob.kpmlAvail = 0

11463802.004 |13:50:09.733 |AppInfo  |CcmCcmdbSIPNormalizeHelper::getSipDeviceScriptPkidGivenDeviceName: This is a regular SIPTrunk. deviceName - (Exchange

11463827.010 |13:50:09.749 |AppInfo  |SIPCdpc(221) - getDefSetup: ReqURI is not present

11463827.011 |13:50:09.749 |AppInfo  |SIPCdpc(221) - getDefSetup: Relaying contact header parms from CC to siphandler = [;+u.sip!devicename.ccm.cisco.com="SEP382056446896"]

11463827.012 |13:50:09.749 |AppInfo  |SIPCdpc(221) - appendRPHdr: appendRPHdr - no RPHeader Network Domain set and not precedence call, return

11463827.013 |13:50:09.749 |AppInfo  |SIPCdpc(221) - appendGuidHeader: adding Guid to sipContainerWrapper: 7700240000010000000000360D06AA0A

++++Not able to add Diversion Header

11463827.014 |13:50:09.749 |AppInfo  |SIPCdpc(221) - getRedirectingNumIE: Not adding any Voice mail Diversion header as originalCdpnRedirectReason and lastRedirectingRedirectReason are  SS_RFR_REFER

11463827.015 |13:50:09.749 |AppInfo  |SIPCdpc(221) - getRedirectingNumIE: Redirect reasons: last: 130, orig: 130

11463827.016 |13:50:09.749 |AppInfo  |SIPCdpc(221) - CcPtyNumIdEq: Comparing @, dn: 70001, ti: DN with @, dn: 70001, ti: DN, result: true

11463827.017 |13:50:09.749 |AppInfo  |SIPCdpc(221) - CcPtyNumIdEq: Comparing @, dn: 70001, ti: DN with @, dn: 70001, ti: DN, result: true

11463827.018 |13:50:09.749 |AppInfo  |SIPCdpc(221) - addTransparencyInfo: attaching transparency object

11463827.019 |13:50:09.749 |AppInfo  |//SIP/Stack/Error/0x0/sipAppGetMessagePlatformDataOutbound: Invalid message platform data in the container

++++INVITE sent out without a diversion header:

11463727.001 |13:50:09.654 |AppInfo  |SIPTcp - wait_SdlSPISignal: Outgoing SIP TCP message to 10.148.73.12 on port 49544 index 132662

[2197800,NET]

INVITE sip:c2342852-1db0-1132-bdc9-1fa8d6215ef8@10.148.73.12:49544;transport=tcp SIP/2.0

Via: SIP/2.0/TCP 10.170.6.13:5060;branch=z9hG4bK68bf232c2b2bb

From: <sip:70001@10.170.6.13>;tag=844632~4166cdbc-a7d7-4923-9018-926776b31eb2-39132797

To: "Blue Berry" <sip:9920400@10.170.6.13>;tag=38205644689605e10a87b0b8-6c89bd79

Date: Wed, 12 Apr 2017 17:50:09 GMT

Call-ID: 38205644-68960010-03f43427-034b56a3@10.148.73.12<mailto:38205644-68960010-03f43427-034b56a3@10.148.73.12>

Supported: timer,resource-priority,replaces

User-Agent: Cisco-CUCM10.5

Allow: INVITE, OPTIONS, INFO, BYE, CANCEL, ACK, PRACK, UPDATE, REFER, SUBSCRIBE, NOTIFY

CSeq: 102 INVITE

Max-Forwards: 70

Expires: 180

Allow-Events: presence

Call-Info: <urn:x-cisco-remotecc:callinfo>; security= NotAuthenticated; orientation= to; gci= 2-21107; isVoip; call-instance= 1

Min-SE:  1800

Remote-Party-ID: <sip:70001@10.170.6.13>;party=calling;screen=yes;privacy=off

Contact: <sip:70001@10.170.6.13:5060;transport=tcp>;automata;text;audio;image

Content-Type: application/sdp

Content-Length: 243

v=0

o=CiscoSystemsCCM-SIP 844632 2 IN IP4 10.170.6.13

s=SIP Call

c=IN IP4 0.0.0.0

b=AS:64

t=0 0

m=audio 25716 RTP/AVP 0 101

b=TIAS:64000

a=ptime:20

a=rtpmap:0 PCMU/8000

a=inactive

a=rtpmap:101 telephone-event/8000

a=fmtp:101 0-15

Thanks,

Jim

This sounds like it'll be tricky since it sounds like you only want a diversion header added onto certain calls, correct?  What aspect of these calls would you want to base the diversion header off of?  It's not complicated to add a diversion header to a call, but you have to understand the affect it's going to have on the call itself.  In my scenario, these were calls out to the PSTN, where Verizon needed a diversion header to bill us properly because of a feature we had enabled.  Verizon doesn't use a diversion header for any other reason.  Voicemail systems DO use diversion headers to determine what voicemail box to send the caller to.

It also sounds like Cisco TAC has told you what they think the Microsoft UM expects to see.  Is that correct or did you hear from Microsoft for sure that they're expecting a diversion header? 

Is this a forwarded call on CUCM that is being forwarded to the VM pilot? 


It sounds almost as if you're just trying to dial the voicemail pilot directly from an extension that does not have a voicemail box, like a public space phone, and the user who is dialing it is trying to login to their own mailbox. 

I'm not familiar with Exchange CAS/UM, but I can't imagine a scenario where a diversion header would be required just to dial a voicemail pilot directly.  Typically a diversion header is used to identify where the call has been diverted from.  For example, in Cisco Unity Connection, extension 2000 dialing extension 2001 will get forwarded to the VM pilot which is 2500, and the diversion header on the forwarded call will be 2001, and Unity Connection knows to drop that call into the Voicemail greeting for 2001. If you just dial the VM pilot without being forwarded to it, you get a generic "Hello, Cisco Unity Messaging.." greeting asking you to dial a number or you can press * to login.  If you add a diversion header onto a call directly from a phone to a voicemail pilot in Unity Connection, you will get the greeting for the extension listed in the diversion header.  I would think the same thing would occur for Exchange UM. 

If i'm understanding your issue correctly, maybe there is a way to configure a voicemail access number that users can dial into to login to voicemail instead of using the pilot number? 

Well, you can always check for the existence (or lack thereof) of any particular header and add if they don't exist...

M = {}

function M.outbound_INVITE(msg)

  local diversHeader = msg:getHeader("Diversion")

  if not diversHeader

  then

    -- Add a new diversion header

  end

end

return M

Thanks -  as it turns out in release 11.5 of CUCM the issue is resolved. I will grab some traces to see what has changed.

cheers

Getting Started

Find answers to your questions by entering keywords or phrases in the Search bar above. New here? Use these resources to familiarize yourself with the community: