1ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen/* 2ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen * libjingle 3ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen * Copyright 2004--2010, Google Inc. 4ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen * 5ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen * Redistribution and use in source and binary forms, with or without 6ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen * modification, are permitted provided that the following conditions are met: 7ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen * 8ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen * 1. Redistributions of source code must retain the above copyright notice, 9ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen * this list of conditions and the following disclaimer. 10ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen * 2. Redistributions in binary form must reproduce the above copyright notice, 11ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen * this list of conditions and the following disclaimer in the documentation 12ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen * and/or other materials provided with the distribution. 13ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen * 3. The name of the author may not be used to endorse or promote products 14ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen * derived from this software without specific prior written permission. 15ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen * 16ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED 17ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 18ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO 19ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 20ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 21ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 22ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 23ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 24ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 25ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen */ 27ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 28ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "talk/session/phone/rtcpmuxfilter.h" 29ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 30ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "talk/base/logging.h" 31ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 32ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsennamespace cricket { 33ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 34ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian MonsenRtcpMuxFilter::RtcpMuxFilter() : state_(ST_INIT), offer_enable_(false) { 35ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen} 36ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 37ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenbool RtcpMuxFilter::IsActive() const { 38ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // We can receive muxed media prior to the accept, so we have to be able to 39ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // deal with that. 40ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen return (state_ == ST_SENTOFFER || state_ == ST_ACTIVE); 41ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen} 42ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 43ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenbool RtcpMuxFilter::SetOffer(bool offer_enable, ContentSource source) { 44ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen bool ret = false; 45ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen if (state_ == ST_INIT) { 46ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen offer_enable_ = offer_enable; 47ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen state_ = (source == CS_LOCAL) ? ST_SENTOFFER : ST_RECEIVEDOFFER; 48ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen ret = true; 49ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen } else { 50ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen LOG(LS_ERROR) << "Invalid state for RTCP mux offer"; 51ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen } 52ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen return ret; 53ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen} 54ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 55ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenbool RtcpMuxFilter::SetAnswer(bool answer_enable, ContentSource source) { 56ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen bool ret = false; 57ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen if ((state_ == ST_SENTOFFER && source == CS_REMOTE) || 58ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen (state_ == ST_RECEIVEDOFFER && source == CS_LOCAL)) { 59ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen if (offer_enable_) { 60ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen state_ = (answer_enable) ? ST_ACTIVE : ST_INIT; 61ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen ret = true; 62ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen } else { 63ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // If the offer didn't specify RTCP mux, the answer shouldn't either. 64ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen if (!answer_enable) { 65ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen ret = true; 66ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen state_ = ST_INIT; 67ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen } else { 68ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen LOG(LS_WARNING) << "Invalid parameters in RTCP mux answer"; 69ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen } 70ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen } 71ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen } else { 72ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen LOG(LS_ERROR) << "Invalid state for RTCP mux answer"; 73ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen } 74ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen return ret; 75ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen} 76ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 77ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenbool RtcpMuxFilter::DemuxRtcp(const char* data, int len) { 78ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // If we're muxing RTP/RTCP, we must inspect each packet delivered and 79ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // determine whether it is RTP or RTCP. We do so by checking the packet type, 80ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // and assuming RTP if type is 0-63 or 96-127. For additional details, see 81ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // http://tools.ietf.org/html/rfc5761. 82ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // Note that if we offer RTCP mux, we may receive muxed RTCP before we 83ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // receive the answer, so we operate in that state too. 84ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen if (!IsActive()) { 85ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen return false; 86ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen } 87ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 88ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen int type = (len >= 2) ? (static_cast<uint8>(data[1]) & 0x7F) : 0; 89ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen return (type >= 64 && type < 96); 90ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen} 91ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 92ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen} // namespace cricket 93