Fix issue 454
This commit is contained in:
parent
4c0f326ff0
commit
616569765e
|
@ -576,6 +576,7 @@ typedef struct tsip_stack_s
|
|||
|
||||
char *local_ip[TSIP_TRANSPORT_IDX_MAX];
|
||||
tnet_port_t local_port[TSIP_TRANSPORT_IDX_MAX];
|
||||
tsk_bool_t local_ip_is_set_by_user[TSIP_TRANSPORT_IDX_MAX]; // whether the address (ip and port) is set by the user or retrieved
|
||||
|
||||
char *proxy_cscf[TSIP_TRANSPORT_IDX_MAX];
|
||||
tnet_port_t proxy_cscf_port[TSIP_TRANSPORT_IDX_MAX];
|
||||
|
|
|
@ -1,23 +1,23 @@
|
|||
/*
|
||||
* Copyright (C) 2010-2011 Mamadou Diop.
|
||||
* Copyright (C) 2012 Doubango Telecom <http://doubango.org>
|
||||
*
|
||||
* This file is part of Open Source Doubango Framework.
|
||||
*
|
||||
* DOUBANGO 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.
|
||||
*
|
||||
* DOUBANGO 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 DOUBANGO.
|
||||
*
|
||||
*/
|
||||
* Copyright (C) 2010-2011 Mamadou Diop.
|
||||
* Copyright (C) 2012 Doubango Telecom <http://doubango.org>
|
||||
*
|
||||
* This file is part of Open Source Doubango Framework.
|
||||
*
|
||||
* DOUBANGO 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.
|
||||
*
|
||||
* DOUBANGO 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 DOUBANGO.
|
||||
*
|
||||
*/
|
||||
|
||||
/**@file tsip.c
|
||||
* @brief SIP (RFC 3261) and 3GPP IMS/LTE (TS 24.229) implementation.
|
||||
|
@ -50,23 +50,23 @@
|
|||
static void* TSK_STDCALL run(void* self);
|
||||
|
||||
/* For tests:
|
||||
* http://www.voip-info.org/wiki/view/PROTOS+Test-Suite
|
||||
* http://tools.ietf.org/html/rfc4475
|
||||
* http://portal.etsi.org/docbox/EC_Files/EC_Files/ts_10202702v030101p.pdf
|
||||
*/
|
||||
* http://www.voip-info.org/wiki/view/PROTOS+Test-Suite
|
||||
* http://tools.ietf.org/html/rfc4475
|
||||
* http://portal.etsi.org/docbox/EC_Files/EC_Files/ts_10202702v030101p.pdf
|
||||
*/
|
||||
|
||||
|
||||
/**@defgroup tsip_stack_group 3GPP IMS/LTE Stack
|
||||
*/
|
||||
*/
|
||||
|
||||
extern tsip_event_t* tsip_event_create(tsip_ssession_t* ss, short code, const char* phrase, const tsip_message_t* sipmessage, tsip_event_type_t type);
|
||||
#define TSIP_STACK_SIGNAL(self, code, phrase) \
|
||||
{ \
|
||||
tsip_event_t* e; \
|
||||
if((e = tsip_event_create(tsk_null, code, phrase, tsk_null, tsip_event_stack))){ \
|
||||
TSK_RUNNABLE_ENQUEUE_OBJECT(TSK_RUNNABLE(self), e); \
|
||||
} \
|
||||
}
|
||||
{ \
|
||||
tsip_event_t* e; \
|
||||
if((e = tsip_event_create(tsk_null, code, phrase, tsk_null, tsip_event_stack))){ \
|
||||
TSK_RUNNABLE_ENQUEUE_OBJECT(TSK_RUNNABLE(self), e); \
|
||||
} \
|
||||
}
|
||||
|
||||
static int __tsip_stack_get_transport_idx_by_name(tsip_stack_t *self, const char* name)
|
||||
{
|
||||
|
@ -190,6 +190,7 @@ static int __tsip_stack_set(tsip_stack_t *self, va_list* app)
|
|||
if(t_idx < 0) { TSK_DEBUG_ERROR("%s not valid as transport or you're probably using deprecated function", TRANSPORT_STR); return -1; }
|
||||
|
||||
tsk_strupdate(&self->network.local_ip[t_idx], IP_STR);
|
||||
self->network.local_ip_is_set_by_user[t_idx] = tsk_true; // do not query best source when stack is re-started
|
||||
if(TSIP_STACK_MODE_IS_SERVER(self) && !tsk_strnullORempty(TRANSPORT_STR)){
|
||||
self->network.transport_types[t_idx] = tsip_transport_get_type_by_name(TRANSPORT_STR);
|
||||
}
|
||||
|
@ -462,27 +463,27 @@ bail:
|
|||
}
|
||||
|
||||
/**@ingroup tsip_stack_group
|
||||
* Creates new 3GPP IMS/LTE stack handle.
|
||||
* As the 3GPP IMS/LTE stack depends on the network library (tinyNET), you MUST call <a href="http://doubango.org/API/tinyNET/tnet_8c.html#affba6c2710347476f615b0135777c640"> tnet_startup()</a> before using any SIP function (tsip_*).
|
||||
* <a href="http://doubango.org/API/tinyNET/tnet_8c.html#ac42b22a7ac5831f04326aee9de033c84"> tnet_cleanup()</a> is used to terminate use of network functions.
|
||||
* @param callback Callback function to call to alert the application for new SIP or media events.
|
||||
* @param realm_uri The realm is the name of the domain name to authenticate to. It should be a valid SIP URI (e.g. sip:open-ims.test).
|
||||
* @param impi_uri The IMPI is a unique identifier assigned to a user (or UE) by the home network.
|
||||
* It could be either a SIP URI (e.g. sip:bob@open-ims.test), a tel URI (e.g. tel:+33100000) or any alphanumeric string (e.g. bob@open-ims.test or bob).
|
||||
* It is used to authenticate the UE (username field in SIP Authorization/Proxy-Authorization header).
|
||||
* @param impu_uri As its name says, it’s you public visible identifier where you are willing to receive calls or any demands.
|
||||
* An IMPU could be either a SIP or tel URI (e.g. tel:+33100000 or sip:bob@open-ims.test). In IMS world, a user can have multiple IMPUs associated to its unique IMPI.
|
||||
* @param ... Any TSIP_STACK_SET_*() macros.
|
||||
* @retval A valid handle if succeed and Null-handle otherwise. As a stack is a well-defined object, you should use @a TSK_OBJECT_SAFE_FREE() to safely destroy the handle.
|
||||
*
|
||||
* @code
|
||||
int app_callback(const tsip_event_t *sipevent);
|
||||
* Creates new 3GPP IMS/LTE stack handle.
|
||||
* As the 3GPP IMS/LTE stack depends on the network library (tinyNET), you MUST call <a href="http://doubango.org/API/tinyNET/tnet_8c.html#affba6c2710347476f615b0135777c640"> tnet_startup()</a> before using any SIP function (tsip_*).
|
||||
* <a href="http://doubango.org/API/tinyNET/tnet_8c.html#ac42b22a7ac5831f04326aee9de033c84"> tnet_cleanup()</a> is used to terminate use of network functions.
|
||||
* @param callback Callback function to call to alert the application for new SIP or media events.
|
||||
* @param realm_uri The realm is the name of the domain name to authenticate to. It should be a valid SIP URI (e.g. sip:open-ims.test).
|
||||
* @param impi_uri The IMPI is a unique identifier assigned to a user (or UE) by the home network.
|
||||
* It could be either a SIP URI (e.g. sip:bob@open-ims.test), a tel URI (e.g. tel:+33100000) or any alphanumeric string (e.g. bob@open-ims.test or bob).
|
||||
* It is used to authenticate the UE (username field in SIP Authorization/Proxy-Authorization header).
|
||||
* @param impu_uri As its name says, it’s you public visible identifier where you are willing to receive calls or any demands.
|
||||
* An IMPU could be either a SIP or tel URI (e.g. tel:+33100000 or sip:bob@open-ims.test). In IMS world, a user can have multiple IMPUs associated to its unique IMPI.
|
||||
* @param ... Any TSIP_STACK_SET_*() macros.
|
||||
* @retval A valid handle if succeed and Null-handle otherwise. As a stack is a well-defined object, you should use @a TSK_OBJECT_SAFE_FREE() to safely destroy the handle.
|
||||
*
|
||||
* @code
|
||||
int app_callback(const tsip_event_t *sipevent);
|
||||
|
||||
const char* realm_uri = "sip:open-ims.test";
|
||||
const char* impi_uri = "bob@open-ims.test";
|
||||
const char* impu_uri = "sip:bob@open-ims.test";
|
||||
const char* realm_uri = "sip:open-ims.test";
|
||||
const char* impi_uri = "bob@open-ims.test";
|
||||
const char* impu_uri = "sip:bob@open-ims.test";
|
||||
|
||||
tsip_stack_handle_t* stack = tsip_stack_create(app_callback, realm_uri, impi_uri, impu_uri,
|
||||
tsip_stack_handle_t* stack = tsip_stack_create(app_callback, realm_uri, impi_uri, impu_uri,
|
||||
TSIP_STACK_SET_PASSWORD("mysecret"),
|
||||
// ...other macros...
|
||||
TSIP_STACK_SET_NULL());
|
||||
|
@ -490,9 +491,9 @@ tsip_stack_handle_t* stack = tsip_stack_create(app_callback, realm_uri, impi_uri
|
|||
// ...whatever
|
||||
|
||||
TSK_OBJECT_SAFE_FREE(stack);
|
||||
* @endcode
|
||||
* @sa @ref tsip_stack_set()<br>@ref tsip_stack_start()
|
||||
*/
|
||||
* @endcode
|
||||
* @sa @ref tsip_stack_set()<br>@ref tsip_stack_start()
|
||||
*/
|
||||
tsip_stack_handle_t* tsip_stack_create(tsip_stack_callback_f callback, const char* realm_uri, const char* impi_uri, const char* impu_uri, ...)
|
||||
{
|
||||
tsip_stack_t* stack = tsk_null;
|
||||
|
@ -605,10 +606,10 @@ bail:
|
|||
|
||||
|
||||
/**@ingroup tsip_stack_group
|
||||
* Starts a 3GPP IMS/LTE stack. This function MUST be called before you start calling any SIP function (@a tsip_*).
|
||||
* @param self The 3GPP IMS/LTE stack to start. This handle should be created using @ref tsip_stack_create().
|
||||
* @retval Zero if succeed and non-zero error code otherwise.
|
||||
*/
|
||||
* Starts a 3GPP IMS/LTE stack. This function MUST be called before you start calling any SIP function (@a tsip_*).
|
||||
* @param self The 3GPP IMS/LTE stack to start. This handle should be created using @ref tsip_stack_create().
|
||||
* @retval Zero if succeed and non-zero error code otherwise.
|
||||
*/
|
||||
int tsip_stack_start(tsip_stack_handle_t *self)
|
||||
{
|
||||
int ret = -1, t_idx, tx_count;
|
||||
|
@ -655,10 +656,10 @@ int tsip_stack_start(tsip_stack_handle_t *self)
|
|||
|
||||
/* === Set Max FDs === */
|
||||
if (stack->network.max_fds > 0 && stack->network.max_fds < 0xFFFF) {
|
||||
TSK_DEBUG_INFO("Setting max FDs to %u", stack->network.max_fds);
|
||||
TSK_DEBUG_INFO("Setting max FDs to %u", (unsigned)stack->network.max_fds);
|
||||
ret = tnet_set_fd_max_allowed(stack->network.max_fds);
|
||||
if (ret) {
|
||||
TSK_DEBUG_ERROR("Failed to set max FDs to %u", stack->network.max_fds);
|
||||
TSK_DEBUG_ERROR("Failed to set max FDs to %u", (unsigned)stack->network.max_fds);
|
||||
/* goto bail; */ // Not fatal error
|
||||
}
|
||||
}
|
||||
|
@ -717,20 +718,26 @@ int tsip_stack_start(tsip_stack_handle_t *self)
|
|||
}// !Server mode
|
||||
|
||||
/* === Get Best source address === */
|
||||
if(tsk_strnullORempty(stack->network.local_ip[t_idx]) || tsk_striequals(stack->network.local_ip[t_idx], "127.0.0.1")){ /* loacal-ip is missing? */
|
||||
// Best local address must be updated if not defined or none is set by the user.
|
||||
// The local address could be no-null if the stack is re-starting: https://code.google.com/p/doubango/issues/detail?id=454 and https://code.google.com/p/idoubs/issues/detail?id=195
|
||||
if (!stack->network.local_ip_is_set_by_user[t_idx] || tsk_strnullORempty(stack->network.local_ip[t_idx]) || tsk_striequals(stack->network.local_ip[t_idx], "127.0.0.1")) { /* loacal-ip is missing? */
|
||||
tnet_ip_t bestsource;
|
||||
if((ret = tnet_getbestsource(stack->network.proxy_cscf[t_idx] ? stack->network.proxy_cscf[t_idx] : "google.com",
|
||||
if ((ret = tnet_getbestsource(stack->network.proxy_cscf[t_idx] ? stack->network.proxy_cscf[t_idx] : "google.com",
|
||||
stack->network.proxy_cscf_port[t_idx] ? stack->network.proxy_cscf_port[t_idx] : 5060,
|
||||
tx_values[t_idx],
|
||||
&bestsource)))
|
||||
{
|
||||
TSK_DEBUG_ERROR("Failed to get best source [%d].", ret);
|
||||
TSK_DEBUG_ERROR("Failed to get best source [%d]", ret);
|
||||
/* do not exit ==> will use default IP address */
|
||||
}
|
||||
else{
|
||||
else {
|
||||
tsk_strupdate(&stack->network.local_ip[t_idx], bestsource);
|
||||
TSK_DEBUG_INFO("Best source at %d: %s", t_idx, bestsource);
|
||||
}
|
||||
}
|
||||
else {
|
||||
TSK_DEBUG_INFO("Do not query for best source address at %d, local_ip_is_set_by_user=%d, local_ip=%s", t_idx, stack->network.local_ip_is_set_by_user[t_idx], stack->network.local_ip[t_idx]);
|
||||
}
|
||||
} /* for (t_idx...) */
|
||||
|
||||
/* === Runnable === */
|
||||
|
@ -828,19 +835,19 @@ bail:
|
|||
}
|
||||
|
||||
/**@ingroup tsip_stack_group
|
||||
* Configures the stack.
|
||||
* @param self The 3GPP IMS/LTE stack to configure. This handle should be created using @ref tsip_stack_create().
|
||||
* @param ... Any TSIP_STACK_SET_*() or TSIP_STACK_UNSET_*() macros.
|
||||
* @retval Zero if succeed and non-zero error code otherwise.
|
||||
*
|
||||
* @code
|
||||
int ret = tsip_stack_set(stack,
|
||||
* Configures the stack.
|
||||
* @param self The 3GPP IMS/LTE stack to configure. This handle should be created using @ref tsip_stack_create().
|
||||
* @param ... Any TSIP_STACK_SET_*() or TSIP_STACK_UNSET_*() macros.
|
||||
* @retval Zero if succeed and non-zero error code otherwise.
|
||||
*
|
||||
* @code
|
||||
int ret = tsip_stack_set(stack,
|
||||
TSIP_STACK_SET_HEADER("User-Agent", "IM-client/OMA1.0 doubango/v1.0.0"),
|
||||
TSIP_STACK_SET_NULL());
|
||||
* @endcode
|
||||
*
|
||||
* @sa @ref tsip_stack_create()
|
||||
*/
|
||||
* @endcode
|
||||
*
|
||||
* @sa @ref tsip_stack_create()
|
||||
*/
|
||||
int tsip_stack_set(tsip_stack_handle_t *self, ...)
|
||||
{
|
||||
if(self){
|
||||
|
@ -860,9 +867,9 @@ int tsip_stack_set(tsip_stack_handle_t *self, ...)
|
|||
}
|
||||
|
||||
/**@ingroup tsip_stack_group
|
||||
* Gets user's data, previously set using @ref TSIP_STACK_SET_USERDATA() macro.
|
||||
* @param self Stack from which to get the user's data.
|
||||
*/
|
||||
* Gets user's data, previously set using @ref TSIP_STACK_SET_USERDATA() macro.
|
||||
* @param self Stack from which to get the user's data.
|
||||
*/
|
||||
const void* tsip_stack_get_userdata(const tsip_stack_handle_t *self)
|
||||
{
|
||||
if(self){
|
||||
|
@ -875,7 +882,7 @@ const void* tsip_stack_get_userdata(const tsip_stack_handle_t *self)
|
|||
}
|
||||
|
||||
/**@ingroup tsip_stack_group
|
||||
*/
|
||||
*/
|
||||
tnet_dns_ctx_t* tsip_stack_get_dnsctx(tsip_stack_handle_t *self)
|
||||
{
|
||||
if(self){
|
||||
|
@ -888,7 +895,7 @@ tnet_dns_ctx_t* tsip_stack_get_dnsctx(tsip_stack_handle_t *self)
|
|||
}
|
||||
|
||||
/**@ingroup tsip_stack_group
|
||||
*/
|
||||
*/
|
||||
tsip_uri_t* tsip_stack_get_preferred_id(tsip_stack_handle_t *self)
|
||||
{
|
||||
if(self){
|
||||
|
@ -901,7 +908,7 @@ tsip_uri_t* tsip_stack_get_preferred_id(tsip_stack_handle_t *self)
|
|||
}
|
||||
|
||||
/**@ingroup tsip_stack_group
|
||||
*/
|
||||
*/
|
||||
int tsip_stack_get_local_ip_n_port(const tsip_stack_handle_t *self, const char* protocol, tnet_port_t *port, tnet_ip_t *ip)
|
||||
{
|
||||
const tsip_stack_t *stack = self;
|
||||
|
@ -929,13 +936,13 @@ int tsip_stack_get_local_ip_n_port(const tsip_stack_handle_t *self, const char*
|
|||
}
|
||||
|
||||
/**@ingroup tsip_stack_group
|
||||
* Stops the stack.
|
||||
* @param self The 3GPP IMS/LTE stack to stop. This handle should be created using @ref tsip_stack_create() and started using tsip_stack_start().
|
||||
* This function is also called by the garbage collector when the stack is destroyed but you should call it yourself before destroying the stack.<br>
|
||||
* Before stopping, the stack will hangup all SIP dialogs (starting with non-register dialogs) and destroy all sessions. This is called shutdown phase.
|
||||
* At the end of this phase, all the SIP sessions will be destroyed.
|
||||
* @sa @ref tsip_stack_create()<br>@ref tsip_stack_start()
|
||||
*/
|
||||
* Stops the stack.
|
||||
* @param self The 3GPP IMS/LTE stack to stop. This handle should be created using @ref tsip_stack_create() and started using tsip_stack_start().
|
||||
* This function is also called by the garbage collector when the stack is destroyed but you should call it yourself before destroying the stack.<br>
|
||||
* Before stopping, the stack will hangup all SIP dialogs (starting with non-register dialogs) and destroy all sessions. This is called shutdown phase.
|
||||
* At the end of this phase, all the SIP sessions will be destroyed.
|
||||
* @sa @ref tsip_stack_create()<br>@ref tsip_stack_start()
|
||||
*/
|
||||
int tsip_stack_stop(tsip_stack_handle_t *self)
|
||||
{
|
||||
tsip_stack_t *stack = self;
|
||||
|
@ -1009,7 +1016,7 @@ int tsip_stack_stop(tsip_stack_handle_t *self)
|
|||
|
||||
TSK_DEBUG_INFO("SIP STACK -- STOP");
|
||||
|
||||
bail:
|
||||
bail:
|
||||
tsk_safeobj_unlock(stack);
|
||||
|
||||
return ret;
|
||||
|
|
Loading…
Reference in New Issue