mirror of
https://git.jami.net/savoirfairelinux/jami-daemon.git
synced 2025-08-12 22:09:25 +08:00
Temporary commit - SDP modification
This commit is contained in:
@ -29,6 +29,7 @@ sflphoned_SOURCES = \
|
||||
call.cpp \
|
||||
account.cpp \
|
||||
sipcall.cpp \
|
||||
sdp.cpp \
|
||||
$(IAXSOURCES)
|
||||
|
||||
sflphoned_CXXFLAGS = \
|
||||
@ -67,7 +68,8 @@ noinst_HEADERS = \
|
||||
accountcreator.h \
|
||||
sipvoiplink.h \
|
||||
call.h \
|
||||
sipcall.h
|
||||
sipcall.h \
|
||||
sdp.h
|
||||
|
||||
libsflphone_la_LIBADD = \
|
||||
$(src)/libs/stund/libstun.la \
|
||||
|
335
src/sdp.cpp
Normal file
335
src/sdp.cpp
Normal file
@ -0,0 +1,335 @@
|
||||
/*
|
||||
* Copyright (C) 2009 Savoir-Faire Linux inc.
|
||||
*
|
||||
* Author: Emmanuel Milou <emmanuel.milou@savoirfairelinux.com>
|
||||
*
|
||||
* This program 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 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program 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., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
#include "sdp.h"
|
||||
#include "global.h"
|
||||
|
||||
#define _SENDRECV 0
|
||||
#define _SENDONLY 1
|
||||
#define _RECVONLY 2
|
||||
|
||||
Sdp::Sdp( pj_pool_t *pool ) : _localSDP(NULL)
|
||||
, _negociator(NULL)
|
||||
, _codecMap()
|
||||
, _ipAddr("")
|
||||
{
|
||||
_pool = pool;
|
||||
}
|
||||
|
||||
Sdp::~Sdp() {}
|
||||
|
||||
bool
|
||||
Sdp::SIPCallInvite(pjsip_rx_data *rdata)
|
||||
{
|
||||
pj_status_t status;
|
||||
|
||||
// We retrieve the remote sdp offer in the rdata struct to begin the negociation
|
||||
pjmedia_sdp_session* remote_sdp = getRemoteSDPFromRequest(rdata);
|
||||
if (remote_sdp == 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Have to do some stuff here with the SDP
|
||||
_localSDP = PJ_POOL_ZALLOC_T(_pool, pjmedia_sdp_session);
|
||||
_localSDP->conn = PJ_POOL_ZALLOC_T(_pool, pjmedia_sdp_conn);
|
||||
|
||||
_localSDP->origin.version = 0;
|
||||
sdpAddOrigin();
|
||||
_localSDP->name = pj_str((char*)"sflphone");
|
||||
sdpAddConnectionInfo();
|
||||
_localSDP->time.start = _localSDP->time.stop = 0;
|
||||
sdpAddMediaDescription();
|
||||
|
||||
status = pjmedia_sdp_validate( _localSDP );
|
||||
if (status != PJ_SUCCESS) {
|
||||
_debug("Can not generate valid local sdp\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
_debug("Before create negociator!\n");
|
||||
status = pjmedia_sdp_neg_create_w_remote_offer(_pool, _localSDP, remote_sdp, &_negociator);
|
||||
if (status != PJ_SUCCESS) {
|
||||
_debug("Can not create negociator\n");
|
||||
return false;
|
||||
}
|
||||
_debug("After create negociator!\n");
|
||||
|
||||
pjmedia_sdp_media* remote_med = getRemoteMedia(remote_sdp);
|
||||
if (remote_med == 0) {
|
||||
_debug("SIP Failure: unable to get remote media\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
_debug("Before set audio!\n");
|
||||
if (!setRemoteAudioFromSDP(remote_sdp, remote_med)) {
|
||||
_debug("SIP Failure: unable to set IP address and port from SDP\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
_debug("Before set codec!\n");
|
||||
if (!setAudioCodecFromSDP(remote_med)) {
|
||||
_debug("SIP Failure: unable to set audio codecs from the remote SDP\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
Sdp::SIPCallAnsweredWithoutHold(pjsip_rx_data *rdata)
|
||||
{
|
||||
pjmedia_sdp_session* remote_sdp = getRemoteSDPFromRequest(rdata);
|
||||
if (remote_sdp == NULL) {
|
||||
_debug("SIP Failure: no remote sdp\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
pjmedia_sdp_media* remote_med = getRemoteMedia(remote_sdp);
|
||||
if (remote_med==NULL) {
|
||||
return false;
|
||||
}
|
||||
|
||||
_debug("Before set audio!\n");
|
||||
if (!setRemoteAudioFromSDP(remote_sdp, remote_med)) {
|
||||
_debug("SIP Failure: unable to set IP address and port from SDP\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
_debug("Before set codec!\n");
|
||||
if (!setAudioCodecFromSDP(remote_med)) {
|
||||
_debug("SIP Failure: unable to set audio codecs from the remote SDP\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
pjmedia_sdp_session*
|
||||
Sdp::getRemoteSDPFromRequest(pjsip_rx_data *rdata)
|
||||
{
|
||||
pjmedia_sdp_session *sdp;
|
||||
pjsip_msg *msg;
|
||||
pjsip_msg_body *body;
|
||||
|
||||
msg = rdata->msg_info.msg;
|
||||
body = msg->body;
|
||||
|
||||
pjmedia_sdp_parse( rdata->tp_info.pool, (char*)body->data, body->len, &sdp );
|
||||
|
||||
return sdp;
|
||||
}
|
||||
|
||||
bool
|
||||
Sdp::setRemoteAudioFromSDP(pjmedia_sdp_session* remote_sdp, pjmedia_sdp_media *remote_med)
|
||||
{
|
||||
std::string remoteIP(remote_sdp->conn->addr.ptr, remote_sdp->conn->addr.slen);
|
||||
_debug(" Remote Audio IP: %s\n", remoteIP.data());
|
||||
//setRemoteIP(remoteIP);
|
||||
int remotePort = remote_med->desc.port;
|
||||
_debug(" Remote Audio Port: %d\n", remotePort);
|
||||
//setRemoteAudioPort(remotePort);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
Sdp::setAudioCodecFromSDP(pjmedia_sdp_media* remote_med)
|
||||
{
|
||||
// Remote Payload
|
||||
int payLoad = -1;
|
||||
int codecCount = remote_med->desc.fmt_count;
|
||||
for(int i = 0; i < codecCount; i++) {
|
||||
payLoad = atoi(remote_med->desc.fmt[i].ptr);
|
||||
if (_codecMap.isActive((AudioCodecType)payLoad))
|
||||
break;
|
||||
|
||||
payLoad = -1;
|
||||
}
|
||||
|
||||
if(payLoad != -1) {
|
||||
_debug(" Payload: %d\n", payLoad);
|
||||
setAudioCodec((AudioCodecType)payLoad);
|
||||
} else
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void Sdp::sdpAddOrigin( void )
|
||||
{
|
||||
pj_time_val tv;
|
||||
pj_gettimeofday(&tv);
|
||||
|
||||
_localSDP->origin.user = pj_str(pj_gethostname()->ptr);
|
||||
// Use Network Time Protocol format timestamp to ensure uniqueness.
|
||||
_localSDP->origin.id = tv.sec + 2208988800UL;
|
||||
// The type of network ( IN for INternet )
|
||||
_localSDP->origin.net_type = pj_str((char*)"IN"); //STR_IN;
|
||||
// The type of address
|
||||
_localSDP->origin.addr_type = pj_str((char*)"IP4"); //STR_IP4;
|
||||
// The address of the machine from which the session was created
|
||||
_localSDP->origin.addr = pj_str( (char*)_ipAddr.c_str() );
|
||||
}
|
||||
|
||||
void Sdp::sdpAddConnectionInfo( void )
|
||||
{
|
||||
_localSDP->conn->net_type = _localSDP->origin.net_type;
|
||||
_localSDP->conn->addr_type = _localSDP->origin.addr_type;
|
||||
_localSDP->conn->addr = _localSDP->origin.addr;
|
||||
}
|
||||
|
||||
void Sdp::sdpAddMediaDescription()
|
||||
{
|
||||
pjmedia_sdp_media* med;
|
||||
pjmedia_sdp_attr *attr;
|
||||
pjmedia_sdp_rtpmap rtpMap;
|
||||
//int nbMedia, i;
|
||||
|
||||
med = PJ_POOL_ZALLOC_T(_pool, pjmedia_sdp_media);
|
||||
//nbMedia = getSDPMediaList().size();
|
||||
_localSDP->media_count = 1;
|
||||
|
||||
med->desc.media = pj_str((char*)"audio");
|
||||
med->desc.port_count = 1;
|
||||
med->desc.port = getLocalExternAudioPort();
|
||||
med->desc.transport = pj_str((char*)"RTP/AVP");
|
||||
|
||||
CodecOrder::iterator itr;
|
||||
|
||||
itr = _codecMap.getActiveCodecs().begin();
|
||||
int count = _codecMap.getActiveCodecs().size();
|
||||
med->desc.fmt_count = count;
|
||||
|
||||
int i = 0;
|
||||
|
||||
while(itr != _codecMap.getActiveCodecs().end()) {
|
||||
std::ostringstream format;
|
||||
format << *itr;
|
||||
pj_strdup2(_pool, &med->desc.fmt[i], format.str().data());
|
||||
|
||||
rtpMap.pt = med->desc.fmt[i];
|
||||
rtpMap.enc_name = pj_str((char *)_codecMap.getCodecName(*itr).data());
|
||||
rtpMap.clock_rate = _codecMap.getSampleRate(*itr);
|
||||
if(_codecMap.getChannel(*itr) > 1) {
|
||||
std::ostringstream channel;
|
||||
channel << _codecMap.getChannel(*itr);
|
||||
rtpMap.param = pj_str((char *)channel.str().data());
|
||||
} else
|
||||
rtpMap.param.slen = 0;
|
||||
|
||||
pjmedia_sdp_rtpmap_to_attr( _pool, &rtpMap, &attr );
|
||||
med->attr[i] = attr;
|
||||
i++;
|
||||
itr++;
|
||||
}
|
||||
|
||||
//FIXME! Add the direction stream
|
||||
attr = (pjmedia_sdp_attr*)pj_pool_zalloc( _pool, sizeof(pjmedia_sdp_attr) );
|
||||
pj_strdup2( _pool, &attr->name, "sendrecv");
|
||||
med->attr[ i++] = attr;
|
||||
med->attr_count = i;
|
||||
|
||||
_localSDP->media[0] = med;
|
||||
/*for( i=0; i<nbMedia; i++ ){
|
||||
getMediaDescriptorLine( getSDPMediaList()[i], pool, &med );
|
||||
this->_local_offer->media[i] = med;
|
||||
} */
|
||||
|
||||
}
|
||||
|
||||
pjmedia_sdp_media* Sdp::getRemoteMedia(pjmedia_sdp_session *remote_sdp)
|
||||
{
|
||||
int count, i;
|
||||
|
||||
count = remote_sdp->media_count;
|
||||
for(i = 0; i < count; ++i) {
|
||||
if(pj_stricmp2(&remote_sdp->media[i]->desc.media, "audio") == 0)
|
||||
return remote_sdp->media[i];
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
bool Sdp::startNegociation()
|
||||
{
|
||||
pj_status_t status;
|
||||
_debug("Before negotiate!\n");
|
||||
status = pjmedia_sdp_neg_negotiate(_pool, _negociator, 0);
|
||||
|
||||
return (status == PJ_SUCCESS);
|
||||
}
|
||||
|
||||
bool Sdp::createInitialOffer()
|
||||
{
|
||||
pj_status_t status;
|
||||
|
||||
// Have to do some stuff here with the SDP
|
||||
_localSDP = PJ_POOL_ZALLOC_T(_pool, pjmedia_sdp_session);
|
||||
_localSDP->conn = PJ_POOL_ZALLOC_T(_pool, pjmedia_sdp_conn);
|
||||
|
||||
_localSDP->origin.version = 0;
|
||||
sdpAddOrigin();
|
||||
_localSDP->name = pj_str((char*)"sflphone");
|
||||
sdpAddConnectionInfo();
|
||||
_localSDP->time.start = _localSDP->time.stop = 0;
|
||||
sdpAddMediaDescription();
|
||||
|
||||
_debug("Before validate SDP!\n");
|
||||
status = pjmedia_sdp_validate( _localSDP );
|
||||
if (status != PJ_SUCCESS) {
|
||||
_debug("Can not generate valid local sdp %d\n", status);
|
||||
return false;
|
||||
}
|
||||
|
||||
_debug("Before create negociator!\n");
|
||||
// Create the SDP negociator instance with local offer
|
||||
status = pjmedia_sdp_neg_create_w_local_offer( _pool, _localSDP, &_negociator);
|
||||
//state = pjmedia_sdp_neg_get_state( _negociator );
|
||||
|
||||
PJ_ASSERT_RETURN( status == PJ_SUCCESS, 1 );
|
||||
|
||||
return true;
|
||||
|
||||
}
|
||||
|
||||
int Sdp::receiving_initial_offer( pjmedia_sdp_session* remote )
|
||||
{
|
||||
// Create the SDP negociator instance by calling
|
||||
// pjmedia_sdp_neg_create_w_remote_offer with the remote offer, and by providing the local offer ( optional )
|
||||
|
||||
pj_status_t status;
|
||||
pjmedia_sdp_neg_state state;
|
||||
|
||||
// Create the SDP negociator instance by calling
|
||||
// pjmedia_sdp_neg_create_w_remote_offer with the remote offer, and by providing the local offer ( optional )
|
||||
|
||||
// Build the local offer to respond
|
||||
createInitialOffer();
|
||||
|
||||
status = pjmedia_sdp_neg_create_w_remote_offer( _pool,
|
||||
getLocalSDPSession(), remote, &_negociator );
|
||||
state = pjmedia_sdp_neg_get_state( _negociator );
|
||||
PJ_ASSERT_RETURN( status == PJ_SUCCESS, 1 );
|
||||
|
||||
return PJ_SUCCESS;
|
||||
|
||||
|
||||
}
|
169
src/sdp.h
Normal file
169
src/sdp.h
Normal file
@ -0,0 +1,169 @@
|
||||
/*
|
||||
* Copyright (C) 2009 Savoir-Faire Linux inc.
|
||||
*
|
||||
* Author: Emmanuel Milou <emmanuel.milou@savoirfairelinux.com>
|
||||
*
|
||||
* This program 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 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program 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., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
#ifndef _SDP_H
|
||||
#define _SDP_H
|
||||
|
||||
#include <pjmedia/sdp.h>
|
||||
#include <pjmedia/sdp_neg.h>
|
||||
#include <pjsip/sip_transport.h>
|
||||
#include <pjlib.h>
|
||||
#include <pj/pool.h>
|
||||
#include <pj/assert.h>
|
||||
|
||||
#include "audio/codecDescriptor.h"
|
||||
|
||||
class Sdp {
|
||||
|
||||
public:
|
||||
|
||||
Sdp(pj_pool_t *pool);
|
||||
|
||||
~Sdp();
|
||||
|
||||
/**
|
||||
* Setup incoming call, and verify for errors, before ringing the user.
|
||||
* @param pjsip_rx_data *rdata
|
||||
* @param pj_pool_t *pool
|
||||
* @return bool True on success
|
||||
* false otherwise
|
||||
*/
|
||||
bool SIPCallInvite(pjsip_rx_data *rdata);
|
||||
|
||||
bool SIPCallAnsweredWithoutHold(pjsip_rx_data *rdata);
|
||||
|
||||
/**
|
||||
* Get the local SDP
|
||||
* @param void
|
||||
* @return _localSDP pjmedia_sdp_session
|
||||
*/
|
||||
pjmedia_sdp_session* getLocalSDPSession( void ) { return _localSDP; }
|
||||
|
||||
/**
|
||||
* Begin negociation of media information between caller and callee
|
||||
* @param pj_pool_t *pool
|
||||
* @return bool True if ok
|
||||
*/
|
||||
bool startNegociation();
|
||||
|
||||
/**
|
||||
* Create the localSDP, media negociation and codec information
|
||||
* @param pj_pool_t *pool
|
||||
* @return void
|
||||
*/
|
||||
bool createInitialOffer();
|
||||
|
||||
/**
|
||||
* Set internal codec Map: initialization only, not protected
|
||||
* @param map The codec map
|
||||
*/
|
||||
void setCodecMap(const CodecDescriptor& map) { _codecMap = map; }
|
||||
|
||||
/**
|
||||
* Save IP Address
|
||||
* @param ip std::string
|
||||
* @return void
|
||||
*/
|
||||
void setIp(std::string ip) {_ipAddr = ip;}
|
||||
|
||||
/**
|
||||
* Get internal codec Map: initialization only, not protected
|
||||
* @return CodecDescriptor The codec map
|
||||
*/
|
||||
CodecDescriptor& getCodecMap();
|
||||
|
||||
void setLocalExternAudioPort(int port){ _localPort = port; }
|
||||
|
||||
int getLocalExternAudioPort (void){ return _localPort; }
|
||||
|
||||
int receiving_initial_offer( pjmedia_sdp_session* remote );
|
||||
|
||||
private:
|
||||
/**
|
||||
* Set the audio codec used. [not protected]
|
||||
* @param audioCodec The payload of the codec
|
||||
*/
|
||||
void setAudioCodec(AudioCodecType audioCodec) { _audioCodec = audioCodec; }
|
||||
|
||||
/** Codec pointer */
|
||||
AudioCodecType _audioCodec;
|
||||
|
||||
/** IP address */
|
||||
std::string _ipAddr;
|
||||
|
||||
int _localPort;
|
||||
|
||||
/**
|
||||
* Get a valid remote media
|
||||
* @param remote_sdp pjmedia_sdp_session*
|
||||
* @return pjmedia_sdp_media*. A valid sdp_media_t or 0
|
||||
*/
|
||||
pjmedia_sdp_media* getRemoteMedia(pjmedia_sdp_session *remote_sdp);
|
||||
|
||||
pjmedia_sdp_session * getRemoteSDPFromRequest (pjsip_rx_data *rdata);
|
||||
|
||||
/**
|
||||
* Set Audio Port and Audio IP from Remote SDP Info
|
||||
* @param remote_med Remote Media info
|
||||
* @param remote_sdp Remote SDP pointer
|
||||
* @return bool True if everything is set correctly
|
||||
*/
|
||||
bool setRemoteAudioFromSDP(pjmedia_sdp_session* remote_sdp, pjmedia_sdp_media* remote_med);
|
||||
|
||||
/**
|
||||
* Set Audio Codec with the remote choice
|
||||
* @param remote_med Remote Media info
|
||||
* @return bool True if everything is set correctly
|
||||
*/
|
||||
bool setAudioCodecFromSDP(pjmedia_sdp_media* remote_med);
|
||||
|
||||
/** Local SDP */
|
||||
pjmedia_sdp_session *_localSDP;
|
||||
pjmedia_sdp_session *_negociated_offer;
|
||||
|
||||
/** negociator */
|
||||
pjmedia_sdp_neg *_negociator;
|
||||
|
||||
// The pool to allocate memory
|
||||
pj_pool_t *_pool;
|
||||
|
||||
/** Codec Map */
|
||||
CodecDescriptor _codecMap;
|
||||
|
||||
/**
|
||||
* Set origin information for local SDP
|
||||
*/
|
||||
void sdpAddOrigin( void );
|
||||
|
||||
/**
|
||||
* Set connection information for local SDP
|
||||
*/
|
||||
void sdpAddConnectionInfo( void );
|
||||
/**
|
||||
* Set media information including codec for localSDP
|
||||
* @param pj_pool_t* pool
|
||||
* @return void
|
||||
*/
|
||||
void sdpAddMediaDescription();
|
||||
|
||||
};
|
||||
|
||||
|
||||
#endif
|
282
src/sipcall.cpp
282
src/sipcall.cpp
@ -23,17 +23,11 @@
|
||||
#include "sipcall.h"
|
||||
#include "global.h" // for _debug
|
||||
|
||||
#define _SENDRECV 0
|
||||
#define _SENDONLY 1
|
||||
#define _RECVONLY 2
|
||||
|
||||
SIPCall::SIPCall(const CallID& id, Call::CallType type) : Call(id, type)
|
||||
, _cid(0)
|
||||
, _did(0)
|
||||
, _tid(0)
|
||||
, _localSDP(NULL)
|
||||
, _negociator(NULL)
|
||||
, _ipAddr("")
|
||||
, _xferSub(NULL)
|
||||
, _invSession(NULL)
|
||||
{
|
||||
@ -43,281 +37,9 @@ SIPCall::SIPCall(const CallID& id, Call::CallType type) : Call(id, type)
|
||||
SIPCall::~SIPCall()
|
||||
{
|
||||
|
||||
_debug("SIPCALL::Destructor for this clss is called \n");
|
||||
delete _local_sdp; _local_sdp = 0;
|
||||
_debug("SIPCALL::Destructor for this clss is called \n");
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
SIPCall::SIPCallInvite(pjsip_rx_data *rdata, pj_pool_t *pool)
|
||||
{
|
||||
pj_status_t status;
|
||||
|
||||
// We retrieve the remote sdp offer in the rdata struct to begin the negociation
|
||||
pjmedia_sdp_session* remote_sdp = getRemoteSDPFromRequest(rdata);
|
||||
if (remote_sdp == 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Have to do some stuff here with the SDP
|
||||
_localSDP = PJ_POOL_ZALLOC_T(pool, pjmedia_sdp_session);
|
||||
_localSDP->conn = PJ_POOL_ZALLOC_T(pool, pjmedia_sdp_conn);
|
||||
|
||||
_localSDP->origin.version = 0;
|
||||
sdpAddOrigin();
|
||||
_localSDP->name = pj_str((char*)"sflphone");
|
||||
sdpAddConnectionInfo();
|
||||
_localSDP->time.start = _localSDP->time.stop = 0;
|
||||
sdpAddMediaDescription(pool);
|
||||
|
||||
status = pjmedia_sdp_validate( _localSDP );
|
||||
if (status != PJ_SUCCESS) {
|
||||
_debug("Can not generate valid local sdp\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
_debug("Before create negociator!\n");
|
||||
status = pjmedia_sdp_neg_create_w_remote_offer(pool, _localSDP, remote_sdp, &_negociator);
|
||||
if (status != PJ_SUCCESS) {
|
||||
_debug("Can not create negociator\n");
|
||||
return false;
|
||||
}
|
||||
_debug("After create negociator!\n");
|
||||
|
||||
pjmedia_sdp_media* remote_med = getRemoteMedia(remote_sdp);
|
||||
if (remote_med == 0) {
|
||||
_debug("SIP Failure: unable to get remote media\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
_debug("Before set audio!\n");
|
||||
if (!setRemoteAudioFromSDP(remote_sdp, remote_med)) {
|
||||
_debug("SIP Failure: unable to set IP address and port from SDP\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
_debug("Before set codec!\n");
|
||||
if (!setAudioCodecFromSDP(remote_med)) {
|
||||
_debug("SIP Failure: unable to set audio codecs from the remote SDP\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
SIPCall::SIPCallAnsweredWithoutHold(pjsip_rx_data *rdata)
|
||||
{
|
||||
pjmedia_sdp_session* remote_sdp = getRemoteSDPFromRequest(rdata);
|
||||
if (remote_sdp == NULL) {
|
||||
_debug("SIP Failure: no remote sdp\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
pjmedia_sdp_media* remote_med = getRemoteMedia(remote_sdp);
|
||||
if (remote_med==NULL) {
|
||||
return false;
|
||||
}
|
||||
|
||||
_debug("Before set audio!\n");
|
||||
if (!setRemoteAudioFromSDP(remote_sdp, remote_med)) {
|
||||
_debug("SIP Failure: unable to set IP address and port from SDP\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
_debug("Before set codec!\n");
|
||||
if (!setAudioCodecFromSDP(remote_med)) {
|
||||
_debug("SIP Failure: unable to set audio codecs from the remote SDP\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
pjmedia_sdp_session*
|
||||
SIPCall::getRemoteSDPFromRequest(pjsip_rx_data *rdata)
|
||||
{
|
||||
pjmedia_sdp_session *sdp;
|
||||
pjsip_msg *msg;
|
||||
pjsip_msg_body *body;
|
||||
|
||||
msg = rdata->msg_info.msg;
|
||||
body = msg->body;
|
||||
|
||||
pjmedia_sdp_parse( rdata->tp_info.pool, (char*)body->data, body->len, &sdp );
|
||||
|
||||
return sdp;
|
||||
}
|
||||
|
||||
bool
|
||||
SIPCall::setRemoteAudioFromSDP(pjmedia_sdp_session* remote_sdp, pjmedia_sdp_media *remote_med)
|
||||
{
|
||||
std::string remoteIP(remote_sdp->conn->addr.ptr, remote_sdp->conn->addr.slen);
|
||||
_debug(" Remote Audio IP: %s\n", remoteIP.data());
|
||||
setRemoteIP(remoteIP);
|
||||
int remotePort = remote_med->desc.port;
|
||||
_debug(" Remote Audio Port: %d\n", remotePort);
|
||||
setRemoteAudioPort(remotePort);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
SIPCall::setAudioCodecFromSDP(pjmedia_sdp_media* remote_med)
|
||||
{
|
||||
// Remote Payload
|
||||
int payLoad = -1;
|
||||
int codecCount = remote_med->desc.fmt_count;
|
||||
for(int i = 0; i < codecCount; i++) {
|
||||
payLoad = atoi(remote_med->desc.fmt[i].ptr);
|
||||
if (_codecMap.isActive((AudioCodecType)payLoad))
|
||||
break;
|
||||
|
||||
payLoad = -1;
|
||||
}
|
||||
|
||||
if(payLoad != -1) {
|
||||
_debug(" Payload: %d\n", payLoad);
|
||||
setAudioCodec((AudioCodecType)payLoad);
|
||||
} else
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void SIPCall::sdpAddOrigin( void )
|
||||
{
|
||||
pj_time_val tv;
|
||||
pj_gettimeofday(&tv);
|
||||
|
||||
_localSDP->origin.user = pj_str(pj_gethostname()->ptr);
|
||||
// Use Network Time Protocol format timestamp to ensure uniqueness.
|
||||
_localSDP->origin.id = tv.sec + 2208988800UL;
|
||||
// The type of network ( IN for INternet )
|
||||
_localSDP->origin.net_type = pj_str((char*)"IN"); //STR_IN;
|
||||
// The type of address
|
||||
_localSDP->origin.addr_type = pj_str((char*)"IP4"); //STR_IP4;
|
||||
// The address of the machine from which the session was created
|
||||
_localSDP->origin.addr = pj_str( (char*)_ipAddr.c_str() );
|
||||
}
|
||||
|
||||
void SIPCall::sdpAddConnectionInfo( void )
|
||||
{
|
||||
_localSDP->conn->net_type = _localSDP->origin.net_type;
|
||||
_localSDP->conn->addr_type = _localSDP->origin.addr_type;
|
||||
_localSDP->conn->addr = _localSDP->origin.addr;
|
||||
}
|
||||
|
||||
void SIPCall::sdpAddMediaDescription(pj_pool_t* pool)
|
||||
{
|
||||
pjmedia_sdp_media* med;
|
||||
pjmedia_sdp_attr *attr;
|
||||
pjmedia_sdp_rtpmap rtpMap;
|
||||
//int nbMedia, i;
|
||||
|
||||
med = PJ_POOL_ZALLOC_T(pool, pjmedia_sdp_media);
|
||||
//nbMedia = getSDPMediaList().size();
|
||||
_localSDP->media_count = 1;
|
||||
|
||||
med->desc.media = pj_str((char*)"audio");
|
||||
med->desc.port_count = 1;
|
||||
med->desc.port = getLocalExternAudioPort();
|
||||
med->desc.transport = pj_str((char*)"RTP/AVP");
|
||||
|
||||
CodecOrder::iterator itr;
|
||||
|
||||
itr = _codecMap.getActiveCodecs().begin();
|
||||
int count = _codecMap.getActiveCodecs().size();
|
||||
med->desc.fmt_count = count;
|
||||
|
||||
int i = 0;
|
||||
|
||||
while(itr != _codecMap.getActiveCodecs().end()) {
|
||||
std::ostringstream format;
|
||||
format << *itr;
|
||||
pj_strdup2(pool, &med->desc.fmt[i], format.str().data());
|
||||
|
||||
rtpMap.pt = med->desc.fmt[i];
|
||||
rtpMap.enc_name = pj_str((char *)_codecMap.getCodecName(*itr).data());
|
||||
rtpMap.clock_rate = _codecMap.getSampleRate(*itr);
|
||||
if(_codecMap.getChannel(*itr) > 1) {
|
||||
std::ostringstream channel;
|
||||
channel << _codecMap.getChannel(*itr);
|
||||
rtpMap.param = pj_str((char *)channel.str().data());
|
||||
} else
|
||||
rtpMap.param.slen = 0;
|
||||
|
||||
pjmedia_sdp_rtpmap_to_attr( pool, &rtpMap, &attr );
|
||||
med->attr[i] = attr;
|
||||
i++;
|
||||
itr++;
|
||||
}
|
||||
|
||||
//FIXME! Add the direction stream
|
||||
attr = (pjmedia_sdp_attr*)pj_pool_zalloc( pool, sizeof(pjmedia_sdp_attr) );
|
||||
pj_strdup2( pool, &attr->name, "sendrecv");
|
||||
med->attr[ i++] = attr;
|
||||
med->attr_count = i;
|
||||
|
||||
_localSDP->media[0] = med;
|
||||
/*for( i=0; i<nbMedia; i++ ){
|
||||
getMediaDescriptorLine( getSDPMediaList()[i], pool, &med );
|
||||
this->_local_offer->media[i] = med;
|
||||
} */
|
||||
|
||||
}
|
||||
|
||||
pjmedia_sdp_media* SIPCall::getRemoteMedia(pjmedia_sdp_session *remote_sdp)
|
||||
{
|
||||
int count, i;
|
||||
|
||||
count = remote_sdp->media_count;
|
||||
for(i = 0; i < count; ++i) {
|
||||
if(pj_stricmp2(&remote_sdp->media[i]->desc.media, "audio") == 0)
|
||||
return remote_sdp->media[i];
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
bool SIPCall::startNegociation(pj_pool_t *pool)
|
||||
{
|
||||
pj_status_t status;
|
||||
_debug("Before negotiate!\n");
|
||||
status = pjmedia_sdp_neg_negotiate(pool, _negociator, 0);
|
||||
|
||||
return (status == PJ_SUCCESS);
|
||||
}
|
||||
|
||||
bool SIPCall::createInitialOffer(pj_pool_t *pool)
|
||||
{
|
||||
pj_status_t status;
|
||||
|
||||
// Have to do some stuff here with the SDP
|
||||
_localSDP = PJ_POOL_ZALLOC_T(pool, pjmedia_sdp_session);
|
||||
_localSDP->conn = PJ_POOL_ZALLOC_T(pool, pjmedia_sdp_conn);
|
||||
|
||||
_localSDP->origin.version = 0;
|
||||
sdpAddOrigin();
|
||||
_localSDP->name = pj_str((char*)"sflphone");
|
||||
sdpAddConnectionInfo();
|
||||
_localSDP->time.start = _localSDP->time.stop = 0;
|
||||
sdpAddMediaDescription(pool);
|
||||
|
||||
_debug("Before validate SDP!\n");
|
||||
status = pjmedia_sdp_validate( _localSDP );
|
||||
if (status != PJ_SUCCESS) {
|
||||
_debug("Can not generate valid local sdp %d\n", status);
|
||||
return false;
|
||||
}
|
||||
|
||||
_debug("Before create negociator!\n");
|
||||
// Create the SDP negociator instance with local offer
|
||||
status = pjmedia_sdp_neg_create_w_local_offer( pool, _localSDP, &_negociator);
|
||||
//state = pjmedia_sdp_neg_get_state( _negociator );
|
||||
|
||||
PJ_ASSERT_RETURN( status == PJ_SUCCESS, 1 );
|
||||
|
||||
return true;
|
||||
|
||||
}
|
||||
|
107
src/sipcall.h
107
src/sipcall.h
@ -23,7 +23,6 @@
|
||||
|
||||
#include "call.h"
|
||||
#include "sipvoiplink.h"
|
||||
#include "audio/codecDescriptor.h"
|
||||
|
||||
class AudioCodec;
|
||||
|
||||
@ -78,51 +77,13 @@ class SIPCall : public Call
|
||||
*/
|
||||
int getTid() { return _tid; }
|
||||
|
||||
|
||||
/**
|
||||
* Transaction identifier
|
||||
* @param tid SIP transaction id
|
||||
*/
|
||||
void setTid(int tid) { _tid = tid; }
|
||||
|
||||
/**
|
||||
* Setup incoming call, and verify for errors, before ringing the user.
|
||||
* @param pjsip_rx_data *rdata
|
||||
* @param pj_pool_t *pool
|
||||
* @return bool True on success
|
||||
* false otherwise
|
||||
*/
|
||||
bool SIPCallInvite(pjsip_rx_data *rdata, pj_pool_t *pool);
|
||||
|
||||
bool SIPCallAnsweredWithoutHold(pjsip_rx_data *rdata);
|
||||
|
||||
/**
|
||||
* Save IP Address
|
||||
* @param ip std::string
|
||||
* @return void
|
||||
*/
|
||||
void setIp(std::string ip) {_ipAddr = ip;}
|
||||
|
||||
/**
|
||||
* Get the local SDP
|
||||
* @param void
|
||||
* @return _localSDP pjmedia_sdp_session
|
||||
*/
|
||||
pjmedia_sdp_session* getLocalSDPSession( void ) { return _localSDP; }
|
||||
|
||||
/**
|
||||
* Begin negociation of media information between caller and callee
|
||||
* @param pj_pool_t *pool
|
||||
* @return bool True if ok
|
||||
*/
|
||||
bool startNegociation(pj_pool_t *pool);
|
||||
|
||||
/**
|
||||
* Create the localSDP, media negociation and codec information
|
||||
* @param pj_pool_t *pool
|
||||
* @return void
|
||||
*/
|
||||
bool createInitialOffer(pj_pool_t *pool);
|
||||
|
||||
void setXferSub(pjsip_evsub* sub) {_xferSub = sub;}
|
||||
pjsip_evsub *getXferSub() {return _xferSub;}
|
||||
|
||||
@ -131,74 +92,16 @@ class SIPCall : public Call
|
||||
|
||||
private:
|
||||
|
||||
int _cid;
|
||||
int _did;
|
||||
int _tid;
|
||||
|
||||
// Copy Constructor
|
||||
SIPCall(const SIPCall& rh);
|
||||
|
||||
// Assignment Operator
|
||||
SIPCall& operator=( const SIPCall& rh);
|
||||
|
||||
/**
|
||||
* Get a valid remote SDP or return a 400 bad request response if invalid
|
||||
* @param
|
||||
* @return
|
||||
*/
|
||||
pjmedia_sdp_session* getRemoteSDPFromRequest(pjsip_rx_data *rdata);
|
||||
|
||||
/**
|
||||
* Get a valid remote media
|
||||
* @param remote_sdp pjmedia_sdp_session*
|
||||
* @return pjmedia_sdp_media*. A valid sdp_media_t or 0
|
||||
*/
|
||||
pjmedia_sdp_media* getRemoteMedia(pjmedia_sdp_session *remote_sdp);
|
||||
|
||||
/**
|
||||
* Set Audio Port and Audio IP from Remote SDP Info
|
||||
* @param remote_med Remote Media info
|
||||
* @param remote_sdp Remote SDP pointer
|
||||
* @return bool True if everything is set correctly
|
||||
*/
|
||||
bool setRemoteAudioFromSDP(pjmedia_sdp_session* remote_sdp, pjmedia_sdp_media* remote_med);
|
||||
|
||||
/**
|
||||
* Set Audio Codec with the remote choice
|
||||
* @param remote_med Remote Media info
|
||||
* @return bool True if everything is set correctly
|
||||
*/
|
||||
bool setAudioCodecFromSDP(pjmedia_sdp_media* remote_med);
|
||||
|
||||
/** SIP call id */
|
||||
int _cid;
|
||||
|
||||
/** SIP domain id */
|
||||
int _did;
|
||||
|
||||
/** SIP transaction id */
|
||||
int _tid;
|
||||
|
||||
/** Local SDP */
|
||||
pjmedia_sdp_session *_localSDP;
|
||||
|
||||
/** negociator */
|
||||
pjmedia_sdp_neg *_negociator;
|
||||
|
||||
/**
|
||||
* Set origin information for local SDP
|
||||
*/
|
||||
void sdpAddOrigin( void );
|
||||
|
||||
/**
|
||||
* Set connection information for local SDP
|
||||
*/
|
||||
void sdpAddConnectionInfo( void );
|
||||
/**
|
||||
* Set media information including codec for localSDP
|
||||
* @param pj_pool_t* pool
|
||||
* @return void
|
||||
*/
|
||||
void sdpAddMediaDescription(pj_pool_t* pool);
|
||||
|
||||
/** IP address */
|
||||
std::string _ipAddr;
|
||||
|
||||
pjsip_evsub *_xferSub;
|
||||
pjsip_inv_session *_invSession;
|
||||
|
@ -27,6 +27,8 @@
|
||||
|
||||
/**************** EXTERN VARIABLES AND FUNCTIONS (callbacks) **************************/
|
||||
|
||||
int getModId();
|
||||
|
||||
/*
|
||||
* The global pool factory
|
||||
*/
|
||||
@ -53,7 +55,6 @@ pjsip_module _mod_ua;
|
||||
pj_thread_t *thread;
|
||||
pj_thread_desc desc;
|
||||
|
||||
|
||||
/**
|
||||
* Get the number of voicemail waiting in a SIP message
|
||||
*/
|
||||
@ -107,6 +108,8 @@ void call_on_forked(pjsip_inv_session *inv, pjsip_event *e);
|
||||
*/
|
||||
void call_on_tsx_changed(pjsip_inv_session *inv, pjsip_transaction *tsx, pjsip_event *e);
|
||||
|
||||
void on_rx_offer( pjsip_inv_session *inv, const pjmedia_sdp_session *offer );
|
||||
|
||||
/*
|
||||
* Registration callback
|
||||
*/
|
||||
@ -205,6 +208,7 @@ SIPVoIPLink::terminate()
|
||||
delete _evThread; _evThread = NULL;
|
||||
}
|
||||
|
||||
|
||||
/* Clean shutdown of pjsip library */
|
||||
if( initDone() )
|
||||
{
|
||||
@ -453,7 +457,7 @@ SIPVoIPLink::answer(const CallID& id)
|
||||
}
|
||||
|
||||
// User answered the incoming call, tell peer this news
|
||||
if (call->startNegociation(_pool)) {
|
||||
if (call->startNegociation()) {
|
||||
// Create and send a 200(OK) response
|
||||
_debug("UserAgent: Negociation success!\n");
|
||||
status = pjsip_inv_answer(call->getInvSession(), PJSIP_SC_OK, NULL, NULL, &tdata);
|
||||
@ -904,14 +908,14 @@ SIPVoIPLink::SIPStartCall(SIPCall* call, const std::string& subject UNUSED)
|
||||
PJ_ASSERT_RETURN(status == PJ_SUCCESS, false);
|
||||
|
||||
setCallAudioLocal(call, getLocalIPAddress(), useStun(), getStunServer());
|
||||
call->setIp(getLocalIP());
|
||||
_local_sdp->setIp(getLocalIP());
|
||||
|
||||
// Building the local SDP offer
|
||||
call->createInitialOffer(_pool);
|
||||
_local_sdp->createInitialOffer();
|
||||
|
||||
// Create the invite session for this call
|
||||
pjsip_inv_session *inv;
|
||||
status = pjsip_inv_create_uac(dialog, call->getLocalSDPSession(), 0, &inv);
|
||||
status = pjsip_inv_create_uac(dialog, _local_sdp->getLocalSDPSession(), 0, &inv);
|
||||
PJ_ASSERT_RETURN(status == PJ_SUCCESS, false);
|
||||
|
||||
// Set auth information
|
||||
@ -980,6 +984,7 @@ std::string SIPVoIPLink::getSipTo(const std::string& to_url, std::string hostnam
|
||||
call->setLocalIp(localIP);
|
||||
call->setLocalAudioPort(callLocalAudioPort);
|
||||
call->setLocalExternAudioPort(callLocalExternAudioPort);
|
||||
_local_sdp->setLocalExternAudioPort(callLocalExternAudioPort);
|
||||
|
||||
return true;
|
||||
}
|
||||
@ -1056,7 +1061,7 @@ std::string SIPVoIPLink::getSipTo(const std::string& to_url, std::string hostnam
|
||||
|
||||
if (call->getConnectionState() != Call::Connected) {
|
||||
//call->SIPCallAnswered(event);
|
||||
call->SIPCallAnsweredWithoutHold(rdata);
|
||||
_local_sdp->SIPCallAnsweredWithoutHold(rdata);
|
||||
|
||||
call->setConnectionState(Call::Connected);
|
||||
call->setState(Call::Active);
|
||||
@ -1241,6 +1246,7 @@ std::string SIPVoIPLink::getSipTo(const std::string& to_url, std::string hostnam
|
||||
inv_cb.on_new_session = &call_on_forked;
|
||||
inv_cb.on_media_update = &call_on_media_update;
|
||||
inv_cb.on_tsx_state_changed = &call_on_tsx_changed;
|
||||
inv_cb.on_rx_offer = &on_rx_offer;
|
||||
|
||||
// Initialize session invite module
|
||||
status = pjsip_inv_usage_init(_endpt, &inv_cb);
|
||||
@ -1258,6 +1264,10 @@ std::string SIPVoIPLink::getSipTo(const std::string& to_url, std::string hostnam
|
||||
// Register "application/sdp" in ACCEPT header
|
||||
pjsip_endpt_add_capability(_endpt, &_mod_ua, PJSIP_H_ACCEPT, NULL, 1, &accepted);
|
||||
|
||||
|
||||
/* Create the SDP object */
|
||||
_local_sdp = new Sdp (_pool);
|
||||
|
||||
_debug("UserAgent: pjsip version %s for %s initialized\n", pj_get_version(), PJ_OS_NAME);
|
||||
|
||||
// Create the secondary thread to poll sip events
|
||||
@ -1434,7 +1444,7 @@ std::string SIPVoIPLink::getSipTo(const std::string& to_url, std::string hostnam
|
||||
/* Done. */
|
||||
}
|
||||
|
||||
int SIPVoIPLink::getModId(){
|
||||
int getModId(){
|
||||
return _mod_ua.id;
|
||||
}
|
||||
|
||||
@ -1481,6 +1491,7 @@ std::string SIPVoIPLink::getSipTo(const std::string& to_url, std::string hostnam
|
||||
|
||||
PJ_UNUSED_ARG(inv);
|
||||
|
||||
|
||||
SIPCall *call = reinterpret_cast<SIPCall*> (inv->mod_data[_mod_ua.id]);
|
||||
if(!call)
|
||||
return;
|
||||
@ -1568,6 +1579,8 @@ std::string SIPVoIPLink::getSipTo(const std::string& to_url, std::string hostnam
|
||||
rdata = e->body.tsx_state.src.rdata;
|
||||
|
||||
if (tsx->role == PJSIP_ROLE_UAC) {
|
||||
|
||||
|
||||
switch (tsx->state) {
|
||||
case PJSIP_TSX_STATE_TERMINATED:
|
||||
if (tsx->status_code == 200 &&
|
||||
@ -1665,6 +1678,7 @@ std::string SIPVoIPLink::getSipTo(const std::string& to_url, std::string hostnam
|
||||
}
|
||||
break;
|
||||
default:
|
||||
_debug("default: %i\n", tsx->status_code);
|
||||
break;
|
||||
} // end of switch
|
||||
}
|
||||
@ -1833,9 +1847,9 @@ std::string SIPVoIPLink::getSipTo(const std::string& to_url, std::string hostnam
|
||||
|
||||
// Set the codec map, IP, peer number and so on... for the SIPCall object
|
||||
setCallAudioLocal(call, link->getLocalIPAddress(), link->useStun(), link->getStunServer());
|
||||
call->setCodecMap(Manager::instance().getCodecDescriptorMap());
|
||||
_local_sdp->setCodecMap(Manager::instance().getCodecDescriptorMap());
|
||||
call->setConnectionState(Call::Progressing);
|
||||
call->setIp(link->getLocalIPAddress());
|
||||
_local_sdp->setIp(link->getLocalIPAddress());
|
||||
call->setPeerNumber(peerNumber);
|
||||
|
||||
/* Call the SIPCallInvite function to generate the local sdp,
|
||||
@ -1845,7 +1859,7 @@ std::string SIPVoIPLink::getSipTo(const std::string& to_url, std::string hostnam
|
||||
* remote IP and port number
|
||||
* possilbe audio codec will be used in this call
|
||||
*/
|
||||
if (call->SIPCallInvite(rdata, _pool)) {
|
||||
if (_local_sdp->SIPCallInvite(rdata)) {
|
||||
|
||||
// Notify UI there is an incoming call
|
||||
if (Manager::instance().incomingCall(call, account_id)) {
|
||||
@ -1876,7 +1890,7 @@ std::string SIPVoIPLink::getSipTo(const std::string& to_url, std::string hostnam
|
||||
|
||||
// Specify media capability during invite session creation
|
||||
pjsip_inv_session *inv;
|
||||
status = pjsip_inv_create_uas(dialog, rdata, call->getLocalSDPSession(), 0, &inv);
|
||||
status = pjsip_inv_create_uas(dialog, rdata, _local_sdp->getLocalSDPSession(), 0, &inv);
|
||||
PJ_ASSERT_RETURN(status == PJ_SUCCESS, 1);
|
||||
|
||||
// Associate the call in the invite session
|
||||
@ -2287,3 +2301,20 @@ std::string SIPVoIPLink::getSipTo(const std::string& to_url, std::string hostnam
|
||||
_debug("UserAgent: Xfer server subscription terminated\n");
|
||||
}
|
||||
}
|
||||
|
||||
void on_rx_offer( pjsip_inv_session *inv, const pjmedia_sdp_session *offer ){
|
||||
PJ_UNUSED_ARG( inv );
|
||||
|
||||
SIPCall *call;
|
||||
pj_status_t status;
|
||||
|
||||
call = (SIPCall*)inv->mod_data[getModId()];
|
||||
if (!call)
|
||||
return;
|
||||
|
||||
_local_sdp->receiving_initial_offer( (pjmedia_sdp_session*)offer);
|
||||
status=pjsip_inv_set_sdp_answer( call->getInvSession(), _local_sdp->getLocalSDPSession() );
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
@ -33,7 +33,6 @@
|
||||
#include <pjnath/stun_config.h>
|
||||
///////////////////////////////
|
||||
|
||||
|
||||
class EventThread;
|
||||
class SIPCall;
|
||||
class AudioRtp;
|
||||
@ -42,7 +41,7 @@ class AudioRtp;
|
||||
#define RANDOM_SIP_PORT rand() % 64000 + 1024
|
||||
|
||||
// To set the verbosity. From 0 (min) to 6 (max)
|
||||
#define PJ_LOG_LEVEL 1
|
||||
#define PJ_LOG_LEVEL 6
|
||||
|
||||
/**
|
||||
* @file sipvoiplink.h
|
||||
@ -309,7 +308,6 @@ class SIPVoIPLink : public VoIPLink
|
||||
static SIPVoIPLink* _instance;
|
||||
|
||||
void busy_sleep(unsigned msec);
|
||||
int getModId();
|
||||
|
||||
/**
|
||||
* Initialize the PJSIP library
|
||||
|
Reference in New Issue
Block a user