session.cxx
来自「MiniSip Client with DomainKeys Authentic」· CXX 代码 · 共 635 行 · 第 1/2 页
CXX
635 行
/* Copyright (C) 2004-2006 the Minisip Team This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library 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 Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA *//* Copyright (C) 2004 * * Authors: Erik Eliasson <eliasson@it.kth.se> * Johan Bilien <jobi@via.ecp.fr> * Joachim Orrblad <joachim@orrblad.com>*/#include <config.h>#include<libminisip/mediahandler/Session.h>#include<libminisip/mediahandler/MediaStream.h>#include<libminisip/mediahandler/Media.h>#include<libminisip/mediahandler/AudioMedia.h>#include<libminisip/mediahandler/RtpReceiver.h>#include<libminisip/mediahandler/DtmfSender.h>#include<libminisip/codecs/Codec.h>#include<libminisip/ipprovider/IpProvider.h>#include<libminisip/sdp/SdpPacket.h>#include<libminisip/sdp/SdpHeaderV.h>#include<libminisip/sdp/SdpHeaderT.h>#include<libminisip/sdp/SdpHeaderC.h>#include<libminisip/sdp/SdpHeaderA.h>#include<libminisip/sdp/SdpHeaderM.h>#include<libminisip/sdp/SdpHeaderS.h>#include<libminisip/sdp/SdpHeaderO.h>#include<libmikey/keyagreement.h>#include<libmikey/keyagreement_dh.h>#include<libmutil/dbg.h>#include<libmutil/itoa.h>#include<libmutil/Timestamp.h>#ifdef _WIN32_WCE# include"../include/minisip_wce_extra_includes.h"#endif#define SESSION_LINE "s=Minisip Session"// pn501 Added for multicodec list operationsusing namespace std;SessionRegistry * Session::registry = NULL;MRef<KeyAgreement *> Session::precomputedKa = NULL;Session::Session( string localIp, SipDialogSecurityConfig &security, SipCommonConfig &common ):ka(NULL),localIpString(localIp){ this->securityConfig = security; // hardcopy this->commonConfig = common; // hardcopy this->ka = Session::precomputedKa; dtmfTOProvider = new TimeoutProvider<DtmfEvent *, MRef<DtmfSender *> >; Session::precomputedKa = NULL; mutedSenders = true; silencedSources = false; if( registry ){ registry->registerSession( this ); }}void Session::unregister(){ if( registry ){ registry->unregisterSession( this ); } if( Session::precomputedKa.isNull() ){ Session::precomputedKa = new KeyAgreementDH( securityConfig.cert, securityConfig.cert_db, DH_GROUP_OAKLEY5 ); }}Session::~Session(){ dtmfTOProvider->stopThread();}MRef<SdpPacket *> Session::emptySdp(){ MRef<SdpPacket *> result; result = new SdpPacket; MRef<SdpHeader*> v = new SdpHeaderV(0); result->addHeader(v); /* FIXME */ string addrtype = "IP4"; MRef<SdpHeader*> o = new SdpHeaderO("","3344","3344","IN", addrtype, localIpString ); result->addHeader(o); MRef<SdpHeader*> s = new SdpHeaderS(SESSION_LINE); result->addHeader(s); MRef<SdpHeader*> c = new SdpHeaderC("IN", addrtype, localIpString ); result->addHeader(c); MRef<SdpHeader*> t = new SdpHeaderT(0,0); result->addHeader(t); return result;}MRef<SdpPacket *> Session::getSdpOffer(){ // used by the initiator when creating the first message MRef<SdpPacket *> result; list< MRef<MediaStreamReceiver *> >::iterator i; std::list<std::string>::iterator iAttribute; std::list<std::string> attributes; string type; uint16_t localPort; MRef<SdpHeaderM *> m; string keyMgmtMessage; std::list<MRef<Codec *> > codecs; std::list<MRef<Codec *> >::iterator iC; uint8_t payloadType; string rtpmap; const char *transport = NULL;// cerr << "Session::getSdpOffer" << endl; result = emptySdp(); if( securityConfig.secured ){ MRef<SdpHeaderA *> a; keyMgmtMessage = initiatorCreate(); //in KeyAgreement.cxx if( ! securityConfig.secured ){ // something went wrong return NULL; } result->setSessionLevelAttribute( "key-mgmt", keyMgmtMessage ); transport = "RTP/SAVP"; } else{ transport = "RTP/AVP"; } for( i = mediaStreamReceivers.begin(); i != mediaStreamReceivers.end(); i++ ){ codecs = (*i)->getAvailableCodecs(); type = (*i)->getSdpMediaType(); localPort = (*i)->getPort(); m = new SdpHeaderM( type, localPort, 1, transport ); for( iC = codecs.begin(); iC != codecs.end(); iC ++ ){ payloadType = (*iC)->getSdpMediaType(); rtpmap = (*iC)->getSdpMediaAttributes(); m->addFormat( payloadType ); if( rtpmap != "" ){ MRef<SdpHeaderA*> a = new SdpHeaderA("a=X"); a->setAttributes( "rtpmap:" + itoa( payloadType) + " " + rtpmap ); m->addAttribute( *a ); } if( (*iC)->getCodecName() == "iLBC" ) { //for now, iLBC codec only supports 20ms frames MRef<SdpHeaderA*> ilbc_fmtp = new SdpHeaderA("a=X"); ilbc_fmtp->setAttributes("fmtp:" + itoa( payloadType) + " mode=20" ); m->addAttribute(*ilbc_fmtp); } } //added static DTMF SDP headers in INVITE m->addFormat(101); MRef<SdpHeaderA*> dtmf = new SdpHeaderA("a=X"); dtmf->setAttributes("rtpmap:101 telephone-event/8000"); m->addAttribute(*dtmf); MRef<SdpHeaderA*> dtmf_fmtp = new SdpHeaderA("a=X"); dtmf_fmtp->setAttributes("fmtp:101 0-15"); m->addAttribute(*dtmf_fmtp); result->addHeader( *m ); attributes = (*i)->getSdpAttributes(); for( iAttribute = attributes.begin(); iAttribute != attributes.end(); iAttribute ++ ){ MRef<SdpHeaderA*> a = new SdpHeaderA("a=X"); a->setAttributes( *iAttribute ); m->addAttribute( *a ); } }#ifdef DEBUG_OUTPUT cerr << "Session::getSdpOffer: " << endl << result->getString() << endl << endl;#endif return result;}bool Session::setSdpAnswer( MRef<SdpPacket *> answer, string peerUri ){ unsigned int i; int j; MRef<MediaStreamReceiver *> receiver; IPAddress * remoteAddress; // Not used int port; this->peerUri = peerUri;#ifdef DEBUG_OUTPUT// cerr << "Session::setSdpAnswer" << endl;#endif if( securityConfig.secured ){ /* get the keymgt: attribute */ string keyMgmtMessage = answer->getSessionLevelAttribute( "key-mgmt" ); if( !initiatorAuthenticate( keyMgmtMessage ) ){ errorString = "Could not authenticate the key management message"; fprintf( stderr, "Auth failed\n"); return false; } string mikeyErrorMsg = initiatorParse(); if( mikeyErrorMsg != "" ){ errorString = "Could not parse the key management message. "; errorString += mikeyErrorMsg; fprintf( stderr, "Parse failed\n"); return false; } /* else{ if( ka && ka->type() == KEY_AGREEMENT_TYPE_DH ){ ((KeyAgreementDH *)*ka)->computeTgk(); } } */ } remoteAddress = answer->getRemoteAddr( port ); for( i = 0; i < answer->getHeaders().size(); i++ ){ if( answer->getHeaders()[i]->getType() == SDP_HEADER_TYPE_M ){ MRef<SdpHeaderM *> m = ((SdpHeaderM*)*(answer->getHeaders()[i]));#ifdef DEBUG_OUTPUT cerr << "Session::setSdpAnswer - trying media line " << m->getString() << endl;#endif for( j = 0; j < m->getNrFormats(); j++ ){ receiver = matchFormat( m, j, remoteAddress );#ifdef DEBUG_OUTPUT if( receiver ) cerr << "Session::setSdpAnswer - Found receiver!" << endl;#endif if( receiver && m->getPort() == 0 ){ /* This offer was rejected */ receiver->disabled = true; } else if( receiver ){ /* Be ready to receive */ receiver->start(); } } } } return true;}MRef<MediaStreamReceiver *> Session::matchFormat( MRef<SdpHeaderM *> m, uint32_t iFormat, IPAddress * remoteAddress ){ list< MRef<MediaStreamSender *> >::iterator iSStream; list< MRef<MediaStreamReceiver *> >::iterator iRStream; /* If we have a sender for this format, activate it */#ifdef DEBUG_OUTPUT mdbg << "Session::matchFormat: Starting senders loop" << end;#endif uint8_t j = 1; mediaStreamSendersLock.lock(); for( iSStream = mediaStreamSenders.begin(); iSStream != mediaStreamSenders.end(); iSStream++,j++ ){#ifdef DEBUG_OUTPUT mdbg << "Trying a sender"<< end;#endif if( (*iSStream)->matches( m, iFormat ) ){#ifdef DEBUG_OUTPUT mdbg << "Found sender for " << (*iSStream)->getSdpMediaType()<< end;#endif#if 0 if( ka ){ ka->addSrtpStream( (*iStream)->getSsrc(), 0, /*ROC */ 0, /* policy (fix me) */ 2*j/* CSID */ ); }#endif (*iSStream)->setPort( (uint16_t)m->getPort() ); (*iSStream)->setRemoteAddress( remoteAddress ); } } mediaStreamSendersLock.unlock(); /* Look for a receiver */#ifdef DEBUG_OUTPUT mdbg << "Starting receivers loop"<< end;#endif for( iRStream = mediaStreamReceivers.begin(); iRStream != mediaStreamReceivers.end(); iRStream ++ ){ if( (*iRStream)->matches( m, iFormat ) ){#ifdef DEBUG_OUTPUT mdbg << "Found receiver for " << (*iRStream)->getSdpMediaType()<< end;#endif return (*iRStream); } } return NULL;}bool Session::setSdpOffer( MRef<SdpPacket *> offer, string peerUri ){ // used by the responder when receiving the first message unsigned int i; int j;
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?