[ CUCM – VCS ] Provides interoperability for endpoints registered to the Video Communications Server (VCS)

Related Post

  • No related post.

 

[ CUCM – VCS ] Provides interoperability for endpoints registered to the Video Communications Server (VCS)

 

====================== Below is the Script =====================

 

–[[

Description:
Provides interoperability for endpoints registered to the Video Communications Server (VCS)

1. Use configured top-level-domain for calling party number.

2. If Tandberg includes crypto but audio/video profile is AVP, change it to SAVP and
include the X-cisco-srtp-fallback supported option. This allows endpoints to
use SRTP if both sides support it or fallback to RTP if either side does not.

Script Parameters:
top-level-domain —   Configure this parameter if the script needs to convert From,
Remote-Party-ID, and P-Asserted-Identity headers so that the
host portion of the URI is the configured top-level-domain.

Release: 8.6(1)

Copyright (c) 2009-2011 Cisco Systems, Inc. All rights reserved.
All rights reserved.
–]]

M = {}

local top_level_domain = scriptParameters.getValue(“top-level-domain”)

local function getMediaDescriptions(sdp)
— initialize table of media descriptions
local mds = {}

— there won’t be more than 10 media descrpitions; loop below exits on the first index
— that returns nil; that will be the one after the last valid index
for i = 1, 10
do
mds[i] = sdp:getMediaDescription(i)

if not mds[i]
then
— the last one we got was the last media description in this SDP; exit the loop
break
end
end

return mds
end

local function avp_to_savp(md)
— returns modified media descriptions if m-line contains RTP/AVP and there is a crypto line;
— otherwise returns nil if the media descrpition was not modified.
if not md
then
— media description was NOT modified
return nil
end

local crypto = md:getLine(“a=”, “crypto”)

if md:match(“RTP/AVP”) and crypto
then
md = md:gsub(“RTP/AVP”, “RTP/SAVP”)
return md
end

— media description was NOT modified
return nil
end

local function inbound_srtp_fallback(msg, sdp, mds)
for i, md in ipairs(mds)
do
–trace.format(“media description[%d] \n===>\n%s<===\n”, i, md)

local md_savp = avp_to_savp(md)

if md_savp
then
sdp = sdp:modifyMediaDescription(i, md_savp)
end
end

— we may have changed several media descriptions but only need to add the header once
msg:addHeader(“Supported”, “X-cisco-srtp-fallback”)

return sdp
end

local function savp_to_avp(md)
— returns modified media descriptions if m-line contains RTP/SAVP and there is a crypto line;
— otherwise returns nil if the media descrpition was not modified.
if not md
then
— media description was NOT modified
return nil
end

local crypto = md:getLine(“a=”, “crypto”)

if md:match(“RTP/SAVP”) and crypto
then
md = md:gsub(“RTP/SAVP”, “RTP/AVP”)
return md
end

— media description was NOT modified
return nil
end

local function outbound_srtp_fallback(msg, sdp, mds)
for i, md in ipairs(mds)
do
–trace.format(“media description[%d] \n===>\n%s<===\n”, i, md)

local md_avp = savp_to_avp(md)

if md_avp
then
sdp = sdp:modifyMediaDescription(i, md_avp)
end
end

return sdp
end

local function remove_malformed_media_description(sdp)
local mds = getMediaDescriptions(sdp)

local malformed_index = 0

for i, md in ipairs(mds)
do
if md:match(“m=application %d+ RTP/AVP\r?\n”)
then
malformed_index = i
break
end
end

if malformed_index > 0
then
return sdp:removeMediaDescription(malformed_index)
end

return sdp
end

local function process_inbound_SDP(msg)
local sdp = msg:getSdp()

if not sdp
then
— there is no inbound SDP
return
end

local context = msg:getContext()

— get a table (indexed by media level) of the media descriptions
local mds = getMediaDescriptions(sdp)
sdp = inbound_srtp_fallback(msg, sdp, mds)

msg:setSdp(sdp)
end

local function modify_rhs_of_uri(msg, header, rhs)
local value = msg:getHeader(header)

if value and rhs
then
local replacePattern = string.format(“<sip:%s@%s>”, “%1”, rhs)
value = value:gsub(“<sip:(.*)@(.*)>”, replacePattern)
msg:modifyHeader(header, value)
end
end

local function modify_rhs_of_uri_for_calling_party(msg)
if not top_level_domain
then
return
end

modify_rhs_of_uri(msg, “From”, top_level_domain)
modify_rhs_of_uri(msg, “Remote-Party-Id”, top_level_domain)
modify_rhs_of_uri(msg, “P-Asserted-Identity”, top_level_domain)
end

local function process_outbound_SDP(msg, isInvite)
local sdp = msg:getSdp()

if not sdp
then
— there is no outbound SDP
return
end

if isInvite
then
if msg:isInitialInviteRequest()
then
— get a table (indexed by media level) of the media descriptions
local mds = getMediaDescriptions(sdp)
sdp = outbound_srtp_fallback(msg, sdp, mds)
end
end

— remove application media description if it doesn’t contain payloads
sdp = remove_malformed_media_description(sdp)

msg:setSdp(sdp)
end

local function process_outbound_request(msg, isInvite)
modify_rhs_of_uri_for_calling_party(msg)
process_outbound_SDP(msg, isInvite)
end

M.inbound_INVITE     = process_inbound_SDP
M.inbound_18X_INVITE = process_inbound_SDP
M.inbound_200_INVITE = process_inbound_SDP
M.inbound_PRACK      = process_inbound_SDP
M.inbound_200_PRACK  = process_inbound_SDP
M.inbound_ACK        = process_inbound_SDP
M.inbound_UPDATE     = process_inbound_SDP
M.inbound_200_UPDATE = process_inbound_SDP

M.outbound_INVITE     = function(msg)
process_outbound_request(msg, true)
end
M.outbound_18X_INVITE = process_outbound_SDP
M.outbound_200_INVITE = process_outbound_SDP
M.outbound_PRACK      = process_outbound_request
M.outbound_200_PRACK  = process_outbound_SDP
M.outbound_ACK        = process_outbound_request
M.outbound_UPDATE     = process_outbound_request
M.outbound_200_UPDATE = process_outbound_SDP

return M

COMMENTS

  • <cite class="fn">ZBIErmelin</cite>

    It’s difficult to find well-informed people about this subject, however, you sound like you know what you’re talking about! Thanks

Comments are closed.