Cisco Phone not receiving calls from a 3rd party PBX via SIP-Trunk

Today I had an issue on an incoming SIP Trunk from an Avaya PBX to a CUCM. The calling name of the Avaya users included a “greater as”-sign ( > ). This mixed up the Contact field on CUCM and the phones were sending back a “400 Bad Request”.

In the incoming INVITE, the Contact field looked like this:

Contact: “John Doe >1000” <;transport=tls;gsid=80b03730-2d3d-4a01-958f-5bff121d0000>

The CUCM then sent it to the phone like this:

Contact: <;transport=tcp>1000″ <;transport=tls;gsid=80644a7a-4f3c-4a01-9830-5bff121d0000>

The phone came back with a 400:

SIP/2.0 400 Bad Request
Via: SIP/2.0/TCP;branch=z9hG4bK5391c7ca89d90
From: “John Doe >1000” < >;tag=2812787~ab46fa2c-6c59-41ed-818f-ce5a53804375-44072776
To: <>
Session-ID: 157ee9db00105000a0000072784970f4;remote=9f1f3bd2c18dc694892250dab2812786
Date: Wed, 22 Jan 2020 10:11:04 GMT
Warning: 399 Cisco-CP8851 “Bad Request – ‘Malformed/Missing Contact field'”
CSeq: 101 INVITE
Content-Length: 0

As you can see, the CUCM malformed the Contact fiel with putting the “>1000” after the first part:

Contact: <;transport=tcp>1000″ <;transport=tls;gsid=80644a7a-4f3c-4a01-9830-5bff121d0000>

Because it was not possible to change all the names in the Avaya system because of different reasons, I had to fix it on the CUCM. I decided to create a SIP Normalization script, which removes the calling name from the INVITE coming from the Avaya PBX.

After the normalization, the Contact field looked then like this:


The CUCM can now handle the correctly and the phones are receiving the calls.

An interesting thing we saw, the calls which were routed to an MRA-Device via Expressway, could receive the calls despite the issue. Probably the Expressway could handle the malformed INVITE or does not check the Contact Field.

Here the script I’ve created:

M = {}
function M.inbound_ANY(msg)
trace.format(“Fix malformed contact” )
— Get Contact-Info Header. If there was no Call-Info header then return
local contactInfo = msg:getHeader(“Contact”)
if not contactInfo
trace.format(“Contact is empty, returning” )
trace.format(“ContactInfo is %s”, contactInfo )
— extract the contact-Info
local start_contact = string.find(contactInfo, “sip:”)
local contact_new = string.sub(contactInfo, start_contact-1)
trace.format(“ContactInfo New is %s”, contact_new )
— replace the header
msg:modifyHeader(“Contact”, contact_new)
trace.format(“header modified”)
return M

Leave a Reply

Your email address will not be published. Required fields are marked *