From 0390cd894a08933b52fc3d62fec1bded2f6473dc Mon Sep 17 00:00:00 2001 From: Stefan Sayer Date: Tue, 16 Aug 2011 20:56:44 +0200 Subject: [PATCH] b/f: add missing payload names to SDP when filtered missing payload descriptions (a line in SDP) valid for known payloads with pt < 69 would lead the SDP filter which matches on the codec name to fail. sdp_filter=transparent/blacklist/whitelist enables normalization of SDP if sdp_filter is not set, no normalization is done. --- apps/sbc/RTPParameters.cpp | 69 ++++++++++++++++++++++++++++++++++++++ apps/sbc/RTPParameters.h | 39 +++++++++++++++++++++ apps/sbc/SBC.cpp | 20 +++++++---- apps/sbc/SDPFilter.cpp | 39 ++++++++++++++++++++- apps/sbc/SDPFilter.h | 3 ++ 5 files changed, 163 insertions(+), 7 deletions(-) create mode 100644 apps/sbc/RTPParameters.cpp create mode 100644 apps/sbc/RTPParameters.h diff --git a/apps/sbc/RTPParameters.cpp b/apps/sbc/RTPParameters.cpp new file mode 100644 index 00000000..80c3f586 --- /dev/null +++ b/apps/sbc/RTPParameters.cpp @@ -0,0 +1,69 @@ +/* + * Copyright (C) 2011 Stefan Sayer + * + * This file is part of SEMS, a free SIP media server. + * + * SEMS is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * For a license to use the SEMS software under conditions + * other than those described here, or to purchase support for this + * software, please contact iptel.org by e-mail at the following addresses: + * info@iptel.org + * + * SEMS is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include "RTPParameters.h" + +const iana_rtp_payload IANA_RTP_PAYLOADS[IANA_RTP_PAYLOADS_SIZE] = { + // from http://www.iana.org/assignments/rtp-parameters + { "PCMU", true, 8000, 1}, // 0 PCMU A 8000 1 [RFC3551] + { "", true, 0, 0}, // 1 Reserved + { "", true, 0, 0}, // 2 Reserved + { "GSM", true, 8000, 1}, // 3 GSM A 8000 1 [RFC3551] + { "G723", true, 8000, 1}, // 4 G723 A 8000 1 [Kumar][RFC3551] + { "DVI4", true, 8000, 1}, // 5 DVI4 A 8000 1 [RFC3551] + { "DVI4", true, 16000, 1}, // 6 DVI4 A 16000 1 [RFC3551] + { "LPC", true, 8000, 1}, // 7 LPC A 8000 1 [RFC3551] + { "PCMA", true, 8000, 1}, // 8 PCMA A 8000 1 [RFC3551] + { "G722", true, 8000, 1}, // 9 G722 A 8000 1 [RFC3551] + { "L16", true, 44100, 2}, // 10 L16 A 44100 2 [RFC3551] + { "L16", true, 44100, 1}, // 11 L16 A 44100 1 [RFC3551] + { "QCELP",true, 8000, 1}, // 12 QCELP A 8000 1 [RFC3551] + { "CN", true, 8000, 1}, // 13 CN A 8000 1 [RFC3389] + { "MPA", true, 90000, 0}, // 14 MPA A 90000 [RFC3551][RFC2250] + { "G728", true, 8000, 1}, // 15 G728 A 8000 1 [RFC3551] + { "DVI4", true, 11025, 1}, // 16 DVI4 A 11025 1 [DiPol] + { "DVI4", true, 22050, 1}, // 17 DVI4 A 22050 1 [DiPol] + { "G729", true, 8000, 1}, // 18 G729 A 8000 1 [RFC3551] + { "", true, 0, 0}, // 19 Reserved A + { "", true, 0, 0}, // 20 Unassigned A + { "", true, 0, 0}, // 21 Unassigned A + { "", true, 0, 0}, // 22 Unassigned A + { "", true, 0, 0}, // 23 Unassigned A + { "", true, 0, 0}, // 24 Unassigned V + { "CelB", false, 90000, 0}, // 25 CelB V 90000 [RFC2029] + { "JPEG", false, 90000, 0}, // 26 JPEG V 90000 [RFC2435] + { "", false, 0, 0}, // 27 Unassigned V + { "nv", false, 90000, 0}, // 28 nv V 90000 [RFC3551] + { "", false, 0, 0}, // 29 Unassigned V + { "", false, 0, 0}, // 30 Unassigned V + { "H261", false, 90000, 0}, // 31 H261 V 90000 [RFC4587] + { "MPV", false, 90000, 0}, // 32 MPV V 90000 [RFC2250] + { "MP2T", false, 90000, 0}, // 33 MP2T AV 90000 [RFC2250] + { "H263", false, 90000, 0} // 34 H263 V 90000 [Zhu] + // 35-71 Unassigned ? + // 72-76 Reserved for RTCP conflict avoidance [RFC3551] + // 77-95 Unassigned ? + // 96-127 dynamic ? [RFC3551] +}; diff --git a/apps/sbc/RTPParameters.h b/apps/sbc/RTPParameters.h new file mode 100644 index 00000000..efec8045 --- /dev/null +++ b/apps/sbc/RTPParameters.h @@ -0,0 +1,39 @@ +/* + * Copyright (C) 2011 Stefan Sayer + * + * This file is part of SEMS, a free SIP media server. + * + * SEMS is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * For a license to use the SEMS software under conditions + * other than those described here, or to purchase support for this + * software, please contact iptel.org by e-mail at the following addresses: + * info@iptel.org + * + * SEMS is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef _RTPParameters_h_ +#define _RTPParameters_h_ + +struct iana_rtp_payload { + const char* payload_name; + bool is_audio; + unsigned int clock_rate; + unsigned int channels; +}; + +#define IANA_RTP_PAYLOADS_SIZE 35 +extern const iana_rtp_payload IANA_RTP_PAYLOADS[IANA_RTP_PAYLOADS_SIZE]; + +#endif diff --git a/apps/sbc/SBC.cpp b/apps/sbc/SBC.cpp index e3d8a762..f429cb4f 100644 --- a/apps/sbc/SBC.cpp +++ b/apps/sbc/SBC.cpp @@ -787,9 +787,13 @@ int SBCDialog::relayEvent(AmEvent* ev) { } int SBCDialog::filterBody(AmSdp& sdp, bool is_a2b) { - if (call_profile.sdpfilter_enabled && - call_profile.sdpfilter != Transparent) { - filterSDP(sdp, call_profile.sdpfilter, call_profile.sdpfilter_list); + if (call_profile.sdpfilter_enabled) { + // normalize SDP + normalizeSDP(sdp); + // filter SDP + if (call_profile.sdpfilter != Transparent) { + filterSDP(sdp, call_profile.sdpfilter, call_profile.sdpfilter_list); + } } return 0; } @@ -1220,9 +1224,13 @@ void SBCCalleeSession::onSendRequest(const string& method, const string& content } int SBCCalleeSession::filterBody(AmSdp& sdp, bool is_a2b) { - if (call_profile.sdpfilter_enabled && - call_profile.sdpfilter != Transparent) { - filterSDP(sdp, call_profile.sdpfilter, call_profile.sdpfilter_list); + if (call_profile.sdpfilter_enabled) { + // normalize SDP + normalizeSDP(sdp); + // filter SDP + if (call_profile.sdpfilter != Transparent) { + filterSDP(sdp, call_profile.sdpfilter, call_profile.sdpfilter_list); + } } return 0; } diff --git a/apps/sbc/SDPFilter.cpp b/apps/sbc/SDPFilter.cpp index 37f5c096..add2f4c3 100644 --- a/apps/sbc/SDPFilter.cpp +++ b/apps/sbc/SDPFilter.cpp @@ -26,7 +26,8 @@ #include "SDPFilter.h" #include #include "log.h" - +#include "AmUtils.h" +#include "RTPParameters.h" int filterSDP(AmSdp& sdp, FilterType sdpfilter, const std::set& sdpfilter_list) { @@ -59,3 +60,39 @@ int filterSDP(AmSdp& sdp, FilterType sdpfilter, const std::set& sdpfilte return 0; } + +void fix_missing_encodings(SdpMedia& m) { + for (std::vector::iterator p_it= + m.payloads.begin(); p_it!=m.payloads.end(); p_it++) { + SdpPayload& p = *p_it; + if (!p.encoding_name.empty()) + continue; + if (p.payload_type > (IANA_RTP_PAYLOADS_SIZE-1) || p.payload_type < 0) + continue; // todo: throw out this payload + if (IANA_RTP_PAYLOADS[p.payload_type].payload_name[0]=='\0') + continue; // todo: throw out this payload + + p.encoding_name = IANA_RTP_PAYLOADS[p.payload_type].payload_name; + p.clock_rate = IANA_RTP_PAYLOADS[p.payload_type].clock_rate; + if (IANA_RTP_PAYLOADS[p.payload_type].channels > 1) + p.encoding_param = IANA_RTP_PAYLOADS[p.payload_type].channels; + + DBG("named SDP payload type %d with %s/%d%s\n", + p.payload_type, IANA_RTP_PAYLOADS[p.payload_type].payload_name, + IANA_RTP_PAYLOADS[p.payload_type].clock_rate, + IANA_RTP_PAYLOADS[p.payload_type].channels > 1 ? + ("/"+int2str(IANA_RTP_PAYLOADS[p.payload_type].channels)).c_str() : ""); + } +} + +int normalizeSDP(AmSdp& sdp) { + for (std::vector::iterator m_it= + sdp.media.begin(); m_it != sdp.media.end(); m_it++) { + if (m_it->type != MT_AUDIO && m_it->type != MT_VIDEO) + continue; + + // fill missing encoding names (a= lines) + fix_missing_encodings(*m_it); + } + return 0; +} diff --git a/apps/sbc/SDPFilter.h b/apps/sbc/SDPFilter.h index 1fe06a4e..84856466 100644 --- a/apps/sbc/SDPFilter.h +++ b/apps/sbc/SDPFilter.h @@ -37,4 +37,7 @@ using std::string; int filterSDP(AmSdp& sdp, FilterType sdpfilter, const std::set& sdpfilter_list); +/** normalize SDP, fixing some common issues */ +int normalizeSDP(AmSdp& sdp); + #endif