Fixing SIP Problems with UC Manager's SIP Normalization Tools Mark Stover
Why have this session? More systems than ever use SIP I counted 103 SIP Products on SIP Wikipedia Page Google Search for SIP Server yields 2.8 Million Hits Many of the SIP bits don t quite match up Hence, the need for Interoperability events Things in the real world don t go the way of data sheets and Interoperability Forums! 3
What this Session is About Fact 1: SIP is a Standard Fact 2: SIP Configurations are not standardized Which headers are included Format of data in headers (URIs, etc.) Ordering of header fields Contents of the SIP Message Body What do we do when Fact #1 and Fact #2 are at odds in our deployment? We have a tool in our toolbox: SIP Transparency and Normalization 4
Typical Interop Scenario 5
Agenda Brief review of SIP When things don t work Overview of SIP Transparency and Normalization Overview of Lua Normalization Scripts Case Study Some Common Scripting Forms Case Study 2 Conclusion 6
Brief Review of SIP
Basic Design SIP is a Client-Server Protocol Clients send requests, receive responses Servers receive requests, send responses Modeled after HTTP Text Encoded Protocol Client request Server Each request invokes method on server Main purpose of request response Messages contain bodies 8
SIP Methods and Messages Call signaling performed by SIP Methods Six Original SIP Methods: INVITE ACK OPTIONS BYE CANCEL REGISTER SIP Messages have distinct parts: IP/TCP/UDP Envelope SIP Header SIP Message Body MIME-Encoded Session Description Protocol (SDP) May contain other data 9
SIP Methods INVITE Invites a participant to a session idempotent - reinvites for session modification BYE Ends a client s participation in a session CANCEL Terminates a search For Your Reference OPTIONS Queries a participant about their media capabilities, and finds them, but doesn t invite PING identifies reachability ACK For reliability and call acceptance REGISTER Informs a SIP server about the location of a user 10
SIP Message Syntax Many header fields from http Payload contains a media description SDP Session Description Protocol INVITE sip:alice@company.com SIP/2.0 From: Bob <sip:bob@university.edu> To: Alice <sip:alice@company.com> Via: SIP/2.0/UDP pc.university.edu Call-ID: 199723450578@192.169.100.100 Content-type: application/sdp CSeq: 4711 INVITE Content-Length: 187 v=0 o=ccm-sip 2000 1 IN IP4 192.168.100.100 s=sip Call c=in IP4 192.168.200.200 m=audio 26542 RTP/AVP 0 8 18 101 a=rtpmap:0 PCMU/8000 a=ptime:20 a=mid:1 c=in IP6 2001:0db8:aaaa::0987:65ff:fe01:234b m=audio 26662 RTP/AVP 0 a=mid:2 11
Negotiating the Session For Your Reference Called party receives SDP offered by caller Each stream can be accepted rejected Accepting involves generating an SDP listing same stream port number and address of called party subset of codecs from SDP in request Rejecting indicated by setting port to zero Resulting SDP returned in 200 OK Audio stream accepted, PCMU only Video stream rejected, Port 0 v=0 o=user2 16255765 8267374637 IN IP4 4.3.2.1 t=0 0 m=audio 3456 RTP/AVP 0 c=in IP4 4.3.2.1 m=video 0 RTP/AVP 86 c=in IP4 4.3.2.1 Media can now be exchanged 12
SIP Responses Look much like requests Headers, bodies Differ in top line Status Code Numeric, 100-699 Meant for computer processing Protocol behavior based on 100s digit Other digits give extra info Reason Phrase Text phrase for humans Can be anything Status Code Classes 100-199 (1XX): Informational 200-299 (2XX): Success 300-399 (3XX): Redirection 400-499 (4XX): Client Error 500-599 (5XX): Server Error 600-699 (6XX): Global Failure Two groups 100-199: Provisional (Not reliable) 200-699: Final, Definitive Example 200 OK 180 Ringing 13
SIP Transactions Fundamental unit of messaging exchange Request Zero or more provisional responses Usually one final response Maybe ACK All signaling composed of independent transactions Transactions identified by Cseq Sequence number Method tag 14
When things don t work
Identifying A Problem Goal is to make two SIP systems talk Both systems already configured with: Appropriate Network Configurations Trunk configuration to reach the other system Routing (dial plan) information in place Make a call From: 1001 on System A; To: 2001 on System Z Both phones exist, are configured, and are able to make other calls And wait 16
Symptoms Possible failure modes: Wait forever and get fast busy Call rejected right away Calls work, but other services (e.g. MWI) fail These can be symptoms of numerous problems No bandwidth No DNS Bad Codecs SIP Header Mismatches Etc. Unfortunately, it will take some troubleshooting to isolate the issue 17
Gather Information Logs are good: Will help you determine if SIP is the problem May not reflect what is really on the wire May not include the header level detail Packet Capture is your friend Various ways to gather traces Further discussion just ahead Review Paul Giralt s SIP Troubleshooting session for many more details: BRKUCC-2932 Troubleshooting SIP with Cisco Unified Communications It is scheduled for Thursday Afternoon 18
Getting SIP Messages Three main sources of SIP Message Information 1. Unified CM Trace Files 2. Unified CM Network Capture utils network capture 3. Network Packet Capture (Wireshark) 19
Example of Unified CM Trace File 17:38:59.871 //SIP/SIPTcp/wait_SdlReadRsp: Incoming SIP TCP message from 192.168.100.100 on port 65067 with 1872 bytes: INVITE sip:4125551212@192.168.200.200:5060 SIP/2.0 Via: SIP/2.0/TCP 192.168.100.100:5060;branch=z9hG4bK1266281727 From: "Alice" <sip:918145551212@192.168.100.100>;tag=3e6d44cc-ce4 To: <sip:4125551212@192.168.200.200> Date: Wed, 12 Oct 2011 21:38:59 GMT Call-ID: 6E2FCA41-F45111E0-95FBF44A-5979DA79@192.168.100.100 Supported: 100rel,timer,resource-priority,replaces,sdp-anat Cisco-Guid: 1847785776-4098953696-3044132940-1967707264 User-Agent: Cisco-SIPGateway/IOS-12.x CSeq: 101 INVITE Timestamp: 1318455539 Expires: 180 Allow-Events: telephone-event Content-Type: multipart/mixed;boundary=uniqueboundary Mime-Version: 1.0 Content-Length: 929 --uniqueboundary Content-Type: application/sdp Content-Disposition: session;handling=required v=0 o=ciscosystemssip-gw-useragent 4535 5918 IN IP4 192.168.100.100 s=sip Call c=in IP4 192.168.100.100 t=0 0 m=audio 17620 RTP/AVP 0 100 101 c=in IP4 192.168.100.100 a=rtpmap:0 PCMU/8000 20
Using Unified CM Network Capture admin:utils network capture size 1500 port 5060 file testsipcap verbose Executing command with options: size=1500 count=1000 interface=eth0 src= dest= port=5060 ip= admin:file list activelog platform/cli/ testsipcap.cap dir count = 0, file count = 1 admin:file get activelog platform/cli/testsipcap.cap Please wait while the system is gathering files info...done. Sub-directories were not traversed. Number of files affected: 1 Total size in Bytes: 6040 Total size in Kbytes: 5.8984375 Would you like to proceed [y/n]? y SFTP server IP: 192.168.101.101 SFTP server port [22]: User ID: admin Password: ******** Download directory: Downloads. Transfer completed. 21
Using Wireshark 22
Determine Needed Results 1. Make calls in both directions: Get SIP Captures of test calls in both directions 2. Traces may give you a clue: Mismatch in domain names No domain in one direction Mailbox you want is last redirect instead of first in list 3. May have to research each system s SIP trunk requirements Compare it to the other vendor s normal operation 4. Use your research and troubleshooting to determine the fix: Change the domain name of messages from incorrectly configured system Add a missing domain Remove headers that cause a failure 23
Write, Test, and Deploy Use the desired result to formulate a plan Create Normalization Script that process appropriate SIP headers Test against traffic on a SIP trunk that does not carry production traffic Deploy to production trunk and verify 24
Overview of SIP Transparency & Normalization
Goals of SIP Transparency & Normalization Provide an interface for customization of SIP messages Initially conceived for Cisco Unified CM Session Management Edition (SME) Also supports Cisco Unified Communications Manager without SME Available in Release 8.5 and later Include: A Lua execution environment SIP Transparency & Normalization APIs Support: Transparent passing of SIP information from one call leg to another Normalizing SIP Messages to provide interoperability 26
SIP Transparency Unified CM is a Back to Back User Agent (B2BUA) In a Session Management role, Unified CM will (by default ) insert itself in the call Will become the call agent for next leg Will remove any unsupported headers on the next leg Transparency allows SIP information to be passed from one call leg to another What that means? Transparency allows 3rd-Party Headers to pass through Unified CM 27
SIP Normalization The process of transforming inbound and outbound SIP messages Inbound normalization makes the SIP message useable by Unified CM For Example, how can we handle SIP redirecting numbers? Unified CM uses the Diversion header for redirecting number(s) Other SIP devices use the History-Info header for this purpose Normalization can transform History-Info headers into Diversion headers Outbound normalization makes the SIP message useable by another SIP device Use normalization to transform Unified CM s Diversion headers into History-Info headers for another SIP PBX 28
Normalization Script Examples Reorder codecs in the SDP of an early offer Remove specific headers such as Cisco-Guid Mask the number to E.164 in a Diversion header to meet Service Provider requirements Fix the domain name of a system with the wrong one Convert IP addresses to domain names Add content to the SIP Message Body 29
What can a normalization script change? Manipulate almost every aspect of a SIP message Currently, SIP Normalization can change: The request URI The response code and phrase SIP headers SIP parameters Content bodies SDP 30
What can a transparency script do? To provide transparency, the script has to pass SIP information Almost any information in a SIP message can be passed through Currently, SIP Transparency can manage: SIP headers SIP parameters Content bodies 31
Case Study-Problem Statement Customer has several PBXs trunked to a Unified CM cluster Unified CM SIP trunked to a 3rd-party voice mail system After multiple call forwards, some calls are sent to voice mail Most calls go to the correct voice mail box Calls from one PBX did not In the broken case: Reaching the greeting for the station that finally forwarded the call to voice mail Not reaching the voice mail of the station originally called Will solve this problem with SIP Normalization in just a little while 32
Overview of Lua
What is Lua? A powerful, fast, lightweight, embeddable scripting language A fast language engine with a small footprint that can embed easily into other applications Lua has a simple and well documented API that allows strong integration with code in other languages Adding Lua to an application does not bloat it Many more details about Lua can be found online: http://www.lua.org/about.html http://www.lua.org/manual/5.2/ 34
A Brief Lua Tutorial This is not a programming course! Will cover some Lua basics to allow writing SIP T&N Scripts Will briefly consider: Lua Data Types Lua Tables Lua Control Structures Unified CM Support for Lua 35
Lua Data Types Lua has the typical data types you would expect: Numbers Strings Boolean (true or false) Lua has one data type you might not have heard of: Tables Tables are the only aggregate data type available in Lua 36
Lua Tables Tables are used for storing collections lists, arrays, and associative arrays Tables can contain other objects including numbers, strings, or tables Tables created using a pair of curly brackets { } t = { 1,1,2,3,5,8,13 } t[1] == 1 Note that table indexes begin at 1 Methods (functions) exist to insert and remove table elements Library functions allow iterating over the contents of a table 37
Using Lua Tables for SIP Headers Tables are a key part of how Lua can process SIP headers Tables are useful when more than one of a specific header is present For example: History-Info: <sip:userb@hostb?reason=sip;cause=408>;index=1 History-Info: <sip:userc@hostc?reason=sip;cause=302>;index=1.1 History-Info: <sip:userd@hostd>;index=1.1.1 Values from all three headers can be stored in a Table (history_info) history_info[1] == "<sip:userb@hostb?reason=sip;cause=408>;index=1" history_info[2] == "<sip:userc@hostc?reason=sip;cause=302>;index=1.1" history_info[3] == "<sip:userd@hostd>;index=1.1.1" 38
Lua Control Structures Lua has the typical programmatic control structures There are four main forms: 1. While: conditional looping statement with the form: while <exp> do <block> end 2. Repeat: conditional looping statement with the form: repeat <block> until <exp> 3. If: selection statement with the form: if <exp> then <block> { elseif <exp> then <block> } [ else <block> ] end 4. For: iterating statement (see the next slide) 39
Looping With For The two forms that for can take The first is for numerical iteration for <var> = <from_exp>, <to_exp> [, <step_exp>] do <block> end for count = 1,3 do print(count) end The second is for sequential iteration for <var> {, <var>} in <explist> do <block> end Example: Use for to print the contents of a table: For is passed an function, pairs(), that supplies the values of each iteration for key,value in pairs({10, math.pi, "banana"}) do print(key, value) end 1 10 2 3.14159 3 banana 40
pairs and ipairs Part of the standard Lua library pairs() function iterates over all key-value pairs items are NOT returned in a defined order for key,value in pairs(t) do print(key,value) end 3 10 1 3 4 17 2 7 pi 3.14159 banana yellow ipairs() function iterates over only index-value pairs Returned in numeric order of the indices; Non-integer keys are skipped for index,value in ipairs(t) do print(index,value) end 1 3 2 7 3 10 4 17 41
Handy Lua Bits Available on Unified CM tostring() is handy for getting numbers back to strings for SIP headers Comments can be single or multiple lines: -- This is a comment --[[ This is a comment that crosses multiple lines --]] 42
Lua Demo Using Lua on your computer Running the Lua environment Hello World 43
CUCM Lua Support Cisco SIP Lua Environment supports the following libraries: The complete string library A subset of the base library Other Lua libraries are not supported Cisco SIP Lua Environment provides Global environment for the scripts to use Default Lua global environment (_G) is not available to SIP T&N scripts Supported base library functions: ipairs pairs next unpack error type tostring 44
Pop Quiz! True or False: Cisco created Lua just for processing SIP messages? A. True B. False Which Lua Libraries does Unified CM Normalization Scripts support? A. None of Them B. All of Them C. Complete String Library D. Subset of Base Library E. Both C & D 45
Overview of Normalization Scripts
Putting SIP Normalization to Work Using message handlers to manipulate SIP messages Message Handler name tells you: When the Handler will be invoked What type of message the Handler is for You want your script to process INVITEs received by Unified CM: Script should have an inbound_invite message handler Corresponding message handler invoked anytime an inbound INVITE is received A single parameter called msg represents the SIP Message in script Scripts use Cisco SIP Message API library to access and manipulate the msg parameter Let s try looking at a diagram 47
How a Normalization Script Gets Run 48
How a Normalization Script Gets Run 49
How a Normalization Script Gets Run 50
How a Normalization Script Gets Run 51
How a Normalization Script Gets Run 52
How a Normalization Script Gets Run 53
How a Normalization Script Gets Run 54
How a Normalization Script Gets Run 55
Let s Start with a Simple Script Need to convert incoming History-Info headers into Diversion headers Script will run when Unified CM receives an INVITE Need to remove Cisco-Guid from outgoing headers Script will run when Unified CM sends an INVITE 56
Our First SIP Normalization Script M = {} function M.inbound_INVITE(msg) msg:converthitodiversion() end function M.outbound_INVITE(msg) msg:removeheader("cisco-guid") end return M 57
Focus on SIP Normalization Script - 1 M = {} Creates an empty Lua Table called M for all Handlers M is also the name of the Lua Module function M.inbound_INVITE(msg) msg:converthitodiversion() end function M.outbound_INVITE(msg) msg:removeheader("cisco-guid") end return M 58
Focus on SIP Normalization Script - 2 M = {} function M.inbound_INVITE(msg) msg:converthitodiversion() end Inbound INVITE Message Handler Inbound SIP Message accessed through msg Invokes an API call to perform the actual conversion function M.outbound_INVITE(msg) msg:removeheader("cisco-guid") end return M 59
Focus on SIP Normalization Script - 3 M = {} function M.inbound_INVITE(msg) msg:converthitodiversion() End function M.outbound_INVITE(msg) msg:removeheader("cisco-guid") end Outbound INVITE Message Handler Outbound SIP Message accessed through msg Invokes API call to remove a header (in this case, Cisco-Guid) return M 60
Focus on SIP Normalization Script - 4 M = {} function M.inbound_INVITE(msg) msg:converthitodiversion() end function M.outbound_INVITE(msg) msg:removeheader("cisco-guid") end return M Line is required Returns the Lua Table containing the message handlers to Unified CM execution environment Cisco SIP Lua Environment uses Table M to identify the message handlers 61
SIP Message Handler Formalities Each Transparency and Normalization script provides: Set of call-back functions to manipulate SIP messages Call-back functions are called message handlers The message handler s name indicates when a handler is invoked Only one Transparency AND Normalization Script per SIP Trunk Must define all message handlers in that single script Mix and match methods and directions in a single script Handlers for requests and responses have slightly different formats Will be covered next 62
Request Message Handlers Request message handler is named by combining: the SIP message direction AND the SIP method name Identify the method name from the 'request line' of the SIP message Request format: <direction>_<method> Examples: inbound_invite outbound_update 63
Response Message Handlers Response message handler is named by combining: the message direction PLUS the response code AND the SIP method Identify the method name from the CSeq header Response format: <direction>_<response code>_<method> Examples: inbound_183_invite inbound_200_invite outbound_200_update 64
Using Wild Cards in Message Handler Names For Request Messages A wildcard ANY can be used in place of <method> <direction> does not support a wild card For Response Messages: A wildcard ANY can be used in place of <method> A wildcard ANY can be used in place of <response code> <method> and <response code> can both be ANY <direction> does not support a wild card Cannot have a wildcard ANY <method> with a specific <response code> A wildcard character X can be used in <response code> 65
Examples of Wild Cards Valid Request Message Handler Names M.inbound_INVITE M.inbound_ANY M.outbound_ANY Valid Response Message Handler Names M.inbound_183_INVITE M.inbound_18X_INVITE M.outbound_ANY_INVITE M.outbound_ANY_ANY Invalid Response Names M.inbound_183_ANY 66
Rules for picking a message handler For Your Reference Unified CM uses these rules to choose a message handler: Message handlers are case-sensitive The direction is either inbound or outbound The direction is always written as lowercase The message direction is relative to Unified CM Note: The message direction has nothing to do with the dialog direction of the SIP session The method name in the SIP message is converted to uppercase to pick the message handler Longest match criteria: Unified CM uses the longest-match to choose the message handler A script has two message handlers: inbound_any_any and inbound_183_invite A 183 response is received by Unified CM The inbound_183_invite handler will be executed since it is the longest match 67
Built-In Normalization Scripts 68
APIs for SIP and SDP Normalization For Your Reference SIP Messages APIs: Allows script to manipulate the SIP message SDP APIs: Allows script to manipulate the SDP SIP Pass Through APIs: Allows script to pass information from one call leg to another SIP Utility APIs: Utilities to manipulate header data such a parsing URIs into a SIP URI object SIP URI APIs: Allows script to manipulate the parsed SIP URI object Trace APIs: Allows script to enable, disable and manage tracing Script Parameters API: Allows script to obtain trunk or line specific parameters 69
SIP Objects and Normalization Which SIP methods can be normalized? You can invoke a scripts based on any Method that Unified CM handles Which SIP headers can your script access? You can access any headers in the message that invokes the script Which lines in the message s SDP can you access? Your script can access any of the SDP lines For normalization, scripts can manipulate almost every aspect of a SIP message 70
SIP Objects and Transparency support Transparency is limited to INVITE dialogs on SIP trunks Transparency scripts can pass almost any information in a SIP message SIP Headers SIP Parameters Content Bodies These SIP objects do not support Transparency scripts SUBSCRIBE dialogs PUBLISH out-of-dialog REFER out-of-dialog unsolicited NOTIFY MESSAGE 71
Case Study
Case Study Calls going to the wrong mail box Customer has several PBXs trunked to Cisco Unified CM Unified CM interfaced to a 3rd-party voice mail system via SIP Calls sent to voice mail after multiple call forwards Most calls were going to the correct voice mail box Calls from one PBX were not In the broken case, calls were going to the voice mail box of the last station the call was forwarded to Let s look in detail at these call flows 73
Case study call flow 5 Call from PSTN for x1100 1 Call from PSTN for x2100 6 Call Forward All to x1200 7 No Answer to Voice Mail 2 Call Forward All to x2200 3 No Answer to Voice Mail Bad Result 8 Greeting for x1200 4 Greeting for x2100 Good Result 74
Problem: SIP header from call to wrong mail box INVITE sip:4125553000@192.168.1.1:5060 SIP/2.0 Via: SIP/2.0/TCP 192.168.2.2:5060;branch=z9hG4bK12b5cc229a69621 From: "PSTN" <sip:8145551212@192.168.2.2>;tag=16101269~0458486e-22501993c802-145785687 To: <sip:4125553000@192.168.1.1> Date: Wed, 19 Dec 2012 16:45:01 GMT Call-ID: c9d9ea00-eef16a0d-46c59c-a5086cc6@192.168.2.2 Supported: 100rel,timer,resource-priority,replaces User-Agent: Cisco-CUCM8.5 Allow: INVITE, OPTIONS, INFO, BYE, CANCEL, ACK, PRACK, UPDATE, REFER, SUBSCRIBE, NOTIFY CSeq: 101 INVITE Expires: 180 Call-Info: <sip:192.168.2.2:5060>;method="notify;event=telephone-event;duration=500" Cisco-Guid: 3386501632-0000065536-0002912165-2768792774 Session-Expires: 1800 Diversion: <sip:4125551200@192.168.2.2>;reason=no-answer;privacy=off;screen=yes Diversion: <sip:4125551100@192.168.2.2>;reason=unconditional;privacy=off;screen=yes Contact: sip:8145551212@192.168.2.2:5060;transport=tcp Content-Length: 0 Call goes to x1200 greeting instead of x1100 75
What the script will have to accomplish Keep it simple & just remove the headers we don t need for voice mail 76
Minimal Normalization Script for outbound INVITEs M = {} function M.outbound_INVITE(msg) -- Process outbound INVITES to VM -- Process INVITE to normalize it... end return M 77
Add logic to remove extra Diversion Headers local DiversArray = msg:getheadervalues("diversion ) local DiversCount = #DiversArray if DiversCount > 1 then for I = 1, (DiversCount - 1) do -- Get all Diversion Headers -- Number of Diversion Headers -- Only if there s more than one -- Remove all but last header msg:removeheadervalue("diversion", DiversArray[I]) -- remove a Diversion Header end end 78
Completed Script M = {} function M.outbound_INVITE(msg) -- Process outbound INVITES to VM local DiversArray = msg:getheadervalues("diversion ) -- Get all Diversion Headers local DiversCount = #DiversArray if DiversCount > 1 then for I = 1, (DiversCount - 1) do -- Number of Diversion Headers in Invite -- Only if there s more than one -- Remove all but last header msg:removeheadervalue("diversion", DiversArray[I]) -- remove a Diversion Header end end end return M 79
Deploy the script to Unified CM Now that we have a script, what do we do with it? Apply it to the voice mail SIP trunk in Unified CM: 1. Add a SIP Normalization Script 2. Can be imported from a text file or copy/paste 3. Save the Script 4. Apply the Script to the appropriate SIP trunk 80
Add a SIP Normalization Script 81
Import the Script 82
Configure and save the Script 83
Apply the Script to the SIP trunk 84
Verify that your script fixes the problem INVITE sip:4125553000@192.168.1.1:5060 SIP/2.0 Via: SIP/2.0/TCP 192.168.2.2:5060;branch=z9hG4bK12b5cc229a69621 From: "PSTN" <sip:8145551212@192.168.2.2>;tag=16101269~0458486e-22501993c802-145785687 To: <sip:4125553000@192.168.1.1> Date: Wed, 19 Dec 2012 16:45:01 GMT Call-ID: c9d9ea00-eef16a0d-46c59c-a5086cc6@192.168.2.2 Supported: 100rel,timer,resource-priority,replaces User-Agent: Cisco-CUCM8.5 Allow: INVITE, OPTIONS, INFO, BYE, CANCEL, ACK, PRACK, UPDATE, REFER, SUBSCRIBE, NOTIFY CSeq: 101 INVITE Expires: 180 Call-Info: <sip:192.168.2.2:5060>;method="notify;event=telephone-event;duration=500" Cisco-Guid: 3386501632-0000065536-0002912165-2768792774 Session-Expires: 1800 Diversion: <sip:4125551100@192.168.2.2>;reason=unconditional;privacy=off;screen=yes Contact: sip:8145551212@192.168.2.2:5060;transport=tcp Content-Length: 0 Call now goes to x1100 greeting (1 Diversion Header) 85
Some Common Scripting Forms 86
Navigating Script Formats Sample Normalization Scripts are available Can be confusing, not all scripts follow same format Scripts follow two basic formats: Function Name made up of the direction and SIP method example: function M.inbound_INVITE(msg) Function Name indicates purpose, but not direction or SIP Method example: function add_reply_to_header(msg) 87
Name = Direction + Method M = {} function M.inbound_INVITE(msg)... (function code)... end return M Good: Know exactly what SIP messages will be acted on Bad: Cannot reuse the function for anything else Need to repeat the code to duplicate processing on outbound INVITE 88
Example: Name with Purpose M = {} local function add_reply_to_header(msg)... (function code)... end M.outbound_INVITE = add_reply_to_header return M 89
Name with Purpose Good: Function name describes exactly what it does Can reuse the function without repeating it To use add_reply_to_header for inbound INVITES: M.inbound_INVITE = add_reply_to_header To use add_reply_to_header for outbound INVITES: M.outbound_INVITE = add_reply_to_header Bad: Might search through entire script to figure out the direction and SIP Method 90
Using Script Parameters SIP T&N allows you to set script parameters Available in Unified CM Admin pages Allows deployment of a generic script Provide script with site settings at load time Use same script in multiple locations without rewriting Example: local mydomain = scriptparameters.getvalue("localdomain") local fqdn = host..... mydomain 91
Setting a Script Parameter Access Unified CM Admin Set on the SIP Trunk Configuration page Must know the Parameter Name from the script Parameters are not indexed by Unified CM No pick-list provided 92
Enabling Tracing in Scripts Scripts can write trace information to Unified CM logs Tracing must be enabled in BOTH: Your script Unified CM Configuration Can embed tracing in every script: Use for testing and troubleshooting Disable from Unified CM Admin in production to optimize performance Trace output added to Unified CM SDI Trace 93
Adding Tracing to Your Scripts trace.enable() function M.inbound_NOTIFY(msg) local callid = msg:getheader("call-id") trace.format("m.inbound_notify: callid is '%s'", callid) trace.format(" -- missing URI host, no changes made") 94
Enabling Tracing from Unified CM 95
Case Study 2 96
MWI Lights Don t Light Adapting SIP Notify Problem: Unity Connection provides voicemail for user on multiple vendor PBXs Unity Connection homed to Unified CM SME SME connects to other PBXs via SIP One vendors PBX fails to update MWI status Initial Troubleshooting: Gathered traces: SIP Notify being sent to system Opened case with vendor Software release running on system needs Message-Account in the Notify 97
First Try Add a Message-Account header No detail available on what Notify should look like You need a Message-Account Header Make it look like the To: Header That s easy Use geturi(to) gives me the URI from the To: Use that to add a new header to message: addheader( Message-Account, <uri from geturi>) Turns out it wasn t so easy 98
Revisiting the Problem Discover that Message-Account isn t a SIP Header at least for this release Message-Account should be in the content body Oh, and by the way Can you make sure it is right after the Messages-Waiting line That s a bit more complicated 99
Tackling the Problem Can use the geturi( To ) function to grab the To: header like before You can t edit the content body in place: Read the body and save it: getcontentbody() Delete the current body: removecontentbody() Add updated body: addcontentbody() Easy: Add the Message-Account: line to beginning or end of body Harder content body processing: Add Message-Account: line right after Messages-Waiting: line Don t know where in the body Messages-Waiting: line is Maintain CR-LF terminator on each line of body Use string matching and (partial) substitution 100
Updating the Content Body Before and After Content-Body from Unity Connection: Messages-Waiting: yes Voice-Message: 5/0 (0/0) Fax-Message: 0/0 (0/0) Content-Body desired: Messages-Waiting: yes Message-Account: sip:5000@10.10.10.10 Voice-Message: 5/0 (0/0) Fax-Message: 0/0 (0/0) 101
Build the Script Basics M = {} function M.outbound_NOTIFY(msg)... end return M 102
Create the Message-Account Line -- Get the URI from To: and extract user and host local uristring = msg:geturi("to") local nuri = siputils.parseuri(uristring) nuser = nuri:getuser() nhost = nuri:gethost() -- Build the Message-Account line ma = "Message-Account: sip:".. nuser.. @.. nhost ma = ma.. "\r\n" 103
Update the Content Body -- Set the content type of the body local ct = "application/simple-message-summary" -- Get the existing content body local cb = msg:getcontentbody(ct) -- Build a new content body local ncb = string.gsub(cb, "Messages%-Waiting%:%s%w+%c+", "%0".. ma) -- Have to remove the existing content body and re-add msg:removecontentbody(ct) msg:addcontentbody(ct, ncb) 104
Taking a Look at the String Operation Breaking down the key string operation string.gsub(cb, "Messages%-Waiting%:%s%w+%c+", "%0".. ma) string.gsub takes three arguments: 1. String you want to process 2. String you want to find (match) 3. What you want to replace the matched string with Looking for Messages-Waiting: yes\r\n (or no) Take what we matched: %0 concatenate on the Message-Address we built before get the two lines we want for the Content Body Apply to the SIP trunk going to the offending PBX 105
Lua Demo Testing Your Lua Script Locally Processing Message-Account Test Message 106
A Brief Look at Other Sample Scripts 107
Two Additional Normalization Scripts Set-Silence Modifies SDP to set Silence Suppression off Add-Reply Adds a Header to the SIP INVITE 108
SDP Example: Set Silence Suppression M = {} local function M.outbound_INVITE(msg) local sdp = msg:getsdp() if sdp then sdp = sdp:gsub("a=rtpmap:8 PCMA/8000", "a=rtpmap:8 PCMA/8000\r\na=silenceSupp:off - - - -") msg:setsdp(sdp) end end return M 109
Add Header Example: Add Reply-To Header M = {} local top_level_domain = scriptparameters.getvalue("top-level-domain") local function add_reply_to_header(msg) if not top_level_domain then return end local rpid = msg:getheader("remote-party-id") if not rpid then return end local replacement = string.format("<sip:%s@%s>", "%1", top_level_domain) local reply_to = rpid:gsub("<sip:(.*)@[^>]*>.*", replacement) if reply_to then msg:addheader("reply-to", reply_to) end end M.outbound_INVITE = add_reply_to_header return M 110
Conclusion 111
Some Final Thoughts If you can identify the problem, you can fix it Traces and packet captures are your friend All normalization scripts have same beginnings Just need a few Lua basics Test, write, test, fix, test, then go to production 112
Resources Use these for additional details SIP Chapter in Unified CM System Guide: http://www.cisco.com/en/us/docs/voice_ip_comm/cucm/admin/10_0_1/ccmsys/cucm_ BK_SE5FCFB6_00_cucm-system-guide-100_chapter_0101000.html Developer Guide for SIP Transparency and Normalization http://www.cisco.com/en/us/docs/voice_ip_comm/cucm/sip_tn/9_1_1/sip_t_n.html Cisco Interoperability Portal http://www.cisco.com/go/interoperability Cisco Developer Network http://developer.cisco.com/ 113
Resources: Where to Ask Questions Cisco Developer Network has a SIP Transparency and Normalization Forum Part of the SIP Developer Portal http://developer.cisco.com/web/sip/ community/-/message_boards/ category/3128940 Post questions there and interact with other developers 114
Related / Recommended Sessions Milan 2014 Session Number Session Name Speaker Day BRKUCC-2932 Troubleshooting SIP with Cisco Unified Communications Paul Giralt Tuesday BRKUCC-2934 Implementation and Management of Cisco's Enterprise Session Border Controller - Cisco Unified Border Element Darryl Sladden Tuesday BRKCOL-2020 Cisco Interoperability with Microsoft Tobias Neumann Tuesday BRKUCC-2801 Cisco Expressway at the Collaboration Edge design session Kevin Roarty Tuesday BRKUCC-2008 Enterprise Dial Plan Fundamentals Johannes Krohn Wednesday BRKUCC-2340 Best practices to enable rich-media Collaboration between businesses Viraj Raut Wednesday BRKUCC-2501 Cisco UC Manager Security Kevin Roarty Wednesday Fixing SIP Problems with Cisco Unified Communications Manager's SIP Normalization Tools Mark Stover Thursday BRKUCC-3000 Advanced Dial Plan Design for Unified Communications Networks Johannes Krohn Thursday BRKUCC-2006 SIP Trunk design and deployment in Enterprise UC networks Anthony Mulchrone Friday 115
Questions? Thanks for Attending! I will be in the Meet the Engineer area for walk-in meetings: Thursday from 5-6 Other times by appointment through the MTE Scheduler 116
Key References for SIP T&N 117
Recommended Reading for 118
Call to Action Visit the World of Solutions:- Cisco Campus Walk-in Labs Technical Solutions Clinics Meet the Engineer Lunch Time Table Topics, held in the main Catering Hall Recommended Reading: For reading material and further resources for this session, please visit www.pearson-books.com/clmilan2014 119
Complete Your Online Session Evaluation Give us your feedback and you could win fabulous prizes. Winners announced daily. Receive 20 Cisco Daily Challenge points for each session evaluation you complete. Complete your session evaluation online now through either the mobile app or internet kiosk stations. Maximize your Cisco Live experience with your free Cisco Live 365 account. Download session PDFs, view sessions on-demand and participate in live activities throughout the year. Click the Enter Cisco Live 365 button in your Cisco Live portal to log in. 120