04-23-2013 10:18 PM - edited 03-18-2019 12:59 AM
I have a VCS Control X7.2.1 and CUCM 8.0. The setup is otherwise working correctly except for one issue. When a VCS registered video device is connected with a phone on the CUCM side (internal or on the PSTN), if the phone on the CUCM side hangs up the call, the VCS resgistred video device does not disconnect (the endpoint still shows in the call, the VCS still shows a call is connected). I don't know what it shows on the CUCM side (I am not the admin for the CUCM). Note, this happens only with SIP <-> SIP calls. If the call is internworked (H323 <-> SIP) the call is disconnected properly.
As mentioned, calls are all connecting properly and this is the only issue. For the VCS <-> CUCM zone on the VCS, I am using the CUCM profile that comes with the VCS box. It is a SIP only zone. The VCS's general SIP settings are default.
10-16-2013 01:20 AM
Hi Timothy
Did you find a solution for that?
/Martin
10-16-2013 02:59 PM
Hi Martin,
No I did not find a solution. SIP to SIP calls initiated on the CUCM side will not disconnect.
The ultimate work around is I configured the VCSC search rules to force all VCSC<->CUCM calls to be interworked to H323 on the VCSC side. With the call interworked the problem does not exist.
10-17-2013 05:54 PM
have you checked if you have a VCS interoperability normalisation script enable on the CUCM side of the VCS-CUCM trunk?
here's an example:
--[[
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("<>", "%1", rhs)>
value = value:gsub("<>", 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 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
--[[
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("<>", "%1", rhs)>
value = value:gsub("<>", 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 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
=============================
Please remember to rate useful posts, by clicking on the stars below.
=============================
10-24-2013 02:24 AM
this is a new bug : CSCul01863
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: