Skip to content
GitLab
Menu
Projects
Groups
Snippets
/
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Sign in / Register
Toggle navigation
Menu
Open sidebar
savoirfairelinux
jami-daemon
Commits
13dadfa2
Commit
13dadfa2
authored
Sep 19, 2011
by
Rafaël Carré
Browse files
* #6905 : SIP refactor
parent
f498e9ed
Changes
5
Hide whitespace changes
Inline
Side-by-side
daemon/src/managerimpl.cpp
View file @
13dadfa2
...
...
@@ -576,22 +576,15 @@ void ManagerImpl::transferSucceded ()
bool
ManagerImpl
::
attendedTransfer
(
const
std
::
string
&
transferID
,
const
std
::
string
&
targetID
)
{
bool
returnValue
;;
if
(
getConfigFromCall
(
transferID
)
==
Call
::
IPtoIP
)
return
SIPVoIPLink
::
instance
()
->
attendedTransfer
(
transferID
,
targetID
);
// Direct IP to IP call
if
(
getConfigFromCall
(
transferID
)
==
Call
::
IPtoIP
)
returnValue
=
SIPVoIPLink
::
instance
()
->
attendedTransfer
(
transferID
,
targetID
);
else
{
// Classic call, attached to an account
std
::
string
accountid
=
getAccountFromCall
(
transferID
);
if
(
accountid
.
empty
())
return
false
;
returnValue
=
getAccountLink
(
accountid
)
->
attendedTransfer
(
transferID
,
targetID
);
}
getMainBuffer
()
->
stateInfo
();
// Classic call, attached to an account
std
::
string
accountid
=
getAccountFromCall
(
transferID
);
if
(
accountid
.
empty
())
return
false
;
return
returnValue
;
return
getAccountLink
(
accountid
)
->
attendedTransfer
(
transferID
,
targetID
)
;
}
//THREAD=Main : Call:Incoming
...
...
@@ -2682,7 +2675,7 @@ bool ManagerImpl::associateCallToAccount (const std::string& callID,
return
false
;
}
std
::
string
ManagerImpl
::
getAccountFromCall
(
const
std
::
string
&
callID
)
std
::
string
ManagerImpl
::
getAccountFromCall
(
const
std
::
string
&
callID
)
{
ost
::
MutexLock
m
(
_callAccountMapMutex
);
CallAccountMap
::
iterator
iter
=
_callAccountMap
.
find
(
callID
);
...
...
daemon/src/sip/sipaccount.cpp
View file @
13dadfa2
...
...
@@ -43,7 +43,7 @@ SIPAccount::SIPAccount (const std::string& accountID)
,
transport
(
NULL
)
,
regc_
(
NULL
)
,
bRegister_
(
false
)
,
registrationExpire_
(
""
)
,
registrationExpire_
(
600
)
,
interface_
(
"default"
)
,
publishedSameasLocal_
(
true
)
,
publishedIpAddress_
(
""
)
...
...
@@ -102,7 +102,9 @@ void SIPAccount::serialize (Conf::YamlEmitter *emitter)
Conf
::
ScalarNode
hostname
(
Account
::
hostname_
);
Conf
::
ScalarNode
enable
(
enabled_
);
Conf
::
ScalarNode
type
(
Account
::
type_
);
Conf
::
ScalarNode
expire
(
registrationExpire_
);
std
::
stringstream
expirevalstr
;
expirevalstr
<<
registrationExpire_
;
Conf
::
ScalarNode
expire
(
expirevalstr
);
Conf
::
ScalarNode
interface
(
interface_
);
std
::
stringstream
portstr
;
portstr
<<
localPort_
;
...
...
@@ -381,7 +383,7 @@ void SIPAccount::setAccountDetails (std::map<std::string, std::string> details)
stunEnabled_
=
details
[
STUN_ENABLE
]
==
"true"
;
dtmfType_
=
details
[
ACCOUNT_DTMF_TYPE
]
==
"overrtp"
?
OVERRTP
:
SIPINFO
;
registrationExpire_
=
details
[
CONFIG_ACCOUNT_REGISTRATION_EXPIRE
];
registrationExpire_
=
atoi
(
details
[
CONFIG_ACCOUNT_REGISTRATION_EXPIRE
]
.
c_str
())
;
userAgent_
=
details
[
USERAGENT
];
...
...
@@ -464,7 +466,9 @@ std::map<std::string, std::string> SIPAccount::getAccountDetails() const
a
[
ROUTESET
]
=
serviceRoute_
;
a
[
USERAGENT
]
=
userAgent_
;
a
[
CONFIG_ACCOUNT_REGISTRATION_EXPIRE
]
=
registrationExpire_
;
std
::
stringstream
expireval
;
expireval
<<
registrationExpire_
;
a
[
CONFIG_ACCOUNT_REGISTRATION_EXPIRE
]
=
expireval
.
str
();
a
[
LOCAL_INTERFACE
]
=
interface_
;
a
[
PUBLISHED_SAMEAS_LOCAL
]
=
publishedSameasLocal_
?
"true"
:
"false"
;
a
[
PUBLISHED_ADDRESS
]
=
publishedIpAddress_
;
...
...
@@ -619,8 +623,8 @@ void SIPAccount::initStunConfiguration (void)
void
SIPAccount
::
loadConfig
()
{
if
(
registrationExpire_
.
empty
()
)
registrationExpire_
=
"
600
"
;
/** Default expire value for registration */
if
(
registrationExpire_
==
0
)
registrationExpire_
=
600
;
/** Default expire value for registration */
if
(
tlsEnable_
==
"true"
)
{
initTlsConfiguration
();
...
...
daemon/src/sip/sipaccount.h
View file @
13dadfa2
...
...
@@ -165,19 +165,21 @@ class SIPAccount : public Account
* interval that indicates how long the client would like the
* registration to be valid.
*
* @return
A string describing
the expiration value.
* @return the expiration value.
*/
const
std
::
string
&
getRegistrationExpire
(
void
)
const
{
return
registrationExpire_
;
unsigned
getRegistrationExpire
(
void
)
const
{
if
(
registrationExpire_
==
0
)
return
PJSIP_REGC_EXPIRATION_NOT_SPECIFIED
;
return
registrationExpire_
;
}
/**
* Setting the Expiration Interval of Contact Addresses.
*
* @param A string describing the expiration value.
* Doubles the Expiration Interval of Contact Addresses.
*/
void
setRegistrationExpire
(
const
std
::
string
&
expr
)
{
registrationExpire_
=
expr
;
void
doubleRegistrationExpire
(
void
)
{
registrationExpire_
*=
2
;
if
(
registrationExpire_
<
0
)
registrationExpire_
=
0
;
}
bool
fullMatch
(
const
std
::
string
&
username
,
const
std
::
string
&
hostname
)
const
;
...
...
@@ -444,7 +446,7 @@ class SIPAccount : public Account
bool
bRegister_
;
// Network settings
std
::
str
in
g
registrationExpire_
;
in
t
registrationExpire_
;
// interface name on which this account is bound
std
::
string
interface_
;
...
...
daemon/src/sip/sipvoiplink.cpp
View file @
13dadfa2
...
...
@@ -53,7 +53,6 @@
#include
"im/InstantMessaging.h"
#include
"audio/audiolayer.h"
#include
"audio/audiortp/AudioRtpFactory.h"
#include
"pjsip/sip_endpoint.h"
#include
"pjsip/sip_transport_tls.h"
...
...
@@ -76,8 +75,8 @@
using
namespace
sfl
;
namespace
{
/** The default transport (5060) */
static
pjsip_transport
*
_localUDPTransport
=
NULL
;
static
pjsip_transport
*
_localUDPTransport
=
NULL
;
/** The default transport (5060) */
/** A map to retreive SFLphone internal call id
* Given a SIP call ID (usefull for transaction sucha as transfer)*/
...
...
@@ -270,19 +269,13 @@ SIPVoIPLink::getEvent()
if
(
!
pj_thread_is_registered
())
pj_thread_register
(
NULL
,
desc
,
&
thread
);
// PJSIP polling
pj_time_val
timeout
=
{
0
,
10
};
static
const
pj_time_val
timeout
=
{
0
,
10
};
pjsip_endpt_handle_events
(
_endpt
,
&
timeout
);
}
void
SIPVoIPLink
::
sendRegister
(
Account
*
a
)
{
SIPAccount
*
account
=
static_cast
<
SIPAccount
*>
(
a
);
if
(
account
->
transport
)
pjsip_transport_dec_ref
(
account
->
transport
);
createSipTransport
(
account
);
account
->
setRegister
(
true
);
...
...
@@ -303,12 +296,7 @@ void SIPVoIPLink::sendRegister (Account *a)
pj_str_t
pjContact
=
pj_str
((
char
*
)
contact
.
c_str
());
pj_str_t
pjSrv
=
pj_str
((
char
*
)
srvUri
.
c_str
());
int
expire_value
=
atoi
(
account
->
getRegistrationExpire
().
c_str
());
if
(
!
expire_value
)
expire_value
=
PJSIP_REGC_EXPIRATION_NOT_SPECIFIED
;
if
(
pjsip_regc_init
(
regc
,
&
pjSrv
,
&
pjFrom
,
&
pjFrom
,
1
,
&
pjContact
,
expire_value
)
!=
PJ_SUCCESS
)
if
(
pjsip_regc_init
(
regc
,
&
pjSrv
,
&
pjFrom
,
&
pjFrom
,
1
,
&
pjContact
,
account
->
getRegistrationExpire
())
!=
PJ_SUCCESS
)
throw
VoipLinkException
(
"Unable to initialize account registration structure"
);
if
(
!
account
->
getServiceRoute
().
empty
())
...
...
@@ -567,10 +555,8 @@ SIPVoIPLink::offhold (const std::string& id)
sdpSession
->
removeAttributeFromLocalAudioMedia
(
"sendrecv"
);
sdpSession
->
removeAttributeFromLocalAudioMedia
(
"sendonly"
);
sdpSession
->
addAttributeToLocalAudioMedia
(
"sendrecv"
);
/* Create re-INVITE with new offer */
if
(
SIPSessionReinvite
(
call
)
==
PJ_SUCCESS
)
call
->
setState
(
Call
::
Active
);
}
...
...
@@ -596,33 +582,16 @@ SIPVoIPLink::sendTextMessage (sfl::InstantMessaging *module, const std::string&
module
->
send_sip_message
(
call
->
inv
,
callID
,
module
->
appendUriList
(
message
,
list
));
}
void
SIPVoIPLink
::
transfer
(
const
std
::
string
&
id
,
const
std
::
string
&
to
)
bool
SIPVoIPLink
::
transfer
Common
(
SIPCall
*
call
,
pj_str_t
*
dst
)
{
SIPCall
*
call
=
getSIPCall
(
id
);
call
->
stopRecording
();
std
::
string
account_id
(
Manager
::
instance
().
getAccountFromCall
(
id
));
SIPAccount
*
account
=
dynamic_cast
<
SIPAccount
*>
(
Manager
::
instance
().
getAccount
(
account_id
));
if
(
account
==
NULL
)
throw
VoipLinkException
(
"Could not find account"
);
std
::
string
dest
;
pj_str_t
pjDest
;
if
(
to
.
find
(
"@"
)
==
std
::
string
::
npos
)
{
dest
=
account
->
getToUri
(
to
);
pj_cstr
(
&
pjDest
,
dest
.
c_str
());
}
pjsip_evsub_user
xfer_cb
;
pj_bzero
(
&
xfer_cb
,
sizeof
(
xfer_cb
));
xfer_cb
.
on_evsub_state
=
&
transfer_client_cb
;
pjsip_evsub
*
sub
;
if
(
pjsip_xfer_create_uac
(
call
->
inv
->
dlg
,
&
xfer_cb
,
&
sub
)
!=
PJ_SUCCESS
)
throw
VoipLinkException
(
"Could not create xfer request"
)
;
return
false
;
/* Associate this voiplink of call with the client subscription
* We can not just associate call with the client subscription
...
...
@@ -636,8 +605,8 @@ SIPVoIPLink::transfer (const std::string& id, const std::string& to)
*/
pjsip_tx_data
*
tdata
;
if
(
pjsip_xfer_initiate
(
sub
,
&
pjDe
st
,
&
tdata
)
!=
PJ_SUCCESS
)
throw
VoipLinkException
(
"Could not create REFER request"
)
;
if
(
pjsip_xfer_initiate
(
sub
,
d
st
,
&
tdata
)
!=
PJ_SUCCESS
)
return
false
;
// Put SIP call id in map in order to retrieve call during transfer callback
std
::
string
callidtransfer
(
call
->
inv
->
dlg
->
call_id
->
id
.
ptr
,
call
->
inv
->
dlg
->
call_id
->
id
.
slen
);
...
...
@@ -645,68 +614,57 @@ SIPVoIPLink::transfer (const std::string& id, const std::string& to)
/* Send. */
if
(
pjsip_xfer_send_request
(
sub
,
tdata
)
!=
PJ_SUCCESS
)
throw
VoipLinkException
(
"Could not send xfer request"
);
return
false
;
return
true
;
}
bool
SIPVoIPLink
::
attendedTransfer
(
const
std
::
string
&
transferId
,
const
std
::
string
&
targetId
)
void
SIPVoIPLink
::
transfer
(
const
std
::
string
&
id
,
const
std
::
string
&
to
)
{
char
str_dest_buf
[
PJSIP_MAX_URL_SIZE
*
2
];
SIPCall
*
call
=
getSIPCall
(
id
);
call
->
stopRecording
();
std
::
string
account_id
(
Manager
::
instance
().
getAccountFromCall
(
id
));
SIPAccount
*
account
=
dynamic_cast
<
SIPAccount
*>
(
Manager
::
instance
().
getAccount
(
account_id
));
if
(
account
==
NULL
)
throw
VoipLinkException
(
"Could not find account"
);
pjsip_dialog
*
target_dlg
=
getSIPCall
(
targetId
)
->
inv
->
dlg
;
std
::
string
toUri
;
pj_str_t
dst
=
{
NULL
,
0
};
/* Print URI */
pj_str_t
str_dest
=
{
NULL
,
0
}
;
str_dest_buf
[
0
]
=
'<'
;
str_dest
.
slen
=
1
;
if
(
to
.
find
(
"@"
)
==
std
::
string
::
npos
)
{
toUri
=
account
->
getToUri
(
to
)
;
pj_cstr
(
&
dst
,
toUri
.
c_str
())
;
}
if
(
!
transferCommon
(
getSIPCall
(
id
),
&
dst
))
throw
VoipLinkException
(
"Couldn't transfer"
);
}
bool
SIPVoIPLink
::
attendedTransfer
(
const
std
::
string
&
id
,
const
std
::
string
&
to
)
{
pjsip_dialog
*
target_dlg
=
getSIPCall
(
to
)
->
inv
->
dlg
;
pjsip_uri
*
uri
=
(
pjsip_uri
*
)
pjsip_uri_get_uri
(
target_dlg
->
remote
.
info
->
uri
);
int
len
=
pjsip_uri_print
(
PJSIP_URI_IN_REQ_URI
,
uri
,
str_dest_buf
+
1
,
sizeof
(
str_dest_buf
)
-
1
);
str_dest
.
slen
+=
len
;
len
=
pj_ansi_snprintf
(
str_dest_buf
+
str_dest
.
slen
,
sizeof
(
str_dest_buf
)
-
str_dest
.
slen
,
char
str_dest_buf
[
PJSIP_MAX_URL_SIZE
*
2
]
=
{
'<'
};
pj_str_t
dst
=
{
str_dest_buf
,
1
};
dst
.
slen
+=
pjsip_uri_print
(
PJSIP_URI_IN_REQ_URI
,
uri
,
str_dest_buf
+
1
,
sizeof
(
str_dest_buf
)
-
1
);
dst
.
slen
+=
pj_ansi_snprintf
(
str_dest_buf
+
dst
.
slen
,
sizeof
(
str_dest_buf
)
-
dst
.
slen
,
"?"
"Replaces=%.*s"
"%%3Bto-tag%%3D%.*s"
"%%3Bfrom-tag%%3D%.*s>"
,
(
int
)
target_dlg
->
call_id
->
id
.
slen
,
target_dlg
->
call_id
->
id
.
ptr
,
target_dlg
->
call_id
->
id
.
ptr
,
(
int
)
target_dlg
->
remote
.
info
->
tag
.
slen
,
target_dlg
->
remote
.
info
->
tag
.
ptr
,
target_dlg
->
remote
.
info
->
tag
.
ptr
,
(
int
)
target_dlg
->
local
.
info
->
tag
.
slen
,
target_dlg
->
local
.
info
->
tag
.
ptr
);
str_dest
.
ptr
=
str_dest_buf
;
str_dest
.
slen
+=
len
;
SIPCall
*
transferCall
=
getSIPCall
(
transferId
);
/* Create xfer client subscription. */
struct
pjsip_evsub_user
xfer_cb
;
pj_bzero
(
&
xfer_cb
,
sizeof
(
xfer_cb
));
xfer_cb
.
on_evsub_state
=
&
transfer_client_cb
;
pjsip_evsub
*
sub
;
if
(
pjsip_xfer_create_uac
(
transferCall
->
inv
->
dlg
,
&
xfer_cb
,
&
sub
)
!=
PJ_SUCCESS
)
return
false
;
target_dlg
->
local
.
info
->
tag
.
ptr
);
/* Associate this voiplink of call with the client subscription
* We can not just associate call with the client subscription
* because after this function, we can no find the cooresponding
* voiplink from the call any more. But the voiplink is useful!
*/
pjsip_evsub_set_mod_data
(
sub
,
_mod_ua
.
id
,
this
);
pjsip_tx_data
*
tdata
;
if
(
pjsip_xfer_initiate
(
sub
,
&
str_dest
,
&
tdata
)
!=
PJ_SUCCESS
)
return
false
;
// Put SIP call id in map in order to retrieve call during transfer callback
pj_str_t
*
callidtr
=
&
transferCall
->
inv
->
dlg
->
call_id
->
id
;
transferCallID
[
std
::
string
(
callidtr
->
ptr
,
callidtr
->
slen
)]
=
transferCall
->
getCallId
();
return
pjsip_xfer_send_request
(
sub
,
tdata
)
==
PJ_SUCCESS
;
return
transferCommon
(
getSIPCall
(
id
),
&
dst
);
}
bool
...
...
@@ -924,6 +882,7 @@ bool SIPVoIPLink::SIPNewIpToIpCall (const std::string& id, const std::string& to
return
false
;
}
shutdownSipTransport
(
account
);
createTlsTransport
(
account
,
remoteAddr
);
if
(
!
account
->
transport
)
{
delete
call
;
...
...
@@ -1020,7 +979,6 @@ void SIPVoIPLink::createTlsListener (SIPAccount *account, pjsip_tpfactory **list
void
SIPVoIPLink
::
createTlsTransport
(
SIPAccount
*
account
,
std
::
string
remoteAddr
)
{
account
->
transport
=
NULL
;
pj_str_t
remote
;
pj_cstr
(
&
remote
,
remoteAddr
.
c_str
());
...
...
@@ -1037,6 +995,8 @@ void SIPVoIPLink::createTlsTransport (SIPAccount *account, std::string remoteAdd
void
SIPVoIPLink
::
createSipTransport
(
SIPAccount
*
account
)
{
shutdownSipTransport
(
account
);
if
(
account
->
isTlsEnabled
())
{
std
::
string
remoteSipUri
(
account
->
getServerUri
());
size_t
sips
=
remoteSipUri
.
find
(
"<sips:"
)
+
6
;
...
...
@@ -1063,7 +1023,6 @@ void SIPVoIPLink::createSipTransport (SIPAccount *account)
void
SIPVoIPLink
::
createUdpTransport
(
SIPAccount
*
account
)
{
account
->
transport
=
NULL
;
std
::
string
listeningAddress
;
pj_uint16_t
listeningPort
=
account
->
getLocalPort
();
...
...
@@ -1117,7 +1076,6 @@ pjsip_tpselector *SIPVoIPLink::initTransportSelector (pjsip_transport *transport
void
SIPVoIPLink
::
createStunTransport
(
SIPAccount
*
account
)
{
account
->
transport
=
NULL
;
pj_str_t
stunServer
=
account
->
getStunServerName
();
pj_uint16_t
stunPort
=
account
->
getStunPort
();
...
...
@@ -1577,13 +1535,12 @@ void registration_cb (struct pjsip_regc_cbparam *param)
account
->
setRegistrationState
(
ErrorAuth
);
account
->
setRegister
(
false
);
SIPVoIPLink
::
instance
()
->
shutdownSipTransport
(
account
);
SIPVoIPLink
::
instance
()
->
shutdownSipTransport
(
account
);
return
;
}
if
(
param
->
code
<
0
||
param
->
code
>=
300
)
{
switch
(
param
->
code
)
{
case
606
:
account
->
setRegistrationState
(
ErrorConfStun
);
break
;
...
...
@@ -1600,16 +1557,7 @@ void registration_cb (struct pjsip_regc_cbparam *param)
break
;
case
423
:
{
// Expiration Interval Too Brief
int
expire_value
;
std
::
istringstream
stream
(
account
->
getRegistrationExpire
());
stream
>>
expire_value
;
std
::
stringstream
out
;
out
<<
(
expire_value
*
2
);
std
::
string
s
=
out
.
str
();
account
->
setRegistrationExpire
(
s
);
account
->
doubleRegistrationExpire
();
account
->
registerVoIPLink
();
}
break
;
...
...
@@ -1634,27 +1582,23 @@ void registration_cb (struct pjsip_regc_cbparam *param)
}
/**
* Helper function to parse incoming OPTION message
*/
static
void
handleIncomingOptions
(
pjsip_rx_data
*
rdata
)
{
pjsip_tx_data
*
tdata
;
if
(
pjsip_endpt_create_response
(
_endpt
,
rdata
,
PJSIP_SC_OK
,
NULL
,
&
tdata
)
!=
PJ_SUCCESS
)
return
;
#define ADD_CAP(cap) do { \
const pjsip_hdr *cap_hdr = pjsip_endpt_get_capability(_endpt, cap, NULL); \
if (cap_hdr) \
pjsip_msg_add_hdr (tdata->msg, (pjsip_hdr*) pjsip_hdr_clone (tdata->pool, cap_hdr)); \
} while(0)
#define ADD_HDR(hdr) do { \
const pjsip_hdr *cap_hdr = hdr; \
if (cap_hdr) \
pjsip_msg_add_hdr (tdata->msg, (pjsip_hdr*) pjsip_hdr_clone (tdata->pool, cap_hdr)); \
} while(0)
#define ADD_CAP(cap) ADD_HDR(pjsip_endpt_get_capability(_endpt, cap, NULL));
ADD_CAP
(
PJSIP_H_ALLOW
);
ADD_CAP
(
PJSIP_H_ACCEPT
);
ADD_CAP
(
PJSIP_H_SUPPORTED
);
const
pjsip_hdr
*
cap_hdr
=
pjsip_evsub_get_allow_events_hdr
(
NULL
);
if
(
cap_hdr
)
pjsip_msg_add_hdr
(
tdata
->
msg
,
(
pjsip_hdr
*
)
pjsip_hdr_clone
(
tdata
->
pool
,
cap_hdr
));
ADD_HDR
(
pjsip_evsub_get_allow_events_hdr
(
NULL
));
pjsip_response_addr
res_addr
;
pjsip_get_response_addr
(
tdata
->
pool
,
rdata
,
&
res_addr
);
...
...
@@ -1664,41 +1608,20 @@ static void handleIncomingOptions (pjsip_rx_data *rdata)
}
// Optional function to be called to process incoming request message.
pj_bool_t
transaction_request_cb
(
pjsip_rx_data
*
rdata
)
static
pj_bool_t
transaction_request_cb
(
pjsip_rx_data
*
rdata
)
{
pjsip_method
*
method
=
&
rdata
->
msg_info
.
msg
->
line
.
req
.
method
;
if
(
method
->
id
==
PJSIP_ACK_METHOD
&&
pjsip_rdata_get_dlg
(
rdata
))
return
true
;
/* First, let's got the username and server name from the invite.
* We will use them to detect which account is the callee.
*/
pjsip_sip_uri
*
sip_to_uri
=
(
pjsip_sip_uri
*
)
pjsip_uri_get_uri
(
rdata
->
msg_info
.
to
->
uri
);
pjsip_sip_uri
*
sip_from_uri
=
(
pjsip_sip_uri
*
)
pjsip_uri_get_uri
(
rdata
->
msg_info
.
from
->
uri
);
std
::
string
userName
(
sip_to_uri
->
user
.
ptr
,
sip_to_uri
->
user
.
slen
);
std
::
string
server
(
sip_from_uri
->
host
.
ptr
,
sip_from_uri
->
host
.
slen
);
// Get the account id of callee from username and server
std
::
string
account_id
(
Manager
::
instance
().
getAccountIdFromNameAndServer
(
userName
,
server
));
/* If we don't find any account to receive the call */
/* Get the voip link associated to the incoming call */
/* The account must before have been associated to the call in ManagerImpl */
SIPVoIPLink
*
link
=
dynamic_cast
<
SIPVoIPLink
*>
(
Manager
::
instance
().
getAccountLink
(
account_id
));
assert
(
link
);
std
::
string
displayName
(
parseDisplayName
(
rdata
->
msg_info
.
msg_buf
));
/* Now, it is the time to find the information of the caller */
// Store the peer number
char
tmp
[
PJSIP_MAX_URL_SIZE
];
int
length
=
pjsip_uri_print
(
PJSIP_URI_IN_FROMTO_HDR
,
sip_from_uri
,
tmp
,
PJSIP_MAX_URL_SIZE
);
std
::
string
peerNumber
(
tmp
,
length
);
stripSipUriPrefix
(
peerNumber
);
if
(
method
->
id
==
PJSIP_OTHER_METHOD
)
{
pj_str_t
*
str
=
&
method
->
name
;
std
::
string
request
(
str
->
ptr
,
str
->
slen
);
...
...
@@ -1743,7 +1666,6 @@ transaction_request_cb (pjsip_rx_data *rdata)
UrlHook
::
runAction
(
Manager
::
instance
().
hookPreference
.
getUrlCommand
(),
header_value
);
}
SIPCall
*
call
=
new
SIPCall
(
Manager
::
instance
().
getNewCallID
(),
Call
::
Incoming
,
_cp
);
Manager
::
instance
().
associateCallToAccount
(
call
->
getCallId
(),
account_id
);
...
...
@@ -1753,11 +1675,7 @@ transaction_request_cb (pjsip_rx_data *rdata)
?
account
->
getPublishedAddress
()
:
addrToUse
;
pjsip_transport
*
transport
=
account
->
transport
;
assert
(
transport
);
// Set the appropriate transport to have the right VIA header
pjsip_tpselector
*
tp
=
link
->
initTransportSelector
(
transport
,
call
->
getMemoryPool
());
pjsip_tpselector
*
tp
=
SIPVoIPLink
::
instance
()
->
initTransportSelector
(
account
->
transport
,
call
->
getMemoryPool
());
if
(
addrToUse
==
"0.0.0.0"
)
addrToUse
=
loadSIPLocalIP
();
...
...
@@ -1765,6 +1683,11 @@ transaction_request_cb (pjsip_rx_data *rdata)
if
(
addrSdp
==
"0.0.0.0"
)
addrSdp
=
addrToUse
;
char
tmp
[
PJSIP_MAX_URL_SIZE
];
int
length
=
pjsip_uri_print
(
PJSIP_URI_IN_FROMTO_HDR
,
sip_from_uri
,
tmp
,
PJSIP_MAX_URL_SIZE
);
std
::
string
peerNumber
(
tmp
,
length
);
stripSipUriPrefix
(
peerNumber
);
call
->
setConnectionState
(
Call
::
Progressing
);
call
->
setPeerNumber
(
peerNumber
);
call
->
setDisplayName
(
displayName
);
...
...
@@ -1777,7 +1700,6 @@ transaction_request_cb (pjsip_rx_data *rdata)
call
->
getAudioRtp
()
->
initAudioRtpConfig
();
call
->
getAudioRtp
()
->
initAudioSymmetricRtpSession
();
// Retreive crypto offer from body, if any
if
(
rdata
->
msg_info
.
msg
->
body
)
{
char
sdpbuffer
[
1000
];
int
len
=
rdata
->
msg_info
.
msg
->
body
->
print_body
(
rdata
->
msg_info
.
msg
->
body
,
sdpbuffer
,
sizeof
sdpbuffer
);
...
...
@@ -1804,7 +1726,6 @@ transaction_request_cb (pjsip_rx_data *rdata)
call
->
getLocalSDP
()
->
receiveOffer
(
r_sdp
,
account
->
getActiveCodecs
());
// Init default codec for early media session
sfl
::
Codec
*
audiocodec
=
Manager
::
instance
().
audioCodecFactory
.
instantiateCodec
(
PAYLOAD_CODEC_ULAW
);
call
->
getAudioRtp
()
->
start
(
static_cast
<
sfl
::
AudioCodec
*>
(
audiocodec
));
...
...
@@ -1812,23 +1733,18 @@ transaction_request_cb (pjsip_rx_data *rdata)
if
(
pjsip_dlg_create_uas
(
pjsip_ua_instance
(),
rdata
,
NULL
,
&
dialog
)
!=
PJ_SUCCESS
)
goto
fail
;
// Specify media capability during invite session creation
pjsip_inv_session
*
inv
;
pjsip_inv_create_uas
(
dialog
,
rdata
,
call
->
getLocalSDP
()
->
getLocalSdpSession
(),
0
,
&
inv
);
pjsip_inv_create_uas
(
dialog
,
rdata
,
call
->
getLocalSDP
()
->
getLocalSdpSession
(),
0
,
&
call
->
inv
);
// Explicitly set the transport, set_transport methods increment transport's reference counter
PJ_ASSERT_RETURN
(
pjsip_dlg_set_transport
(
dialog
,
tp
)
==
PJ_SUCCESS
,
1
);
// Associate the call in the invite session
inv
->
mod_data
[
_mod_ua
.
id
]
=
call
;
call
->
inv
->
mod_data
[
_mod_ua
.
id
]
=
call
;
// Check whether Replaces header is present in the request and process accordingly.
pjsip_dialog
*
replaced_dlg
;
pjsip_tx_data
*
response
;
if
(
pjsip_replaces_verify_request
(
rdata
,
&
replaced_dlg
,
PJ_FALSE
,
&
response
)
!=
PJ_SUCCESS
)
{
_warn
(
"UserAgent: Error: Something wrong with Replaces request."
);
// Respond with 500 (Internal Server Error)
pjsip_endpt_respond_stateless
(
_endpt
,
rdata
,
500
,
NULL
,
NULL
,
NULL
);
_error
(
"Something wrong with Replaces request."
);
pjsip_endpt_respond_stateless
(
_endpt
,
rdata
,
500
/* internal server error */
,
NULL
,
NULL
,
NULL
);
}
// Check if call has been transfered
...
...
@@ -1836,8 +1752,8 @@ transaction_request_cb (pjsip_rx_data *rdata)
if
(
replaced_dlg
)
{
// If Replace header present
// Always answer the new INVITE with 200, regardless whether
// the replaced call is in early or confirmed state.
if
(
pjsip_inv_answer
(
inv
,
200
,
NULL
,
NULL
,
&
response
)
==
PJ_SUCCESS
)
pjsip_inv_send_msg
(
inv
,
response
);
if
(
pjsip_inv_answer
(
call
->
inv
,
200
,
NULL
,
NULL
,
&
response
)
==
PJ_SUCCESS
)
pjsip_inv_send_msg
(
call
->
inv
,
response
);
// Get the INVITE session associated with the replaced dialog.
pjsip_inv_session
*
replaced_inv
=
pjsip_dlg_get_inv_session
(
replaced_dlg
);
...
...
@@ -1845,13 +1761,10 @@ transaction_request_cb (pjsip_rx_data *rdata)
// Disconnect the "replaced" INVITE session.
if
(
pjsip_inv_end_session
(
replaced_inv
,
PJSIP_SC_GONE
,
NULL
,
&
tdata
)
==
PJ_SUCCESS
&&
tdata
)
pjsip_inv_send_msg
(
replaced_inv
,
tdata
);
call
->
inv
=
inv
;
}
else
{
// Prooceed with normal call flow
PJ_ASSERT_RETURN
(
pjsip_inv_initial_answer
(
inv
,
rdata
,
PJSIP_SC_RINGING
,
NULL
,
NULL
,
&
tdata
)
==
PJ_SUCCESS
,
1
);
PJ_ASSERT_RETURN
(
pjsip_inv_send_msg
(
inv
,
tdata
)
==
PJ_SUCCESS
,
1
);
PJ_ASSERT_RETURN
(
pjsip_inv_initial_answer
(
call
->
inv
,
rdata
,
PJSIP_SC_RINGING
,
NULL
,
NULL
,
&
tdata
)
==
PJ_SUCCESS
,
1
);
PJ_ASSERT_RETURN
(
pjsip_inv_send_msg
(
call
->
inv
,
tdata
)
==
PJ_SUCCESS
,
1
);
call
->
inv
=
inv
;
call
->
setConnectionState
(
Call
::
Ringing
);
if
(
!
Manager
::
instance
().
incomingCall
(
call
,
account_id
))
...
...
@@ -1868,7 +1781,7 @@ fail:
return
false
;
}
pj_bool_t
transaction_response_cb
(
pjsip_rx_data
*
rdata
)
static
pj_bool_t
transaction_response_cb
(
pjsip_rx_data
*
rdata
)
{
pjsip_dialog
*
dlg
=
pjsip_rdata_get_dlg
(
rdata
);
if
(
!
dlg
)
...
...
@@ -1878,11 +1791,7 @@ pj_bool_t transaction_response_cb (pjsip_rx_data *rdata)
if
(
!
tsx
||
tsx
->
method
.
id
!=
PJSIP_INVITE_METHOD
)
return
PJ_SUCCESS
;
if
(
tsx
->
status_code
<
200
)
_info
(
"UserAgent: Received provisional response"
);
else
if
(
tsx
->
status_code
>=
300
)
_warn
(
"UserAgent: Dialog failed"
);
else
{
if
(
tsx
->
status_code
/
100
==
2
)
{