2007-03-31 19:01:33 +00:00
/*
* FreeSWITCH Modular Media Switching Software Library / Soft - Switch Application
2010-02-06 03:38:24 +00:00
* Copyright ( C ) 2005 - 2010 , Anthony Minessale II < anthm @ freeswitch . org >
2007-03-31 19:01:33 +00:00
*
* Version : MPL 1.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 ( the " License " ) ; you may not use this file except in compliance with
* the License . You may obtain a copy of the License at
* http : //www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an " AS IS " basis ,
* WITHOUT WARRANTY OF ANY KIND , either express or implied . See the License
* for the specific language governing rights and limitations under the
* License .
*
* The Original Code is FreeSWITCH Modular Media Switching Software Library / Soft - Switch Application
*
* The Initial Developer of the Original Code is
2009-02-04 21:20:54 +00:00
* Anthony Minessale II < anthm @ freeswitch . org >
2007-03-31 19:01:33 +00:00
* Portions created by the Initial Developer are Copyright ( C )
* the Initial Developer . All Rights Reserved .
*
* Contributor ( s ) :
*
2009-02-04 21:20:54 +00:00
* Anthony Minessale II < anthm @ freeswitch . org >
2007-03-31 19:01:33 +00:00
* Ken Rice , Asteria Solutions Group , Inc < ken @ asteriasgi . com >
* Paul D . Tinsley < pdt at jackhammer . org >
* Bret McDanel < trixter AT 0xdecafbad . com >
2007-04-07 03:04:46 +00:00
* Marcel Barbulescu < marcelbarbulescu @ gmail . com >
2008-01-12 19:53:12 +00:00
* Norman Brandinger
2009-09-08 22:16:45 +00:00
* Raymond Chandler < intralanman @ gmail . com >
2009-11-23 19:46:37 +00:00
* Nathan Patrick < npatrick at corp . sonic . net >
2007-03-31 19:01:33 +00:00
*
*
2007-04-02 19:54:25 +00:00
* sofia . c - - SOFIA SIP Endpoint ( sofia code )
2007-03-31 19:01:33 +00:00
*
*/
# include "mod_sofia.h"
2009-04-27 23:36:03 +00:00
2007-09-11 14:51:13 +00:00
2007-03-31 19:01:33 +00:00
extern su_log_t tport_log [ ] ;
2007-12-13 02:42:00 +00:00
extern su_log_t iptsec_log [ ] ;
extern su_log_t nea_log [ ] ;
extern su_log_t nta_log [ ] ;
extern su_log_t nth_client_log [ ] ;
extern su_log_t nth_server_log [ ] ;
extern su_log_t nua_log [ ] ;
extern su_log_t soa_log [ ] ;
extern su_log_t sresolv_log [ ] ;
extern su_log_t stun_log [ ] ;
2009-03-04 20:17:36 +00:00
extern su_log_t su_log_default [ ] ;
2009-03-04 18:54:43 +00:00
2010-01-15 00:31:43 +00:00
2010-02-06 03:38:24 +00:00
void sofia_handle_sip_i_reinvite ( switch_core_session_t * session ,
nua_t * nua , sofia_profile_t * profile , nua_handle_t * nh , sofia_private_t * sofia_private , sip_t const * sip ,
tagi_t tags [ ] ) ;
2010-01-15 00:31:43 +00:00
2008-01-12 19:53:12 +00:00
static void set_variable_sip_param ( switch_channel_t * channel , char * header_type , sip_param_t const * params ) ;
2007-03-31 19:01:33 +00:00
2009-10-07 22:35:21 +00:00
2008-01-02 17:06:07 +00:00
2007-04-17 06:08:39 +00:00
static void sofia_handle_sip_i_state ( switch_core_session_t * session , int status ,
char const * phrase ,
2008-05-27 04:54:52 +00:00
nua_t * nua , sofia_profile_t * profile , nua_handle_t * nh , sofia_private_t * sofia_private , sip_t const * sip ,
tagi_t tags [ ] ) ;
2007-03-31 19:01:33 +00:00
2007-12-18 01:12:50 +00:00
static void sofia_handle_sip_r_invite ( switch_core_session_t * session , int status ,
2008-05-27 04:54:52 +00:00
char const * phrase ,
nua_t * nua , sofia_profile_t * profile , nua_handle_t * nh , sofia_private_t * sofia_private , sip_t const * sip ,
tagi_t tags [ ] ) ;
static void sofia_handle_sip_r_options ( switch_core_session_t * session , int status , char const * phrase , nua_t * nua , sofia_profile_t * profile ,
nua_handle_t * nh , sofia_private_t * sofia_private , sip_t const * sip , tagi_t tags [ ] ) ;
2007-12-18 16:31:05 +00:00
2007-10-24 23:20:47 +00:00
void sofia_handle_sip_r_notify ( switch_core_session_t * session , int status ,
char const * phrase ,
nua_t * nua , sofia_profile_t * profile , nua_handle_t * nh , sofia_private_t * sofia_private , sip_t const * sip , tagi_t tags [ ] )
{
2008-12-11 20:20:20 +00:00
#if 0
2008-05-06 23:49:35 +00:00
if ( status > = 300 & & sip & & sip - > sip_call_id ) {
2007-12-15 00:39:53 +00:00
char * sql ;
2008-05-06 23:49:35 +00:00
sql = switch_mprintf ( " delete from sip_subscriptions where call_id='%q' " , sip - > sip_call_id - > i_id ) ;
2007-12-15 00:39:53 +00:00
switch_assert ( sql ! = NULL ) ;
2008-03-05 20:31:18 +00:00
sofia_glue_execute_sql ( profile , & sql , SWITCH_TRUE ) ;
2007-12-15 00:39:53 +00:00
}
2008-12-11 20:20:20 +00:00
# endif
2007-10-24 23:20:47 +00:00
}
2010-01-18 20:55:19 +00:00
# define url_set_chanvars(session, url, varprefix) _url_set_chanvars(session, url, #varprefix "_user", #varprefix "_host", #varprefix "_port", #varprefix "_uri", #varprefix "_params")
2010-01-18 20:31:47 +00:00
2010-01-18 20:55:19 +00:00
static const char * _url_set_chanvars ( switch_core_session_t * session , url_t * url , const char * user_var ,
2010-02-06 03:38:24 +00:00
const char * host_var , const char * port_var , const char * uri_var , const char * params_var )
2010-01-18 20:31:47 +00:00
{
const char * user = NULL , * host = NULL , * port = NULL ;
2010-01-18 20:55:19 +00:00
char * uri = NULL ;
2010-01-18 20:31:47 +00:00
switch_channel_t * channel = switch_core_session_get_channel ( session ) ;
char new_port [ 25 ] = " " ;
if ( url ) {
user = url - > url_user ;
host = url - > url_host ;
port = url - > url_port ;
if ( ! zstr ( url - > url_params ) ) {
switch_channel_set_variable ( channel , params_var , url - > url_params ) ;
}
}
if ( zstr ( user ) ) {
user = " nobody " ;
}
if ( zstr ( host ) ) {
host = " nowhere " ;
}
check_decode ( user , session ) ;
if ( user ) {
switch_channel_set_variable ( channel , user_var , user ) ;
}
if ( port ) {
switch_snprintf ( new_port , sizeof ( new_port ) , " :%s " , port ) ;
}
switch_channel_set_variable ( channel , port_var , port ) ;
2010-01-18 20:55:19 +00:00
if ( host ) {
if ( user ) {
uri = switch_core_session_sprintf ( session , " %s@%s%s " , user , host , new_port ) ;
} else {
uri = switch_core_session_sprintf ( session , " %s%s " , host , new_port ) ;
}
switch_channel_set_variable ( channel , uri_var , uri ) ;
switch_channel_set_variable ( channel , host_var , host ) ;
}
return uri ;
2010-01-18 20:31:47 +00:00
}
2010-02-06 03:38:24 +00:00
static char * strip_quotes ( const char * in )
{
char * t = ( char * ) in ;
char * r = ( char * ) in ;
if ( * t = = ' " ' ) {
t + + ;
if ( end_of ( t ) = = ' " ' ) {
r = strdup ( t ) ;
end_of ( r ) = ' \0 ' ;
}
}
return r ;
}
static void extract_header_vars ( sofia_profile_t * profile , sip_t const * sip , switch_core_session_t * session )
{
switch_channel_t * channel = switch_core_session_get_channel ( session ) ;
char * full ;
if ( sip ) {
if ( sip - > sip_via ) {
if ( ( full = sip_header_as_string ( profile - > home , ( void * ) sip - > sip_via ) ) ) {
const char * v = switch_channel_get_variable ( channel , " sip_full_via " ) ;
if ( ! v ) {
switch_channel_set_variable ( channel , " sip_full_via " , full ) ;
}
su_free ( profile - > home , full ) ;
}
}
if ( sip - > sip_from ) {
char * p = strip_quotes ( sip - > sip_from - > a_display ) ;
if ( p ) {
switch_channel_set_variable ( channel , " sip_from_display " , p ) ;
}
if ( p ! = sip - > sip_from - > a_display ) free ( p ) ;
if ( ( full = sip_header_as_string ( profile - > home , ( void * ) sip - > sip_from ) ) ) {
switch_channel_set_variable ( channel , " sip_full_from " , full ) ;
su_free ( profile - > home , full ) ;
}
}
if ( sip - > sip_to ) {
char * p = strip_quotes ( sip - > sip_to - > a_display ) ;
if ( p ) {
switch_channel_set_variable ( channel , " sip_to_display " , p ) ;
}
if ( p ! = sip - > sip_to - > a_display ) free ( p ) ;
if ( ( full = sip_header_as_string ( profile - > home , ( void * ) sip - > sip_to ) ) ) {
switch_channel_set_variable ( channel , " sip_full_to " , full ) ;
su_free ( profile - > home , full ) ;
}
}
2010-01-18 20:31:47 +00:00
2010-02-06 03:38:24 +00:00
}
}
static void extract_vars ( sofia_profile_t * profile , sip_t const * sip , switch_core_session_t * session )
2010-01-18 20:31:47 +00:00
{
switch_channel_t * channel = switch_core_session_get_channel ( session ) ;
if ( sip ) {
2010-02-06 03:38:24 +00:00
if ( sip - > sip_from & & sip - > sip_from - > a_url )
url_set_chanvars ( session , sip - > sip_from - > a_url , sip_from ) ;
if ( sip - > sip_request & & sip - > sip_request - > rq_url )
url_set_chanvars ( session , sip - > sip_request - > rq_url , sip_req ) ;
if ( sip - > sip_to & & sip - > sip_to - > a_url )
url_set_chanvars ( session , sip - > sip_to - > a_url , sip_to ) ;
if ( sip - > sip_contact & & sip - > sip_contact - > m_url )
url_set_chanvars ( session , sip - > sip_contact - > m_url , sip_contact ) ;
if ( sip - > sip_referred_by & & sip - > sip_referred_by - > b_url )
url_set_chanvars ( session , sip - > sip_referred_by - > b_url , sip_referred_by ) ;
2010-01-18 20:31:47 +00:00
if ( sip - > sip_to & & sip - > sip_to - > a_tag ) {
2010-02-06 03:38:24 +00:00
switch_channel_set_variable ( channel , " sip_to_tag " , sip - > sip_to - > a_tag ) ;
2010-01-18 20:31:47 +00:00
}
if ( sip - > sip_from & & sip - > sip_from - > a_tag ) {
switch_channel_set_variable ( channel , " sip_from_tag " , sip - > sip_from - > a_tag ) ;
}
2010-01-19 16:01:25 +00:00
if ( sip - > sip_cseq & & sip - > sip_cseq - > cs_seq ) {
char sip_cseq [ 40 ] = " " ;
switch_snprintf ( sip_cseq , sizeof ( sip_cseq ) , " %d " , sip - > sip_cseq - > cs_seq ) ;
switch_channel_set_variable ( channel , " sip_cseq " , sip_cseq ) ;
}
2010-02-06 03:38:24 +00:00
if ( sip - > sip_call_id & & sip - > sip_call_id - > i_id ) {
switch_channel_set_variable ( channel , " sip_call_id " , sip - > sip_call_id - > i_id ) ;
}
2010-01-18 20:31:47 +00:00
}
}
2007-10-05 17:33:13 +00:00
void sofia_handle_sip_i_notify ( switch_core_session_t * session , int status ,
2008-05-27 04:54:52 +00:00
char const * phrase ,
nua_t * nua , sofia_profile_t * profile , nua_handle_t * nh , sofia_private_t * sofia_private , sip_t const * sip , tagi_t tags [ ] )
2007-10-05 17:05:31 +00:00
{
2007-10-05 17:33:13 +00:00
switch_channel_t * channel = NULL ;
2008-11-20 02:07:59 +00:00
private_object_t * tech_pvt = NULL ;
2008-11-22 01:50:21 +00:00
switch_event_t * s_event = NULL ;
2008-11-24 15:52:55 +00:00
sofia_gateway_subscription_t * gw_sub_ptr ;
2009-03-22 20:04:56 +00:00
int sub_state ;
2008-05-27 04:54:52 +00:00
2009-03-22 20:04:56 +00:00
tl_gets ( tags , NUTAG_SUBSTATE_REF ( sub_state ) , TAG_END ( ) ) ;
2009-04-01 16:35:37 +00:00
2008-02-02 00:02:28 +00:00
/* make sure we have a proper event */
if ( ! sip | | ! sip - > sip_event ) {
goto error ;
}
2009-01-30 16:46:37 +00:00
/* the following could be refactored back to the calling event handler here in sofia.c XXX MTK */
/* potentially interesting note: for Linksys shared appearance, we'll probably have to set up to get bare notifies
* and pass them inward to the sla handler . we ' ll have to set NUTAG_APPL_METHOD ( " NOTIFY " ) when creating
* nua , and also pick them off special elsewhere here in sofia . c - MTK
* * and * for Linksys , I believe they use " sa " as their magic appearance agent name for those blind notifies , so
* we ' ll probably have to change to match
2010-02-06 03:38:24 +00:00
*/
2009-02-12 14:46:14 +00:00
if ( sofia_test_pflag ( profile , PFLAG_MANAGE_SHARED_APPEARANCE ) ) {
2010-02-06 03:38:24 +00:00
2009-02-01 21:59:50 +00:00
if ( sip - > sip_request - > rq_url - > url_user & & ! strncmp ( sip - > sip_request - > rq_url - > url_user , " sla-agent " , sizeof ( " sla-agent " ) ) ) {
2009-01-30 16:46:37 +00:00
sofia_sla_handle_sip_i_notify ( nua , profile , nh , sip , tags ) ;
2009-03-22 20:04:56 +00:00
goto end ;
2009-01-30 16:46:37 +00:00
}
}
2008-02-02 00:02:28 +00:00
/* Automatically return a 200 OK for Event: keep-alive */
if ( ! strcasecmp ( sip - > sip_event - > o_type , " keep-alive " ) ) {
2009-01-30 16:46:37 +00:00
/* XXX MTK - is this right? in this case isn't sofia is already sending a 200 itself also? */
2008-02-02 00:02:28 +00:00
nua_respond ( nh , SIP_200_OK , NUTAG_WITH_THIS ( nua ) , TAG_END ( ) ) ;
2009-03-22 20:04:56 +00:00
goto end ;
2008-02-02 00:02:28 +00:00
}
2008-11-22 01:50:21 +00:00
2008-11-20 02:07:59 +00:00
if ( session ) {
channel = switch_core_session_get_channel ( session ) ;
switch_assert ( channel ! = NULL ) ;
tech_pvt = switch_core_session_get_private ( session ) ;
switch_assert ( tech_pvt ! = NULL ) ;
}
2008-11-22 01:50:21 +00:00
/* For additional NOTIFY event packages see http://www.iana.org/assignments/sip-events. */
2009-06-22 14:12:35 +00:00
if ( sip - > sip_content_type & &
2010-02-06 03:38:24 +00:00
sip - > sip_content_type - > c_type & & sip - > sip_payload & & sip - > sip_payload - > pl_data & & ! strcasecmp ( sip - > sip_event - > o_type , " refer " ) ) {
2008-11-22 01:50:21 +00:00
if ( switch_event_create_subclass ( & s_event , SWITCH_EVENT_CUSTOM , MY_EVENT_NOTIFY_REFER ) = = SWITCH_STATUS_SUCCESS ) {
switch_event_add_header_string ( s_event , SWITCH_STACK_BOTTOM , " content-type " , sip - > sip_content_type - > c_type ) ;
switch_event_add_body ( s_event , " %s " , sip - > sip_payload - > pl_data ) ;
}
}
/* add common headers for the NOTIFY to the switch_event and fire if it exists */
if ( s_event ! = NULL ) {
switch_event_add_header_string ( s_event , SWITCH_STACK_BOTTOM , " event-package " , sip - > sip_event - > o_type ) ;
switch_event_add_header_string ( s_event , SWITCH_STACK_BOTTOM , " event-id " , sip - > sip_event - > o_id ) ;
2010-02-06 03:38:24 +00:00
2010-01-03 21:10:34 +00:00
if ( sip - > sip_contact & & sip - > sip_contact - > m_url ) {
2010-02-06 03:38:24 +00:00
switch_event_add_header ( s_event , SWITCH_STACK_BOTTOM , " contact " , " %s@%s " ,
2010-01-03 21:10:34 +00:00
sip - > sip_contact - > m_url - > url_user , sip - > sip_contact - > m_url - > url_host ) ;
}
2008-11-22 01:50:21 +00:00
2010-02-06 03:38:24 +00:00
switch_event_add_header ( s_event , SWITCH_STACK_BOTTOM , " from " , " %s@%s " , sip - > sip_from - > a_url - > url_user , sip - > sip_from - > a_url - > url_host ) ;
2008-11-22 01:50:21 +00:00
switch_event_add_header_string ( s_event , SWITCH_STACK_BOTTOM , " from-tag " , sip - > sip_from - > a_tag ) ;
2010-02-06 03:38:24 +00:00
switch_event_add_header ( s_event , SWITCH_STACK_BOTTOM , " to " , " %s@%s " , sip - > sip_to - > a_url - > url_user , sip - > sip_to - > a_url - > url_host ) ;
2008-11-22 01:50:21 +00:00
switch_event_add_header_string ( s_event , SWITCH_STACK_BOTTOM , " to-tag " , sip - > sip_to - > a_tag ) ;
if ( sip - > sip_call_id & & sip - > sip_call_id - > i_id ) {
switch_event_add_header_string ( s_event , SWITCH_STACK_BOTTOM , " call-id " , sip - > sip_call_id - > i_id ) ;
}
if ( sip - > sip_subscription_state & & sip - > sip_subscription_state - > ss_substate ) {
switch_event_add_header_string ( s_event , SWITCH_STACK_BOTTOM , " subscription-substate " , sip - > sip_subscription_state - > ss_substate ) ;
}
if ( sip - > sip_subscription_state & & sip - > sip_subscription_state - > ss_reason ) {
switch_event_add_header_string ( s_event , SWITCH_STACK_BOTTOM , " subscription-reason " , sip - > sip_subscription_state - > ss_reason ) ;
}
if ( sip - > sip_subscription_state & & sip - > sip_subscription_state - > ss_retry_after ) {
switch_event_add_header_string ( s_event , SWITCH_STACK_BOTTOM , " subscription-retry-after " , sip - > sip_subscription_state - > ss_retry_after ) ;
}
if ( sip - > sip_subscription_state & & sip - > sip_subscription_state - > ss_expires ) {
switch_event_add_header_string ( s_event , SWITCH_STACK_BOTTOM , " subscription-expires " , sip - > sip_subscription_state - > ss_expires ) ;
}
if ( session ) {
switch_event_add_header_string ( s_event , SWITCH_STACK_BOTTOM , " UniqueID " , switch_core_session_get_uuid ( session ) ) ;
}
switch_event_fire ( & s_event ) ;
}
2008-11-20 02:07:59 +00:00
if ( ! strcasecmp ( sip - > sip_event - > o_type , " refer " ) ) {
if ( session & & channel & & tech_pvt ) {
if ( sip - > sip_payload & & sip - > sip_payload - > pl_data ) {
2008-11-21 19:41:11 +00:00
char * p ;
2008-11-24 14:59:30 +00:00
int status_val = 0 ;
2008-11-21 19:41:11 +00:00
if ( ( p = strchr ( sip - > sip_payload - > pl_data , ' ' ) ) ) {
p + + ;
if ( p ) {
2008-11-24 14:59:30 +00:00
status_val = atoi ( p ) ;
2008-11-21 19:41:11 +00:00
}
}
2008-11-24 14:59:30 +00:00
if ( ! status_val | | status_val > = 200 ) {
2008-11-20 02:07:59 +00:00
switch_channel_set_variable ( channel , " sip_refer_reply " , sip - > sip_payload - > pl_data ) ;
2008-11-24 14:59:30 +00:00
if ( status_val = = 200 ) {
2008-11-21 20:55:02 +00:00
switch_channel_hangup ( channel , SWITCH_CAUSE_BLIND_TRANSFER ) ;
}
2008-11-20 02:07:59 +00:00
if ( tech_pvt - > want_event = = 9999 ) {
tech_pvt - > want_event = 0 ;
}
}
}
}
nua_respond ( nh , SIP_200_OK , NUTAG_WITH_THIS ( nua ) , TAG_END ( ) ) ;
}
2008-11-24 15:52:55 +00:00
/* if no session, assume it could be an incoming notify from a gateway subscription */
if ( session ) {
/* make sure we have a proper "talk" event */
if ( strcasecmp ( sip - > sip_event - > o_type , " talk " ) ) {
goto error ;
}
2008-02-02 00:02:28 +00:00
2008-11-24 15:52:55 +00:00
if ( ! switch_channel_test_flag ( channel , CF_OUTBOUND ) ) {
switch_channel_answer ( channel ) ;
switch_channel_set_variable ( channel , " auto_answer_destination " , switch_channel_get_variable ( channel , " destination_number " ) ) ;
switch_ivr_session_transfer ( session , " auto_answer " , NULL , NULL ) ;
nua_respond ( nh , SIP_200_OK , NUTAG_WITH_THIS ( nua ) , TAG_END ( ) ) ;
2009-03-22 20:04:56 +00:00
goto end ;
2008-11-24 15:52:55 +00:00
}
2007-11-20 01:09:39 +00:00
}
2010-02-06 03:38:24 +00:00
2008-11-24 15:52:55 +00:00
if ( ! sofia_private | | ! sofia_private - > gateway ) {
2009-01-22 23:53:59 +00:00
if ( profile - > debug ) {
2010-02-06 03:38:24 +00:00
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( session ) , SWITCH_LOG_DEBUG , " Gateway information missing Subscription Event: %s \n " ,
sip - > sip_event - > o_type ) ;
2009-01-22 23:53:59 +00:00
}
2010-02-06 03:38:24 +00:00
goto error ;
2008-11-24 15:52:55 +00:00
}
2010-02-06 03:38:24 +00:00
2008-11-24 15:52:55 +00:00
/* find the corresponding gateway subscription (if any) */
if ( ! ( gw_sub_ptr = sofia_find_gateway_subscription ( sofia_private - > gateway , sip - > sip_event - > o_type ) ) ) {
2009-08-13 20:35:02 +00:00
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( session ) , SWITCH_LOG_WARNING ,
2008-11-24 15:52:55 +00:00
" Could not find gateway subscription. Gateway: %s. Subscription Event: %s \n " ,
sofia_private - > gateway - > name , sip - > sip_event - > o_type ) ;
2010-02-06 03:38:24 +00:00
goto error ;
2007-10-05 17:33:13 +00:00
}
2008-11-24 15:52:55 +00:00
if ( ! ( gw_sub_ptr - > state = = SUB_STATE_SUBED | | gw_sub_ptr - > state = = SUB_STATE_SUBSCRIBE ) ) {
2010-02-06 03:38:24 +00:00
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( session ) , SWITCH_LOG_WARNING , " Ignoring notify due to subscription state: %d \n " , gw_sub_ptr - > state ) ;
goto error ;
2008-11-24 15:52:55 +00:00
}
/* dispatch freeswitch event */
if ( switch_event_create ( & s_event , SWITCH_EVENT_NOTIFY_IN ) = = SWITCH_STATUS_SUCCESS ) {
2009-04-21 01:02:45 +00:00
switch_event_add_header_string ( s_event , SWITCH_STACK_BOTTOM , " event " , sip - > sip_event - > o_type ) ;
switch_event_add_header_string ( s_event , SWITCH_STACK_BOTTOM , " pl_data " , sip - > sip_payload - > pl_data ) ;
switch_event_add_header_string ( s_event , SWITCH_STACK_BOTTOM , " sip_content_type " , sip - > sip_content_type - > c_type ) ;
2008-11-24 15:52:55 +00:00
switch_event_add_header ( s_event , SWITCH_STACK_BOTTOM , " port " , " %d " , sofia_private - > gateway - > profile - > sip_port ) ;
2009-04-21 01:02:45 +00:00
switch_event_add_header_string ( s_event , SWITCH_STACK_BOTTOM , " module_name " , " mod_sofia " ) ;
switch_event_add_header_string ( s_event , SWITCH_STACK_BOTTOM , " profile_name " , sofia_private - > gateway - > profile - > name ) ;
switch_event_add_header_string ( s_event , SWITCH_STACK_BOTTOM , " profile_uri " , sofia_private - > gateway - > profile - > url ) ;
switch_event_add_header_string ( s_event , SWITCH_STACK_BOTTOM , " gateway_name " , sofia_private - > gateway - > name ) ;
2008-11-24 15:52:55 +00:00
switch_event_fire ( & s_event ) ;
2009-08-13 20:35:02 +00:00
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( session ) , SWITCH_LOG_DEBUG , " dispatched freeswitch event for message-summary NOTIFY \n " ) ;
2008-11-24 15:52:55 +00:00
} else {
2009-08-13 20:35:02 +00:00
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( session ) , SWITCH_LOG_ERROR , " Failed to create event \n " ) ;
2010-02-06 03:38:24 +00:00
goto error ;
2008-11-24 15:52:55 +00:00
}
2009-03-22 20:04:56 +00:00
goto end ;
2007-10-05 17:33:13 +00:00
2008-05-27 04:54:52 +00:00
error :
2009-03-22 20:04:56 +00:00
2009-04-09 22:43:00 +00:00
if ( sip & & sip - > sip_event & & sip - > sip_event - > o_type & & ! strcasecmp ( sip - > sip_event - > o_type , " message-summary " ) ) {
2009-04-01 16:35:37 +00:00
/* unsolicited mwi, just say ok */
nua_respond ( nh , SIP_200_OK , NUTAG_WITH_THIS ( nua ) , TAG_END ( ) ) ;
} else {
nua_respond ( nh , 481 , " Subscription Does Not Exist " , NUTAG_WITH_THIS ( nua ) , TAG_END ( ) ) ;
}
2010-02-06 03:38:24 +00:00
end :
if ( sub_state = = nua_substate_terminated & & sofia_private & & sofia_private ! = & mod_sofia_globals . destroy_private & &
2009-04-29 19:15:42 +00:00
sofia_private ! = & mod_sofia_globals . keep_private ) {
2009-04-29 19:05:51 +00:00
sofia_private - > destroy_nh = 1 ;
sofia_private - > destroy_me = 1 ;
2009-03-22 20:04:56 +00:00
}
2007-10-05 17:05:31 +00:00
}
2007-12-26 22:41:40 +00:00
void sofia_handle_sip_i_bye ( switch_core_session_t * session , int status ,
2008-05-27 04:54:52 +00:00
char const * phrase ,
nua_t * nua , sofia_profile_t * profile , nua_handle_t * nh , sofia_private_t * sofia_private , sip_t const * sip , tagi_t tags [ ] )
2007-12-26 22:41:40 +00:00
{
2008-01-29 19:57:13 +00:00
const char * tmp ;
switch_channel_t * channel ;
2008-08-01 16:21:51 +00:00
private_object_t * tech_pvt ;
2009-08-11 00:54:39 +00:00
char * extra_headers ;
2009-12-24 05:44:23 +00:00
const char * call_info = NULL ;
2009-07-02 17:40:16 +00:00
# ifdef MANUAL_BYE
int cause ;
char st [ 80 ] = " " ;
# endif
2008-01-29 19:57:13 +00:00
2008-05-27 04:54:52 +00:00
if ( ! session )
return ;
2008-01-29 19:57:13 +00:00
2008-05-27 04:54:52 +00:00
channel = switch_core_session_get_channel ( session ) ;
2008-08-01 16:21:51 +00:00
tech_pvt = switch_core_session_get_private ( session ) ;
2008-02-02 00:49:25 +00:00
2009-07-02 17:40:16 +00:00
# ifdef MANUAL_BYE
status = 200 ;
phrase = " OK " ;
2010-02-06 03:38:24 +00:00
2009-07-02 17:40:16 +00:00
sofia_set_flag_locked ( tech_pvt , TFLAG_BYE ) ;
2010-01-28 20:35:17 +00:00
call_info = switch_channel_get_variable ( channel , " presence_call_info_full " ) ;
2009-07-02 17:40:16 +00:00
2010-02-06 03:38:24 +00:00
if ( sip - > sip_reason & & sip - > sip_reason - > re_protocol & & ( ! strcasecmp ( sip - > sip_reason - > re_protocol , " Q.850 " )
| | ! strcasecmp ( sip - > sip_reason - > re_protocol , " FreeSWITCH " )
| | ! strcasecmp ( sip - > sip_reason - > re_protocol , profile - > username ) ) & & sip - > sip_reason - > re_cause ) {
2008-05-27 04:54:52 +00:00
tech_pvt - > q850_cause = atoi ( sip - > sip_reason - > re_cause ) ;
2009-07-02 17:40:16 +00:00
cause = tech_pvt - > q850_cause ;
} else {
cause = sofia_glue_sip_cause_to_freeswitch ( status ) ;
}
switch_snprintf ( st , sizeof ( st ) , " %d " , status ) ;
switch_channel_set_variable ( channel , " sip_term_status " , st ) ;
switch_snprintf ( st , sizeof ( st ) , " sip:%d " , status ) ;
if ( phrase ) {
switch_channel_set_variable_partner ( channel , " sip_hangup_phrase " , phrase ) ;
2008-05-27 04:54:52 +00:00
}
2008-02-02 00:49:25 +00:00
2009-07-02 17:40:16 +00:00
switch_snprintf ( st , sizeof ( st ) , " %d " , cause ) ;
switch_channel_set_variable ( channel , " sip_term_cause " , st ) ;
2010-02-06 03:38:24 +00:00
2009-08-11 00:54:39 +00:00
extra_headers = sofia_glue_get_extra_headers ( channel , SOFIA_SIP_BYE_HEADER_PREFIX ) ;
sofia_glue_set_extra_headers ( channel , sip , SOFIA_SIP_BYE_HEADER_PREFIX ) ;
2010-02-06 03:38:24 +00:00
2009-07-02 17:40:16 +00:00
switch_channel_hangup ( channel , cause ) ;
2010-02-06 03:38:24 +00:00
nua_respond ( nh , SIP_200_OK , NUTAG_WITH_THIS ( nua ) ,
TAG_IF ( call_info , SIPTAG_CALL_INFO_STR ( call_info ) ) , TAG_IF ( ! zstr ( extra_headers ) , SIPTAG_HEADER_STR ( extra_headers ) ) , TAG_END ( ) ) ;
2009-08-11 00:54:39 +00:00
switch_safe_free ( extra_headers ) ;
2009-07-02 17:40:16 +00:00
if ( sofia_private ) {
2010-02-06 03:38:24 +00:00
sofia_private - > destroy_me = 1 ;
sofia_private - > destroy_nh = 1 ;
}
2009-07-02 17:40:16 +00:00
# endif
2009-10-23 16:03:42 +00:00
if ( sip - > sip_user_agent & & ! zstr ( sip - > sip_user_agent - > g_string ) ) {
2008-01-29 19:57:13 +00:00
switch_channel_set_variable ( channel , " sip_user_agent " , sip - > sip_user_agent - > g_string ) ;
2009-10-23 16:03:42 +00:00
} else if ( sip - > sip_server & & ! zstr ( sip - > sip_server - > g_string ) ) {
2008-07-23 22:21:24 +00:00
switch_channel_set_variable ( channel , " sip_user_agent " , sip - > sip_server - > g_string ) ;
2008-01-29 19:57:13 +00:00
}
2008-07-23 22:21:24 +00:00
2008-01-29 19:57:13 +00:00
if ( ( tmp = sofia_glue_get_unknown_header ( sip , " rtp-txstat " ) ) ) {
switch_channel_set_variable ( channel , " sip_rtp_txstat " , tmp ) ;
}
if ( ( tmp = sofia_glue_get_unknown_header ( sip , " rtp-rxstat " ) ) ) {
switch_channel_set_variable ( channel , " sip_rtp_rxstat " , tmp ) ;
2007-12-26 22:41:40 +00:00
}
2008-06-23 16:52:38 +00:00
if ( ( tmp = sofia_glue_get_unknown_header ( sip , " P-RTP-Stat " ) ) ) {
switch_channel_set_variable ( channel , " sip_p_rtp_stat " , tmp ) ;
}
2010-02-06 03:38:24 +00:00
2008-08-01 16:21:51 +00:00
tech_pvt - > got_bye = 1 ;
2010-02-06 03:38:24 +00:00
switch_channel_set_variable ( channel , " sip_hangup_disposition " , " recv_bye " ) ;
2009-07-02 17:40:16 +00:00
2007-12-26 22:41:40 +00:00
return ;
}
2007-10-05 17:05:31 +00:00
2008-01-29 19:57:13 +00:00
void sofia_handle_sip_r_message ( int status , sofia_profile_t * profile , nua_handle_t * nh , sip_t const * sip )
{
}
2008-11-20 02:07:59 +00:00
void sofia_wait_for_reply ( struct private_object * tech_pvt , nua_event_t event , uint32_t timeout )
{
2009-01-25 21:23:07 +00:00
time_t exp = switch_epoch_time_now ( NULL ) + timeout ;
2010-02-06 03:38:24 +00:00
2008-11-20 02:07:59 +00:00
tech_pvt - > want_event = event ;
2010-02-06 03:38:24 +00:00
while ( switch_channel_ready ( tech_pvt - > channel ) & & tech_pvt - > want_event & & switch_epoch_time_now ( NULL ) < exp ) {
2008-11-20 02:07:59 +00:00
switch_yield ( 100000 ) ;
}
2010-02-06 03:38:24 +00:00
2008-11-20 02:07:59 +00:00
}
2010-02-06 03:38:24 +00:00
void sofia_send_callee_id ( switch_core_session_t * session , const char * name , const char * number )
2009-10-07 22:35:21 +00:00
{
const char * uuid ;
switch_core_session_t * session_b ;
switch_channel_t * channel = switch_core_session_get_channel ( session ) ;
switch_caller_profile_t * caller_profile = switch_channel_get_caller_profile ( channel ) ;
2009-10-23 16:03:42 +00:00
if ( zstr ( name ) ) {
2009-10-07 22:35:21 +00:00
name = caller_profile - > callee_id_name ;
}
2009-10-23 16:03:42 +00:00
if ( zstr ( number ) ) {
2009-10-07 22:35:21 +00:00
number = caller_profile - > callee_id_number ;
}
2009-10-23 16:03:42 +00:00
if ( zstr ( name ) ) {
2009-10-21 18:48:28 +00:00
name = number ;
2009-10-07 22:35:21 +00:00
}
2010-02-06 03:38:24 +00:00
2009-10-23 16:03:42 +00:00
if ( zstr ( number ) ) {
2009-10-07 22:35:21 +00:00
number = caller_profile - > destination_number ;
}
2009-10-13 20:59:50 +00:00
2009-10-07 22:35:21 +00:00
if ( ( uuid = switch_channel_get_variable ( channel , SWITCH_SIGNAL_BOND_VARIABLE ) ) & & ( session_b = switch_core_session_locate ( uuid ) ) ) {
2009-10-12 22:23:55 +00:00
switch_core_session_message_t * msg ;
2009-10-21 18:48:28 +00:00
//switch_channel_t *channel_b = switch_core_session_get_channel(session_b);
//switch_channel_set_profile_var(channel_b, "callee_id_name", name);
//switch_channel_set_profile_var(channel_b, "callee_id_number", number);
2009-10-12 22:23:55 +00:00
msg = switch_core_session_alloc ( session_b , sizeof ( * msg ) ) ;
2009-10-13 20:28:45 +00:00
MESSAGE_STAMP_FFL ( msg ) ;
2009-10-12 22:23:55 +00:00
msg - > message_id = SWITCH_MESSAGE_INDICATE_DISPLAY ;
msg - > string_array_arg [ 0 ] = switch_core_session_strdup ( session_b , name ) ;
msg - > string_array_arg [ 1 ] = switch_core_session_strdup ( session_b , number ) ;
msg - > from = __FILE__ ;
switch_core_session_queue_message ( session_b , msg ) ;
2009-10-07 22:35:21 +00:00
switch_core_session_rwunlock ( session_b ) ;
}
}
void sofia_update_callee_id ( switch_core_session_t * session , sofia_profile_t * profile , sip_t const * sip , switch_bool_t send )
{
switch_channel_t * channel = switch_core_session_get_channel ( session ) ;
sip_p_asserted_identity_t * passerted = NULL ;
2009-10-21 18:48:28 +00:00
char * name = NULL ;
2009-10-07 22:35:21 +00:00
const char * number = " unknown " , * tmp ;
switch_caller_profile_t * caller_profile ;
char * dup = NULL ;
2009-10-08 16:52:55 +00:00
switch_event_t * event ;
2009-10-21 18:48:28 +00:00
const char * val ;
int fs = 0 ;
2009-10-07 22:35:21 +00:00
2009-10-23 22:04:34 +00:00
if ( switch_true ( switch_channel_get_variable ( channel , SWITCH_IGNORE_DISPLAY_UPDATES_VARIABLE ) ) ) {
return ;
}
2009-10-07 22:35:21 +00:00
if ( sip - > sip_to ) {
number = sip - > sip_to - > a_url - > url_user ;
}
2009-10-21 18:48:28 +00:00
if ( ( val = sofia_glue_get_unknown_header ( sip , " X-FS-Display-Number " ) ) ) {
number = val ;
fs + + ;
}
if ( ( val = sofia_glue_get_unknown_header ( sip , " X-FS-Display-Name " ) ) ) {
2010-02-06 03:38:24 +00:00
name = ( char * ) val ;
2009-10-21 18:48:28 +00:00
fs + + ;
}
if ( ! fs ) {
if ( ( passerted = sip_p_asserted_identity ( sip ) ) ) {
if ( passerted - > paid_url & & passerted - > paid_url - > url_user ) {
number = passerted - > paid_url - > url_user ;
2009-10-07 22:35:21 +00:00
}
2009-10-23 16:03:42 +00:00
if ( ! zstr ( passerted - > paid_display ) ) {
2009-10-21 18:48:28 +00:00
dup = strdup ( passerted - > paid_display ) ;
if ( * dup = = ' " ' ) {
name = dup + 1 ;
} else {
name = dup ;
}
if ( end_of ( name ) = = ' " ' ) {
end_of ( name ) = ' \0 ' ;
}
2009-10-07 22:35:21 +00:00
}
}
}
2009-10-21 18:48:28 +00:00
2009-11-06 16:00:56 +00:00
if ( ( ( tmp = switch_channel_get_variable ( channel , " effective_callee_id_name " ) ) | |
2010-02-06 03:38:24 +00:00
( tmp = switch_channel_get_variable ( channel , " sip_callee_id_name " ) ) | |
2009-11-06 16:00:56 +00:00
( tmp = switch_channel_get_variable ( channel , " callee_id_name " ) ) ) & & ! zstr ( tmp ) ) {
2010-02-06 03:38:24 +00:00
name = ( char * ) tmp ;
2009-10-07 22:35:21 +00:00
}
2009-11-06 16:00:56 +00:00
if ( ( ( tmp = switch_channel_get_variable ( channel , " effective_callee_id_number " ) ) | |
2010-02-06 03:38:24 +00:00
( tmp = switch_channel_get_variable ( channel , " sip_callee_id_number " ) ) | |
2009-11-06 16:00:56 +00:00
( tmp = switch_channel_get_variable ( channel , " callee_id_number " ) ) ) & & ! zstr ( tmp ) ) {
2009-10-07 22:35:21 +00:00
number = tmp ;
}
2010-02-06 03:38:24 +00:00
if ( zstr ( name ) )
name = ( char * ) number ;
2009-11-05 06:51:51 +00:00
2009-11-06 16:00:56 +00:00
if ( zstr ( name ) & & zstr ( number ) ) {
2009-11-05 06:51:51 +00:00
goto end ;
}
2009-10-21 18:48:28 +00:00
2009-10-08 16:52:55 +00:00
if ( switch_event_create ( & event , SWITCH_EVENT_CALL_UPDATE ) = = SWITCH_STATUS_SUCCESS ) {
const char * uuid = switch_channel_get_variable ( channel , SWITCH_SIGNAL_BOND_VARIABLE ) ;
switch_event_add_header_string ( event , SWITCH_STACK_BOTTOM , " Direction " , " RECV " ) ;
switch_event_add_header_string ( event , SWITCH_STACK_BOTTOM , " Callee-Name " , name ) ;
switch_event_add_header_string ( event , SWITCH_STACK_BOTTOM , " Callee-Number " , number ) ;
if ( uuid ) {
switch_event_add_header_string ( event , SWITCH_STACK_BOTTOM , " Bridged-To " , uuid ) ;
}
switch_channel_event_set_data ( channel , event ) ;
switch_event_fire ( & event ) ;
}
2010-02-06 03:38:24 +00:00
2009-10-07 22:35:21 +00:00
caller_profile = switch_channel_get_caller_profile ( channel ) ;
2009-10-13 22:29:20 +00:00
2009-12-11 22:38:48 +00:00
if ( ! strcmp ( caller_profile - > callee_id_name , name ) & & ! strcmp ( caller_profile - > callee_id_number , number ) ) {
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_DEBUG1 , " Same Callee ID \" %s \" <%s> \n " , name , number ) ;
send = 0 ;
} else {
caller_profile - > callee_id_name = switch_sanitize_number ( switch_core_strdup ( caller_profile - > pool , name ) ) ;
caller_profile - > callee_id_number = switch_sanitize_number ( switch_core_strdup ( caller_profile - > pool , number ) ) ;
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_INFO , " Update Callee ID to \" %s \" <%s> \n " , name , number ) ;
}
2009-11-15 02:16:10 +00:00
2009-10-07 22:35:21 +00:00
if ( send ) {
sofia_send_callee_id ( session , NULL , NULL ) ;
}
2010-02-06 03:38:24 +00:00
end :
2009-10-07 22:35:21 +00:00
switch_safe_free ( dup ) ;
}
2007-03-31 19:01:33 +00:00
void sofia_event_callback ( nua_event_t event ,
2007-12-18 16:31:05 +00:00
int status ,
char const * phrase ,
2008-05-27 04:54:52 +00:00
nua_t * nua , sofia_profile_t * profile , nua_handle_t * nh , sofia_private_t * sofia_private , sip_t const * sip , tagi_t tags [ ] )
2007-03-31 19:01:33 +00:00
{
struct private_object * tech_pvt = NULL ;
auth_res_t auth_res = AUTH_FORBIDDEN ;
switch_core_session_t * session = NULL ;
switch_channel_t * channel = NULL ;
2007-12-04 00:21:32 +00:00
sofia_gateway_t * gateway = NULL ;
2008-11-05 00:20:30 +00:00
int locked = 0 ;
2009-01-30 16:46:37 +00:00
int check_destroy = 1 ;
2007-03-31 19:01:33 +00:00
2009-03-21 02:34:37 +00:00
if ( nh & & sofia_private = = & mod_sofia_globals . keep_private ) {
if ( status > = 300 ) {
nua_handle_bind ( nh , NULL ) ;
nua_handle_destroy ( nh ) ;
return ;
}
}
2008-05-07 20:06:46 +00:00
if ( sofia_private & & sofia_private ! = & mod_sofia_globals . destroy_private & & sofia_private ! = & mod_sofia_globals . keep_private ) {
2007-12-04 00:21:32 +00:00
if ( ( gateway = sofia_private - > gateway ) ) {
if ( switch_thread_rwlock_tryrdlock ( gateway - > profile - > rwlock ) ! = SWITCH_STATUS_SUCCESS ) {
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_ERROR , " Profile %s is locked \n " , gateway - > profile - > name ) ;
return ;
}
2009-10-23 16:03:42 +00:00
} else if ( ! zstr ( sofia_private - > uuid ) ) {
2007-12-04 00:21:32 +00:00
if ( ( session = switch_core_session_locate ( sofia_private - > uuid ) ) ) {
tech_pvt = switch_core_session_get_private ( session ) ;
2009-03-20 01:52:53 +00:00
channel = switch_core_session_get_channel ( session ) ;
if ( tech_pvt ) {
switch_mutex_lock ( tech_pvt - > sofia_mutex ) ;
2010-02-06 03:38:24 +00:00
locked = 1 ;
2009-03-20 01:52:53 +00:00
} else {
switch_core_session_rwunlock ( session ) ;
return ;
}
2009-03-20 17:03:46 +00:00
2008-11-03 17:39:09 +00:00
if ( status > = 180 & & ! * sofia_private - > auth_gateway_name ) {
const char * gwname = switch_channel_get_variable ( channel , " sip_use_gateway " ) ;
2009-10-23 16:03:42 +00:00
if ( ! zstr ( gwname ) ) {
2008-11-03 17:39:09 +00:00
switch_set_string ( sofia_private - > auth_gateway_name , gwname ) ;
}
}
2007-12-04 00:21:32 +00:00
if ( ! tech_pvt - > call_id & & sip & & sip - > sip_call_id & & sip - > sip_call_id - > i_id ) {
tech_pvt - > call_id = switch_core_session_strdup ( session , sip - > sip_call_id - > i_id ) ;
switch_channel_set_variable ( channel , " sip_call_id " , tech_pvt - > call_id ) ;
}
2009-07-22 19:14:47 +00:00
2007-12-04 13:48:20 +00:00
if ( tech_pvt - > gateway_name ) {
gateway = sofia_reg_find_gateway ( tech_pvt - > gateway_name ) ;
}
2009-07-22 19:14:47 +00:00
if ( channel & & switch_channel_down ( channel ) ) {
2009-08-13 20:35:02 +00:00
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( session ) , SWITCH_LOG_DEBUG , " Channel is already hungup. \n " ) ;
2009-07-22 19:14:47 +00:00
goto done ;
}
2007-12-04 00:21:32 +00:00
} else {
2009-07-22 19:14:47 +00:00
/* we can't find the session it must be hanging up or something else, its too late to do anything with it. */
2007-12-04 00:21:32 +00:00
return ;
2007-03-31 19:01:33 +00:00
}
}
}
2008-10-10 03:59:55 +00:00
2009-02-09 17:56:38 +00:00
if ( sofia_test_pflag ( profile , PFLAG_AUTH_ALL ) & & tech_pvt & & tech_pvt - > key & & sip ) {
2007-03-31 19:01:33 +00:00
sip_authorization_t const * authorization = NULL ;
2008-05-27 04:54:52 +00:00
2007-03-31 19:01:33 +00:00
if ( sip - > sip_authorization ) {
authorization = sip - > sip_authorization ;
} else if ( sip - > sip_proxy_authorization ) {
authorization = sip - > sip_proxy_authorization ;
}
if ( authorization ) {
2007-04-20 18:06:06 +00:00
char network_ip [ 80 ] ;
2010-02-06 03:38:24 +00:00
sofia_glue_get_addr ( nua_current_request ( nua ) , network_ip , sizeof ( network_ip ) , NULL ) ;
2008-05-27 04:54:52 +00:00
auth_res = sofia_reg_parse_auth ( profile , authorization , sip ,
( char * ) sip - > sip_request - > rq_method_name , tech_pvt - > key , strlen ( tech_pvt - > key ) , network_ip , NULL , 0 ,
2009-11-12 03:52:07 +00:00
REG_INVITE , NULL , NULL , NULL ) ;
2007-03-31 19:01:33 +00:00
}
2010-02-06 03:38:24 +00:00
2007-03-31 19:01:33 +00:00
if ( auth_res ! = AUTH_OK ) {
2009-03-02 23:55:00 +00:00
//switch_channel_hangup(channel, SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER);
2007-03-31 19:01:33 +00:00
nua_respond ( nh , SIP_401_UNAUTHORIZED , TAG_END ( ) ) ;
goto done ;
}
if ( channel ) {
switch_channel_set_variable ( channel , " sip_authorized " , " true " ) ;
}
}
if ( sip & & ( status = = 401 | | status = = 407 ) ) {
2008-11-03 17:39:09 +00:00
sofia_reg_handle_sip_r_challenge ( status , phrase , nua , profile , nh , sofia_private , session , gateway , sip , tags ) ;
2007-03-31 19:01:33 +00:00
goto done ;
}
switch ( event ) {
2007-10-05 16:49:15 +00:00
case nua_r_get_params :
2007-03-31 19:01:33 +00:00
case nua_i_fork :
case nua_r_info :
2009-08-13 20:35:02 +00:00
break ;
2007-03-31 19:01:33 +00:00
case nua_r_bye :
2009-03-22 20:52:41 +00:00
case nua_r_unregister :
2007-03-31 19:01:33 +00:00
case nua_r_unsubscribe :
case nua_r_publish :
case nua_i_cancel :
2008-10-10 02:31:17 +00:00
case nua_r_cancel :
2007-03-31 19:01:33 +00:00
case nua_i_error :
case nua_i_active :
case nua_i_terminated :
case nua_r_set_params :
2008-10-10 03:59:55 +00:00
case nua_i_prack :
case nua_r_prack :
break ;
2009-10-14 19:26:10 +00:00
case nua_i_ack :
2010-01-18 20:31:47 +00:00
{
if ( channel & & sip ) {
if ( sip - > sip_to & & sip - > sip_to - > a_tag ) {
switch_channel_set_variable ( channel , " sip_to_tag " , sip - > sip_to - > a_tag ) ;
}
2010-02-06 03:38:24 +00:00
2010-01-18 20:31:47 +00:00
if ( sip - > sip_from & & sip - > sip_from - > a_tag ) {
switch_channel_set_variable ( channel , " sip_from_tag " , sip - > sip_from - > a_tag ) ;
}
2010-01-19 16:01:25 +00:00
if ( sip - > sip_cseq & & sip - > sip_cseq - > cs_seq ) {
char sip_cseq [ 40 ] = " " ;
switch_snprintf ( sip_cseq , sizeof ( sip_cseq ) , " %d " , sip - > sip_cseq - > cs_seq ) ;
switch_channel_set_variable ( channel , " sip_cseq " , sip_cseq ) ;
}
2010-02-06 03:38:24 +00:00
if ( sip - > sip_call_id & & sip - > sip_call_id - > i_id ) {
switch_channel_set_variable ( channel , " sip_call_id " , sip - > sip_call_id - > i_id ) ;
}
extract_header_vars ( profile , sip , session ) ;
sofia_glue_tech_track ( tech_pvt - > profile , session ) ;
2010-01-18 20:31:47 +00:00
}
}
2009-10-14 19:26:10 +00:00
case nua_r_ack :
2010-02-06 03:38:24 +00:00
if ( channel )
switch_channel_set_flag ( channel , CF_MEDIA_ACK ) ;
2009-10-14 19:26:10 +00:00
break ;
2008-10-10 03:59:55 +00:00
case nua_r_shutdown :
2010-02-06 03:38:24 +00:00
if ( status > = 200 )
su_root_break ( profile - > s_root ) ;
2008-10-10 03:59:55 +00:00
break ;
case nua_r_message :
sofia_handle_sip_r_message ( status , profile , nh , sip ) ;
break ;
case nua_r_invite :
sofia_handle_sip_r_invite ( session , status , phrase , nua , profile , nh , sofia_private , sip , tags ) ;
break ;
case nua_r_options :
sofia_handle_sip_r_options ( session , status , phrase , nua , profile , nh , sofia_private , sip , tags ) ;
break ;
case nua_i_bye :
sofia_handle_sip_i_bye ( session , status , phrase , nua , profile , nh , sofia_private , sip , tags ) ;
2007-03-31 19:01:33 +00:00
break ;
2007-10-24 23:20:47 +00:00
case nua_r_notify :
sofia_handle_sip_r_notify ( session , status , phrase , nua , profile , nh , sofia_private , sip , tags ) ;
break ;
2007-10-05 17:05:31 +00:00
case nua_i_notify :
2007-10-05 17:33:13 +00:00
sofia_handle_sip_i_notify ( session , status , phrase , nua , profile , nh , sofia_private , sip , tags ) ;
2007-10-05 17:05:31 +00:00
break ;
2007-03-31 19:01:33 +00:00
case nua_r_register :
sofia_reg_handle_sip_r_register ( status , phrase , nua , profile , nh , sofia_private , sip , tags ) ;
break ;
case nua_i_options :
sofia_handle_sip_i_options ( status , phrase , nua , profile , nh , sofia_private , sip , tags ) ;
break ;
case nua_i_invite :
2010-01-15 00:31:43 +00:00
if ( session ) {
sofia_handle_sip_i_reinvite ( session , nua , profile , nh , sofia_private , sip , tags ) ;
} else {
sofia_handle_sip_i_invite ( nua , profile , nh , sofia_private , sip , tags ) ;
}
2007-03-31 19:01:33 +00:00
break ;
case nua_i_publish :
sofia_presence_handle_sip_i_publish ( nua , profile , nh , sofia_private , sip , tags ) ;
break ;
case nua_i_register :
2009-03-27 00:27:07 +00:00
//nua_respond(nh, SIP_200_OK, SIPTAG_CONTACT(sip->sip_contact), NUTAG_WITH_THIS(nua), TAG_END());
//nua_handle_destroy(nh);
2007-03-31 19:01:33 +00:00
sofia_reg_handle_sip_i_register ( nua , profile , nh , sofia_private , sip , tags ) ;
break ;
case nua_i_state :
2007-04-17 06:08:39 +00:00
sofia_handle_sip_i_state ( session , status , phrase , nua , profile , nh , sofia_private , sip , tags ) ;
2007-03-31 19:01:33 +00:00
break ;
case nua_i_message :
sofia_presence_handle_sip_i_message ( status , phrase , nua , profile , nh , sofia_private , sip , tags ) ;
break ;
case nua_i_info :
sofia_handle_sip_i_info ( nua , profile , nh , session , sip , tags ) ;
break ;
2009-10-07 22:35:21 +00:00
case nua_i_update :
break ;
2009-05-30 03:44:14 +00:00
case nua_r_update :
2009-10-21 18:48:28 +00:00
if ( session & & tech_pvt & & locked ) {
sofia_clear_flag_locked ( tech_pvt , TFLAG_UPDATING_DISPLAY ) ;
}
2009-05-30 03:44:14 +00:00
break ;
2007-03-31 19:01:33 +00:00
case nua_r_refer :
2007-12-18 16:31:05 +00:00
break ;
case nua_i_refer :
2010-02-06 03:38:24 +00:00
if ( session )
sofia_handle_sip_i_refer ( nua , profile , nh , session , sip , tags ) ;
2007-12-18 16:31:05 +00:00
break ;
case nua_r_subscribe :
sofia_presence_handle_sip_r_subscribe ( status , phrase , nua , profile , nh , sofia_private , sip , tags ) ;
break ;
case nua_i_subscribe :
sofia_presence_handle_sip_i_subscribe ( status , phrase , nua , profile , nh , sofia_private , sip , tags ) ;
break ;
default :
if ( status > 100 ) {
2010-02-06 03:38:24 +00:00
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( session ) , SWITCH_LOG_DEBUG , " %s: unknown event %d: %03d %s \n " , nua_event_name ( event ) , event ,
status , phrase ) ;
2007-12-18 16:31:05 +00:00
} else {
2009-08-13 20:35:02 +00:00
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( session ) , SWITCH_LOG_DEBUG , " %s: unknown event %d \n " , nua_event_name ( event ) , event ) ;
2007-12-18 16:31:05 +00:00
}
break ;
}
2007-12-18 01:12:50 +00:00
2007-12-18 16:31:05 +00:00
done :
2008-02-25 16:35:19 +00:00
2008-11-20 02:07:59 +00:00
if ( tech_pvt & & tech_pvt - > want_event & & event = = tech_pvt - > want_event ) {
tech_pvt - > want_event = 0 ;
}
2008-05-07 20:06:46 +00:00
switch ( event ) {
case nua_i_subscribe :
2009-01-30 16:46:37 +00:00
case nua_r_notify :
check_destroy = 0 ;
break ;
case nua_i_notify :
2010-02-06 03:38:24 +00:00
2009-02-02 17:10:04 +00:00
if ( sip & & sip - > sip_event & & ! strcmp ( sip - > sip_event - > o_type , " dialog " ) & & sip - > sip_event - > o_params & & ! strcmp ( sip - > sip_event - > o_params [ 0 ] , " sla " ) ) {
2009-01-30 16:46:37 +00:00
check_destroy = 0 ;
}
2008-05-07 20:06:46 +00:00
break ;
default :
2009-01-30 16:46:37 +00:00
break ;
}
2009-05-04 21:48:10 +00:00
if ( ( sofia_private & & sofia_private = = & mod_sofia_globals . destroy_private ) ) {
2009-04-01 16:53:04 +00:00
nua_handle_bind ( nh , NULL ) ;
nua_handle_destroy ( nh ) ;
nh = NULL ;
}
2009-01-30 16:46:37 +00:00
if ( check_destroy ) {
2008-05-07 20:06:46 +00:00
if ( nh & & ( ( sofia_private & & sofia_private - > destroy_nh ) | | ! nua_handle_magic ( nh ) ) ) {
2008-05-12 14:19:48 +00:00
if ( sofia_private ) {
nua_handle_bind ( nh , NULL ) ;
}
2008-05-07 20:06:46 +00:00
nua_handle_destroy ( nh ) ;
2008-05-12 16:18:38 +00:00
nh = NULL ;
2008-05-07 20:06:46 +00:00
}
2008-05-06 22:56:55 +00:00
}
2010-02-06 03:38:24 +00:00
2008-05-09 19:35:51 +00:00
if ( sofia_private & & sofia_private - > destroy_me ) {
2009-05-05 22:15:52 +00:00
if ( tech_pvt ) {
2010-02-06 03:38:24 +00:00
tech_pvt - > sofia_private = NULL ;
}
2009-05-05 22:15:52 +00:00
2008-05-12 16:18:38 +00:00
if ( nh ) {
nua_handle_bind ( nh , NULL ) ;
}
sofia_private - > destroy_me = 12 ;
2009-03-22 05:15:17 +00:00
sofia_private_free ( sofia_private ) ;
2008-05-09 19:35:51 +00:00
}
2007-12-18 16:31:05 +00:00
if ( gateway ) {
sofia_reg_release_gateway ( gateway ) ;
}
2009-03-20 01:52:53 +00:00
if ( locked & & tech_pvt ) {
switch_mutex_unlock ( tech_pvt - > sofia_mutex ) ;
}
2010-02-06 03:38:24 +00:00
2007-12-18 16:31:05 +00:00
if ( session ) {
switch_core_session_rwunlock ( session ) ;
}
}
void event_handler ( switch_event_t * event )
{
char * subclass , * sql ;
2010-02-05 07:05:33 +00:00
char * class ;
switch_event_t * pevent ;
/* Get Original Event Name */
class = switch_event_get_header_nil ( event , " orig-event-name " ) ;
if ( ! strcasecmp ( class , " PRESENCE_IN " ) ) {
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_DEBUG , " \n Got Presence IN event via MultiCast \n " ) ;
if ( switch_event_create ( & pevent , SWITCH_EVENT_PRESENCE_IN ) = = SWITCH_STATUS_SUCCESS ) {
switch_event_add_header_string ( pevent , SWITCH_STACK_BOTTOM , " proto " , switch_event_get_header_nil ( event , " orig-proto " ) ) ;
switch_event_add_header_string ( pevent , SWITCH_STACK_BOTTOM , " login " , switch_event_get_header_nil ( event , " orig-login " ) ) ;
switch_event_add_header_string ( pevent , SWITCH_STACK_BOTTOM , " from " , switch_event_get_header_nil ( event , " orig-from " ) ) ;
switch_event_add_header_string ( pevent , SWITCH_STACK_BOTTOM , " rpid " , switch_event_get_header_nil ( event , " orig-rpid " ) ) ;
switch_event_add_header_string ( pevent , SWITCH_STACK_BOTTOM , " status " , switch_event_get_header_nil ( event , " orig-status " ) ) ;
switch_event_add_header_string ( pevent , SWITCH_STACK_BOTTOM , " answer-state " , switch_event_get_header_nil ( event , " orig-answer-state " ) ) ;
switch_event_add_header_string ( pevent , SWITCH_STACK_BOTTOM , " alt_event_type " , switch_event_get_header_nil ( event , " orig-alt_event_type " ) ) ;
switch_event_add_header_string ( pevent , SWITCH_STACK_BOTTOM , " presence-call-direction " , switch_event_get_header_nil ( event , " orig-presence-call-direction " ) ) ;
switch_event_add_header_string ( pevent , SWITCH_STACK_BOTTOM , " channel-state " , switch_event_get_header_nil ( event , " orig-channel-state " ) ) ;
switch_event_add_header_string ( pevent , SWITCH_STACK_BOTTOM , " call-direction " , switch_event_get_header_nil ( event , " orig-call-direction " ) ) ;
/* we cannot use switch_event_fire, or otherwise we'll start an endless loop */
sofia_presence_event_handler ( pevent ) ;
return ;
} else {
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_DEBUG , " \n Cannot inject PRESENCE_IN event \n " ) ;
return ;
}
} else if ( ! strcasecmp ( class , " MESSAGE_WAITING " ) ) {
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_DEBUG , " \n Got MWI event via MultiCast \n " ) ;
if ( switch_event_create ( & pevent , SWITCH_EVENT_MESSAGE_WAITING ) = = SWITCH_STATUS_SUCCESS ) {
switch_event_add_header_string ( pevent , SWITCH_STACK_BOTTOM , " MWI-Messages-Waiting " , switch_event_get_header_nil ( event , " orig-MWI-Messages-Waiting " ) ) ;
switch_event_add_header_string ( pevent , SWITCH_STACK_BOTTOM , " MWI-Message-Account " , switch_event_get_header_nil ( event , " orig-MWI-Message-Account " ) ) ;
switch_event_add_header_string ( pevent , SWITCH_STACK_BOTTOM , " MWI-Voice-Message " , switch_event_get_header_nil ( event , " orig-MWI-Voice-Message " ) ) ;
/* we cannot use switch_event_fire, or otherwise we'll start an endless loop */
sofia_presence_mwi_event_handler ( pevent ) ;
return ;
} else {
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_DEBUG , " \n Cannot inject MWI event \n " ) ;
return ;
}
} else if ( ( subclass = switch_event_get_header_nil ( event , " orig-event-subclass " ) ) & & ! strcasecmp ( subclass , MY_EVENT_REGISTER ) ) {
char * from_user = switch_event_get_header_nil ( event , " orig-from-user " ) ;
char * from_host = switch_event_get_header_nil ( event , " orig-from-host " ) ;
char * to_host = switch_event_get_header_nil ( event , " orig-to-host " ) ;
char * contact_str = switch_event_get_header_nil ( event , " orig-contact " ) ;
char * exp_str = switch_event_get_header_nil ( event , " orig-expires " ) ;
char * rpid = switch_event_get_header_nil ( event , " orig-rpid " ) ;
char * call_id = switch_event_get_header_nil ( event , " orig-call-id " ) ;
char * user_agent = switch_event_get_header_nil ( event , " orig-user-agent " ) ;
2009-01-25 21:23:07 +00:00
long expires = ( long ) switch_epoch_time_now ( NULL ) ;
2010-02-05 07:05:33 +00:00
char * profile_name = switch_event_get_header_nil ( event , " orig-profile-name " ) ;
char * to_user = switch_event_get_header_nil ( event , " orig-to-user " ) ;
char * presence_hosts = switch_event_get_header_nil ( event , " orig-presence-hosts " ) ;
char * network_ip = switch_event_get_header_nil ( event , " orig-network-ip " ) ;
char * network_port = switch_event_get_header_nil ( event , " orig-network-port " ) ;
char * username = switch_event_get_header_nil ( event , " orig-username " ) ;
char * realm = switch_event_get_header_nil ( event , " orig-realm " ) ;
char * orig_server_host = switch_event_get_header_nil ( event , " orig-FreeSWITCH-IPv4 " ) ;
char * orig_hostname = switch_event_get_header_nil ( event , " orig-FreeSWITCH-Hostname " ) ;
2009-07-24 19:34:32 +00:00
char * fixed_contact_str = NULL ;
2009-03-25 20:14:07 +00:00
2007-12-18 16:31:05 +00:00
sofia_profile_t * profile = NULL ;
2009-09-25 20:16:18 +00:00
char guess_ip4 [ 256 ] ;
2007-12-18 16:31:05 +00:00
2009-09-25 20:07:40 +00:00
char * mwi_account = NULL ;
char * dup_mwi_account = NULL ;
char * mwi_user = NULL ;
char * mwi_host = NULL ;
2010-02-05 07:05:33 +00:00
if ( ( mwi_account = switch_event_get_header_nil ( event , " orig-mwi-account " ) ) ) {
2009-09-25 20:07:40 +00:00
dup_mwi_account = strdup ( mwi_account ) ;
switch_assert ( dup_mwi_account ! = NULL ) ;
sofia_glue_get_user_host ( dup_mwi_account , & mwi_user , & mwi_host ) ;
}
if ( ! mwi_user ) {
mwi_user = ( char * ) from_user ;
}
if ( ! mwi_host ) {
mwi_host = ( char * ) from_host ;
}
2008-02-09 05:16:58 +00:00
if ( exp_str ) {
expires + = atol ( exp_str ) ;
}
2007-12-18 16:31:05 +00:00
if ( ! rpid ) {
rpid = " unknown " ;
}
if ( ! profile_name | | ! ( profile = sofia_glue_find_profile ( profile_name ) ) ) {
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_ERROR , " Invalid Profile \n " ) ;
2009-09-25 20:07:40 +00:00
goto end ;
2007-12-18 16:31:05 +00:00
}
if ( sofia_test_pflag ( profile , PFLAG_MULTIREG ) ) {
sql = switch_mprintf ( " delete from sip_registrations where call_id='%q' " , call_id ) ;
} else {
sql = switch_mprintf ( " delete from sip_registrations where sip_user='%q' and sip_host='%q' " , from_user , from_host ) ;
}
2007-12-18 01:12:50 +00:00
2009-07-24 19:34:32 +00:00
if ( mod_sofia_globals . rewrite_multicasted_fs_path & & contact_str ) {
const char * needle = " ;fs_path= " ;
char * sptr , * eptr = NULL ;
/* allocate enough room for worst-case scenario */
size_t len = strlen ( contact_str ) + strlen ( to_host ) + 14 ;
fixed_contact_str = malloc ( len ) ;
switch_assert ( fixed_contact_str ) ;
switch_copy_string ( fixed_contact_str , contact_str , len ) ;
2010-02-06 03:38:24 +00:00
2009-07-24 19:34:32 +00:00
if ( ( sptr = strstr ( fixed_contact_str , needle ) ) ) {
2009-07-27 16:18:16 +00:00
char * origsptr = strstr ( contact_str , needle ) ;
eptr = strchr ( + + origsptr , ' ; ' ) ;
2009-07-24 19:34:32 +00:00
} else {
sptr = strchr ( fixed_contact_str , ' \0 ' ) - 1 ;
}
2010-02-05 07:05:33 +00:00
switch ( mod_sofia_globals . rewrite_multicasted_fs_path ) {
case 1 :
switch_snprintf ( sptr , len - ( sptr - fixed_contact_str ) , " ;fs_path=sip:%s%s " , to_host , eptr ? eptr : " > " ) ;
break ;
case 2 :
switch_snprintf ( sptr , len - ( sptr - fixed_contact_str ) , " ;fs_path=sip:%s%s " , orig_server_host , eptr ? eptr : " > " ) ;
break ;
case 3 :
switch_snprintf ( sptr , len - ( sptr - fixed_contact_str ) , " ;fs_path=sip:%s%s " , orig_hostname , eptr ? eptr : " > " ) ;
break ;
default :
switch_snprintf ( sptr , len - ( sptr - fixed_contact_str ) , " ;fs_path=sip:%s%s " , to_host , eptr ? eptr : " > " ) ;
break ;
}
2009-07-24 19:34:32 +00:00
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_DEBUG , " Rewrote contact string from '%s' to '%s' \n " , contact_str , fixed_contact_str ) ;
contact_str = fixed_contact_str ;
}
2007-12-18 16:31:05 +00:00
switch_mutex_lock ( profile - > ireg_mutex ) ;
2008-03-05 20:31:18 +00:00
sofia_glue_execute_sql ( profile , & sql , SWITCH_TRUE ) ;
2010-02-06 03:38:24 +00:00
2009-06-02 16:55:10 +00:00
switch_find_local_ip ( guess_ip4 , sizeof ( guess_ip4 ) , NULL , AF_INET ) ;
2008-09-18 00:01:03 +00:00
sql = switch_mprintf ( " insert into sip_registrations "
2009-06-16 18:46:28 +00:00
" (call_id, sip_user, sip_host, presence_hosts, contact, status, rpid, expires, "
2010-02-05 07:05:33 +00:00
" user_agent, server_user, server_host, profile_name, hostname, network_ip, network_port, sip_username, sip_realm, "
" mwi_user, mwi_host, orig_server_host, orig_hostname) "
" values ('%q','%q','%q','%q','%q','Registered','%q',%ld, '%q','%q','%q','%q','%q','%q','%q','%q','%q','%q','%q','%q','%q') " ,
2010-02-06 03:38:24 +00:00
call_id , from_user , from_host , presence_hosts , contact_str , rpid , expires , user_agent , to_user , guess_ip4 ,
2010-02-05 07:05:33 +00:00
profile_name , mod_sofia_globals . hostname , network_ip , network_port , username , realm , mwi_user , mwi_host ,
orig_server_host , orig_hostname ) ;
2007-12-18 01:12:50 +00:00
2007-12-18 16:31:05 +00:00
if ( sql ) {
2008-03-05 20:31:18 +00:00
sofia_glue_execute_sql ( profile , & sql , SWITCH_TRUE ) ;
2007-12-18 16:31:05 +00:00
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_DEBUG , " Propagating registration for %s@%s->%s \n " , from_user , from_host , contact_str ) ;
}
switch_mutex_unlock ( profile - > ireg_mutex ) ;
2007-12-18 01:12:50 +00:00
2007-12-18 16:31:05 +00:00
if ( profile ) {
sofia_glue_release_profile ( profile ) ;
}
2010-02-06 03:38:24 +00:00
end :
2009-07-24 19:34:32 +00:00
switch_safe_free ( fixed_contact_str ) ;
2009-09-25 20:07:40 +00:00
switch_safe_free ( dup_mwi_account ) ;
2007-12-18 16:31:05 +00:00
}
}
2007-12-18 01:12:50 +00:00
2010-02-06 03:38:24 +00:00
static void sofia_perform_profile_start_failure ( sofia_profile_t * profile , char * profile_name , char * file , int line )
2009-12-09 14:42:30 +00:00
{
int arg = 0 ;
switch_event_t * s_event ;
if ( profile ) {
if ( ! strcasecmp ( profile - > shutdown_type , " true " ) ) {
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_CRIT , " Profile %s could not load! Shutting down! \n " , profile - > name ) ;
switch_core_session_ctl ( SCSC_SHUTDOWN , & arg ) ;
} else if ( ! strcasecmp ( profile - > shutdown_type , " elegant " ) ) {
2010-02-06 03:38:24 +00:00
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_CRIT , " Profile %s could not load! Waiting for calls to finish, then shutting down! \n " ,
profile - > name ) ;
2009-12-09 14:42:30 +00:00
switch_core_session_ctl ( SCSC_SHUTDOWN_ELEGANT , & arg ) ;
} else if ( ! strcasecmp ( profile - > shutdown_type , " asap " ) ) {
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_CRIT , " Profile %s could not load! Shutting down ASAP! \n " , profile - > name ) ;
switch_core_session_ctl ( SCSC_SHUTDOWN_ASAP , & arg ) ;
}
}
if ( ( switch_event_create ( & s_event , SWITCH_EVENT_FAILURE ) = = SWITCH_STATUS_SUCCESS ) ) {
switch_event_add_header_string ( s_event , SWITCH_STACK_BOTTOM , " module_name " , " mod_sofia " ) ;
switch_event_add_header_string ( s_event , SWITCH_STACK_BOTTOM , " profile_name " , profile_name ) ;
if ( profile ) {
switch_event_add_header_string ( s_event , SWITCH_STACK_BOTTOM , " profile_uri " , profile - > url ) ;
}
switch_event_add_header_string ( s_event , SWITCH_STACK_BOTTOM , " failure_message " , " Profile failed to start. " ) ;
switch_event_add_header_string ( s_event , SWITCH_STACK_BOTTOM , " file " , file ) ;
switch_event_add_header ( s_event , SWITCH_STACK_BOTTOM , " line " , " %d " , line ) ;
switch_event_fire ( & s_event ) ;
}
}
2010-02-06 03:38:24 +00:00
2009-12-09 14:42:30 +00:00
# define sofia_profile_start_failure(p, xp) sofia_perform_profile_start_failure(p, xp, __FILE__, __LINE__)
2009-10-23 20:09:34 +00:00
# define SQLLEN 1024 * 64
2008-03-04 23:53:23 +00:00
void * SWITCH_THREAD_FUNC sofia_profile_worker_thread_run ( switch_thread_t * thread , void * obj )
{
sofia_profile_t * profile = ( sofia_profile_t * ) obj ;
uint32_t ireg_loops = 0 ;
uint32_t gateway_loops = 0 ;
int loops = 0 ;
2008-03-05 20:31:18 +00:00
uint32_t qsize ;
2009-03-31 23:57:07 +00:00
void * pop ;
2009-10-23 20:09:34 +00:00
int loop_count = 0 ;
switch_size_t sql_len = SQLLEN ;
char * tmp , * sqlbuf = NULL ;
if ( sofia_test_pflag ( profile , PFLAG_SQL_IN_TRANS ) ) {
sqlbuf = ( char * ) malloc ( sql_len ) ;
}
2008-03-04 23:53:23 +00:00
ireg_loops = IREG_SECONDS ;
gateway_loops = GATEWAY_SECONDS ;
sofia_set_pflag_locked ( profile , PFLAG_WORKER_RUNNING ) ;
2008-05-27 04:54:52 +00:00
2008-08-24 01:52:27 +00:00
switch_queue_create ( & profile - > sql_queue , SOFIA_QUEUE_SIZE , profile - > pool ) ;
2008-05-27 04:54:52 +00:00
2008-03-05 20:31:18 +00:00
qsize = switch_queue_size ( profile - > sql_queue ) ;
while ( ( mod_sofia_globals . running = = 1 & & sofia_test_pflag ( profile , PFLAG_RUNNING ) ) | | qsize ) {
2009-10-23 20:09:34 +00:00
if ( sofia_test_pflag ( profile , PFLAG_SQL_IN_TRANS ) ) {
2009-12-24 05:44:23 +00:00
if ( qsize > 0 & & ( qsize > = 1024 | | + + loop_count > = profile - > trans_timeout ) ) {
2009-10-23 20:09:34 +00:00
switch_size_t newlen ;
uint32_t itterations = 0 ;
switch_size_t len = 0 ;
2010-02-06 03:38:24 +00:00
//switch_mutex_lock(profile->ireg_mutex);
2009-11-21 18:57:15 +00:00
//sofia_glue_actually_execute_sql(profile, "begin;\n", NULL);
2009-10-23 20:09:34 +00:00
while ( switch_queue_trypop ( profile - > sql_queue , & pop ) = = SWITCH_STATUS_SUCCESS & & pop ) {
char * sql = ( char * ) pop ;
2010-02-06 03:38:24 +00:00
2009-10-23 20:09:34 +00:00
newlen = strlen ( sql ) + 2 ;
2010-02-06 03:38:24 +00:00
2009-10-23 20:09:34 +00:00
if ( newlen + 10 < SQLLEN ) {
itterations + + ;
if ( len + newlen + 10 > sql_len ) {
sql_len = len + 10 + SQLLEN ;
if ( ! ( tmp = realloc ( sqlbuf , sql_len ) ) ) {
abort ( ) ;
break ;
}
sqlbuf = tmp ;
}
sprintf ( sqlbuf + len , " %s; \n " , sql ) ;
len + = newlen ;
}
free ( pop ) ;
}
//printf("TRANS:\n%s\n", sqlbuf);
2010-02-06 03:38:24 +00:00
sofia_glue_actually_execute_sql_trans ( profile , sqlbuf , profile - > ireg_mutex ) ;
2009-11-21 18:57:15 +00:00
//sofia_glue_actually_execute_sql(profile, "commit;\n", NULL);
2010-02-06 03:38:24 +00:00
//switch_mutex_unlock(profile->ireg_mutex);
2009-10-23 20:09:34 +00:00
loop_count = 0 ;
}
} else {
if ( qsize ) {
2010-02-06 03:38:24 +00:00
//switch_mutex_lock(profile->ireg_mutex);
2009-10-23 20:09:34 +00:00
while ( switch_queue_trypop ( profile - > sql_queue , & pop ) = = SWITCH_STATUS_SUCCESS & & pop ) {
2010-02-06 03:38:24 +00:00
sofia_glue_actually_execute_sql ( profile , ( char * ) pop , profile - > ireg_mutex ) ;
2009-10-23 20:09:34 +00:00
free ( pop ) ;
}
2010-02-06 03:38:24 +00:00
//switch_mutex_unlock(profile->ireg_mutex);
2008-03-05 20:31:18 +00:00
}
2008-03-04 23:53:23 +00:00
}
2010-02-06 03:38:24 +00:00
2009-11-11 16:00:30 +00:00
if ( + + loops > = 1000 ) {
2008-03-04 23:53:23 +00:00
if ( + + ireg_loops > = IREG_SECONDS ) {
2009-11-12 19:54:50 +00:00
time_t now = switch_epoch_time_now ( NULL ) ;
sofia_reg_check_expire ( profile , now , 0 ) ;
2008-03-04 23:53:23 +00:00
ireg_loops = 0 ;
}
if ( + + gateway_loops > = GATEWAY_SECONDS ) {
2009-01-25 21:23:07 +00:00
sofia_reg_check_gateway ( profile , switch_epoch_time_now ( NULL ) ) ;
2008-03-04 23:53:23 +00:00
gateway_loops = 0 ;
}
2008-11-24 15:52:55 +00:00
sofia_sub_check_gateway ( profile , time ( NULL ) ) ;
2008-03-04 23:53:23 +00:00
loops = 0 ;
}
2009-03-31 23:57:07 +00:00
switch_cond_next ( ) ;
2008-03-05 20:31:18 +00:00
qsize = switch_queue_size ( profile - > sql_queue ) ;
2008-03-04 23:53:23 +00:00
}
2008-05-27 04:54:52 +00:00
2009-03-31 23:57:07 +00:00
switch_mutex_lock ( profile - > ireg_mutex ) ;
while ( switch_queue_trypop ( profile - > sql_queue , & pop ) = = SWITCH_STATUS_SUCCESS & & pop ) {
2009-11-12 03:52:07 +00:00
sofia_glue_actually_execute_sql ( profile , ( char * ) pop , NULL ) ;
2009-03-31 23:57:07 +00:00
free ( pop ) ;
}
switch_mutex_unlock ( profile - > ireg_mutex ) ;
2008-03-04 23:53:23 +00:00
sofia_clear_pflag_locked ( profile , PFLAG_WORKER_RUNNING ) ;
2009-10-23 20:09:34 +00:00
switch_safe_free ( sqlbuf ) ;
2008-05-27 04:54:52 +00:00
2008-03-04 23:53:23 +00:00
return NULL ;
}
2009-03-03 20:16:05 +00:00
switch_thread_t * launch_sofia_worker_thread ( sofia_profile_t * profile )
2008-03-04 23:53:23 +00:00
{
switch_thread_t * thread ;
switch_threadattr_t * thd_attr = NULL ;
2008-03-05 20:31:18 +00:00
int x = 0 ;
2008-03-04 23:53:23 +00:00
switch_threadattr_create ( & thd_attr , profile - > pool ) ;
switch_threadattr_stacksize_set ( thd_attr , SWITCH_THREAD_STACKSIZE ) ;
switch_threadattr_priority_increase ( thd_attr ) ;
switch_thread_create ( & thread , thd_attr , sofia_profile_worker_thread_run , profile , profile - > pool ) ;
2008-03-05 20:31:18 +00:00
2008-05-27 04:54:52 +00:00
while ( ! sofia_test_pflag ( profile , PFLAG_WORKER_RUNNING ) ) {
2008-03-05 20:31:18 +00:00
switch_yield ( 100000 ) ;
if ( + + x > = 100 ) {
break ;
}
}
2009-03-03 20:16:05 +00:00
return thread ;
2008-03-04 23:53:23 +00:00
}
2007-12-18 16:31:05 +00:00
void * SWITCH_THREAD_FUNC sofia_profile_thread_run ( switch_thread_t * thread , void * obj )
{
sofia_profile_t * profile = ( sofia_profile_t * ) obj ;
switch_memory_pool_t * pool ;
sip_alias_node_t * node ;
switch_event_t * s_event ;
2008-04-14 19:20:12 +00:00
int use_100rel = ! sofia_test_pflag ( profile , PFLAG_DISABLE_100REL ) ;
int use_timer = ! sofia_test_pflag ( profile , PFLAG_DISABLE_TIMER ) ;
const char * supported = NULL ;
2009-02-05 17:14:12 +00:00
int sanity ;
2009-03-03 20:16:05 +00:00
switch_thread_t * worker_thread ;
switch_status_t st ;
2009-03-20 01:52:53 +00:00
2007-12-18 16:31:05 +00:00
switch_mutex_lock ( mod_sofia_globals . mutex ) ;
mod_sofia_globals . threads + + ;
switch_mutex_unlock ( mod_sofia_globals . mutex ) ;
profile - > s_root = su_root_create ( NULL ) ;
profile - > home = su_home_new ( sizeof ( * profile - > home ) ) ;
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_DEBUG , " Creating agent for %s \n " , profile - > name ) ;
if ( ! sofia_glue_init_sql ( profile ) ) {
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_CRIT , " Cannot Open SQL Database [%s]! \n " , profile - > name ) ;
2009-12-09 14:42:30 +00:00
sofia_profile_start_failure ( profile , profile - > name ) ;
2007-12-18 16:31:05 +00:00
sofia_glue_del_profile ( profile ) ;
goto end ;
}
2007-12-18 01:12:50 +00:00
2010-02-06 03:38:24 +00:00
supported = switch_core_sprintf ( profile - > pool , " %s%sprecondition, path, replaces " , use_100rel ? " 100rel, " : " " , use_timer ? " timer, " : " " ) ;
2008-04-14 19:20:12 +00:00
2009-06-08 23:26:30 +00:00
if ( sofia_test_pflag ( profile , PFLAG_AUTO_NAT ) & & switch_core_get_variable ( " nat_type " ) ) {
2009-06-30 18:59:05 +00:00
if ( switch_nat_add_mapping ( profile - > sip_port , SWITCH_NAT_UDP , NULL , SWITCH_FALSE ) = = SWITCH_STATUS_SUCCESS ) {
2009-06-03 21:08:34 +00:00
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_DEBUG , " Created UDP nat mapping for %s port %d \n " , profile - > name , profile - > sip_port ) ;
}
2009-06-30 18:59:05 +00:00
if ( switch_nat_add_mapping ( profile - > sip_port , SWITCH_NAT_TCP , NULL , SWITCH_FALSE ) = = SWITCH_STATUS_SUCCESS ) {
2009-06-03 21:08:34 +00:00
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_DEBUG , " Created TCP nat mapping for %s port %d \n " , profile - > name , profile - > sip_port ) ;
}
2010-02-06 03:38:24 +00:00
if ( sofia_test_pflag ( profile , PFLAG_TLS )
& & switch_nat_add_mapping ( profile - > tls_sip_port , SWITCH_NAT_TCP , NULL , SWITCH_FALSE ) = = SWITCH_STATUS_SUCCESS ) {
2009-06-03 21:08:34 +00:00
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_DEBUG , " Created TCP/TLS nat mapping for %s port %d \n " , profile - > name , profile - > tls_sip_port ) ;
}
}
2007-12-18 16:31:05 +00:00
profile - > nua = nua_create ( profile - > s_root , /* Event loop */
2008-05-27 04:54:52 +00:00
sofia_event_callback , /* Callback for processing events */
profile , /* Additional data to pass to callback */
2010-02-06 03:38:24 +00:00
NUTAG_URL ( profile - > bindurl ) , NTATAG_USER_VIA ( 1 ) , TAG_IF ( ! strchr ( profile - > sipip , ' : ' ) , SOATAG_AF ( SOA_AF_IP4_ONLY ) ) , TAG_IF ( strchr ( profile - > sipip , ' : ' ) , SOATAG_AF ( SOA_AF_IP6_ONLY ) ) , TAG_IF ( sofia_test_pflag ( profile , PFLAG_TLS ) , NUTAG_SIPS_URL ( profile - > tls_bindurl ) ) , TAG_IF ( sofia_test_pflag ( profile , PFLAG_TLS ) , NUTAG_CERTIFICATE_DIR ( profile - > tls_cert_dir ) ) , TAG_IF ( sofia_test_pflag ( profile , PFLAG_TLS ) , TPTAG_TLS_VERIFY_POLICY ( 0 ) ) , TAG_IF ( sofia_test_pflag ( profile , PFLAG_TLS ) , TPTAG_TLS_VERSION ( profile - > tls_version ) ) , TAG_IF ( sofia_test_pflag ( profile , PFLAG_TLS ) , TPTAG_KEEPALIVE ( 20000 ) ) , TAG_IF ( ! strchr ( profile - > sipip , ' : ' ) , NTATAG_UDP_MTU ( 65535 ) ) , TAG_IF ( sofia_test_pflag ( profile , PFLAG_DISABLE_SRV ) , NTATAG_USE_SRV ( 0 ) ) , TAG_IF ( sofia_test_pflag ( profile , PFLAG_DISABLE_NAPTR ) , NTATAG_USE_NAPTR ( 0 ) ) , NTATAG_DEFAULT_PROXY ( profile - > outbound_proxy ) , NTATAG_SERVER_RPORT ( profile - > rport_level ) , TPTAG_LOG ( sofia_test_flag ( profile , TFLAG_TPORT_LOG ) ) , TAG_IF ( sofia_test_pflag ( profile , PFLAG_SIPCOMPACT ) , NTATAG_SIPFLAGS ( MSG_DO_COMPACT ) ) , TAG_IF ( profile - > timer_t1 , NTATAG_SIP_T1 ( profile - > timer_t1 ) ) , TAG_IF ( profile - > timer_t1x64 , NTATAG_SIP_T1X64 ( profile - > timer_t1x64 ) ) , TAG_IF ( profile - > timer_t2 , NTATAG_SIP_T2 ( profile - > timer_t2 ) ) , TAG_IF ( profile - > timer_t4 , NTATAG_SIP_T4 ( profile - > timer_t4 ) ) , TAG_END ( ) ) ; /* Last tag should always finish the sequence */
2007-12-18 01:12:50 +00:00
2007-12-18 16:31:05 +00:00
if ( ! profile - > nua ) {
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_ERROR , " Error Creating SIP UA for profile: %s \n " , profile - > name ) ;
2009-12-09 14:42:30 +00:00
sofia_profile_start_failure ( profile , profile - > name ) ;
2007-12-18 16:31:05 +00:00
sofia_glue_del_profile ( profile ) ;
goto end ;
}
2007-12-18 01:12:50 +00:00
2007-12-18 16:31:05 +00:00
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_DEBUG , " Created agent for %s \n " , profile - > name ) ;
2007-12-18 01:12:50 +00:00
2007-12-18 16:31:05 +00:00
nua_set_params ( profile - > nua ,
2009-10-26 19:57:28 +00:00
SIPTAG_ALLOW_STR ( " INVITE, ACK, BYE, CANCEL, OPTIONS, MESSAGE, UPDATE, INFO " ) ,
2008-01-03 00:50:53 +00:00
NUTAG_APPL_METHOD ( " OPTIONS " ) ,
2009-08-31 18:11:26 +00:00
NUTAG_APPL_METHOD ( " REFER " ) ,
NUTAG_APPL_METHOD ( " REGISTER " ) ,
2010-02-06 03:38:24 +00:00
NUTAG_APPL_METHOD ( " NOTIFY " ) , NUTAG_APPL_METHOD ( " INFO " ) , NUTAG_APPL_METHOD ( " ACK " ) , NUTAG_APPL_METHOD ( " SUBSCRIBE " ) ,
2009-07-02 17:40:16 +00:00
# ifdef MANUAL_BYE
NUTAG_APPL_METHOD ( " BYE " ) ,
# endif
2008-01-03 00:50:53 +00:00
NUTAG_AUTOANSWER ( 0 ) ,
2009-10-29 21:58:37 +00:00
NUTAG_AUTOACK ( 0 ) ,
2008-01-03 00:50:53 +00:00
NUTAG_AUTOALERT ( 0 ) ,
2008-07-23 18:19:56 +00:00
NUTAG_ENABLEMESSENGER ( 1 ) ,
2008-03-07 14:36:08 +00:00
TAG_IF ( ( profile - > mflags & MFLAG_REGISTER ) , NUTAG_ALLOW ( " REGISTER " ) ) ,
TAG_IF ( ( profile - > mflags & MFLAG_REFER ) , NUTAG_ALLOW ( " REFER " ) ) ,
2009-08-31 18:11:26 +00:00
TAG_IF ( ! sofia_test_pflag ( profile , PFLAG_DISABLE_100REL ) , NUTAG_ALLOW ( " PRACK " ) ) ,
2008-01-03 00:50:53 +00:00
NUTAG_ALLOW ( " INFO " ) ,
NUTAG_ALLOW ( " NOTIFY " ) ,
NUTAG_ALLOW_EVENTS ( " talk " ) ,
NUTAG_SESSION_TIMER ( profile - > session_timeout ) ,
NTATAG_MAX_PROCEEDING ( profile - > max_proceeding ) ,
2008-09-18 00:01:03 +00:00
TAG_IF ( profile - > pres_type , NUTAG_ALLOW ( " PUBLISH " ) ) ,
TAG_IF ( profile - > pres_type , NUTAG_ALLOW ( " SUBSCRIBE " ) ) ,
TAG_IF ( profile - > pres_type , NUTAG_ENABLEMESSAGE ( 1 ) ) ,
TAG_IF ( profile - > pres_type , NUTAG_ALLOW_EVENTS ( " presence " ) ) ,
2009-02-12 14:46:14 +00:00
TAG_IF ( ( profile - > pres_type | | sofia_test_pflag ( profile , PFLAG_MANAGE_SHARED_APPEARANCE ) ) , NUTAG_ALLOW_EVENTS ( " dialog " ) ) ,
2009-12-16 00:29:43 +00:00
TAG_IF ( ( profile - > pres_type | | sofia_test_pflag ( profile , PFLAG_MANAGE_SHARED_APPEARANCE ) ) , NUTAG_ALLOW_EVENTS ( " line-seize " ) ) ,
2008-09-18 00:01:03 +00:00
TAG_IF ( profile - > pres_type , NUTAG_ALLOW_EVENTS ( " call-info " ) ) ,
2009-02-12 14:46:14 +00:00
TAG_IF ( ( profile - > pres_type | | sofia_test_pflag ( profile , PFLAG_MANAGE_SHARED_APPEARANCE ) ) , NUTAG_ALLOW_EVENTS ( " sla " ) ) ,
2008-09-18 00:01:03 +00:00
TAG_IF ( profile - > pres_type , NUTAG_ALLOW_EVENTS ( " include-session-description " ) ) ,
TAG_IF ( profile - > pres_type , NUTAG_ALLOW_EVENTS ( " presence.winfo " ) ) ,
TAG_IF ( profile - > pres_type , NUTAG_ALLOW_EVENTS ( " message-summary " ) ) ,
2010-02-06 03:38:24 +00:00
NUTAG_ALLOW_EVENTS ( " refer " ) , SIPTAG_SUPPORTED_STR ( supported ) , SIPTAG_USER_AGENT_STR ( profile - > user_agent ) , TAG_END ( ) ) ;
2007-12-18 01:12:50 +00:00
2007-12-18 16:31:05 +00:00
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_DEBUG , " Set params for %s \n " , profile - > name ) ;
2007-12-18 01:12:50 +00:00
2007-12-18 16:31:05 +00:00
for ( node = profile - > aliases ; node ; node = node - > next ) {
node - > nua = nua_create ( profile - > s_root , /* Event loop */
2008-05-27 04:54:52 +00:00
sofia_event_callback , /* Callback for processing events */
profile , /* Additional data to pass to callback */
2008-06-05 15:59:09 +00:00
NTATAG_SERVER_RPORT ( profile - > rport_level ) , NUTAG_URL ( node - > url ) , TAG_END ( ) ) ; /* Last tag should always finish the sequence */
2007-12-18 01:12:50 +00:00
2007-12-18 16:31:05 +00:00
nua_set_params ( node - > nua ,
2008-03-07 14:36:08 +00:00
NUTAG_APPL_METHOD ( " OPTIONS " ) ,
2009-08-31 18:11:26 +00:00
NUTAG_APPL_METHOD ( " REFER " ) ,
2009-11-05 04:21:08 +00:00
NUTAG_APPL_METHOD ( " SUBSCRIBE " ) ,
2008-03-07 14:36:08 +00:00
NUTAG_AUTOANSWER ( 0 ) ,
2009-10-29 21:58:37 +00:00
NUTAG_AUTOACK ( 0 ) ,
2008-03-07 14:36:08 +00:00
NUTAG_AUTOALERT ( 0 ) ,
TAG_IF ( ( profile - > mflags & MFLAG_REGISTER ) , NUTAG_ALLOW ( " REGISTER " ) ) ,
TAG_IF ( ( profile - > mflags & MFLAG_REFER ) , NUTAG_ALLOW ( " REFER " ) ) ,
NUTAG_ALLOW ( " INFO " ) ,
2008-09-18 00:01:03 +00:00
TAG_IF ( profile - > pres_type , NUTAG_ALLOW ( " PUBLISH " ) ) ,
TAG_IF ( profile - > pres_type , NUTAG_ENABLEMESSAGE ( 1 ) ) ,
2008-05-27 04:54:52 +00:00
SIPTAG_SUPPORTED_STR ( supported ) , SIPTAG_USER_AGENT_STR ( profile - > user_agent ) , TAG_END ( ) ) ;
2007-12-18 16:31:05 +00:00
}
2007-12-18 01:12:50 +00:00
2008-10-11 05:42:52 +00:00
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_DEBUG , " Activated db for %s \n " , profile - > name ) ;
2007-12-18 01:12:50 +00:00
2007-12-18 16:31:05 +00:00
switch_mutex_init ( & profile - > ireg_mutex , SWITCH_MUTEX_NESTED , profile - > pool ) ;
switch_mutex_init ( & profile - > gateway_mutex , SWITCH_MUTEX_NESTED , profile - > pool ) ;
2007-12-18 01:12:50 +00:00
2007-12-18 16:31:05 +00:00
if ( switch_event_create ( & s_event , SWITCH_EVENT_PUBLISH ) = = SWITCH_STATUS_SUCCESS ) {
2007-12-18 19:12:45 +00:00
switch_event_add_header ( s_event , SWITCH_STACK_BOTTOM , " service " , " _sip._udp,_sip._tcp,_sip._sctp%s " ,
2007-12-18 19:15:08 +00:00
( sofia_test_pflag ( profile , PFLAG_TLS ) ) ? " ,_sips._tcp " : " " ) ;
2007-12-18 19:12:45 +00:00
2007-12-18 16:31:05 +00:00
switch_event_add_header ( s_event , SWITCH_STACK_BOTTOM , " port " , " %d " , profile - > sip_port ) ;
2008-08-16 02:19:43 +00:00
switch_event_add_header_string ( s_event , SWITCH_STACK_BOTTOM , " module_name " , " mod_sofia " ) ;
switch_event_add_header_string ( s_event , SWITCH_STACK_BOTTOM , " profile_name " , profile - > name ) ;
switch_event_add_header_string ( s_event , SWITCH_STACK_BOTTOM , " profile_uri " , profile - > url ) ;
2007-12-18 19:12:45 +00:00
if ( sofia_test_pflag ( profile , PFLAG_TLS ) ) {
switch_event_add_header ( s_event , SWITCH_STACK_BOTTOM , " tls_port " , " %d " , profile - > tls_sip_port ) ;
2008-08-16 02:19:43 +00:00
switch_event_add_header_string ( s_event , SWITCH_STACK_BOTTOM , " profile_tls_uri " , profile - > tls_url ) ;
2007-12-18 19:12:45 +00:00
}
2007-12-18 16:31:05 +00:00
switch_event_fire ( & s_event ) ;
}
2007-12-18 01:12:50 +00:00
2007-12-18 16:31:05 +00:00
sofia_glue_add_profile ( profile - > name , profile ) ;
2007-12-18 01:12:50 +00:00
2008-09-18 00:01:03 +00:00
if ( profile - > pres_type ) {
2007-12-18 16:31:05 +00:00
sofia_presence_establish_presence ( profile ) ;
}
2007-12-18 01:12:50 +00:00
2007-12-18 16:31:05 +00:00
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_DEBUG , " Starting thread for %s \n " , profile - > name ) ;
2007-12-18 01:12:50 +00:00
2009-01-25 21:23:07 +00:00
profile - > started = switch_epoch_time_now ( NULL ) ;
2007-12-18 01:12:50 +00:00
2007-12-18 16:31:05 +00:00
sofia_set_pflag_locked ( profile , PFLAG_RUNNING ) ;
2009-03-03 20:16:05 +00:00
worker_thread = launch_sofia_worker_thread ( profile ) ;
2007-12-18 01:12:50 +00:00
2008-03-05 20:31:18 +00:00
switch_yield ( 1000000 ) ;
2009-12-10 20:51:13 +00:00
2008-03-04 23:53:23 +00:00
while ( mod_sofia_globals . running = = 1 & & sofia_test_pflag ( profile , PFLAG_RUNNING ) & & sofia_test_pflag ( profile , PFLAG_WORKER_RUNNING ) ) {
2007-12-18 16:31:05 +00:00
su_root_step ( profile - > s_root , 1000 ) ;
}
2007-12-18 01:12:50 +00:00
2008-10-13 19:26:28 +00:00
sofia_clear_pflag_locked ( profile , PFLAG_RUNNING ) ;
switch_core_session_hupall_matching_var ( " sofia_profile_name " , profile - > name , SWITCH_CAUSE_MANAGER_REQUEST ) ;
2009-02-05 17:14:12 +00:00
sanity = 10 ;
2008-10-13 19:26:28 +00:00
while ( profile - > inuse ) {
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_CRIT , " Waiting for %d session(s) \n " , profile - > inuse ) ;
su_root_step ( profile - > s_root , 1000 ) ;
2009-02-05 17:14:12 +00:00
if ( ! - - sanity ) {
break ;
} else if ( sanity = = 5 ) {
switch_core_session_hupall_matching_var ( " sofia_profile_name " , profile - > name , SWITCH_CAUSE_MANAGER_REQUEST ) ;
}
2008-10-13 19:26:28 +00:00
}
2007-12-18 16:31:05 +00:00
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_DEBUG , " Write lock %s \n " , profile - > name ) ;
switch_thread_rwlock_wrlock ( profile - > rwlock ) ;
sofia_reg_unregister ( profile ) ;
nua_shutdown ( profile - > nua ) ;
su_root_run ( profile - > s_root ) ;
2010-02-06 03:38:24 +00:00
2008-03-04 23:53:23 +00:00
sofia_clear_pflag_locked ( profile , PFLAG_RUNNING ) ;
2008-10-11 05:42:52 +00:00
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_NOTICE , " Waiting for worker thread \n " ) ;
2008-03-04 23:53:23 +00:00
2009-03-03 20:16:05 +00:00
switch_thread_join ( & st , worker_thread ) ;
2010-02-06 03:38:24 +00:00
2009-02-05 17:14:12 +00:00
sanity = 4 ;
2008-05-27 04:54:52 +00:00
while ( profile - > inuse ) {
2009-02-05 17:14:12 +00:00
switch_core_session_hupall_matching_var ( " sofia_profile_name " , profile - > name , SWITCH_CAUSE_MANAGER_REQUEST ) ;
2008-09-09 15:25:31 +00:00
switch_yield ( 5000000 ) ;
2008-10-11 05:42:52 +00:00
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_CRIT , " Waiting for %d session(s) \n " , profile - > inuse ) ;
2009-02-05 17:14:12 +00:00
if ( ! - - sanity ) {
2008-09-09 15:25:31 +00:00
break ;
}
2008-01-08 16:35:20 +00:00
}
2007-12-18 16:31:05 +00:00
nua_destroy ( profile - > nua ) ;
2010-02-06 03:38:24 +00:00
2007-12-18 16:31:05 +00:00
switch_mutex_lock ( profile - > ireg_mutex ) ;
switch_mutex_unlock ( profile - > ireg_mutex ) ;
2007-12-18 01:12:50 +00:00
2008-01-08 16:35:20 +00:00
switch_mutex_lock ( profile - > flag_mutex ) ;
switch_mutex_unlock ( profile - > flag_mutex ) ;
2007-12-18 16:31:05 +00:00
if ( switch_event_create ( & s_event , SWITCH_EVENT_UNPUBLISH ) = = SWITCH_STATUS_SUCCESS ) {
2007-12-18 19:12:45 +00:00
switch_event_add_header ( s_event , SWITCH_STACK_BOTTOM , " service " , " _sip._udp,_sip._tcp,_sip._sctp%s " ,
2008-05-27 04:54:52 +00:00
( sofia_test_pflag ( profile , PFLAG_TLS ) ) ? " ,_sips._tcp " : " " ) ;
2007-12-18 19:12:45 +00:00
2007-12-18 16:31:05 +00:00
switch_event_add_header ( s_event , SWITCH_STACK_BOTTOM , " port " , " %d " , profile - > sip_port ) ;
2008-08-16 02:19:43 +00:00
switch_event_add_header_string ( s_event , SWITCH_STACK_BOTTOM , " module_name " , " mod_sofia " ) ;
switch_event_add_header_string ( s_event , SWITCH_STACK_BOTTOM , " profile_name " , profile - > name ) ;
switch_event_add_header_string ( s_event , SWITCH_STACK_BOTTOM , " profile_uri " , profile - > url ) ;
2007-12-18 19:12:45 +00:00
if ( sofia_test_pflag ( profile , PFLAG_TLS ) ) {
switch_event_add_header ( s_event , SWITCH_STACK_BOTTOM , " tls_port " , " %d " , profile - > tls_sip_port ) ;
2008-08-16 02:19:43 +00:00
switch_event_add_header_string ( s_event , SWITCH_STACK_BOTTOM , " profile_tls_uri " , profile - > tls_url ) ;
2007-12-18 19:12:45 +00:00
}
2007-12-18 16:31:05 +00:00
switch_event_fire ( & s_event ) ;
}
2007-12-18 01:12:50 +00:00
2009-06-08 23:26:30 +00:00
if ( sofia_test_pflag ( profile , PFLAG_AUTO_NAT ) & & switch_core_get_variable ( " nat_type " ) ) {
2009-06-03 21:08:34 +00:00
if ( switch_nat_del_mapping ( profile - > sip_port , SWITCH_NAT_UDP ) = = SWITCH_STATUS_SUCCESS ) {
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_DEBUG , " Deleted UDP nat mapping for %s port %d \n " , profile - > name , profile - > sip_port ) ;
}
if ( switch_nat_del_mapping ( profile - > sip_port , SWITCH_NAT_TCP ) = = SWITCH_STATUS_SUCCESS ) {
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_DEBUG , " Deleted TCP nat mapping for %s port %d \n " , profile - > name , profile - > sip_port ) ;
}
2009-12-11 01:20:26 +00:00
if ( sofia_test_pflag ( profile , PFLAG_TLS ) & & switch_nat_del_mapping ( profile - > tls_sip_port , SWITCH_NAT_TCP ) = = SWITCH_STATUS_SUCCESS ) {
2009-06-03 21:08:34 +00:00
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_DEBUG , " Deleted TCP/TLS nat mapping for %s port %d \n " , profile - > name , profile - > tls_sip_port ) ;
}
}
2007-12-18 16:31:05 +00:00
su_home_unref ( profile - > home ) ;
su_root_destroy ( profile - > s_root ) ;
pool = profile - > pool ;
2007-12-18 01:12:50 +00:00
2007-12-18 16:31:05 +00:00
sofia_glue_del_profile ( profile ) ;
switch_core_hash_destroy ( & profile - > chat_hash ) ;
2007-12-18 01:12:50 +00:00
2007-12-18 16:31:05 +00:00
switch_thread_rwlock_unlock ( profile - > rwlock ) ;
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_DEBUG , " Write unlock %s \n " , profile - > name ) ;
2007-12-18 01:12:50 +00:00
2007-12-18 16:31:05 +00:00
if ( sofia_test_pflag ( profile , PFLAG_RESPAWN ) ) {
config_sofia ( 1 , profile - > name ) ;
}
2007-12-18 01:12:50 +00:00
2007-12-18 16:31:05 +00:00
switch_core_destroy_memory_pool ( & pool ) ;
2007-12-18 01:12:50 +00:00
end :
2007-12-18 16:31:05 +00:00
switch_mutex_lock ( mod_sofia_globals . mutex ) ;
mod_sofia_globals . threads - - ;
switch_mutex_unlock ( mod_sofia_globals . mutex ) ;
return NULL ;
}
void launch_sofia_profile_thread ( sofia_profile_t * profile )
{
switch_thread_t * thread ;
switch_threadattr_t * thd_attr = NULL ;
switch_threadattr_create ( & thd_attr , profile - > pool ) ;
switch_threadattr_detach_set ( thd_attr , 1 ) ;
switch_threadattr_stacksize_set ( thd_attr , SWITCH_THREAD_STACKSIZE ) ;
2008-03-04 23:53:23 +00:00
switch_threadattr_priority_increase ( thd_attr ) ;
2007-12-18 16:31:05 +00:00
switch_thread_create ( & thread , thd_attr , sofia_profile_thread_run , profile , profile - > pool ) ;
}
static void logger ( void * logarg , char const * fmt , va_list ap )
{
2010-02-06 03:38:24 +00:00
if ( ! fmt )
return ;
2009-11-30 12:20:55 +00:00
if ( ap ) {
2009-06-09 19:52:07 +00:00
switch_log_vprintf ( SWITCH_CHANNEL_LOG_CLEAN , mod_sofia_globals . tracelevel , fmt , ap ) ;
2009-11-30 12:20:55 +00:00
} else {
2009-06-09 19:52:07 +00:00
switch_log_printf ( SWITCH_CHANNEL_LOG_CLEAN , mod_sofia_globals . tracelevel , " %s " , fmt ) ;
2009-03-04 18:54:43 +00:00
}
}
2007-12-18 16:31:05 +00:00
2010-02-06 03:38:24 +00:00
static su_log_t * sofia_get_logger ( const char * name )
2009-03-04 18:54:43 +00:00
{
if ( ! strcasecmp ( name , " tport " ) ) {
2009-03-04 20:17:36 +00:00
return tport_log ;
2009-03-04 18:54:43 +00:00
} else if ( ! strcasecmp ( name , " iptsec " ) ) {
2009-03-04 20:17:36 +00:00
return iptsec_log ;
2009-03-04 18:54:43 +00:00
} else if ( ! strcasecmp ( name , " nea " ) ) {
2009-03-04 20:17:36 +00:00
return nea_log ;
2009-03-04 18:54:43 +00:00
} else if ( ! strcasecmp ( name , " nta " ) ) {
2009-03-04 20:17:36 +00:00
return nta_log ;
2009-03-04 18:54:43 +00:00
} else if ( ! strcasecmp ( name , " nth_client " ) ) {
2009-03-04 20:17:36 +00:00
return nth_client_log ;
2009-03-04 18:54:43 +00:00
} else if ( ! strcasecmp ( name , " nth_server " ) ) {
2009-03-04 20:17:36 +00:00
return nth_server_log ;
2009-03-04 18:54:43 +00:00
} else if ( ! strcasecmp ( name , " nua " ) ) {
2009-03-04 20:17:36 +00:00
return nua_log ;
2009-12-28 15:54:00 +00:00
} else if ( ! strcasecmp ( name , " soa " ) ) {
return soa_log ;
2009-03-04 18:54:43 +00:00
} else if ( ! strcasecmp ( name , " sresolv " ) ) {
2009-03-04 20:17:36 +00:00
return sresolv_log ;
2009-03-04 18:54:43 +00:00
} else if ( ! strcasecmp ( name , " stun " ) ) {
2009-03-04 20:17:36 +00:00
return stun_log ;
} else if ( ! strcasecmp ( name , " default " ) ) {
return su_log_default ;
} else {
return NULL ;
2007-12-18 16:31:05 +00:00
}
2009-03-04 18:54:43 +00:00
}
switch_status_t sofia_set_loglevel ( const char * name , int level )
{
su_log_t * log = NULL ;
2010-02-06 03:38:24 +00:00
2009-03-04 18:54:43 +00:00
if ( level < 0 | | level > 9 ) {
return SWITCH_STATUS_FALSE ;
}
2010-02-06 03:38:24 +00:00
2009-03-04 18:54:43 +00:00
if ( ! strcasecmp ( name , " all " ) ) {
2009-03-04 20:17:36 +00:00
su_log_set_level ( su_log_default , level ) ;
2009-03-04 18:54:43 +00:00
su_log_set_level ( tport_log , level ) ;
su_log_set_level ( iptsec_log , level ) ;
su_log_set_level ( nea_log , level ) ;
su_log_set_level ( nta_log , level ) ;
su_log_set_level ( nth_client_log , level ) ;
su_log_set_level ( nth_server_log , level ) ;
su_log_set_level ( nua_log , level ) ;
su_log_set_level ( soa_log , level ) ;
su_log_set_level ( sresolv_log , level ) ;
su_log_set_level ( stun_log , level ) ;
return SWITCH_STATUS_SUCCESS ;
}
2010-02-06 03:38:24 +00:00
2009-03-04 20:17:36 +00:00
if ( ! ( log = sofia_get_logger ( name ) ) ) {
return SWITCH_STATUS_FALSE ;
2009-03-04 18:54:43 +00:00
}
2010-02-06 03:38:24 +00:00
2009-03-04 20:17:36 +00:00
su_log_set_level ( log , level ) ;
2010-02-06 03:38:24 +00:00
2009-03-04 20:17:36 +00:00
return SWITCH_STATUS_SUCCESS ;
2009-03-04 18:54:43 +00:00
}
int sofia_get_loglevel ( const char * name )
{
su_log_t * log = NULL ;
2010-02-06 03:38:24 +00:00
2009-03-04 20:17:36 +00:00
if ( ( log = sofia_get_logger ( name ) ) ) {
2009-03-04 18:54:43 +00:00
return log - > log_level ;
} else {
return - 1 ;
2007-12-18 16:31:05 +00:00
}
}
2008-11-24 15:52:55 +00:00
static void parse_gateway_subscriptions ( sofia_profile_t * profile , sofia_gateway_t * gateway , switch_xml_t gw_subs_tag )
{
switch_xml_t subscription_tag , param ;
for ( subscription_tag = switch_xml_child ( gw_subs_tag , " subscription " ) ; subscription_tag ; subscription_tag = subscription_tag - > next ) {
sofia_gateway_subscription_t * gw_sub ;
if ( ( gw_sub = switch_core_alloc ( profile - > pool , sizeof ( * gw_sub ) ) ) ) {
char * expire_seconds = " 3600 " , * retry_seconds = " 30 " , * content_type = " NO_CONTENT_TYPE " ;
char * event = ( char * ) switch_xml_attr_soft ( subscription_tag , " event " ) ;
2010-02-06 03:38:24 +00:00
gw_sub - > event = switch_core_strdup ( gateway - > pool , event ) ;
2008-11-24 15:52:55 +00:00
gw_sub - > gateway = gateway ;
gw_sub - > next = NULL ;
2010-02-06 03:38:24 +00:00
2008-11-24 15:52:55 +00:00
for ( param = switch_xml_child ( subscription_tag , " param " ) ; param ; param = param - > next ) {
char * var = ( char * ) switch_xml_attr_soft ( param , " name " ) ;
char * val = ( char * ) switch_xml_attr_soft ( param , " value " ) ;
if ( ! strcmp ( var , " expire-seconds " ) ) {
expire_seconds = val ;
} else if ( ! strcmp ( var , " retry-seconds " ) ) {
retry_seconds = val ;
} else if ( ! strcmp ( var , " content-type " ) ) {
content_type = val ;
}
}
2010-02-06 03:38:24 +00:00
2008-11-24 15:52:55 +00:00
gw_sub - > retry_seconds = atoi ( retry_seconds ) ;
if ( gw_sub - > retry_seconds < 10 ) {
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_WARNING , " INVALID: retry_seconds correcting the value to 30 \n " ) ;
gw_sub - > retry_seconds = 30 ;
}
2010-02-06 03:38:24 +00:00
gw_sub - > expires_str = switch_core_strdup ( gateway - > pool , expire_seconds ) ;
2008-11-24 15:52:55 +00:00
if ( ( gw_sub - > freq = atoi ( gw_sub - > expires_str ) ) < 5 ) {
2010-02-06 03:38:24 +00:00
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_WARNING , " Invalid Freq: %d. Setting Register-Frequency to 3600 \n " , gw_sub - > freq ) ;
2008-11-24 15:52:55 +00:00
gw_sub - > freq = 3600 ;
}
gw_sub - > freq - = 2 ;
gw_sub - > content_type = switch_core_strdup ( gateway - > pool , content_type ) ;
2010-02-06 03:38:24 +00:00
gw_sub - > next = gateway - > subscriptions ;
2008-11-24 15:52:55 +00:00
}
gateway - > subscriptions = gw_sub ;
}
}
2007-12-18 16:31:05 +00:00
static void parse_gateways ( sofia_profile_t * profile , switch_xml_t gateways_tag )
{
2009-01-23 20:33:30 +00:00
switch_xml_t gateway_tag , param = NULL , x_params , gw_subs_tag ;
2007-12-18 16:31:05 +00:00
sofia_gateway_t * gp ;
for ( gateway_tag = switch_xml_child ( gateways_tag , " gateway " ) ; gateway_tag ; gateway_tag = gateway_tag - > next ) {
char * name = ( char * ) switch_xml_attr_soft ( gateway_tag , " name " ) ;
sofia_gateway_t * gateway ;
2009-10-23 16:03:42 +00:00
if ( zstr ( name ) ) {
2007-12-18 16:31:05 +00:00
name = " anonymous " ;
}
2008-04-04 18:53:24 +00:00
switch_mutex_lock ( mod_sofia_globals . hash_mutex ) ;
if ( ( gp = switch_core_hash_find ( mod_sofia_globals . gateway_hash , name ) ) ) {
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_WARNING , " Ignoring duplicate gateway '%s' \n " , name ) ;
switch_mutex_unlock ( mod_sofia_globals . hash_mutex ) ;
goto skip ;
}
switch_mutex_unlock ( mod_sofia_globals . hash_mutex ) ;
2007-12-18 16:31:05 +00:00
if ( ( gateway = switch_core_alloc ( profile - > pool , sizeof ( * gateway ) ) ) ) {
2008-07-03 18:50:15 +00:00
const char * sipip , * format ;
2009-02-18 15:52:33 +00:00
switch_uuid_t uuid ;
2009-11-03 21:32:18 +00:00
uint32_t ping_freq = 0 , extension_in_contact = 0 , distinct_to = 0 ;
2009-12-23 01:57:52 +00:00
int ping_max = 1 , ping_min = - 1 ;
2007-12-18 16:31:05 +00:00
char * register_str = " true " , * scheme = " Digest " ,
* realm = NULL ,
* username = NULL ,
2008-08-15 19:30:34 +00:00
* auth_username = NULL ,
2007-12-18 16:31:05 +00:00
* password = NULL ,
* caller_id_in_from = " false " ,
* extension = NULL ,
* proxy = NULL ,
2009-02-18 14:13:02 +00:00
* context = profile - > context ,
2007-12-18 16:31:05 +00:00
* expire_seconds = " 3600 " ,
* retry_seconds = " 30 " ,
2009-07-21 00:18:20 +00:00
* from_user = " " , * from_domain = NULL , * outbound_proxy = NULL , * register_proxy = NULL , * contact_host = NULL ,
2009-03-09 15:02:04 +00:00
* contact_params = NULL , * params = NULL , * register_transport = NULL ;
2010-02-06 03:38:24 +00:00
2009-02-18 14:13:02 +00:00
if ( ! context ) {
context = " default " ;
}
2010-02-06 03:38:24 +00:00
2008-11-15 02:38:40 +00:00
switch_uuid_get ( & uuid ) ;
switch_uuid_format ( gateway - > uuid_str , & uuid ) ;
2010-02-06 03:38:24 +00:00
2008-01-17 17:37:49 +00:00
gateway - > register_transport = SOFIA_TRANSPORT_UDP ;
2007-12-18 16:31:05 +00:00
gateway - > pool = profile - > pool ;
gateway - > profile = profile ;
gateway - > name = switch_core_strdup ( gateway - > pool , name ) ;
gateway - > freq = 0 ;
gateway - > next = NULL ;
2008-04-30 22:09:54 +00:00
gateway - > ping = 0 ;
gateway - > ping_freq = 0 ;
2009-12-23 01:57:52 +00:00
gateway - > ping_max = 0 ;
gateway - > ping_min = 0 ;
2009-11-23 19:46:37 +00:00
gateway - > ping_count = 0 ;
2010-02-06 03:38:24 +00:00
2009-01-23 20:33:30 +00:00
if ( ( x_params = switch_xml_child ( gateway_tag , " variables " ) ) ) {
param = switch_xml_child ( x_params , " variable " ) ;
} else {
param = switch_xml_child ( gateway_tag , " variable " ) ;
}
2010-02-06 03:38:24 +00:00
2009-01-23 20:33:30 +00:00
for ( ; param ; param = param - > next ) {
const char * var = switch_xml_attr ( param , " name " ) ;
const char * val = switch_xml_attr ( param , " value " ) ;
const char * direction = switch_xml_attr ( param , " direction " ) ;
int in = 0 , out = 0 ;
2010-02-06 03:38:24 +00:00
2009-01-23 20:33:30 +00:00
if ( var & & val ) {
if ( direction ) {
if ( ! strcasecmp ( direction , " inbound " ) ) {
in = 1 ;
} else if ( ! strcasecmp ( direction , " outbound " ) ) {
out = 1 ;
}
} else {
in = out = 1 ;
}
if ( in ) {
if ( ! gateway - > ib_vars ) {
2009-03-24 23:44:03 +00:00
switch_event_create_plain ( & gateway - > ib_vars , SWITCH_EVENT_GENERAL ) ;
2009-01-23 20:33:30 +00:00
}
switch_event_add_header_string ( gateway - > ib_vars , SWITCH_STACK_BOTTOM , var , val ) ;
}
if ( out ) {
if ( ! gateway - > ob_vars ) {
2009-03-24 23:44:03 +00:00
switch_event_create_plain ( & gateway - > ob_vars , SWITCH_EVENT_GENERAL ) ;
2009-01-23 20:33:30 +00:00
}
switch_event_add_header_string ( gateway - > ob_vars , SWITCH_STACK_BOTTOM , var , val ) ;
}
}
}
2007-12-18 16:31:05 +00:00
2009-01-23 20:33:30 +00:00
if ( ( x_params = switch_xml_child ( gateway_tag , " params " ) ) ) {
param = switch_xml_child ( x_params , " param " ) ;
} else {
param = switch_xml_child ( gateway_tag , " param " ) ;
}
2010-02-06 03:38:24 +00:00
2009-01-23 20:33:30 +00:00
for ( ; param ; param = param - > next ) {
2007-12-18 16:31:05 +00:00
char * var = ( char * ) switch_xml_attr_soft ( param , " name " ) ;
char * val = ( char * ) switch_xml_attr_soft ( param , " value " ) ;
2010-02-06 03:38:24 +00:00
2007-12-18 16:31:05 +00:00
if ( ! strcmp ( var , " register " ) ) {
register_str = val ;
} else if ( ! strcmp ( var , " scheme " ) ) {
scheme = val ;
} else if ( ! strcmp ( var , " realm " ) ) {
realm = val ;
} else if ( ! strcmp ( var , " username " ) ) {
username = val ;
2009-03-07 16:03:44 +00:00
} else if ( ! strcmp ( var , " extension-in-contact " ) ) {
extension_in_contact = switch_true ( val ) ;
2008-08-15 19:30:34 +00:00
} else if ( ! strcmp ( var , " auth-username " ) ) {
auth_username = val ;
2007-12-18 16:31:05 +00:00
} else if ( ! strcmp ( var , " password " ) ) {
password = val ;
} else if ( ! strcmp ( var , " caller-id-in-from " ) ) {
caller_id_in_from = val ;
} else if ( ! strcmp ( var , " extension " ) ) {
extension = val ;
2008-04-30 22:09:54 +00:00
} else if ( ! strcmp ( var , " ping " ) ) {
ping_freq = atoi ( val ) ;
2009-11-23 19:46:37 +00:00
} else if ( ! strcmp ( var , " ping-max " ) ) {
ping_max = atoi ( val ) ;
} else if ( ! strcmp ( var , " ping-min " ) ) {
ping_min = atoi ( val ) ;
2007-12-18 16:31:05 +00:00
} else if ( ! strcmp ( var , " proxy " ) ) {
proxy = val ;
} else if ( ! strcmp ( var , " context " ) ) {
context = val ;
} else if ( ! strcmp ( var , " expire-seconds " ) ) {
expire_seconds = val ;
} else if ( ! strcmp ( var , " retry-seconds " ) ) {
retry_seconds = val ;
2010-02-06 03:38:24 +00:00
} else if ( ! strcmp ( var , " retry_seconds " ) ) { // support typo for back compat
2008-11-24 16:56:21 +00:00
retry_seconds = val ;
2007-12-18 16:31:05 +00:00
} else if ( ! strcmp ( var , " from-user " ) ) {
from_user = val ;
} else if ( ! strcmp ( var , " from-domain " ) ) {
from_domain = val ;
2009-03-09 15:02:04 +00:00
} else if ( ! strcmp ( var , " contact-host " ) ) {
contact_host = val ;
2007-12-18 16:31:05 +00:00
} else if ( ! strcmp ( var , " register-proxy " ) ) {
register_proxy = val ;
2009-07-16 00:46:35 +00:00
} else if ( ! strcmp ( var , " outbound-proxy " ) ) {
outbound_proxy = val ;
2009-11-03 21:32:18 +00:00
} else if ( ! strcmp ( var , " distinct-to " ) ) {
distinct_to = switch_true ( val ) ;
2007-12-18 16:31:05 +00:00
} else if ( ! strcmp ( var , " contact-params " ) ) {
contact_params = val ;
} else if ( ! strcmp ( var , " register-transport " ) ) {
2008-01-17 17:37:49 +00:00
sofia_transport_t transport = sofia_glue_str2transport ( val ) ;
if ( transport = = SOFIA_TRANSPORT_UNKNOWN | | ( ! sofia_test_pflag ( profile , PFLAG_TLS ) & & sofia_glue_transport_has_tls ( transport ) ) ) {
2007-12-18 16:31:05 +00:00
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_ERROR , " ERROR: unsupported transport \n " ) ;
goto skip ;
}
2008-01-17 17:37:49 +00:00
gateway - > register_transport = transport ;
2007-12-18 16:31:05 +00:00
}
}
2008-04-30 22:09:54 +00:00
if ( ping_freq ) {
if ( ping_freq > = 5 ) {
gateway - > ping_freq = ping_freq ;
2009-11-23 19:46:37 +00:00
gateway - > ping_max = ping_max ;
gateway - > ping_min = ping_min ;
2009-01-25 21:23:07 +00:00
gateway - > ping = switch_epoch_time_now ( NULL ) + ping_freq ;
2008-04-30 22:09:54 +00:00
} else {
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_ERROR , " ERROR: invalid ping! \n " ) ;
}
}
2008-11-24 15:52:55 +00:00
if ( ( gw_subs_tag = switch_xml_child ( gateway_tag , " subscriptions " ) ) ) {
parse_gateway_subscriptions ( profile , gateway , gw_subs_tag ) ;
}
2010-02-06 03:38:24 +00:00
2009-10-23 16:03:42 +00:00
if ( zstr ( realm ) ) {
if ( zstr ( proxy ) ) {
2009-07-13 14:31:24 +00:00
realm = name ;
} else {
realm = proxy ;
}
2007-12-18 16:31:05 +00:00
}
2009-10-23 16:03:42 +00:00
if ( zstr ( username ) ) {
2007-12-18 16:31:05 +00:00
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_ERROR , " ERROR: username param is REQUIRED! \n " ) ;
goto skip ;
}
2009-10-23 16:03:42 +00:00
if ( zstr ( password ) ) {
2007-12-18 16:31:05 +00:00
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_ERROR , " ERROR: password param is REQUIRED! \n " ) ;
goto skip ;
}
2009-10-23 16:03:42 +00:00
if ( zstr ( from_user ) ) {
2007-12-18 16:31:05 +00:00
from_user = username ;
}
2009-10-23 16:03:42 +00:00
if ( zstr ( extension ) ) {
2007-12-18 16:31:05 +00:00
extension = username ;
}
2009-10-23 16:03:42 +00:00
if ( zstr ( proxy ) ) {
2007-12-18 16:31:05 +00:00
proxy = realm ;
}
if ( ! switch_true ( register_str ) ) {
gateway - > state = REG_STATE_NOREG ;
2008-11-24 16:56:21 +00:00
gateway - > status = SOFIA_GATEWAY_UP ;
2007-12-18 16:31:05 +00:00
}
2009-10-23 16:03:42 +00:00
if ( zstr ( auth_username ) ) {
2008-08-15 19:30:34 +00:00
auth_username = username ;
}
2010-02-06 03:38:24 +00:00
2009-10-23 16:03:42 +00:00
if ( ! zstr ( register_proxy ) ) {
2008-11-17 21:38:17 +00:00
if ( strncasecmp ( register_proxy , " sip: " , 4 ) & & strncasecmp ( register_proxy , " sips: " , 5 ) ) {
2009-07-24 15:07:16 +00:00
gateway - > register_sticky_proxy = switch_core_sprintf ( gateway - > pool , " sip:%s " , register_proxy ) ;
2008-11-17 21:38:17 +00:00
} else {
2009-07-24 15:07:16 +00:00
gateway - > register_sticky_proxy = switch_core_strdup ( gateway - > pool , register_proxy ) ;
2009-07-16 00:46:35 +00:00
}
}
2009-10-23 16:03:42 +00:00
if ( ! zstr ( outbound_proxy ) ) {
2009-07-16 00:46:35 +00:00
if ( strncasecmp ( outbound_proxy , " sip: " , 4 ) & & strncasecmp ( outbound_proxy , " sips: " , 5 ) ) {
2009-07-24 15:07:16 +00:00
gateway - > outbound_sticky_proxy = switch_core_sprintf ( gateway - > pool , " sip:%s " , outbound_proxy ) ;
2009-07-16 00:46:35 +00:00
} else {
2009-07-24 15:07:16 +00:00
gateway - > outbound_sticky_proxy = switch_core_strdup ( gateway - > pool , outbound_proxy ) ;
2008-11-17 21:38:17 +00:00
}
2007-12-18 16:31:05 +00:00
}
gateway - > retry_seconds = atoi ( retry_seconds ) ;
2009-07-16 00:46:35 +00:00
2008-11-24 16:56:21 +00:00
if ( gateway - > retry_seconds < 5 ) {
2008-10-11 05:42:52 +00:00
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_WARNING , " Invalid retry-seconds of %d on gateway %s, using the value of 30 instead. \n " ,
2008-10-07 00:47:16 +00:00
gateway - > retry_seconds , name ) ;
2007-12-18 16:31:05 +00:00
gateway - > retry_seconds = 30 ;
}
2009-07-16 00:46:35 +00:00
2007-12-18 16:31:05 +00:00
gateway - > register_scheme = switch_core_strdup ( gateway - > pool , scheme ) ;
gateway - > register_context = switch_core_strdup ( gateway - > pool , context ) ;
gateway - > register_realm = switch_core_strdup ( gateway - > pool , realm ) ;
gateway - > register_username = switch_core_strdup ( gateway - > pool , username ) ;
2008-08-15 19:30:34 +00:00
gateway - > auth_username = switch_core_strdup ( gateway - > pool , auth_username ) ;
2007-12-18 16:31:05 +00:00
gateway - > register_password = switch_core_strdup ( gateway - > pool , password ) ;
2009-11-03 21:32:18 +00:00
gateway - > distinct_to = distinct_to ;
2009-07-16 00:46:35 +00:00
2007-12-18 16:31:05 +00:00
if ( switch_true ( caller_id_in_from ) ) {
2009-02-09 17:56:38 +00:00
sofia_set_flag ( gateway , REG_FLAG_CALLERID ) ;
2007-12-18 16:31:05 +00:00
}
2009-07-16 00:46:35 +00:00
2008-05-27 04:54:52 +00:00
register_transport = ( char * ) sofia_glue_transport2str ( gateway - > register_transport ) ;
2009-07-16 00:46:35 +00:00
2007-12-18 16:31:05 +00:00
if ( contact_params ) {
if ( * contact_params = = ' ; ' ) {
2009-10-16 19:51:32 +00:00
params = switch_core_sprintf ( gateway - > pool , " %s;transport=%s;gw=%s " , contact_params , register_transport , gateway - > name ) ;
2007-12-18 16:31:05 +00:00
} else {
2009-10-16 19:51:32 +00:00
params = switch_core_sprintf ( gateway - > pool , " ;%s;transport=%s;gw=%s " , contact_params , register_transport , gateway - > name ) ;
2007-12-18 16:31:05 +00:00
}
} else {
2009-10-16 19:51:32 +00:00
params = switch_core_sprintf ( gateway - > pool , " ;transport=%s;gw=%s " , register_transport , gateway - > name ) ;
2007-12-18 16:31:05 +00:00
}
2009-10-23 16:03:42 +00:00
if ( ! zstr ( from_domain ) ) {
2009-07-14 15:09:03 +00:00
gateway - > from_domain = switch_core_strdup ( gateway - > pool , from_domain ) ;
}
2009-07-16 00:46:35 +00:00
gateway - > register_url = switch_core_sprintf ( gateway - > pool , " sip:%s " , proxy ) ;
2010-02-06 03:38:24 +00:00
gateway - > register_from = switch_core_sprintf ( gateway - > pool , " <sip:%s@%s;transport=%s> " ,
2009-10-23 16:03:42 +00:00
from_user , ! zstr ( from_domain ) ? from_domain : proxy , register_transport ) ;
2008-07-03 18:50:15 +00:00
2010-02-06 03:38:24 +00:00
sipip = contact_host ? contact_host : profile - > extsipip ? profile - > extsipip : profile - > sipip ;
2009-07-16 00:46:35 +00:00
2009-03-07 16:03:44 +00:00
if ( extension_in_contact ) {
2009-03-07 15:59:01 +00:00
format = strchr ( sipip , ' : ' ) ? " <sip:%s@[%s]:%d%s> " : " <sip:%s@%s:%d%s> " ;
2009-03-07 16:03:44 +00:00
gateway - > register_contact = switch_core_sprintf ( gateway - > pool , format , extension ,
2009-03-07 15:59:01 +00:00
sipip ,
sofia_glue_transport_has_tls ( gateway - > register_transport ) ?
profile - > tls_sip_port : profile - > sip_port , params ) ;
} else {
format = strchr ( sipip , ' : ' ) ? " <sip:gw+%s@[%s]:%d%s> " : " <sip:gw+%s@%s:%d%s> " ;
gateway - > register_contact = switch_core_sprintf ( gateway - > pool , format , gateway - > name ,
sipip ,
sofia_glue_transport_has_tls ( gateway - > register_transport ) ?
profile - > tls_sip_port : profile - > sip_port , params ) ;
}
2009-07-16 00:46:35 +00:00
2009-01-23 20:33:30 +00:00
gateway - > extension = switch_core_strdup ( gateway - > pool , extension ) ;
2010-02-06 03:38:24 +00:00
2007-12-18 16:31:05 +00:00
if ( ! strncasecmp ( proxy , " sip: " , 4 ) ) {
2009-07-13 16:37:00 +00:00
gateway - > register_proxy = switch_core_strdup ( gateway - > pool , proxy ) ;
2009-07-16 00:46:35 +00:00
gateway - > register_to = switch_core_sprintf ( gateway - > pool , " sip:%s@%s " , username , proxy + 4 ) ;
2007-12-18 16:31:05 +00:00
} else {
2009-07-13 16:37:00 +00:00
gateway - > register_proxy = switch_core_sprintf ( gateway - > pool , " sip:%s " , proxy ) ;
2009-07-16 00:46:35 +00:00
gateway - > register_to = switch_core_sprintf ( gateway - > pool , " sip:%s@%s " , username , proxy ) ;
2007-12-18 16:31:05 +00:00
}
2007-12-18 01:12:50 +00:00
2007-12-18 16:31:05 +00:00
gateway - > expires_str = switch_core_strdup ( gateway - > pool , expire_seconds ) ;
2007-12-18 01:12:50 +00:00
2007-12-18 16:31:05 +00:00
if ( ( gateway - > freq = atoi ( gateway - > expires_str ) ) < 5 ) {
2010-02-06 03:38:24 +00:00
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_WARNING ,
" Invalid register-frequency of %d on gateway %s, using the value of 3600 instead \n " , gateway - > freq , name ) ;
2007-12-18 16:31:05 +00:00
gateway - > freq = 3600 ;
}
2008-10-07 22:15:51 +00:00
2008-04-04 18:53:24 +00:00
gateway - > next = profile - > gateways ;
profile - > gateways = gateway ;
sofia_reg_add_gateway ( gateway - > name , gateway ) ;
2007-12-18 16:31:05 +00:00
}
2008-05-27 04:54:52 +00:00
skip :
2007-12-18 16:31:05 +00:00
switch_assert ( gateway_tag ) ;
}
}
2008-04-01 17:41:38 +00:00
static void parse_domain_tag ( sofia_profile_t * profile , switch_xml_t x_domain_tag , const char * dname , const char * parse , const char * alias )
{
if ( switch_true ( alias ) ) {
if ( sofia_glue_add_profile ( switch_core_strdup ( profile - > pool , dname ) , profile ) = = SWITCH_STATUS_SUCCESS ) {
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_NOTICE , " Adding Alias [%s] for profile [%s] \n " , dname , profile - > name ) ;
} else {
2010-02-06 03:38:24 +00:00
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_WARNING , " Alias [%s] for profile [%s] (already exists) \n " , dname , profile - > name ) ;
2008-04-01 17:41:38 +00:00
}
}
2008-12-27 17:38:21 +00:00
if ( switch_true ( parse ) ) {
2008-12-27 17:42:42 +00:00
switch_xml_t gts , gt , uts , ut , gateways_tag ;
/* Backwards Compatibility */
2008-12-27 17:38:21 +00:00
for ( ut = switch_xml_child ( x_domain_tag , " user " ) ; ut ; ut = ut - > next ) {
if ( ( ( gateways_tag = switch_xml_child ( ut , " gateways " ) ) ) ) {
parse_gateways ( profile , gateways_tag ) ;
}
}
2008-12-27 17:42:42 +00:00
/* New Method with <groups> tags and users are now inside a <users> tag */
2008-12-27 16:56:58 +00:00
for ( gts = switch_xml_child ( x_domain_tag , " groups " ) ; gts ; gts = gts - > next ) {
for ( gt = switch_xml_child ( gts , " group " ) ; gt ; gt = gt - > next ) {
for ( uts = switch_xml_child ( gt , " users " ) ; uts ; uts = uts - > next ) {
for ( ut = switch_xml_child ( uts , " user " ) ; ut ; ut = ut - > next ) {
if ( ( ( gateways_tag = switch_xml_child ( ut , " gateways " ) ) ) ) {
parse_gateways ( profile , gateways_tag ) ;
}
}
}
2008-04-01 17:41:38 +00:00
}
}
}
}
2009-01-12 19:36:04 +00:00
static void parse_rtp_bugs ( sofia_profile_t * profile , const char * str )
{
if ( switch_stristr ( " clear " , str ) ) {
profile - > auto_rtp_bugs = 0 ;
}
if ( switch_stristr ( " CISCO_SKIP_MARK_BIT_2833 " , str ) ) {
profile - > auto_rtp_bugs | = RTP_BUG_CISCO_SKIP_MARK_BIT_2833 ;
}
if ( switch_stristr ( " ~CISCO_SKIP_MARK_BIT_2833 " , str ) ) {
profile - > auto_rtp_bugs & = ~ RTP_BUG_CISCO_SKIP_MARK_BIT_2833 ;
}
2010-02-06 03:38:24 +00:00
2009-01-12 19:36:04 +00:00
if ( switch_stristr ( " SONUS_SEND_INVALID_TIMESTAMP_2833 " , str ) ) {
profile - > auto_rtp_bugs | = RTP_BUG_SONUS_SEND_INVALID_TIMESTAMP_2833 ;
}
if ( switch_stristr ( " ~SONUS_SEND_INVALID_TIMESTAMP_2833 " , str ) ) {
profile - > auto_rtp_bugs & = ~ RTP_BUG_SONUS_SEND_INVALID_TIMESTAMP_2833 ;
}
}
2008-07-08 22:05:34 +00:00
switch_status_t reconfig_sofia ( sofia_profile_t * profile )
{
2008-07-14 23:58:07 +00:00
switch_xml_t cfg , xml = NULL , xprofile , profiles , gateways_tag , domain_tag , domains_tag , aliases_tag , alias_tag , settings , param ;
2008-07-08 22:05:34 +00:00
char * cf = " sofia.conf " ;
2008-07-08 23:17:58 +00:00
switch_event_t * params = NULL ;
2008-07-08 22:05:34 +00:00
switch_status_t status = SWITCH_STATUS_FALSE ;
2008-10-02 17:10:05 +00:00
switch_event_create ( & params , SWITCH_EVENT_REQUEST_PARAMS ) ;
2008-07-08 22:05:34 +00:00
switch_assert ( params ) ;
switch_event_add_header_string ( params , SWITCH_STACK_BOTTOM , " profile " , profile - > name ) ;
switch_event_add_header_string ( params , SWITCH_STACK_BOTTOM , " reconfig " , " true " ) ;
if ( ! ( xml = switch_xml_open_cfg ( cf , & cfg , params ) ) ) {
2008-10-11 05:42:52 +00:00
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_ERROR , " Open of %s failed \n " , cf ) ;
2008-07-08 22:05:34 +00:00
status = SWITCH_STATUS_FALSE ;
goto done ;
}
2010-02-06 03:38:24 +00:00
2008-07-08 22:05:34 +00:00
if ( ( profiles = switch_xml_child ( cfg , " profiles " ) ) ) {
for ( xprofile = switch_xml_child ( profiles , " profile " ) ; xprofile ; xprofile = xprofile - > next ) {
char * xprofilename = ( char * ) switch_xml_attr_soft ( xprofile , " name " ) ;
2008-08-13 17:24:33 +00:00
char * xprofiledomain = ( char * ) switch_xml_attr ( xprofile , " domain " ) ;
2008-07-14 23:58:07 +00:00
2008-07-08 22:05:34 +00:00
if ( strcasecmp ( profile - > name , xprofilename ) ) {
continue ;
}
2008-07-14 23:58:07 +00:00
/* you could change profile->foo here if it was a minor change like context or dialplan ... */
2010-02-06 03:38:24 +00:00
profile - > rport_level = 1 ; /* default setting */
2008-07-21 16:40:28 +00:00
profile - > acl_count = 0 ;
2009-09-08 22:16:45 +00:00
profile - > reg_acl_count = 0 ;
profile - > proxy_acl_count = 0 ;
2009-02-09 17:56:38 +00:00
sofia_set_pflag ( profile , PFLAG_STUN_ENABLED ) ;
2009-10-26 18:16:38 +00:00
sofia_set_pflag ( profile , PFLAG_PASS_CALLEE_ID ) ;
2009-04-21 17:47:22 +00:00
profile - > ib_calls = 0 ;
profile - > ob_calls = 0 ;
profile - > ib_failed_calls = 0 ;
2010-02-06 03:38:24 +00:00
profile - > ob_failed_calls = 0 ;
2009-12-09 14:42:30 +00:00
profile - > shutdown_type = " false " ;
2008-07-14 23:58:07 +00:00
2008-08-13 17:24:33 +00:00
if ( xprofiledomain ) {
profile - > domain_name = switch_core_strdup ( profile - > pool , xprofiledomain ) ;
}
2008-07-14 23:58:07 +00:00
if ( ( settings = switch_xml_child ( xprofile , " settings " ) ) ) {
for ( param = switch_xml_child ( settings , " param " ) ; param ; param = param - > next ) {
char * var = ( char * ) switch_xml_attr_soft ( param , " name " ) ;
char * val = ( char * ) switch_xml_attr_soft ( param , " value " ) ;
if ( ! strcasecmp ( var , " debug " ) ) {
profile - > debug = atoi ( val ) ;
2009-12-09 14:42:30 +00:00
} else if ( ! strcasecmp ( var , " shutdown-on-fail " ) ) {
profile - > shutdown_type = switch_core_strdup ( profile - > pool , val ) ;
2009-06-09 19:52:07 +00:00
} else if ( ! strcasecmp ( var , " tracelevel " ) ) {
mod_sofia_globals . tracelevel = switch_log_str2level ( val ) ;
2009-10-26 18:16:38 +00:00
} else if ( ! strcasecmp ( var , " pass-callee-id " ) ) {
if ( switch_true ( val ) ) {
sofia_set_pflag ( profile , PFLAG_PASS_CALLEE_ID ) ;
} else {
sofia_clear_pflag ( profile , PFLAG_PASS_CALLEE_ID ) ;
}
2009-03-04 19:21:55 +00:00
} else if ( ! strcasecmp ( var , " sip-trace " ) ) {
if ( switch_true ( val ) ) {
sofia_set_flag ( profile , TFLAG_TPORT_LOG ) ;
} else {
sofia_clear_flag ( profile , TFLAG_TPORT_LOG ) ;
}
nua_set_params ( profile - > nua , TPTAG_LOG ( sofia_test_flag ( profile , TFLAG_TPORT_LOG ) ) , TAG_END ( ) ) ;
2009-04-24 14:33:54 +00:00
} else if ( ! strcasecmp ( var , " send-message-query-on-register " ) ) {
if ( switch_true ( val ) ) {
sofia_set_pflag ( profile , PFLAG_MESSAGE_QUERY_ON_REGISTER ) ;
2009-11-10 00:26:54 +00:00
} else if ( ! strcasecmp ( val , " first-only " ) ) {
2009-11-12 03:52:07 +00:00
sofia_clear_pflag ( profile , PFLAG_MESSAGE_QUERY_ON_REGISTER ) ;
2009-11-10 00:26:54 +00:00
sofia_set_pflag ( profile , PFLAG_MESSAGE_QUERY_ON_FIRST_REGISTER ) ;
2009-04-24 14:33:54 +00:00
} else {
sofia_clear_pflag ( profile , PFLAG_MESSAGE_QUERY_ON_REGISTER ) ;
2009-12-09 15:52:35 +00:00
sofia_clear_pflag ( profile , PFLAG_MESSAGE_QUERY_ON_FIRST_REGISTER ) ;
2009-04-24 14:33:54 +00:00
}
2009-01-12 19:36:04 +00:00
} else if ( ! strcasecmp ( var , " auto-rtp-bugs " ) ) {
parse_rtp_bugs ( profile , val ) ;
2010-02-06 03:38:24 +00:00
} else if ( ! strcasecmp ( var , " user-agent-string " ) ) {
2008-07-14 23:58:07 +00:00
profile - > user_agent = switch_core_strdup ( profile - > pool , val ) ;
2009-01-22 23:07:31 +00:00
} else if ( ! strcasecmp ( var , " auto-restart " ) ) {
profile - > auto_restart = switch_true ( val ) ;
2009-11-24 16:11:56 +00:00
} else if ( ! strcasecmp ( var , " log-auth-failures " ) ) {
2010-02-06 03:38:24 +00:00
if ( switch_true ( val ) ) {
2009-11-24 16:24:24 +00:00
sofia_set_pflag ( profile , PFLAG_LOG_AUTH_FAIL ) ;
} else {
sofia_clear_pflag ( profile , PFLAG_LOG_AUTH_FAIL ) ;
}
2008-07-14 23:58:07 +00:00
} else if ( ! strcasecmp ( var , " dtmf-type " ) ) {
if ( ! strcasecmp ( val , " rfc2833 " ) ) {
profile - > dtmf_type = DTMF_2833 ;
} else if ( ! strcasecmp ( val , " info " ) ) {
profile - > dtmf_type = DTMF_INFO ;
} else {
profile - > dtmf_type = DTMF_NONE ;
}
} else if ( ! strcasecmp ( var , " NDLB-force-rport " ) ) {
if ( switch_true ( val ) ) {
profile - > rport_level = 2 ;
}
2009-03-04 23:03:25 +00:00
} else if ( ! strcasecmp ( var , " caller-id-type " ) ) {
profile - > cid_type = sofia_cid_name2type ( val ) ;
2008-07-14 23:58:07 +00:00
} else if ( ! strcasecmp ( var , " record-template " ) ) {
2009-09-08 20:29:24 +00:00
profile - > record_template = switch_core_strdup ( profile - > pool , val ) ;
2009-10-23 15:07:52 +00:00
} else if ( ! strcasecmp ( var , " record-path " ) ) {
profile - > record_path = switch_core_strdup ( profile - > pool , val ) ;
2008-07-14 23:58:07 +00:00
} else if ( ( ! strcasecmp ( var , " inbound-no-media " ) | | ! strcasecmp ( var , " inbound-bypass-media " ) ) ) {
if ( switch_true ( val ) ) {
2009-02-09 17:56:38 +00:00
sofia_set_flag ( profile , TFLAG_INB_NOMEDIA ) ;
2008-07-14 23:58:07 +00:00
} else {
2009-02-11 20:49:45 +00:00
sofia_clear_flag ( profile , TFLAG_INB_NOMEDIA ) ;
2008-07-14 23:58:07 +00:00
}
2008-12-11 20:20:20 +00:00
} else if ( ! strcasecmp ( var , " force-subscription-expires " ) ) {
int tmp = atoi ( val ) ;
if ( tmp > 0 ) {
profile - > force_subscription_expires = tmp ;
}
2008-07-14 23:58:07 +00:00
} else if ( ! strcasecmp ( var , " inbound-late-negotiation " ) ) {
if ( switch_true ( val ) ) {
2009-02-09 17:56:38 +00:00
sofia_set_flag ( profile , TFLAG_LATE_NEGOTIATION ) ;
2008-07-14 23:58:07 +00:00
} else {
2009-02-11 20:49:45 +00:00
sofia_clear_flag ( profile , TFLAG_LATE_NEGOTIATION ) ;
2008-07-14 23:58:07 +00:00
}
} else if ( ! strcasecmp ( var , " inbound-proxy-media " ) ) {
2010-02-06 03:38:24 +00:00
if ( switch_true ( val ) ) {
2009-02-09 17:56:38 +00:00
sofia_set_flag ( profile , TFLAG_PROXY_MEDIA ) ;
2008-07-14 23:58:07 +00:00
} else {
2009-02-11 20:49:45 +00:00
sofia_clear_flag ( profile , TFLAG_PROXY_MEDIA ) ;
2008-07-14 23:58:07 +00:00
}
2008-11-15 17:44:27 +00:00
} else if ( ! strcasecmp ( var , " inbound-use-callid-as-uuid " ) ) {
if ( switch_true ( val ) ) {
2009-02-09 17:56:38 +00:00
sofia_set_pflag ( profile , PFLAG_CALLID_AS_UUID ) ;
2008-11-15 17:44:27 +00:00
} else {
2009-02-09 17:56:38 +00:00
sofia_clear_pflag ( profile , PFLAG_CALLID_AS_UUID ) ;
2008-11-15 17:44:27 +00:00
}
2009-05-07 15:07:04 +00:00
} else if ( ! strcasecmp ( var , " rtp-autoflush-during-bridge " ) ) {
if ( switch_true ( val ) ) {
sofia_set_pflag ( profile , PFLAG_RTP_AUTOFLUSH_DURING_BRIDGE ) ;
} else {
sofia_clear_pflag ( profile , PFLAG_RTP_AUTOFLUSH_DURING_BRIDGE ) ;
}
2009-06-09 19:05:11 +00:00
} else if ( ! strcasecmp ( var , " manual-redirect " ) ) {
2009-05-20 21:01:51 +00:00
if ( switch_true ( val ) ) {
2009-06-09 19:05:11 +00:00
sofia_set_pflag ( profile , PFLAG_MANUAL_REDIRECT ) ;
2009-05-20 21:01:51 +00:00
} else {
2009-06-09 19:05:11 +00:00
sofia_clear_pflag ( profile , PFLAG_MANUAL_REDIRECT ) ;
2009-05-20 21:01:51 +00:00
}
2008-11-15 17:44:27 +00:00
} else if ( ! strcasecmp ( var , " outbound-use-uuid-as-callid " ) ) {
if ( switch_true ( val ) ) {
2009-02-09 17:56:38 +00:00
sofia_set_pflag ( profile , PFLAG_UUID_AS_CALLID ) ;
2008-11-15 17:44:27 +00:00
} else {
2009-02-09 17:56:38 +00:00
sofia_clear_pflag ( profile , PFLAG_UUID_AS_CALLID ) ;
2008-11-15 17:44:27 +00:00
}
2008-07-14 23:58:07 +00:00
} else if ( ! strcasecmp ( var , " NDLB-received-in-nat-reg-contact " ) ) {
if ( switch_true ( val ) ) {
2009-02-09 17:56:38 +00:00
sofia_set_pflag ( profile , PFLAG_RECIEVED_IN_NAT_REG_CONTACT ) ;
2008-07-14 23:58:07 +00:00
} else {
2009-02-09 17:56:38 +00:00
sofia_clear_pflag ( profile , PFLAG_RECIEVED_IN_NAT_REG_CONTACT ) ;
2008-07-14 23:58:07 +00:00
}
2009-11-03 21:32:18 +00:00
} else if ( ! strcasecmp ( var , " NDLB-allow-bad-iananame " ) ) {
if ( switch_true ( val ) ) {
2009-11-09 19:14:31 +00:00
profile - > ndlb | = PFLAG_NDLB_ALLOW_BAD_IANANAME ;
2009-11-03 21:32:18 +00:00
} else {
2009-11-09 19:14:31 +00:00
profile - > ndlb & = ~ PFLAG_NDLB_ALLOW_BAD_IANANAME ;
2009-11-03 21:32:18 +00:00
}
2008-07-14 23:58:07 +00:00
} else if ( ! strcasecmp ( var , " aggressive-nat-detection " ) ) {
2010-02-06 03:38:24 +00:00
if ( switch_true ( val ) ) {
2009-02-09 17:56:38 +00:00
sofia_set_pflag ( profile , PFLAG_AGGRESSIVE_NAT_DETECTION ) ;
2008-07-14 23:58:07 +00:00
} else {
2009-02-09 17:56:38 +00:00
sofia_clear_pflag ( profile , PFLAG_AGGRESSIVE_NAT_DETECTION ) ;
2008-07-14 23:58:07 +00:00
}
} else if ( ! strcasecmp ( var , " disable-rtp-auto-adjust " ) ) {
if ( switch_true ( val ) ) {
2009-02-09 17:56:38 +00:00
sofia_set_pflag ( profile , PFLAG_DISABLE_RTP_AUTOADJ ) ;
2008-07-14 23:58:07 +00:00
} else {
2009-02-09 17:56:38 +00:00
sofia_clear_pflag ( profile , PFLAG_DISABLE_RTP_AUTOADJ ) ;
2008-07-14 23:58:07 +00:00
}
} else if ( ! strcasecmp ( var , " NDLB-support-asterisk-missing-srtp-auth " ) ) {
if ( switch_true ( val ) ) {
2010-02-06 03:38:24 +00:00
sofia_set_pflag ( profile , PFLAG_DISABLE_SRTP_AUTH ) ;
2008-07-14 23:58:07 +00:00
} else {
2010-02-06 03:38:24 +00:00
sofia_clear_pflag ( profile , PFLAG_DISABLE_SRTP_AUTH ) ;
2008-07-14 23:58:07 +00:00
}
2008-07-18 16:18:31 +00:00
} else if ( ! strcasecmp ( var , " NDLB-funny-stun " ) ) {
if ( switch_true ( val ) ) {
2010-02-06 03:38:24 +00:00
sofia_set_pflag ( profile , PFLAG_FUNNY_STUN ) ;
2008-07-18 16:18:31 +00:00
} else {
2010-02-06 03:38:24 +00:00
sofia_clear_pflag ( profile , PFLAG_FUNNY_STUN ) ;
2008-07-18 16:18:31 +00:00
}
2008-07-21 16:40:28 +00:00
} else if ( ! strcasecmp ( var , " stun-enabled " ) ) {
if ( switch_true ( val ) ) {
2009-02-09 17:56:38 +00:00
sofia_set_pflag ( profile , PFLAG_STUN_ENABLED ) ;
2008-07-21 16:40:28 +00:00
} else {
2009-02-09 17:56:38 +00:00
sofia_clear_pflag ( profile , PFLAG_STUN_ENABLED ) ;
2008-07-21 16:40:28 +00:00
}
} else if ( ! strcasecmp ( var , " stun-auto-disable " ) ) {
if ( switch_true ( val ) ) {
2009-02-09 17:56:38 +00:00
sofia_set_pflag ( profile , PFLAG_STUN_AUTO_DISABLE ) ;
2008-07-21 16:40:28 +00:00
} else {
2010-02-06 03:38:24 +00:00
sofia_clear_pflag ( profile , PFLAG_STUN_AUTO_DISABLE ) ;
2008-07-21 16:40:28 +00:00
}
} else if ( ! strcasecmp ( var , " apply-nat-acl " ) ) {
if ( profile - > acl_count < SOFIA_MAX_ACL ) {
2008-08-04 19:20:33 +00:00
if ( ! profile - > extsipip & & switch_check_network_list_ip ( profile - > sipip , val ) ) {
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_ERROR , " Not adding acl %s because it's the local network \n " , val ) ;
} else {
profile - > nat_acl [ profile - > nat_acl_count + + ] = switch_core_strdup ( profile - > pool , val ) ;
}
2008-07-21 16:40:28 +00:00
} else {
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_ERROR , " Max acl records of %d reached \n " , SOFIA_MAX_ACL ) ;
}
} else if ( ! strcasecmp ( var , " apply-inbound-acl " ) ) {
if ( profile - > acl_count < SOFIA_MAX_ACL ) {
profile - > acl [ profile - > acl_count + + ] = switch_core_strdup ( profile - > pool , val ) ;
} else {
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_ERROR , " Max acl records of %d reached \n " , SOFIA_MAX_ACL ) ;
}
2009-09-08 22:16:45 +00:00
} else if ( ! strcasecmp ( var , " apply-proxy-acl " ) ) {
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_INFO , " apply proxy acl [%s] \n " , val ) ;
if ( profile - > proxy_acl_count < SOFIA_MAX_ACL ) {
profile - > proxy_acl [ profile - > proxy_acl_count + + ] = switch_core_strdup ( profile - > pool , val ) ;
} else {
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_ERROR , " Max acl records of %d reached \n " , SOFIA_MAX_ACL ) ;
}
2008-07-21 16:40:28 +00:00
} else if ( ! strcasecmp ( var , " apply-register-acl " ) ) {
if ( profile - > reg_acl_count < SOFIA_MAX_ACL ) {
profile - > reg_acl [ profile - > reg_acl_count + + ] = switch_core_strdup ( profile - > pool , val ) ;
} else {
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_ERROR , " Max acl records of %d reached \n " , SOFIA_MAX_ACL ) ;
}
2010-02-02 21:04:41 +00:00
} else if ( ! strcasecmp ( var , " user-agent-filter " ) ) {
profile - > user_agent_filter = switch_core_strdup ( profile - > pool , val ) ;
} else if ( ! strcasecmp ( var , " max-registrations-per-extension " ) ) {
profile - > max_registrations_perext = atoi ( val ) ;
2008-07-14 23:58:07 +00:00
} else if ( ! strcasecmp ( var , " rfc2833-pt " ) ) {
profile - > te = ( switch_payload_t ) atoi ( val ) ;
2009-02-09 17:56:38 +00:00
} else if ( ! strcasecmp ( var , " cng-pt " ) & & ! ( sofia_test_pflag ( profile , PFLAG_SUPPRESS_CNG ) ) ) {
2008-07-14 23:58:07 +00:00
profile - > cng_pt = ( switch_payload_t ) atoi ( val ) ;
} else if ( ! strcasecmp ( var , " vad " ) ) {
if ( ! strcasecmp ( val , " in " ) ) {
2009-02-09 17:56:38 +00:00
sofia_set_flag ( profile , TFLAG_VAD_IN ) ;
2008-07-14 23:58:07 +00:00
} else if ( ! strcasecmp ( val , " out " ) ) {
2009-02-09 17:56:38 +00:00
sofia_set_flag ( profile , TFLAG_VAD_OUT ) ;
2008-07-14 23:58:07 +00:00
} else if ( ! strcasecmp ( val , " both " ) ) {
2009-02-09 17:56:38 +00:00
sofia_set_flag ( profile , TFLAG_VAD_IN ) ;
sofia_set_flag ( profile , TFLAG_VAD_OUT ) ;
2008-10-29 14:43:07 +00:00
} else if ( strcasecmp ( val , " none " ) ) {
2008-09-05 03:57:57 +00:00
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_ERROR , " Invalid option %s for VAD \n " , val ) ;
2008-07-14 23:58:07 +00:00
}
} else if ( ! strcasecmp ( var , " unregister-on-options-fail " ) ) {
if ( switch_true ( val ) ) {
2009-02-09 17:56:38 +00:00
sofia_set_pflag ( profile , PFLAG_UNREG_OPTIONS_FAIL ) ;
2008-07-14 23:58:07 +00:00
} else {
2009-02-09 17:56:38 +00:00
sofia_clear_pflag ( profile , PFLAG_UNREG_OPTIONS_FAIL ) ;
2008-07-14 23:58:07 +00:00
}
} else if ( ! strcasecmp ( var , " require-secure-rtp " ) ) {
if ( switch_true ( val ) ) {
2009-02-09 17:56:38 +00:00
sofia_set_pflag ( profile , PFLAG_SECURE ) ;
2008-07-14 23:58:07 +00:00
} else {
2009-02-09 17:56:38 +00:00
sofia_clear_pflag ( profile , PFLAG_SECURE ) ;
2008-07-14 23:58:07 +00:00
}
} else if ( ! strcasecmp ( var , " multiple-registrations " ) ) {
2008-11-07 17:00:46 +00:00
if ( ! strcasecmp ( val , " call-id " ) ) {
2009-02-09 17:56:38 +00:00
sofia_set_pflag ( profile , PFLAG_MULTIREG ) ;
2008-11-07 17:00:46 +00:00
} else if ( ! strcasecmp ( val , " contact " ) | | switch_true ( val ) ) {
2009-02-09 17:56:38 +00:00
sofia_set_pflag ( profile , PFLAG_MULTIREG ) ;
sofia_set_pflag ( profile , PFLAG_MULTIREG_CONTACT ) ;
2008-11-12 19:28:05 +00:00
} else if ( switch_true ( val ) ) {
2009-02-09 17:56:38 +00:00
sofia_clear_pflag ( profile , PFLAG_MULTIREG ) ;
//sofia_clear_pflag(profile, PFLAG_MULTIREG_CONTACT);
2008-07-14 23:58:07 +00:00
}
2008-08-28 16:32:06 +00:00
} else if ( ! strcasecmp ( var , " supress-cng " ) | | ! strcasecmp ( var , " suppress-cng " ) ) {
2008-07-14 23:58:07 +00:00
if ( switch_true ( val ) ) {
2009-02-09 17:56:38 +00:00
sofia_set_pflag ( profile , PFLAG_SUPPRESS_CNG ) ;
2008-09-23 13:54:06 +00:00
profile - > cng_pt = 0 ;
2008-07-14 23:58:07 +00:00
} else {
2009-02-09 17:56:38 +00:00
sofia_clear_pflag ( profile , PFLAG_SUPPRESS_CNG ) ;
2008-07-14 23:58:07 +00:00
}
} else if ( ! strcasecmp ( var , " NDLB-broken-auth-hash " ) ) {
if ( switch_true ( val ) ) {
profile - > ndlb | = PFLAG_NDLB_BROKEN_AUTH_HASH ;
} else {
profile - > ndlb & = ~ PFLAG_NDLB_BROKEN_AUTH_HASH ;
}
2009-04-20 17:07:54 +00:00
} else if ( ! strcasecmp ( var , " NDLB-sendrecv-in-session " ) ) {
if ( switch_true ( val ) ) {
profile - > ndlb | = PFLAG_NDLB_SENDRECV_IN_SESSION ;
} else {
profile - > ndlb & = ~ PFLAG_NDLB_SENDRECV_IN_SESSION ;
}
2008-07-14 23:58:07 +00:00
} else if ( ! strcasecmp ( var , " pass-rfc2833 " ) ) {
if ( switch_true ( val ) ) {
2009-02-09 17:56:38 +00:00
sofia_set_pflag ( profile , PFLAG_PASS_RFC2833 ) ;
2008-07-14 23:58:07 +00:00
} else {
2009-02-09 17:56:38 +00:00
sofia_clear_pflag ( profile , PFLAG_PASS_RFC2833 ) ;
2008-07-14 23:58:07 +00:00
}
2009-03-31 19:10:43 +00:00
} else if ( ! strcasecmp ( var , " rtp-autoflush " ) ) {
if ( switch_true ( val ) ) {
sofia_set_pflag ( profile , PFLAG_AUTOFLUSH ) ;
} else {
sofia_clear_pflag ( profile , PFLAG_AUTOFLUSH ) ;
}
2009-04-03 15:07:10 +00:00
} else if ( ! strcasecmp ( var , " rtp-autofix-timing " ) ) {
if ( switch_true ( val ) ) {
sofia_set_pflag ( profile , PFLAG_AUTOFIX_TIMING ) ;
} else {
sofia_clear_pflag ( profile , PFLAG_AUTOFIX_TIMING ) ;
}
2009-04-02 21:53:47 +00:00
} else if ( ! strcasecmp ( var , " nat-options-ping " ) ) {
if ( switch_true ( val ) ) {
sofia_set_pflag ( profile , PFLAG_NAT_OPTIONS_PING ) ;
} else {
sofia_clear_pflag ( profile , PFLAG_NAT_OPTIONS_PING ) ;
}
2008-07-14 23:58:07 +00:00
} else if ( ! strcasecmp ( var , " inbound-codec-negotiation " ) ) {
if ( ! strcasecmp ( val , " greedy " ) ) {
2009-02-09 17:56:38 +00:00
sofia_set_pflag ( profile , PFLAG_GREEDY ) ;
2009-02-11 17:43:00 +00:00
} else if ( ! strcasecmp ( val , " scrooge " ) ) {
sofia_set_pflag ( profile , PFLAG_GREEDY ) ;
sofia_set_pflag ( profile , PFLAG_SCROOGE ) ;
2008-07-14 23:58:07 +00:00
} else {
2009-02-11 17:43:00 +00:00
sofia_clear_pflag ( profile , PFLAG_SCROOGE ) ;
2009-02-09 17:56:38 +00:00
sofia_clear_pflag ( profile , PFLAG_GREEDY ) ;
2008-07-14 23:58:07 +00:00
}
} else if ( ! strcasecmp ( var , " disable-transcoding " ) ) {
if ( switch_true ( val ) ) {
2009-02-09 17:56:38 +00:00
sofia_set_pflag ( profile , PFLAG_DISABLE_TRANSCODING ) ;
2008-07-14 23:58:07 +00:00
} else {
2009-02-09 17:56:38 +00:00
sofia_clear_pflag ( profile , PFLAG_DISABLE_TRANSCODING ) ;
2008-07-14 23:58:07 +00:00
}
} else if ( ! strcasecmp ( var , " rtp-rewrite-timestamps " ) ) {
if ( switch_true ( val ) ) {
2009-02-09 17:56:38 +00:00
sofia_set_pflag ( profile , PFLAG_REWRITE_TIMESTAMPS ) ;
2008-07-14 23:58:07 +00:00
} else {
2009-02-09 17:56:38 +00:00
sofia_clear_pflag ( profile , PFLAG_REWRITE_TIMESTAMPS ) ;
2008-07-14 23:58:07 +00:00
}
} else if ( ! strcasecmp ( var , " auth-calls " ) ) {
if ( switch_true ( val ) ) {
2009-02-09 17:56:38 +00:00
sofia_set_pflag ( profile , PFLAG_AUTH_CALLS ) ;
2008-07-14 23:58:07 +00:00
} else {
2009-02-09 17:56:38 +00:00
sofia_clear_pflag ( profile , PFLAG_AUTH_CALLS ) ;
2008-07-14 23:58:07 +00:00
}
2009-06-03 21:08:34 +00:00
} else if ( ! strcasecmp ( var , " context " ) ) {
2009-02-17 02:45:44 +00:00
profile - > context = switch_core_strdup ( profile - > pool , val ) ;
2009-06-03 21:08:34 +00:00
} else if ( ! strcasecmp ( var , " local-network-acl " ) ) {
2009-12-02 01:58:05 +00:00
if ( ! strcasecmp ( var , " none " ) ) {
profile - > local_network = NULL ;
} else {
profile - > local_network = switch_core_strdup ( profile - > pool , val ) ;
}
2008-07-14 23:58:07 +00:00
} else if ( ! strcasecmp ( var , " force-register-domain " ) ) {
profile - > reg_domain = switch_core_strdup ( profile - > pool , val ) ;
2009-09-24 22:29:52 +00:00
} else if ( ! strcasecmp ( var , " force-subscription-domain " ) ) {
profile - > sub_domain = switch_core_strdup ( profile - > pool , val ) ;
2008-09-08 22:38:37 +00:00
} else if ( ! strcasecmp ( var , " force-register-db-domain " ) ) {
profile - > reg_db_domain = switch_core_strdup ( profile - > pool , val ) ;
2008-07-14 23:58:07 +00:00
} else if ( ! strcasecmp ( var , " hold-music " ) ) {
profile - > hold_music = switch_core_strdup ( profile - > pool , val ) ;
2009-02-09 00:30:32 +00:00
} else if ( ! strcasecmp ( var , " outbound-proxy " ) ) {
profile - > outbound_proxy = switch_core_strdup ( profile - > pool , val ) ;
2008-07-14 23:58:07 +00:00
} else if ( ! strcasecmp ( var , " session-timeout " ) ) {
int v_session_timeout = atoi ( val ) ;
if ( v_session_timeout > = 0 ) {
profile - > session_timeout = v_session_timeout ;
}
} else if ( ! strcasecmp ( var , " rtp-timeout-sec " ) ) {
int v = atoi ( val ) ;
if ( v > = 0 ) {
profile - > rtp_timeout_sec = v ;
}
} else if ( ! strcasecmp ( var , " rtp-hold-timeout-sec " ) ) {
int v = atoi ( val ) ;
if ( v > = 0 ) {
profile - > rtp_hold_timeout_sec = v ;
}
} else if ( ! strcasecmp ( var , " nonce-ttl " ) ) {
profile - > nonce_ttl = atoi ( val ) ;
} else if ( ! strcasecmp ( var , " dialplan " ) ) {
profile - > dialplan = switch_core_strdup ( profile - > pool , val ) ;
} else if ( ! strcasecmp ( var , " max-calls " ) ) {
profile - > max_calls = atoi ( val ) ;
} else if ( ! strcasecmp ( var , " codec-prefs " ) ) {
2009-11-24 18:52:57 +00:00
profile - > inbound_codec_string = switch_core_strdup ( profile - > pool , val ) ;
profile - > outbound_codec_string = switch_core_strdup ( profile - > pool , val ) ;
} else if ( ! strcasecmp ( var , " inbound-codec-prefs " ) ) {
profile - > inbound_codec_string = switch_core_strdup ( profile - > pool , val ) ;
} else if ( ! strcasecmp ( var , " outbound-codec-prefs " ) ) {
profile - > outbound_codec_string = switch_core_strdup ( profile - > pool , val ) ;
2008-09-22 19:14:54 +00:00
} else if ( ! strcasecmp ( var , " challenge-realm " ) ) {
profile - > challenge_realm = switch_core_strdup ( profile - > pool , val ) ;
2008-07-14 23:58:07 +00:00
} else if ( ! strcasecmp ( var , " dtmf-duration " ) ) {
2009-11-04 19:27:35 +00:00
uint32_t dur = atoi ( val ) ;
2009-09-16 21:24:22 +00:00
if ( dur > switch_core_min_dtmf_duration ( 0 ) & & dur < switch_core_max_dtmf_duration ( 0 ) ) {
2008-07-14 23:58:07 +00:00
profile - > dtmf_duration = dur ;
} else {
profile - > dtmf_duration = SWITCH_DEFAULT_DTMF_DURATION ;
2010-02-06 03:38:24 +00:00
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_DEBUG , " Duration out of bounds, using default of %d! \n " ,
SWITCH_DEFAULT_DTMF_DURATION ) ;
2008-07-14 23:58:07 +00:00
}
2009-05-06 18:12:44 +00:00
} else if ( ! strcasecmp ( var , " timer-T1 " ) ) {
int v = atoi ( val ) ;
if ( v > 0 ) {
profile - > timer_t1 = v ;
} else {
profile - > timer_t1 = 500 ;
}
nua_set_params ( profile - > nua , NTATAG_SIP_T1 ( profile - > timer_t1 ) , TAG_END ( ) ) ;
} else if ( ! strcasecmp ( var , " timer-T1X64 " ) ) {
int v = atoi ( val ) ;
if ( v > 0 ) {
profile - > timer_t1x64 = v ;
} else {
profile - > timer_t1x64 = 32000 ;
}
nua_set_params ( profile - > nua , NTATAG_SIP_T1X64 ( profile - > timer_t1x64 ) , TAG_END ( ) ) ;
} else if ( ! strcasecmp ( var , " timer-T2 " ) ) {
int v = atoi ( val ) ;
if ( v > 0 ) {
profile - > timer_t2 = v ;
} else {
profile - > timer_t2 = 4000 ;
}
nua_set_params ( profile - > nua , NTATAG_SIP_T2 ( profile - > timer_t2 ) , TAG_END ( ) ) ;
} else if ( ! strcasecmp ( var , " timer-T4 " ) ) {
int v = atoi ( val ) ;
if ( v > 0 ) {
profile - > timer_t4 = v ;
} else {
profile - > timer_t4 = 4000 ;
}
nua_set_params ( profile - > nua , NTATAG_SIP_T4 ( profile - > timer_t4 ) , TAG_END ( ) ) ;
2008-07-14 23:58:07 +00:00
}
}
}
2008-07-21 16:40:28 +00:00
2008-07-08 22:05:34 +00:00
if ( ( gateways_tag = switch_xml_child ( xprofile , " gateways " ) ) ) {
parse_gateways ( profile , gateways_tag ) ;
}
2010-02-06 03:38:24 +00:00
2008-07-08 22:05:34 +00:00
status = SWITCH_STATUS_SUCCESS ;
if ( ( domains_tag = switch_xml_child ( xprofile , " domains " ) ) ) {
2009-02-06 03:03:50 +00:00
switch_event_t * xml_params ;
switch_event_create ( & xml_params , SWITCH_EVENT_REQUEST_PARAMS ) ;
switch_assert ( xml_params ) ;
switch_event_add_header_string ( xml_params , SWITCH_STACK_BOTTOM , " purpose " , " gateways " ) ;
switch_event_add_header_string ( xml_params , SWITCH_STACK_BOTTOM , " profile " , profile - > name ) ;
2010-02-06 03:38:24 +00:00
2008-07-08 22:05:34 +00:00
for ( domain_tag = switch_xml_child ( domains_tag , " domain " ) ; domain_tag ; domain_tag = domain_tag - > next ) {
switch_xml_t droot , x_domain_tag ;
const char * dname = switch_xml_attr_soft ( domain_tag , " name " ) ;
const char * parse = switch_xml_attr_soft ( domain_tag , " parse " ) ;
const char * alias = switch_xml_attr_soft ( domain_tag , " alias " ) ;
2009-10-23 16:03:42 +00:00
if ( ! zstr ( dname ) ) {
2008-07-08 22:05:34 +00:00
if ( ! strcasecmp ( dname , " all " ) ) {
switch_xml_t xml_root , x_domains ;
2009-02-12 00:27:07 +00:00
if ( switch_xml_locate ( " directory " , NULL , NULL , NULL , & xml_root , & x_domains , xml_params , SWITCH_FALSE ) = = SWITCH_STATUS_SUCCESS ) {
2008-07-08 22:05:34 +00:00
for ( x_domain_tag = switch_xml_child ( x_domains , " domain " ) ; x_domain_tag ; x_domain_tag = x_domain_tag - > next ) {
dname = switch_xml_attr_soft ( x_domain_tag , " name " ) ;
parse_domain_tag ( profile , x_domain_tag , dname , parse , alias ) ;
}
switch_xml_free ( xml_root ) ;
}
2009-02-06 03:03:50 +00:00
} else if ( switch_xml_locate_domain ( dname , xml_params , & droot , & x_domain_tag ) = = SWITCH_STATUS_SUCCESS ) {
2008-07-08 22:05:34 +00:00
parse_domain_tag ( profile , x_domain_tag , dname , parse , alias ) ;
switch_xml_free ( droot ) ;
}
}
}
2010-02-06 03:38:24 +00:00
2009-02-06 03:03:50 +00:00
switch_event_destroy ( & xml_params ) ;
2008-07-08 22:05:34 +00:00
}
2008-07-14 23:58:07 +00:00
if ( ( aliases_tag = switch_xml_child ( xprofile , " aliases " ) ) ) {
for ( alias_tag = switch_xml_child ( aliases_tag , " alias " ) ; alias_tag ; alias_tag = alias_tag - > next ) {
char * aname = ( char * ) switch_xml_attr_soft ( alias_tag , " name " ) ;
2009-10-23 16:03:42 +00:00
if ( ! zstr ( aname ) ) {
2010-02-06 03:38:24 +00:00
2008-07-14 23:58:07 +00:00
if ( sofia_glue_add_profile ( switch_core_strdup ( profile - > pool , aname ) , profile ) = = SWITCH_STATUS_SUCCESS ) {
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_NOTICE , " Adding Alias [%s] for profile [%s] \n " , aname , profile - > name ) ;
} else {
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_WARNING , " Alias [%s] for profile [%s] (already exists) \n " ,
aname , profile - > name ) ;
}
}
}
}
2008-07-08 22:05:34 +00:00
}
}
2010-02-06 03:38:24 +00:00
done :
2008-07-08 22:05:34 +00:00
if ( xml ) {
2010-02-06 03:38:24 +00:00
switch_xml_free ( xml ) ;
}
2008-07-08 22:05:34 +00:00
switch_event_destroy ( & params ) ;
return status ;
}
2007-12-18 16:31:05 +00:00
switch_status_t config_sofia ( int reload , char * profile_name )
{
char * cf = " sofia.conf " ;
switch_xml_t cfg , xml = NULL , xprofile , param , settings , profiles , gateways_tag , domain_tag , domains_tag ;
switch_status_t status = SWITCH_STATUS_SUCCESS ;
sofia_profile_t * profile = NULL ;
char url [ 512 ] = " " ;
int profile_found = 0 ;
2009-09-08 20:29:24 +00:00
switch_event_t * params = NULL ;
2008-05-27 04:54:52 +00:00
2007-12-18 16:31:05 +00:00
if ( ! reload ) {
su_init ( ) ;
if ( sip_update_default_mclass ( sip_extend_mclass ( NULL ) ) < 0 ) {
su_deinit ( ) ;
return SWITCH_STATUS_FALSE ;
}
2010-02-06 03:38:24 +00:00
2009-03-04 18:54:43 +00:00
/* Redirect loggers in sofia */
2009-03-04 20:17:36 +00:00
su_log_redirect ( su_log_default , logger , NULL ) ;
2007-12-18 16:31:05 +00:00
su_log_redirect ( tport_log , logger , NULL ) ;
2009-03-04 18:54:43 +00:00
su_log_redirect ( iptsec_log , logger , NULL ) ;
su_log_redirect ( nea_log , logger , NULL ) ;
su_log_redirect ( nta_log , logger , NULL ) ;
su_log_redirect ( nth_client_log , logger , NULL ) ;
su_log_redirect ( nth_server_log , logger , NULL ) ;
su_log_redirect ( nua_log , logger , NULL ) ;
su_log_redirect ( soa_log , logger , NULL ) ;
su_log_redirect ( sresolv_log , logger , NULL ) ;
su_log_redirect ( stun_log , logger , NULL ) ;
2007-12-18 16:31:05 +00:00
}
2009-10-23 16:03:42 +00:00
if ( ! zstr ( profile_name ) & & ( profile = sofia_glue_find_profile ( profile_name ) ) ) {
2009-05-02 00:58:51 +00:00
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_WARNING , " Profile [%s] Already exists. \n " , switch_str_nil ( profile_name ) ) ;
2007-12-18 16:31:05 +00:00
status = SWITCH_STATUS_FALSE ;
sofia_glue_release_profile ( profile ) ;
return status ;
}
2008-10-02 17:10:05 +00:00
switch_event_create ( & params , SWITCH_EVENT_REQUEST_PARAMS ) ;
2008-01-23 20:59:25 +00:00
switch_assert ( params ) ;
2008-01-24 11:47:28 +00:00
switch_event_add_header_string ( params , SWITCH_STACK_BOTTOM , " profile " , profile_name ) ;
2008-05-27 04:54:52 +00:00
2008-01-23 20:59:25 +00:00
if ( ! ( xml = switch_xml_open_cfg ( cf , & cfg , params ) ) ) {
2008-10-11 05:42:52 +00:00
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_ERROR , " Open of %s failed \n " , cf ) ;
2007-12-18 16:31:05 +00:00
status = SWITCH_STATUS_FALSE ;
goto done ;
}
2008-12-11 20:16:32 +00:00
mod_sofia_globals . auto_restart = SWITCH_TRUE ;
2009-07-24 19:34:32 +00:00
mod_sofia_globals . rewrite_multicasted_fs_path = SWITCH_FALSE ;
2008-12-11 20:16:32 +00:00
2007-12-18 16:31:05 +00:00
if ( ( settings = switch_xml_child ( cfg , " global_settings " ) ) ) {
for ( param = switch_xml_child ( settings , " param " ) ; param ; param = param - > next ) {
char * var = ( char * ) switch_xml_attr_soft ( param , " name " ) ;
char * val = ( char * ) switch_xml_attr_soft ( param , " value " ) ;
if ( ! strcasecmp ( var , " log-level " ) ) {
su_log_set_level ( NULL , atoi ( val ) ) ;
2008-12-10 20:54:24 +00:00
} else if ( ! strcasecmp ( var , " debug-presence " ) ) {
mod_sofia_globals . debug_presence = atoi ( val ) ;
2010-01-07 06:09:35 +00:00
} else if ( ! strcasecmp ( var , " debug-sla " ) ) {
mod_sofia_globals . debug_sla = atoi ( val ) ;
2008-12-11 20:16:32 +00:00
} else if ( ! strcasecmp ( var , " auto-restart " ) ) {
mod_sofia_globals . auto_restart = switch_true ( val ) ;
2009-07-24 19:34:32 +00:00
} else if ( ! strcasecmp ( var , " rewrite-multicasted-fs-path " ) ) {
2010-02-05 07:05:33 +00:00
if ( ( ! strcasecmp ( val , " to_host " ) ) | | ( ! strcasecmp ( val , " 1 " ) ) ) {
/* old behaviour */
mod_sofia_globals . rewrite_multicasted_fs_path = 1 ;
} else if ( ! strcasecmp ( val , " original_server_host " ) ) {
mod_sofia_globals . rewrite_multicasted_fs_path = 2 ;
} else if ( ! strcasecmp ( val , " original_hostname " ) ) {
mod_sofia_globals . rewrite_multicasted_fs_path = 3 ;
} else {
mod_sofia_globals . rewrite_multicasted_fs_path = SWITCH_FALSE ;
}
2007-12-18 16:31:05 +00:00
}
}
}
if ( ( profiles = switch_xml_child ( cfg , " profiles " ) ) ) {
for ( xprofile = switch_xml_child ( profiles , " profile " ) ; xprofile ; xprofile = xprofile - > next ) {
2009-12-09 14:42:30 +00:00
char * xprofilename = ( char * ) switch_xml_attr_soft ( xprofile , " name " ) ;
char * xprofiledomain = ( char * ) switch_xml_attr ( xprofile , " domain " ) ;
2007-12-18 16:31:05 +00:00
if ( ! ( settings = switch_xml_child ( xprofile , " settings " ) ) ) {
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_ERROR , " No Settings, check the new config! \n " ) ;
2009-12-09 14:42:30 +00:00
sofia_profile_start_failure ( NULL , xprofilename ) ;
2007-12-18 16:31:05 +00:00
} else {
switch_memory_pool_t * pool = NULL ;
if ( ! xprofilename ) {
xprofilename = " unnamed " ;
}
if ( profile_name ) {
if ( strcasecmp ( profile_name , xprofilename ) ) {
continue ;
} else {
profile_found = 1 ;
}
}
/* Setup the pool */
if ( ( status = switch_core_new_memory_pool ( & pool ) ) ! = SWITCH_STATUS_SUCCESS ) {
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_CRIT , " Memory Error! \n " ) ;
2009-12-09 14:42:30 +00:00
sofia_profile_start_failure ( NULL , xprofilename ) ;
2007-12-18 16:31:05 +00:00
goto done ;
}
if ( ! ( profile = ( sofia_profile_t * ) switch_core_alloc ( pool , sizeof ( * profile ) ) ) ) {
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_ERROR , " Memory Error! \n " ) ;
2009-12-09 14:42:30 +00:00
sofia_profile_start_failure ( NULL , xprofilename ) ;
2007-12-18 16:31:05 +00:00
goto done ;
}
2009-12-24 05:44:23 +00:00
profile - > trans_timeout = 500 ;
2009-01-12 19:36:04 +00:00
profile - > auto_rtp_bugs = RTP_BUG_CISCO_SKIP_MARK_BIT_2833 | RTP_BUG_SONUS_SEND_INVALID_TIMESTAMP_2833 ;
2007-12-18 16:31:05 +00:00
profile - > pool = pool ;
profile - > user_agent = SOFIA_USER_AGENT ;
profile - > name = switch_core_strdup ( profile - > pool , xprofilename ) ;
switch_snprintf ( url , sizeof ( url ) , " sofia_reg_%s " , xprofilename ) ;
2008-01-21 20:14:53 +00:00
if ( xprofiledomain ) {
profile - > domain_name = switch_core_strdup ( profile - > pool , xprofiledomain ) ;
}
2007-12-18 16:31:05 +00:00
profile - > dbname = switch_core_strdup ( profile - > pool , url ) ;
switch_core_hash_init ( & profile - > chat_hash , profile - > pool ) ;
switch_thread_rwlock_create ( & profile - > rwlock , profile - > pool ) ;
switch_mutex_init ( & profile - > flag_mutex , SWITCH_MUTEX_NESTED , profile - > pool ) ;
profile - > dtmf_duration = 100 ;
2007-12-22 23:50:15 +00:00
profile - > tls_version = 0 ;
2009-10-26 19:57:28 +00:00
profile - > mflags = MFLAG_REFER | MFLAG_REGISTER ;
2008-06-05 15:55:06 +00:00
profile - > rport_level = 1 ;
2009-02-09 17:56:38 +00:00
sofia_set_pflag ( profile , PFLAG_STUN_ENABLED ) ;
sofia_set_pflag ( profile , PFLAG_DISABLE_100REL ) ;
2009-01-22 23:07:31 +00:00
profile - > auto_restart = 1 ;
2009-04-03 15:07:10 +00:00
sofia_set_pflag ( profile , PFLAG_AUTOFIX_TIMING ) ;
2009-05-19 17:49:21 +00:00
sofia_set_pflag ( profile , PFLAG_RTP_AUTOFLUSH_DURING_BRIDGE ) ;
2009-05-19 21:16:03 +00:00
profile - > contact_user = SOFIA_DEFAULT_CONTACT_USER ;
2009-10-26 18:16:38 +00:00
sofia_set_pflag ( profile , PFLAG_PASS_CALLEE_ID ) ;
2009-11-12 03:52:07 +00:00
sofia_set_pflag ( profile , PFLAG_MESSAGE_QUERY_ON_FIRST_REGISTER ) ;
sofia_set_pflag ( profile , PFLAG_SQL_IN_TRANS ) ;
2009-12-09 14:42:30 +00:00
profile - > shutdown_type = " false " ;
2009-12-02 01:58:05 +00:00
profile - > local_network = " localnet.auto " ;
2009-12-19 17:43:05 +00:00
sofia_set_flag ( profile , TFLAG_ENABLE_SOA ) ;
2009-12-02 01:58:05 +00:00
2007-12-18 16:31:05 +00:00
for ( param = switch_xml_child ( settings , " param " ) ; param ; param = param - > next ) {
char * var = ( char * ) switch_xml_attr_soft ( param , " name " ) ;
char * val = ( char * ) switch_xml_attr_soft ( param , " value " ) ;
2009-09-08 22:16:45 +00:00
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_DEBUG , " %s [%s] \n " , var , val ) ;
2007-12-18 16:31:05 +00:00
if ( ! strcasecmp ( var , " debug " ) ) {
profile - > debug = atoi ( val ) ;
2009-12-09 14:42:30 +00:00
} else if ( ! strcasecmp ( var , " shutdown-on-fail " ) ) {
profile - > shutdown_type = switch_core_strdup ( profile - > pool , val ) ;
2007-12-18 16:31:05 +00:00
} else if ( ! strcasecmp ( var , " sip-trace " ) & & switch_true ( val ) ) {
2009-02-09 17:56:38 +00:00
sofia_set_flag ( profile , TFLAG_TPORT_LOG ) ;
2009-10-23 16:03:42 +00:00
} else if ( ! strcasecmp ( var , " odbc-dsn " ) & & ! zstr ( val ) ) {
2009-06-24 16:02:43 +00:00
if ( switch_odbc_available ( ) ) {
profile - > odbc_dsn = switch_core_strdup ( profile - > pool , val ) ;
if ( ( profile - > odbc_user = strchr ( profile - > odbc_dsn , ' : ' ) ) ) {
* profile - > odbc_user + + = ' \0 ' ;
if ( ( profile - > odbc_pass = strchr ( profile - > odbc_user , ' : ' ) ) ) {
* profile - > odbc_pass + + = ' \0 ' ;
}
2007-12-18 16:31:05 +00:00
}
2009-06-24 16:02:43 +00:00
} else {
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_ERROR , " ODBC IS NOT AVAILABLE! \n " ) ;
2007-12-18 16:31:05 +00:00
}
} else if ( ! strcasecmp ( var , " user-agent-string " ) ) {
2008-07-14 23:58:07 +00:00
profile - > user_agent = switch_core_strdup ( profile - > pool , val ) ;
2009-01-22 23:07:31 +00:00
} else if ( ! strcasecmp ( var , " auto-restart " ) ) {
profile - > auto_restart = switch_true ( val ) ;
2009-11-24 16:11:56 +00:00
} else if ( ! strcasecmp ( var , " log-auth-failures " ) ) {
2010-02-06 03:38:24 +00:00
if ( switch_true ( val ) ) {
2009-11-24 16:24:24 +00:00
sofia_set_pflag ( profile , PFLAG_LOG_AUTH_FAIL ) ;
} else {
sofia_clear_pflag ( profile , PFLAG_LOG_AUTH_FAIL ) ;
}
2007-12-22 00:32:20 +00:00
} else if ( ! strcasecmp ( var , " dtmf-type " ) ) {
if ( ! strcasecmp ( val , " rfc2833 " ) ) {
profile - > dtmf_type = DTMF_2833 ;
} else if ( ! strcasecmp ( val , " info " ) ) {
profile - > dtmf_type = DTMF_INFO ;
} else {
profile - > dtmf_type = DTMF_NONE ;
}
2008-06-05 15:55:06 +00:00
} else if ( ! strcasecmp ( var , " NDLB-force-rport " ) ) {
2008-06-05 20:04:33 +00:00
if ( switch_true ( val ) ) {
profile - > rport_level = 2 ;
}
2009-01-12 19:36:04 +00:00
} else if ( ! strcasecmp ( var , " auto-rtp-bugs " ) ) {
parse_rtp_bugs ( profile , val ) ;
2008-09-18 00:01:03 +00:00
} else if ( ! strcasecmp ( var , " dbname " ) ) {
profile - > dbname = switch_core_strdup ( profile - > pool , val ) ;
} else if ( ! strcasecmp ( var , " presence-hosts " ) ) {
profile - > presence_hosts = switch_core_strdup ( profile - > pool , val ) ;
2009-03-04 23:03:25 +00:00
} else if ( ! strcasecmp ( var , " caller-id-type " ) ) {
profile - > cid_type = sofia_cid_name2type ( val ) ;
2007-12-22 00:32:20 +00:00
} else if ( ! strcasecmp ( var , " record-template " ) ) {
2008-09-18 00:01:03 +00:00
profile - > record_template = switch_core_strdup ( profile - > pool , val ) ;
2009-10-23 15:07:52 +00:00
} else if ( ! strcasecmp ( var , " record-path " ) ) {
profile - > record_path = switch_core_strdup ( profile - > pool , val ) ;
2008-07-08 17:32:59 +00:00
} else if ( ( ! strcasecmp ( var , " inbound-no-media " ) | | ! strcasecmp ( var , " inbound-bypass-media " ) ) & & switch_true ( val ) ) {
2009-02-09 17:56:38 +00:00
sofia_set_flag ( profile , TFLAG_INB_NOMEDIA ) ;
2007-12-18 16:31:05 +00:00
} else if ( ! strcasecmp ( var , " inbound-late-negotiation " ) & & switch_true ( val ) ) {
2009-02-09 17:56:38 +00:00
sofia_set_flag ( profile , TFLAG_LATE_NEGOTIATION ) ;
2009-05-07 15:07:04 +00:00
} else if ( ! strcasecmp ( var , " rtp-autoflush-during-bridge " ) ) {
if ( switch_true ( val ) ) {
sofia_set_pflag ( profile , PFLAG_RTP_AUTOFLUSH_DURING_BRIDGE ) ;
} else {
sofia_clear_pflag ( profile , PFLAG_RTP_AUTOFLUSH_DURING_BRIDGE ) ;
}
2009-06-09 19:05:11 +00:00
} else if ( ! strcasecmp ( var , " manual-redirect " ) ) {
2009-05-20 21:01:51 +00:00
if ( switch_true ( val ) ) {
2009-06-09 19:05:11 +00:00
sofia_set_pflag ( profile , PFLAG_MANUAL_REDIRECT ) ;
2009-05-20 21:01:51 +00:00
} else {
2009-06-09 19:05:11 +00:00
sofia_clear_pflag ( profile , PFLAG_MANUAL_REDIRECT ) ;
2009-05-20 21:01:51 +00:00
}
2008-02-21 17:48:41 +00:00
} else if ( ! strcasecmp ( var , " inbound-proxy-media " ) & & switch_true ( val ) ) {
2009-02-09 17:56:38 +00:00
sofia_set_flag ( profile , TFLAG_PROXY_MEDIA ) ;
2008-12-11 20:20:20 +00:00
} else if ( ! strcasecmp ( var , " force-subscription-expires " ) ) {
int tmp = atoi ( val ) ;
if ( tmp > 0 ) {
profile - > force_subscription_expires = tmp ;
}
2009-04-24 14:33:54 +00:00
} else if ( ! strcasecmp ( var , " send-message-query-on-register " ) ) {
if ( switch_true ( val ) ) {
sofia_set_pflag ( profile , PFLAG_MESSAGE_QUERY_ON_REGISTER ) ;
2009-11-10 00:26:54 +00:00
} else if ( ! strcasecmp ( val , " first-only " ) ) {
2009-11-12 03:52:07 +00:00
sofia_clear_pflag ( profile , PFLAG_MESSAGE_QUERY_ON_REGISTER ) ;
2009-11-10 00:26:54 +00:00
sofia_set_pflag ( profile , PFLAG_MESSAGE_QUERY_ON_FIRST_REGISTER ) ;
2009-04-24 14:33:54 +00:00
} else {
sofia_clear_pflag ( profile , PFLAG_MESSAGE_QUERY_ON_REGISTER ) ;
2009-12-09 15:52:35 +00:00
sofia_clear_pflag ( profile , PFLAG_MESSAGE_QUERY_ON_FIRST_REGISTER ) ;
2009-04-24 14:33:54 +00:00
}
2008-11-15 17:44:27 +00:00
} else if ( ! strcasecmp ( var , " inbound-use-callid-as-uuid " ) ) {
if ( switch_true ( val ) ) {
2009-02-09 17:56:38 +00:00
sofia_set_pflag ( profile , PFLAG_CALLID_AS_UUID ) ;
2008-11-15 17:44:27 +00:00
} else {
2009-02-09 17:56:38 +00:00
sofia_clear_pflag ( profile , PFLAG_CALLID_AS_UUID ) ;
2008-11-15 17:44:27 +00:00
}
} else if ( ! strcasecmp ( var , " outbound-use-uuid-as-callid " ) ) {
if ( switch_true ( val ) ) {
2009-02-09 17:56:38 +00:00
sofia_set_pflag ( profile , PFLAG_UUID_AS_CALLID ) ;
2008-11-15 17:44:27 +00:00
} else {
2009-02-09 17:56:38 +00:00
sofia_clear_pflag ( profile , PFLAG_UUID_AS_CALLID ) ;
2008-11-15 17:44:27 +00:00
}
2010-02-06 03:38:24 +00:00
} else if ( ! strcasecmp ( var , " track-calls " ) & & switch_true ( val ) ) {
sofia_set_pflag ( profile , PFLAG_TRACK_CALLS ) ;
2008-05-22 17:30:11 +00:00
} else if ( ! strcasecmp ( var , " NDLB-received-in-nat-reg-contact " ) & & switch_true ( val ) ) {
2009-02-09 17:56:38 +00:00
sofia_set_pflag ( profile , PFLAG_RECIEVED_IN_NAT_REG_CONTACT ) ;
2008-05-21 16:46:48 +00:00
} else if ( ! strcasecmp ( var , " aggressive-nat-detection " ) & & switch_true ( val ) ) {
2009-02-09 17:56:38 +00:00
sofia_set_pflag ( profile , PFLAG_AGGRESSIVE_NAT_DETECTION ) ;
2008-07-07 17:56:16 +00:00
} else if ( ! strcasecmp ( var , " disable-rtp-auto-adjust " ) & & switch_true ( val ) ) {
2009-02-09 17:56:38 +00:00
sofia_set_pflag ( profile , PFLAG_DISABLE_RTP_AUTOADJ ) ;
2008-07-07 17:56:16 +00:00
} else if ( ! strcasecmp ( var , " NDLB-support-asterisk-missing-srtp-auth " ) & & switch_true ( val ) ) {
2009-02-09 17:56:38 +00:00
sofia_set_pflag ( profile , PFLAG_DISABLE_SRTP_AUTH ) ;
2008-07-18 16:18:31 +00:00
} else if ( ! strcasecmp ( var , " NDLB-funny-stun " ) ) {
if ( switch_true ( val ) ) {
2010-02-06 03:38:24 +00:00
sofia_set_pflag ( profile , PFLAG_FUNNY_STUN ) ;
2008-07-18 16:18:31 +00:00
} else {
2010-02-06 03:38:24 +00:00
sofia_clear_pflag ( profile , PFLAG_FUNNY_STUN ) ;
2008-07-18 16:18:31 +00:00
}
2008-07-21 16:40:28 +00:00
} else if ( ! strcasecmp ( var , " stun-enabled " ) ) {
if ( switch_true ( val ) ) {
2009-02-09 17:56:38 +00:00
sofia_set_pflag ( profile , PFLAG_STUN_ENABLED ) ;
2008-07-21 16:40:28 +00:00
} else {
2010-02-06 03:38:24 +00:00
sofia_clear_pflag ( profile , PFLAG_STUN_ENABLED ) ;
2008-07-21 16:40:28 +00:00
}
} else if ( ! strcasecmp ( var , " stun-auto-disable " ) ) {
if ( switch_true ( val ) ) {
2009-02-09 17:56:38 +00:00
sofia_set_pflag ( profile , PFLAG_STUN_AUTO_DISABLE ) ;
2008-07-21 16:40:28 +00:00
} else {
2010-02-06 03:38:24 +00:00
sofia_clear_pflag ( profile , PFLAG_STUN_AUTO_DISABLE ) ;
2008-07-21 16:40:28 +00:00
}
2010-02-02 21:04:41 +00:00
} else if ( ! strcasecmp ( var , " user-agent-filter " ) ) {
profile - > user_agent_filter = switch_core_strdup ( profile - > pool , val ) ;
} else if ( ! strcasecmp ( var , " max-registrations-per-extension " ) ) {
profile - > max_registrations_perext = atoi ( val ) ;
2007-12-18 16:31:05 +00:00
} else if ( ! strcasecmp ( var , " rfc2833-pt " ) ) {
profile - > te = ( switch_payload_t ) atoi ( val ) ;
2009-02-09 17:56:38 +00:00
} else if ( ! strcasecmp ( var , " cng-pt " ) & & ! sofia_test_pflag ( profile , PFLAG_SUPPRESS_CNG ) ) {
2007-12-18 16:31:05 +00:00
profile - > cng_pt = ( switch_payload_t ) atoi ( val ) ;
} else if ( ! strcasecmp ( var , " sip-port " ) ) {
2010-02-06 03:38:24 +00:00
profile - > sip_port = ( switch_port_t ) atoi ( val ) ;
2007-12-18 16:31:05 +00:00
} else if ( ! strcasecmp ( var , " vad " ) ) {
if ( ! strcasecmp ( val , " in " ) ) {
2009-02-09 17:56:38 +00:00
sofia_set_flag ( profile , TFLAG_VAD_IN ) ;
2007-12-18 16:31:05 +00:00
} else if ( ! strcasecmp ( val , " out " ) ) {
2009-02-09 17:56:38 +00:00
sofia_set_flag ( profile , TFLAG_VAD_OUT ) ;
2007-12-18 16:31:05 +00:00
} else if ( ! strcasecmp ( val , " both " ) ) {
2009-02-09 17:56:38 +00:00
sofia_set_flag ( profile , TFLAG_VAD_IN ) ;
sofia_set_flag ( profile , TFLAG_VAD_OUT ) ;
2008-10-29 14:43:07 +00:00
} else if ( strcasecmp ( val , " none " ) ) {
2008-09-05 03:57:57 +00:00
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_ERROR , " Invalid option %s for VAD \n " , val ) ;
2007-12-18 16:31:05 +00:00
}
} else if ( ! strcasecmp ( var , " ext-rtp-ip " ) ) {
2009-10-23 16:03:42 +00:00
if ( ! zstr ( val ) ) {
2008-09-05 03:57:57 +00:00
char * ip = mod_sofia_globals . guess_ip ;
2010-02-06 03:38:24 +00:00
2008-09-05 03:57:57 +00:00
if ( ! strcmp ( val , " 0.0.0.0 " ) ) {
2010-02-06 03:38:24 +00:00
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_WARNING , " Invalid IP 0.0.0.0 replaced with %s \n " ,
mod_sofia_globals . guess_ip ) ;
2009-06-03 21:08:34 +00:00
} else if ( ! strcasecmp ( val , " auto-nat " ) ) {
2009-12-02 01:58:05 +00:00
ip = NULL ;
2008-09-05 03:57:57 +00:00
} else {
2009-06-03 21:08:34 +00:00
ip = strcasecmp ( val , " auto " ) ? val : mod_sofia_globals . guess_ip ;
2009-12-02 01:58:05 +00:00
sofia_clear_pflag ( profile , PFLAG_AUTO_NAT ) ;
}
if ( ip ) {
2009-12-11 20:48:01 +00:00
if ( ! strncasecmp ( ip , " autonat: " , 8 ) ) {
profile - > extrtpip = switch_core_strdup ( profile - > pool , ip + 8 ) ;
sofia_set_pflag ( profile , PFLAG_AUTO_NAT ) ;
} else {
profile - > extrtpip = switch_core_strdup ( profile - > pool , ip ) ;
}
2008-09-05 03:57:57 +00:00
}
2008-04-21 21:00:18 +00:00
} else {
2008-09-05 03:57:57 +00:00
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_ERROR , " Invalid ext-rtp-ip \n " ) ;
2008-04-21 21:00:18 +00:00
}
2007-12-18 16:31:05 +00:00
} else if ( ! strcasecmp ( var , " rtp-ip " ) ) {
2008-04-21 21:00:18 +00:00
char * ip = mod_sofia_globals . guess_ip ;
2010-02-06 03:38:24 +00:00
2008-04-21 21:00:18 +00:00
if ( ! strcmp ( val , " 0.0.0.0 " ) ) {
2008-09-05 03:57:57 +00:00
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_WARNING , " Invalid IP 0.0.0.0 replaced with %s \n " , mod_sofia_globals . guess_ip ) ;
2008-04-21 21:00:18 +00:00
} else {
ip = strcasecmp ( val , " auto " ) ? val : mod_sofia_globals . guess_ip ;
}
profile - > rtpip = switch_core_strdup ( profile - > pool , ip ) ;
2007-12-18 16:31:05 +00:00
} else if ( ! strcasecmp ( var , " sip-ip " ) ) {
2008-04-21 21:00:18 +00:00
char * ip = mod_sofia_globals . guess_ip ;
if ( ! strcmp ( val , " 0.0.0.0 " ) ) {
2008-09-05 03:57:57 +00:00
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_WARNING , " Invalid IP 0.0.0.0 replaced with %s \n " , mod_sofia_globals . guess_ip ) ;
2007-12-18 16:31:05 +00:00
} else {
2008-04-21 21:00:18 +00:00
ip = strcasecmp ( val , " auto " ) ? val : mod_sofia_globals . guess_ip ;
}
profile - > sipip = switch_core_strdup ( profile - > pool , ip ) ;
} else if ( ! strcasecmp ( var , " ext-sip-ip " ) ) {
2009-10-23 16:03:42 +00:00
if ( ! zstr ( val ) ) {
2008-09-05 03:57:57 +00:00
char * ip = mod_sofia_globals . guess_ip ;
char stun_ip [ 50 ] = " " ;
char * myip = stun_ip ;
2010-02-06 03:38:24 +00:00
2008-09-05 03:57:57 +00:00
switch_copy_string ( stun_ip , ip , sizeof ( stun_ip ) ) ;
2010-02-06 03:38:24 +00:00
2008-09-05 03:57:57 +00:00
if ( ! strcasecmp ( val , " 0.0.0.0 " ) ) {
2010-02-06 03:38:24 +00:00
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_WARNING , " Invalid IP 0.0.0.0 replaced with %s \n " ,
mod_sofia_globals . guess_ip ) ;
2009-06-03 21:08:34 +00:00
} else if ( ! strcasecmp ( val , " auto-nat " ) ) {
2009-12-02 01:58:05 +00:00
ip = NULL ;
2008-09-05 03:57:57 +00:00
} else if ( strcasecmp ( val , " auto " ) ) {
switch_port_t port = 0 ;
if ( sofia_glue_ext_address_lookup ( profile , NULL , & myip , & port , val , profile - > pool ) = = SWITCH_STATUS_SUCCESS ) {
ip = myip ;
2009-12-02 01:58:05 +00:00
sofia_clear_pflag ( profile , PFLAG_AUTO_NAT ) ;
2008-09-05 03:57:57 +00:00
} else {
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_ERROR , " Failed to get external ip. \n " ) ;
}
2007-12-18 16:31:05 +00:00
}
2009-12-02 01:58:05 +00:00
if ( ip ) {
2009-12-11 20:48:01 +00:00
if ( ! strncasecmp ( ip , " autonat: " , 8 ) ) {
2010-02-06 03:38:24 +00:00
profile - > extsipip = switch_core_strdup ( profile - > pool , ip + 8 ) ;
2009-12-11 20:48:01 +00:00
sofia_set_pflag ( profile , PFLAG_AUTO_NAT ) ;
} else {
profile - > extsipip = switch_core_strdup ( profile - > pool , ip ) ;
}
2009-12-02 01:58:05 +00:00
}
2008-09-05 03:57:57 +00:00
} else {
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_ERROR , " Invalid ext-sip-ip \n " ) ;
2007-12-18 16:31:05 +00:00
}
2009-06-03 21:08:34 +00:00
} else if ( ! strcasecmp ( var , " local-network-acl " ) ) {
2009-12-02 01:58:05 +00:00
if ( ! strcasecmp ( var , " none " ) ) {
profile - > local_network = NULL ;
} else {
profile - > local_network = switch_core_strdup ( profile - > pool , val ) ;
}
2007-12-18 16:31:05 +00:00
} else if ( ! strcasecmp ( var , " force-register-domain " ) ) {
profile - > reg_domain = switch_core_strdup ( profile - > pool , val ) ;
2008-09-08 22:38:37 +00:00
} else if ( ! strcasecmp ( var , " force-register-db-domain " ) ) {
profile - > reg_db_domain = switch_core_strdup ( profile - > pool , val ) ;
2007-12-18 16:31:05 +00:00
} else if ( ! strcasecmp ( var , " bind-params " ) ) {
profile - > bind_params = switch_core_strdup ( profile - > pool , val ) ;
} else if ( ! strcasecmp ( var , " sip-domain " ) ) {
profile - > sipdomain = switch_core_strdup ( profile - > pool , val ) ;
} else if ( ! strcasecmp ( var , " rtp-timer-name " ) ) {
profile - > timer_name = switch_core_strdup ( profile - > pool , val ) ;
} else if ( ! strcasecmp ( var , " hold-music " ) ) {
profile - > hold_music = switch_core_strdup ( profile - > pool , val ) ;
2009-02-09 00:30:32 +00:00
} else if ( ! strcasecmp ( var , " outbound-proxy " ) ) {
profile - > outbound_proxy = switch_core_strdup ( profile - > pool , val ) ;
2007-12-18 16:31:05 +00:00
} else if ( ! strcasecmp ( var , " session-timeout " ) ) {
int v_session_timeout = atoi ( val ) ;
if ( v_session_timeout > = 0 ) {
profile - > session_timeout = v_session_timeout ;
}
} else if ( ! strcasecmp ( var , " max-proceeding " ) ) {
int v_max_proceeding = atoi ( val ) ;
if ( v_max_proceeding > = 0 ) {
profile - > max_proceeding = v_max_proceeding ;
}
} else if ( ! strcasecmp ( var , " rtp-timeout-sec " ) ) {
int v = atoi ( val ) ;
if ( v > = 0 ) {
profile - > rtp_timeout_sec = v ;
}
2008-01-21 00:35:33 +00:00
} else if ( ! strcasecmp ( var , " rtp-hold-timeout-sec " ) ) {
int v = atoi ( val ) ;
if ( v > = 0 ) {
profile - > rtp_hold_timeout_sec = v ;
}
2008-03-07 14:36:08 +00:00
} else if ( ! strcasecmp ( var , " disable-transfer " ) & & switch_true ( val ) ) {
profile - > mflags & = ~ MFLAG_REFER ;
} else if ( ! strcasecmp ( var , " disable-register " ) & & switch_true ( val ) ) {
profile - > mflags & = ~ MFLAG_REGISTER ;
2008-09-18 21:50:18 +00:00
} else if ( ! strcasecmp ( var , " media-option " ) ) {
if ( ! strcasecmp ( val , " resume-media-on-hold " ) ) {
profile - > media_options | = MEDIA_OPT_MEDIA_ON_HOLD ;
} else if ( ! strcasecmp ( val , " bypass-media-after-att-xfer " ) ) {
profile - > media_options | = MEDIA_OPT_BYPASS_AFTER_ATT_XFER ;
}
2007-12-18 16:31:05 +00:00
} else if ( ! strcasecmp ( var , " manage-presence " ) ) {
2008-09-18 00:01:03 +00:00
if ( ! strcasecmp ( val , " passive " ) ) {
profile - > pres_type = PRES_TYPE_PASSIVE ;
2010-02-06 03:38:24 +00:00
2008-09-18 00:01:03 +00:00
} else if ( switch_true ( val ) ) {
profile - > pres_type = PRES_TYPE_FULL ;
2010-02-06 03:38:24 +00:00
}
2009-01-30 16:46:37 +00:00
} else if ( ! strcasecmp ( var , " manage-shared-appearance " ) ) {
if ( switch_true ( val ) ) {
2009-02-12 14:46:14 +00:00
sofia_set_pflag ( profile , PFLAG_MANAGE_SHARED_APPEARANCE ) ;
2009-11-12 03:52:07 +00:00
profile - > pres_type = PRES_TYPE_FULL ;
2010-01-07 06:09:35 +00:00
sofia_set_pflag ( profile , PFLAG_MULTIREG ) ;
2010-01-09 00:34:17 +00:00
} else if ( ! strcasecmp ( val , " sylantro " ) ) {
2009-06-03 21:08:34 +00:00
profile - > sla_contact = switch_core_sprintf ( profile - > pool , " sla-agent " ) ;
2010-01-09 00:34:17 +00:00
sofia_set_pflag ( profile , PFLAG_MANAGE_SHARED_APPEARANCE_SYLANTRO ) ;
2009-01-30 16:46:37 +00:00
}
2009-02-08 00:38:48 +00:00
} else if ( ! strcasecmp ( var , " disable-srv " ) ) {
if ( switch_true ( val ) ) {
2009-02-12 14:46:14 +00:00
sofia_set_pflag ( profile , PFLAG_DISABLE_SRV ) ;
2009-02-08 00:38:48 +00:00
}
} else if ( ! strcasecmp ( var , " disable-naptr " ) ) {
if ( switch_true ( val ) ) {
2009-02-12 14:46:14 +00:00
sofia_set_pflag ( profile , PFLAG_DISABLE_NAPTR ) ;
2009-02-08 00:38:48 +00:00
}
2008-04-14 15:28:07 +00:00
} else if ( ! strcasecmp ( var , " unregister-on-options-fail " ) ) {
if ( switch_true ( val ) ) {
2009-02-09 17:56:38 +00:00
sofia_set_pflag ( profile , PFLAG_UNREG_OPTIONS_FAIL ) ;
2008-04-14 15:28:07 +00:00
}
2008-01-16 06:01:53 +00:00
} else if ( ! strcasecmp ( var , " require-secure-rtp " ) ) {
if ( switch_true ( val ) ) {
2009-02-09 17:56:38 +00:00
sofia_set_pflag ( profile , PFLAG_SECURE ) ;
2008-01-16 06:01:53 +00:00
}
2007-12-18 16:31:05 +00:00
} else if ( ! strcasecmp ( var , " multiple-registrations " ) ) {
2008-11-07 17:00:46 +00:00
if ( ! strcasecmp ( val , " call-id " ) ) {
2009-02-09 17:56:38 +00:00
sofia_set_pflag ( profile , PFLAG_MULTIREG ) ;
2008-11-07 17:00:46 +00:00
} else if ( ! strcasecmp ( val , " contact " ) | | switch_true ( val ) ) {
2009-02-09 17:56:38 +00:00
sofia_set_pflag ( profile , PFLAG_MULTIREG ) ;
sofia_set_pflag ( profile , PFLAG_MULTIREG_CONTACT ) ;
2008-11-12 19:28:05 +00:00
} else if ( switch_true ( val ) ) {
2009-02-09 17:56:38 +00:00
sofia_clear_pflag ( profile , PFLAG_MULTIREG ) ;
//sofia_clear_pflag(profile, PFLAG_MULTIREG_CONTACT);
2007-12-18 16:31:05 +00:00
}
2008-08-28 16:32:06 +00:00
} else if ( ! strcasecmp ( var , " supress-cng " ) | | ! strcasecmp ( var , " suppress-cng " ) ) {
2007-12-18 16:31:05 +00:00
if ( switch_true ( val ) ) {
2009-02-09 17:56:38 +00:00
sofia_set_pflag ( profile , PFLAG_SUPPRESS_CNG ) ;
2008-09-23 13:54:06 +00:00
profile - > cng_pt = 0 ;
2007-12-18 16:31:05 +00:00
}
} else if ( ! strcasecmp ( var , " NDLB-broken-auth-hash " ) ) {
if ( switch_true ( val ) ) {
profile - > ndlb | = PFLAG_NDLB_BROKEN_AUTH_HASH ;
}
2009-04-20 17:07:54 +00:00
} else if ( ! strcasecmp ( var , " NDLB-sendrecv-in-session " ) ) {
if ( switch_true ( val ) ) {
profile - > ndlb | = PFLAG_NDLB_SENDRECV_IN_SESSION ;
} else {
profile - > ndlb & = ~ PFLAG_NDLB_SENDRECV_IN_SESSION ;
}
2009-11-03 21:32:18 +00:00
} else if ( ! strcasecmp ( var , " NDLB-allow-bad-iananame " ) ) {
if ( switch_true ( val ) ) {
2009-11-09 19:14:31 +00:00
profile - > ndlb | = PFLAG_NDLB_ALLOW_BAD_IANANAME ;
2009-11-03 21:32:18 +00:00
} else {
2009-11-09 19:14:31 +00:00
profile - > ndlb & = ~ PFLAG_NDLB_ALLOW_BAD_IANANAME ;
2009-11-03 21:32:18 +00:00
}
2007-12-18 16:31:05 +00:00
} else if ( ! strcasecmp ( var , " pass-rfc2833 " ) ) {
if ( switch_true ( val ) ) {
2009-02-09 17:56:38 +00:00
sofia_set_pflag ( profile , PFLAG_PASS_RFC2833 ) ;
2007-12-18 16:31:05 +00:00
}
2009-03-31 19:10:43 +00:00
} else if ( ! strcasecmp ( var , " rtp-autoflush " ) ) {
if ( switch_true ( val ) ) {
sofia_set_pflag ( profile , PFLAG_AUTOFLUSH ) ;
} else {
sofia_clear_pflag ( profile , PFLAG_AUTOFLUSH ) ;
}
2009-04-03 15:07:10 +00:00
} else if ( ! strcasecmp ( var , " rtp-autofix-timing " ) ) {
if ( switch_true ( val ) ) {
sofia_set_pflag ( profile , PFLAG_AUTOFIX_TIMING ) ;
} else {
sofia_clear_pflag ( profile , PFLAG_AUTOFIX_TIMING ) ;
}
2009-05-19 21:16:03 +00:00
} else if ( ! strcasecmp ( var , " contact-user " ) ) {
profile - > contact_user = switch_core_strdup ( profile - > pool , val ) ;
2009-04-02 21:53:47 +00:00
} else if ( ! strcasecmp ( var , " nat-options-ping " ) ) {
if ( switch_true ( val ) ) {
sofia_set_pflag ( profile , PFLAG_NAT_OPTIONS_PING ) ;
} else {
sofia_clear_pflag ( profile , PFLAG_NAT_OPTIONS_PING ) ;
}
2007-12-18 16:31:05 +00:00
} else if ( ! strcasecmp ( var , " inbound-codec-negotiation " ) ) {
if ( ! strcasecmp ( val , " greedy " ) ) {
2009-02-09 17:56:38 +00:00
sofia_set_pflag ( profile , PFLAG_GREEDY ) ;
2009-02-11 17:43:00 +00:00
} else if ( ! strcasecmp ( val , " scrooge " ) ) {
sofia_set_pflag ( profile , PFLAG_GREEDY ) ;
sofia_set_pflag ( profile , PFLAG_SCROOGE ) ;
} else {
sofia_clear_pflag ( profile , PFLAG_SCROOGE ) ;
sofia_clear_pflag ( profile , PFLAG_GREEDY ) ;
2007-12-18 16:31:05 +00:00
}
} else if ( ! strcasecmp ( var , " disable-transcoding " ) ) {
if ( switch_true ( val ) ) {
2009-02-09 17:56:38 +00:00
sofia_set_pflag ( profile , PFLAG_DISABLE_TRANSCODING ) ;
2007-12-18 16:31:05 +00:00
}
} else if ( ! strcasecmp ( var , " rtp-rewrite-timestamps " ) ) {
if ( switch_true ( val ) ) {
2009-02-09 17:56:38 +00:00
sofia_set_pflag ( profile , PFLAG_REWRITE_TIMESTAMPS ) ;
2007-12-18 16:31:05 +00:00
}
} else if ( ! strcasecmp ( var , " auth-calls " ) ) {
if ( switch_true ( val ) ) {
2009-02-09 17:56:38 +00:00
sofia_set_pflag ( profile , PFLAG_AUTH_CALLS ) ;
2007-12-18 16:31:05 +00:00
}
} else if ( ! strcasecmp ( var , " nonce-ttl " ) ) {
profile - > nonce_ttl = atoi ( val ) ;
} else if ( ! strcasecmp ( var , " accept-blind-reg " ) ) {
if ( switch_true ( val ) ) {
2009-02-09 17:56:38 +00:00
sofia_set_pflag ( profile , PFLAG_BLIND_REG ) ;
2007-12-18 16:31:05 +00:00
}
2008-05-29 20:02:06 +00:00
} else if ( ! strcasecmp ( var , " enable-3pcc " ) ) {
if ( switch_true ( val ) ) {
2009-02-09 17:56:38 +00:00
sofia_set_pflag ( profile , PFLAG_3PCC ) ;
2009-09-08 20:32:42 +00:00
} else if ( ! strcasecmp ( val , " proxy " ) ) {
2009-02-09 17:56:38 +00:00
sofia_set_pflag ( profile , PFLAG_3PCC_PROXY ) ;
2008-10-10 16:15:45 +00:00
}
2008-03-04 01:23:55 +00:00
} else if ( ! strcasecmp ( var , " accept-blind-auth " ) ) {
if ( switch_true ( val ) ) {
2009-02-09 17:56:38 +00:00
sofia_set_pflag ( profile , PFLAG_BLIND_AUTH ) ;
2008-03-04 01:23:55 +00:00
}
2007-12-18 16:31:05 +00:00
} else if ( ! strcasecmp ( var , " auth-all-packets " ) ) {
if ( switch_true ( val ) ) {
2009-02-09 17:56:38 +00:00
sofia_set_pflag ( profile , PFLAG_AUTH_ALL ) ;
2007-12-18 16:31:05 +00:00
}
} else if ( ! strcasecmp ( var , " full-id-in-dialplan " ) ) {
if ( switch_true ( val ) ) {
2009-02-09 17:56:38 +00:00
sofia_set_pflag ( profile , PFLAG_FULL_ID ) ;
2007-12-18 16:31:05 +00:00
}
2008-01-12 19:15:05 +00:00
} else if ( ! strcasecmp ( var , " inbound-reg-force-matching-username " ) ) {
if ( switch_true ( val ) ) {
2009-02-09 17:56:38 +00:00
sofia_set_pflag ( profile , PFLAG_CHECKUSER ) ;
2008-01-12 19:15:05 +00:00
}
2008-04-14 19:20:12 +00:00
} else if ( ! strcasecmp ( var , " enable-timer " ) ) {
if ( ! switch_true ( val ) ) {
2009-02-09 17:56:38 +00:00
sofia_set_pflag ( profile , PFLAG_DISABLE_TIMER ) ;
2008-04-14 19:20:12 +00:00
}
2008-09-26 18:21:42 +00:00
} else if ( ! strcasecmp ( var , " minimum-session-expires " ) ) {
profile - > minimum_session_expires = atoi ( val ) ;
/* per RFC 4028: minimum_session_expires must be > 90 */
if ( profile - > minimum_session_expires < 90 ) {
profile - > minimum_session_expires = 90 ;
}
2008-04-14 19:20:12 +00:00
} else if ( ! strcasecmp ( var , " enable-100rel " ) ) {
2008-11-12 13:02:44 +00:00
if ( switch_true ( val ) ) {
2009-02-09 17:56:38 +00:00
sofia_clear_pflag ( profile , PFLAG_DISABLE_100REL ) ;
2008-04-14 19:20:12 +00:00
}
2009-08-31 14:33:41 +00:00
} else if ( ! strcasecmp ( var , " enable-compact-headers " ) ) {
if ( switch_true ( val ) ) {
sofia_set_pflag ( profile , PFLAG_SIPCOMPACT ) ;
}
2009-10-26 18:16:38 +00:00
} else if ( ! strcasecmp ( var , " pass-callee-id " ) ) {
if ( switch_true ( val ) ) {
sofia_set_pflag ( profile , PFLAG_PASS_CALLEE_ID ) ;
} else {
sofia_clear_pflag ( profile , PFLAG_PASS_CALLEE_ID ) ;
}
2009-10-23 20:09:34 +00:00
} else if ( ! strcasecmp ( var , " sql-in-transactions " ) ) {
2009-12-24 05:44:23 +00:00
int tmp = atoi ( val ) ;
2009-10-23 20:09:34 +00:00
if ( switch_true ( val ) ) {
2009-12-24 05:44:23 +00:00
tmp = 500 ;
}
if ( tmp > 0 ) {
profile - > trans_timeout = tmp ;
2009-10-23 20:09:34 +00:00
sofia_set_pflag ( profile , PFLAG_SQL_IN_TRANS ) ;
} else {
sofia_clear_pflag ( profile , PFLAG_SQL_IN_TRANS ) ;
}
2009-12-19 17:43:05 +00:00
} else if ( ! strcasecmp ( var , " enable-soa " ) ) {
if ( switch_true ( val ) ) {
sofia_set_flag ( profile , TFLAG_ENABLE_SOA ) ;
} else {
sofia_clear_flag ( profile , TFLAG_ENABLE_SOA ) ;
}
2007-12-18 16:31:05 +00:00
} else if ( ! strcasecmp ( var , " bitpacking " ) ) {
if ( ! strcasecmp ( val , " aal2 " ) ) {
profile - > codec_flags = SWITCH_CODEC_FLAG_AAL2 ;
}
} else if ( ! strcasecmp ( var , " username " ) ) {
profile - > username = switch_core_strdup ( profile - > pool , val ) ;
} else if ( ! strcasecmp ( var , " context " ) ) {
profile - > context = switch_core_strdup ( profile - > pool , val ) ;
2008-05-13 23:22:21 +00:00
} else if ( ! strcasecmp ( var , " apply-nat-acl " ) ) {
if ( profile - > acl_count < SOFIA_MAX_ACL ) {
2008-08-07 15:44:29 +00:00
if ( ! profile - > extsipip & & profile - > sipip & & switch_check_network_list_ip ( profile - > sipip , val ) ) {
2008-08-04 19:20:33 +00:00
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_ERROR , " Not adding acl %s because it's the local network \n " , val ) ;
} else {
profile - > nat_acl [ profile - > nat_acl_count + + ] = switch_core_strdup ( profile - > pool , val ) ;
}
2008-05-13 23:22:21 +00:00
} else {
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_ERROR , " Max acl records of %d reached \n " , SOFIA_MAX_ACL ) ;
}
2008-03-26 22:14:09 +00:00
} else if ( ! strcasecmp ( var , " apply-inbound-acl " ) ) {
if ( profile - > acl_count < SOFIA_MAX_ACL ) {
profile - > acl [ profile - > acl_count + + ] = switch_core_strdup ( profile - > pool , val ) ;
} else {
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_ERROR , " Max acl records of %d reached \n " , SOFIA_MAX_ACL ) ;
}
2009-09-08 22:16:45 +00:00
} else if ( ! strcasecmp ( var , " apply-proxy-acl " ) ) {
if ( profile - > proxy_acl_count < SOFIA_MAX_ACL ) {
profile - > proxy_acl [ profile - > proxy_acl_count + + ] = switch_core_strdup ( profile - > pool , val ) ;
} else {
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_ERROR , " Max acl records of %d reached \n " , SOFIA_MAX_ACL ) ;
}
2008-03-26 22:14:09 +00:00
} else if ( ! strcasecmp ( var , " apply-register-acl " ) ) {
if ( profile - > reg_acl_count < SOFIA_MAX_ACL ) {
profile - > reg_acl [ profile - > reg_acl_count + + ] = switch_core_strdup ( profile - > pool , val ) ;
} else {
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_ERROR , " Max acl records of %d reached \n " , SOFIA_MAX_ACL ) ;
}
2007-12-18 16:31:05 +00:00
} else if ( ! strcasecmp ( var , " alias " ) ) {
sip_alias_node_t * node ;
if ( ( node = switch_core_alloc ( profile - > pool , sizeof ( * node ) ) ) ) {
if ( ( node - > url = switch_core_strdup ( profile - > pool , val ) ) ) {
node - > next = profile - > aliases ;
profile - > aliases = node ;
}
}
} else if ( ! strcasecmp ( var , " dialplan " ) ) {
profile - > dialplan = switch_core_strdup ( profile - > pool , val ) ;
} else if ( ! strcasecmp ( var , " max-calls " ) ) {
profile - > max_calls = atoi ( val ) ;
} else if ( ! strcasecmp ( var , " codec-prefs " ) ) {
2009-11-24 18:52:57 +00:00
profile - > inbound_codec_string = switch_core_strdup ( profile - > pool , val ) ;
profile - > outbound_codec_string = switch_core_strdup ( profile - > pool , val ) ;
} else if ( ! strcasecmp ( var , " inbound-codec-prefs " ) ) {
profile - > inbound_codec_string = switch_core_strdup ( profile - > pool , val ) ;
} else if ( ! strcasecmp ( var , " outbound-codec-prefs " ) ) {
profile - > outbound_codec_string = switch_core_strdup ( profile - > pool , val ) ;
2008-09-22 19:14:54 +00:00
} else if ( ! strcasecmp ( var , " challenge-realm " ) ) {
profile - > challenge_realm = switch_core_strdup ( profile - > pool , val ) ;
2007-12-18 16:31:05 +00:00
} else if ( ! strcasecmp ( var , " dtmf-duration " ) ) {
2009-11-05 17:22:15 +00:00
uint32_t dur = atoi ( val ) ;
2009-09-16 21:24:22 +00:00
if ( dur > switch_core_min_dtmf_duration ( 0 ) & & dur < switch_core_max_dtmf_duration ( 0 ) ) {
2007-12-18 16:31:05 +00:00
profile - > dtmf_duration = dur ;
} else {
2008-07-14 23:58:07 +00:00
profile - > dtmf_duration = SWITCH_DEFAULT_DTMF_DURATION ;
2010-02-06 03:38:24 +00:00
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_DEBUG , " Duration out of bounds, using default of %d! \n " ,
2008-09-22 19:14:54 +00:00
SWITCH_DEFAULT_DTMF_DURATION ) ;
2007-12-18 16:31:05 +00:00
}
2007-12-18 19:12:45 +00:00
2008-05-27 04:54:52 +00:00
/*
* handle TLS params # 1
*/
2007-12-18 19:12:45 +00:00
} else if ( ! strcasecmp ( var , " tls " ) ) {
if ( switch_true ( val ) ) {
sofia_set_pflag ( profile , PFLAG_TLS ) ;
}
} else if ( ! strcasecmp ( var , " tls-bind-params " ) ) {
profile - > tls_bind_params = switch_core_strdup ( profile - > pool , val ) ;
} else if ( ! strcasecmp ( var , " tls-sip-port " ) ) {
2010-02-06 03:38:24 +00:00
profile - > tls_sip_port = ( switch_port_t ) atoi ( val ) ;
2007-12-18 19:12:45 +00:00
} else if ( ! strcasecmp ( var , " tls-cert-dir " ) ) {
profile - > tls_cert_dir = switch_core_strdup ( profile - > pool , val ) ;
2007-12-22 23:50:15 +00:00
} else if ( ! strcasecmp ( var , " tls-version " ) ) {
if ( ! strcasecmp ( val , " tlsv1 " ) ) {
profile - > tls_version = 1 ;
} else {
profile - > tls_version = 0 ;
}
2009-05-06 18:12:44 +00:00
} else if ( ! strcasecmp ( var , " timer-T1 " ) ) {
int v = atoi ( val ) ;
if ( v > 0 ) {
profile - > timer_t1 = v ;
} else {
profile - > timer_t1 = 500 ;
}
} else if ( ! strcasecmp ( var , " timer-T1X64 " ) ) {
int v = atoi ( val ) ;
if ( v > 0 ) {
profile - > timer_t1x64 = v ;
} else {
profile - > timer_t1x64 = 32000 ;
}
} else if ( ! strcasecmp ( var , " timer-T2 " ) ) {
int v = atoi ( val ) ;
if ( v > 0 ) {
profile - > timer_t2 = v ;
} else {
profile - > timer_t2 = 4000 ;
}
} else if ( ! strcasecmp ( var , " timer-T4 " ) ) {
int v = atoi ( val ) ;
if ( v > 0 ) {
profile - > timer_t4 = v ;
} else {
profile - > timer_t4 = 4000 ;
}
2008-05-27 04:54:52 +00:00
}
2007-12-18 16:31:05 +00:00
}
2008-08-28 16:32:06 +00:00
if ( ( ! profile - > cng_pt ) & & ( ! sofia_test_pflag ( profile , PFLAG_SUPPRESS_CNG ) ) ) {
2007-12-18 16:31:05 +00:00
profile - > cng_pt = SWITCH_RTP_CNG_PAYLOAD ;
}
if ( ! profile - > sipip ) {
profile - > sipip = switch_core_strdup ( profile - > pool , mod_sofia_globals . guess_ip ) ;
}
if ( ! profile - > rtpip ) {
profile - > rtpip = switch_core_strdup ( profile - > pool , mod_sofia_globals . guess_ip ) ;
}
2009-12-07 16:29:52 +00:00
if ( switch_core_get_variable ( " nat_type " ) ) {
const char * ip = switch_core_get_variable ( " nat_public_addr " ) ;
if ( ip & & ! strchr ( profile - > sipip , ' : ' ) ) {
if ( ! profile - > extrtpip ) {
profile - > extrtpip = switch_core_strdup ( profile - > pool , ip ) ;
}
if ( ! profile - > extsipip ) {
profile - > extsipip = switch_core_strdup ( profile - > pool , ip ) ;
}
sofia_set_pflag ( profile , PFLAG_AUTO_NAT ) ;
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_NOTICE , " NAT detected setting external ip to %s \n " , ip ) ;
}
}
2007-12-18 16:31:05 +00:00
if ( profile - > nonce_ttl < 60 ) {
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_INFO , " Setting nonce TTL to 60 seconds \n " ) ;
profile - > nonce_ttl = 60 ;
}
if ( ! profile - > username ) {
profile - > username = switch_core_strdup ( profile - > pool , " FreeSWITCH " ) ;
}
if ( ! profile - > rtpip ) {
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_WARNING , " Setting ip to '127.0.0.1' \n " ) ;
profile - > rtpip = switch_core_strdup ( profile - > pool , " 127.0.0.1 " ) ;
}
if ( ! profile - > sip_port ) {
2010-02-06 03:38:24 +00:00
profile - > sip_port = ( switch_port_t ) atoi ( SOFIA_DEFAULT_PORT ) ;
2007-12-18 16:31:05 +00:00
}
if ( ! profile - > dialplan ) {
profile - > dialplan = switch_core_strdup ( profile - > pool , " XML " ) ;
}
2008-07-21 16:40:28 +00:00
if ( ! profile - > context ) {
profile - > context = switch_core_strdup ( profile - > pool , " default " ) ;
}
2007-12-18 16:31:05 +00:00
if ( ! profile - > sipdomain ) {
profile - > sipdomain = switch_core_strdup ( profile - > pool , profile - > sipip ) ;
}
2009-12-10 14:40:47 +00:00
2009-12-02 18:46:17 +00:00
if ( profile - > extsipip ) {
2009-06-03 21:08:34 +00:00
char * ipv6 = strchr ( profile - > extsipip , ' : ' ) ;
profile - > public_url = switch_core_sprintf ( profile - > pool ,
" sip:%s@%s%s%s:%d " ,
profile - > contact_user ,
2010-02-06 03:38:24 +00:00
ipv6 ? " [ " : " " , profile - > extsipip , ipv6 ? " ] " : " " , profile - > sip_port ) ;
2009-06-03 21:08:34 +00:00
}
2009-12-10 14:40:47 +00:00
if ( profile - > extsipip & & ! sofia_test_pflag ( profile , PFLAG_AUTO_NAT ) ) {
2008-07-03 18:50:15 +00:00
char * ipv6 = strchr ( profile - > extsipip , ' : ' ) ;
profile - > url = switch_core_sprintf ( profile - > pool ,
2010-02-06 03:38:24 +00:00
" sip:%s@%s%s%s:%d " ,
profile - > contact_user , ipv6 ? " [ " : " " , profile - > extsipip , ipv6 ? " ] " : " " , profile - > sip_port ) ;
2007-12-18 16:31:05 +00:00
profile - > bindurl = switch_core_sprintf ( profile - > pool , " %s;maddr=%s " , profile - > url , profile - > sipip ) ;
} else {
2008-07-03 18:50:15 +00:00
char * ipv6 = strchr ( profile - > sipip , ' : ' ) ;
profile - > url = switch_core_sprintf ( profile - > pool ,
2010-02-06 03:38:24 +00:00
" sip:%s@%s%s%s:%d " ,
profile - > contact_user , ipv6 ? " [ " : " " , profile - > sipip , ipv6 ? " ] " : " " , profile - > sip_port ) ;
2007-12-18 16:31:05 +00:00
profile - > bindurl = profile - > url ;
}
2010-01-08 01:05:05 +00:00
profile - > tcp_contact = switch_core_sprintf ( profile - > pool , " <%s;transport=tcp> " , profile - > url ) ;
2009-06-03 21:08:34 +00:00
2009-12-02 18:46:17 +00:00
if ( profile - > public_url ) {
2010-01-08 01:05:05 +00:00
profile - > tcp_public_contact = switch_core_sprintf ( profile - > pool , " <%s;transport=tcp> " , profile - > public_url ) ;
2009-06-03 21:08:34 +00:00
}
2007-12-18 16:31:05 +00:00
if ( profile - > bind_params ) {
char * bindurl = profile - > bindurl ;
profile - > bindurl = switch_core_sprintf ( profile - > pool , " %s;%s " , bindurl , profile - > bind_params ) ;
}
2010-02-06 03:38:24 +00:00
2007-12-18 19:12:45 +00:00
/*
* handle TLS params # 2
*/
if ( sofia_test_pflag ( profile , PFLAG_TLS ) ) {
if ( ! profile - > tls_sip_port ) {
2010-02-06 03:38:24 +00:00
profile - > tls_sip_port = ( switch_port_t ) atoi ( SOFIA_DEFAULT_TLS_PORT ) ;
2007-12-18 19:12:45 +00:00
}
2009-12-02 18:46:17 +00:00
if ( profile - > extsipip ) {
2009-06-03 21:08:34 +00:00
char * ipv6 = strchr ( profile - > extsipip , ' : ' ) ;
profile - > tls_public_url = switch_core_sprintf ( profile - > pool ,
2010-02-06 03:38:24 +00:00
" sip:%s@%s%s%s:%d " ,
profile - > contact_user ,
ipv6 ? " [ " : " " , profile - > extsipip , ipv6 ? " ] " : " " , profile - > tls_sip_port ) ;
2009-06-03 21:08:34 +00:00
}
2010-02-06 03:38:24 +00:00
2009-12-10 14:40:47 +00:00
if ( profile - > extsipip & & ! sofia_test_pflag ( profile , PFLAG_AUTO_NAT ) ) {
2008-07-03 18:50:15 +00:00
char * ipv6 = strchr ( profile - > extsipip , ' : ' ) ;
2010-02-06 03:38:24 +00:00
profile - > tls_url =
2008-07-03 18:50:15 +00:00
switch_core_sprintf ( profile - > pool ,
2009-05-19 21:16:03 +00:00
" sip:%s@%s%s%s:%d " ,
2010-02-06 03:38:24 +00:00
profile - > contact_user , ipv6 ? " [ " : " " , profile - > extsipip , ipv6 ? " ] " : " " , profile - > tls_sip_port ) ;
2008-05-27 04:54:52 +00:00
profile - > tls_bindurl =
2008-07-03 18:50:15 +00:00
switch_core_sprintf ( profile - > pool ,
2009-05-19 21:16:03 +00:00
" sips:%s@%s%s%s:%d;maddr=%s " ,
profile - > contact_user ,
2010-02-06 03:38:24 +00:00
ipv6 ? " [ " : " " , profile - > extsipip , ipv6 ? " ] " : " " , profile - > tls_sip_port , profile - > sipip ) ;
2007-12-18 19:12:45 +00:00
} else {
2008-07-03 18:50:15 +00:00
char * ipv6 = strchr ( profile - > sipip , ' : ' ) ;
2010-02-06 03:38:24 +00:00
profile - > tls_url =
2008-07-03 18:50:15 +00:00
switch_core_sprintf ( profile - > pool ,
2009-05-19 21:16:03 +00:00
" sip:%s@%s%s%s:%d " ,
2010-02-06 03:38:24 +00:00
profile - > contact_user , ipv6 ? " [ " : " " , profile - > sipip , ipv6 ? " ] " : " " , profile - > tls_sip_port ) ;
2008-07-03 18:50:15 +00:00
profile - > tls_bindurl =
switch_core_sprintf ( profile - > pool ,
2009-05-19 21:16:03 +00:00
" sips:%s@%s%s%s:%d " ,
2010-02-06 03:38:24 +00:00
profile - > contact_user , ipv6 ? " [ " : " " , profile - > sipip , ipv6 ? " ] " : " " , profile - > tls_sip_port ) ;
2007-12-18 19:12:45 +00:00
}
if ( profile - > tls_bind_params ) {
2007-12-18 20:34:19 +00:00
char * tls_bindurl = profile - > tls_bindurl ;
profile - > tls_bindurl = switch_core_sprintf ( profile - > pool , " %s;%s " , tls_bindurl , profile - > tls_bind_params ) ;
2007-12-18 19:12:45 +00:00
}
if ( ! profile - > tls_cert_dir ) {
profile - > tls_cert_dir = switch_core_sprintf ( profile - > pool , " %s/ssl " , SWITCH_GLOBAL_dirs . conf_dir ) ;
}
2010-01-08 01:05:05 +00:00
profile - > tls_contact = switch_core_sprintf ( profile - > pool , " <%s;transport=tls> " , profile - > tls_url ) ;
2009-12-02 18:46:17 +00:00
if ( profile - > tls_public_url ) {
2010-01-08 01:05:05 +00:00
profile - > tls_public_contact = switch_core_sprintf ( profile - > pool , " <%s;transport=tls> " , profile - > tls_public_url ) ;
2009-06-03 21:08:34 +00:00
}
2007-12-18 19:12:45 +00:00
}
2007-12-18 16:31:05 +00:00
}
if ( profile ) {
switch_xml_t aliases_tag , alias_tag ;
2008-10-11 19:09:26 +00:00
if ( ( gateways_tag = switch_xml_child ( xprofile , " gateways " ) ) ) {
2007-12-18 16:31:05 +00:00
parse_gateways ( profile , gateways_tag ) ;
}
if ( ( domains_tag = switch_xml_child ( xprofile , " domains " ) ) ) {
2009-02-06 03:03:50 +00:00
switch_event_t * xml_params ;
switch_event_create ( & xml_params , SWITCH_EVENT_REQUEST_PARAMS ) ;
switch_assert ( xml_params ) ;
switch_event_add_header_string ( xml_params , SWITCH_STACK_BOTTOM , " purpose " , " gateways " ) ;
switch_event_add_header_string ( xml_params , SWITCH_STACK_BOTTOM , " profile " , profile - > name ) ;
2010-02-06 03:38:24 +00:00
2007-12-18 16:31:05 +00:00
for ( domain_tag = switch_xml_child ( domains_tag , " domain " ) ; domain_tag ; domain_tag = domain_tag - > next ) {
2008-04-01 17:41:38 +00:00
switch_xml_t droot , x_domain_tag ;
const char * dname = switch_xml_attr_soft ( domain_tag , " name " ) ;
const char * parse = switch_xml_attr_soft ( domain_tag , " parse " ) ;
const char * alias = switch_xml_attr_soft ( domain_tag , " alias " ) ;
2008-05-27 04:54:52 +00:00
2009-10-23 16:03:42 +00:00
if ( ! zstr ( dname ) ) {
2008-04-01 17:41:38 +00:00
if ( ! strcasecmp ( dname , " all " ) ) {
switch_xml_t xml_root , x_domains ;
2010-02-06 03:38:24 +00:00
if ( switch_xml_locate ( " directory " , NULL , NULL , NULL , & xml_root , & x_domains , xml_params , SWITCH_FALSE ) = =
SWITCH_STATUS_SUCCESS ) {
2008-05-27 04:54:52 +00:00
for ( x_domain_tag = switch_xml_child ( x_domains , " domain " ) ; x_domain_tag ; x_domain_tag = x_domain_tag - > next ) {
2008-04-01 17:41:38 +00:00
dname = switch_xml_attr_soft ( x_domain_tag , " name " ) ;
parse_domain_tag ( profile , x_domain_tag , dname , parse , alias ) ;
2007-12-18 16:31:05 +00:00
}
2008-04-01 17:41:38 +00:00
switch_xml_free ( xml_root ) ;
2007-12-18 16:31:05 +00:00
}
2009-02-06 03:03:50 +00:00
} else if ( switch_xml_locate_domain ( dname , xml_params , & droot , & x_domain_tag ) = = SWITCH_STATUS_SUCCESS ) {
2008-04-01 17:41:38 +00:00
parse_domain_tag ( profile , x_domain_tag , dname , parse , alias ) ;
2008-05-27 04:54:52 +00:00
switch_xml_free ( droot ) ;
2007-12-18 16:31:05 +00:00
}
}
}
2010-02-06 03:38:24 +00:00
2009-02-06 03:03:50 +00:00
switch_event_destroy ( & xml_params ) ;
2007-12-18 16:31:05 +00:00
}
if ( ( aliases_tag = switch_xml_child ( xprofile , " aliases " ) ) ) {
for ( alias_tag = switch_xml_child ( aliases_tag , " alias " ) ; alias_tag ; alias_tag = alias_tag - > next ) {
char * aname = ( char * ) switch_xml_attr_soft ( alias_tag , " name " ) ;
2009-10-23 16:03:42 +00:00
if ( ! zstr ( aname ) ) {
2007-12-18 16:31:05 +00:00
if ( sofia_glue_add_profile ( switch_core_strdup ( profile - > pool , aname ) , profile ) = = SWITCH_STATUS_SUCCESS ) {
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_NOTICE , " Adding Alias [%s] for profile [%s] \n " , aname , profile - > name ) ;
} else {
2008-05-27 04:54:52 +00:00
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_ERROR , " Error Adding Alias [%s] for profile [%s] (name in use) \n " ,
aname , profile - > name ) ;
2007-12-18 16:31:05 +00:00
}
}
}
}
if ( profile - > sipip ) {
launch_sofia_profile_thread ( profile ) ;
2009-05-07 15:14:28 +00:00
if ( profile - > odbc_dsn ) {
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_NOTICE , " Connecting ODBC Profile %s [%s] \n " , profile - > name , url ) ;
switch_yield ( 1000000 ) ;
} else {
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_NOTICE , " Started Profile %s [%s] \n " , profile - > name , url ) ;
}
2007-12-18 16:31:05 +00:00
} else {
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_NOTICE , " Unable to start Profile %s due to no configured sip-ip \n " , profile - > name ) ;
2009-12-09 14:42:30 +00:00
sofia_profile_start_failure ( profile , profile - > name ) ;
2007-12-18 16:31:05 +00:00
}
profile = NULL ;
}
if ( profile_found ) {
break ;
}
}
}
done :
2008-01-23 20:59:25 +00:00
switch_event_destroy ( & params ) ;
2007-12-18 16:31:05 +00:00
if ( xml ) {
switch_xml_free ( xml ) ;
}
if ( profile_name & & ! profile_found ) {
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_WARNING , " No Such Profile '%s' \n " , profile_name ) ;
status = SWITCH_STATUS_FALSE ;
}
return status ;
}
2008-04-14 15:28:07 +00:00
static void sofia_handle_sip_r_options ( switch_core_session_t * session , int status ,
2008-04-30 22:09:54 +00:00
char const * phrase ,
2008-05-27 04:54:52 +00:00
nua_t * nua , sofia_profile_t * profile , nua_handle_t * nh , sofia_private_t * sofia_private , sip_t const * sip ,
tagi_t tags [ ] )
2008-04-14 15:28:07 +00:00
{
2008-04-30 22:09:54 +00:00
sofia_gateway_t * gateway = NULL ;
2009-11-23 19:46:37 +00:00
static const char * status_names [ ] = { " DOWN " , " UP " , NULL } ;
2008-04-30 22:09:54 +00:00
2009-10-23 16:03:42 +00:00
if ( sofia_private & & ! zstr ( sofia_private - > gateway_name ) ) {
2008-04-30 22:09:54 +00:00
gateway = sofia_reg_find_gateway ( sofia_private - > gateway_name ) ;
2008-05-12 16:18:38 +00:00
sofia_private - > destroy_me = 1 ;
2008-04-30 22:09:54 +00:00
}
if ( gateway ) {
2009-11-19 00:12:15 +00:00
if ( status > = 200 & & status < 600 & & status ! = 408 & & status ! = 503 ) {
2008-05-13 23:22:21 +00:00
if ( gateway - > state = = REG_STATE_FAILED ) {
gateway - > state = REG_STATE_UNREGED ;
}
2009-11-23 19:46:37 +00:00
if ( gateway - > ping_count < gateway - > ping_max ) {
gateway - > ping_count + + ;
2010-02-06 03:38:24 +00:00
if ( gateway - > ping_count > = 0 )
gateway - > status = SOFIA_GATEWAY_UP ;
2009-11-23 19:46:37 +00:00
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( session ) , SWITCH_LOG_WARNING ,
2010-02-06 03:38:24 +00:00
" Ping succeeded %s with code %d - count %d/%d/%d, state %s \n " ,
gateway - > name , status , gateway - > ping_min , gateway - > ping_count , gateway - > ping_max , status_names [ gateway - > status ] ) ;
2009-11-23 19:46:37 +00:00
}
2008-04-30 22:09:54 +00:00
} else {
if ( gateway - > state = = REG_STATE_REGED ) {
2009-08-13 20:35:02 +00:00
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( session ) , SWITCH_LOG_WARNING , " Unregister %s \n " , gateway - > name ) ;
2008-07-02 17:18:34 +00:00
gateway - > state = REG_STATE_FAILED ;
2008-04-30 22:09:54 +00:00
}
2009-11-23 19:46:37 +00:00
if ( gateway - > ping_count > gateway - > ping_min ) {
gateway - > ping_count - - ;
2010-02-06 03:38:24 +00:00
if ( gateway - > ping_count < = 0 )
gateway - > status = SOFIA_GATEWAY_DOWN ;
2009-11-23 19:46:37 +00:00
}
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( session ) , SWITCH_LOG_WARNING ,
2010-02-06 03:38:24 +00:00
" Ping failed %s with code %d - count %d/%d/%d, state %s \n " ,
gateway - > name , status , gateway - > ping_min , gateway - > ping_count , gateway - > ping_max , status_names [ gateway - > status ] ) ;
2008-04-30 22:09:54 +00:00
}
2009-11-23 19:46:37 +00:00
2009-01-25 21:23:07 +00:00
gateway - > ping = switch_epoch_time_now ( NULL ) + gateway - > ping_freq ;
2008-04-30 22:09:54 +00:00
sofia_reg_release_gateway ( gateway ) ;
gateway - > pinging = 0 ;
2009-02-09 17:56:38 +00:00
} else if ( sofia_test_pflag ( profile , PFLAG_UNREG_OPTIONS_FAIL ) & & status ! = 200 & & sip & & sip - > sip_to ) {
2008-04-14 17:36:09 +00:00
char * sql ;
2009-01-25 21:23:07 +00:00
time_t now = switch_epoch_time_now ( NULL ) ;
2009-08-13 20:35:02 +00:00
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( session ) , SWITCH_LOG_WARNING , " Expire registration '%s@%s' due to options failure \n " ,
2008-05-27 04:54:52 +00:00
sip - > sip_to - > a_url - > url_user , sip - > sip_to - > a_url - > url_host ) ;
2008-10-06 16:03:39 +00:00
sql = switch_mprintf ( " update sip_registrations set expires=%ld where sip_user='%s' and sip_host='%s' " ,
2008-05-27 04:54:52 +00:00
( long ) now , sip - > sip_to - > a_url - > url_user , sip - > sip_to - > a_url - > url_host ) ;
2008-04-14 15:28:07 +00:00
sofia_glue_execute_sql ( profile , & sql , SWITCH_TRUE ) ;
}
}
2007-12-18 16:31:05 +00:00
static void sofia_handle_sip_r_invite ( switch_core_session_t * session , int status ,
2007-12-18 01:12:50 +00:00
char const * phrase ,
2008-05-27 04:54:52 +00:00
nua_t * nua , sofia_profile_t * profile , nua_handle_t * nh , sofia_private_t * sofia_private , sip_t const * sip ,
tagi_t tags [ ] )
2007-12-18 16:31:05 +00:00
{
2010-01-07 06:09:35 +00:00
char * call_info = NULL ;
2008-01-03 00:50:53 +00:00
if ( sip & & session ) {
2007-12-18 16:31:05 +00:00
switch_channel_t * channel = switch_core_session_get_channel ( session ) ;
2008-01-03 00:50:53 +00:00
const char * uuid ;
switch_core_session_t * other_session ;
2008-03-24 20:58:44 +00:00
private_object_t * tech_pvt = switch_core_session_get_private ( session ) ;
2008-12-03 17:13:02 +00:00
char network_ip [ 80 ] ;
int network_port = 0 ;
switch_caller_profile_t * caller_profile = NULL ;
2008-05-27 04:54:52 +00:00
2010-02-06 03:38:24 +00:00
sofia_glue_get_addr ( nua_current_request ( nua ) , network_ip , sizeof ( network_ip ) , & network_port ) ;
2008-12-03 17:13:02 +00:00
switch_channel_set_variable ( channel , " sip_reply_host " , network_ip ) ;
switch_channel_set_variable_printf ( channel , " sip_reply_port " , " %d " , network_port ) ;
2010-02-06 03:38:24 +00:00
switch_channel_set_variable_printf ( channel , " sip_network_ip " , " %s " , network_ip ) ;
switch_channel_set_variable_printf ( channel , " sip_network_port " , " %d " , network_port ) ;
2008-12-03 17:13:02 +00:00
if ( ( caller_profile = switch_channel_get_caller_profile ( channel ) ) ) {
caller_profile - > network_addr = switch_core_strdup ( caller_profile - > pool , network_ip ) ;
}
2008-01-26 03:56:40 +00:00
2009-10-19 19:58:23 +00:00
switch_channel_clear_flag ( channel , CF_REQ_MEDIA ) ;
2010-01-12 00:05:11 +00:00
tech_pvt - > last_sdp_str = NULL ;
if ( ! sofia_use_soa ( tech_pvt ) & & sip - > sip_payload & & sip - > sip_payload - > pl_data ) {
tech_pvt - > last_sdp_str = switch_core_session_strdup ( session , sip - > sip_payload - > pl_data ) ;
}
2010-01-07 06:09:35 +00:00
if ( sofia_test_pflag ( profile , PFLAG_MANAGE_SHARED_APPEARANCE ) ) {
if ( channel & & sip - > sip_call_info ) {
char * p ;
call_info = sip_header_as_string ( nua_handle_home ( nh ) , ( void * ) sip - > sip_call_info ) ;
2010-01-28 20:52:28 +00:00
if ( switch_stristr ( " appearance " , call_info ) ) {
2010-01-28 20:35:17 +00:00
switch_channel_set_variable ( channel , " presence_call_info_full " , call_info ) ;
if ( ( p = strchr ( call_info , ' ; ' ) ) ) {
2010-02-06 03:38:24 +00:00
switch_channel_set_variable ( channel , " presence_call_info " , p + 1 ) ;
2010-01-28 20:35:17 +00:00
}
2010-01-07 06:09:35 +00:00
}
} else if ( ( status = = 180 | | status = = 183 | | status = = 200 ) ) {
char buf [ 128 ] = " " ;
char * sql ;
char * state = " active " ;
if ( status ! = 200 ) {
state = " progressing " ;
}
2010-02-06 03:38:24 +00:00
if ( sip & &
2010-01-07 06:09:35 +00:00
sip - > sip_from & & sip - > sip_from - > a_url & & sip - > sip_from - > a_url - > url_user & & sip - > sip_from - > a_url - > url_host & &
sip - > sip_to & & sip - > sip_to - > a_url & & sip - > sip_to - > a_url - > url_user & & sip - > sip_to - > a_url - > url_host ) {
2010-02-06 03:38:24 +00:00
sql =
switch_mprintf ( " select 'appearance-index=1' from sip_subscriptions where expires > -1 and hostname='%q' and event='call-info' and "
" sub_to_user='%q' and sub_to_host='%q' " , mod_sofia_globals . hostname , sip - > sip_to - > a_url - > url_user ,
sip - > sip_from - > a_url - > url_host ) ;
2010-01-07 06:09:35 +00:00
sofia_glue_execute_sql2str ( profile , profile - > ireg_mutex , sql , buf , sizeof ( buf ) ) ;
2010-02-06 03:38:24 +00:00
2010-01-07 06:09:35 +00:00
if ( mod_sofia_globals . debug_sla > 1 ) {
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_ERROR , " QUERY SQL %s [%s] \n " , sql , buf ) ;
}
free ( sql ) ;
if ( ! zstr ( buf ) ) {
sql = switch_mprintf ( " update sip_dialogs set call_info='%q',call_info_state='%q' "
2010-02-06 03:38:24 +00:00
" where uuid='%q' " , buf , state , switch_core_session_get_uuid ( session ) ) ;
2010-01-07 06:09:35 +00:00
if ( mod_sofia_globals . debug_sla > 1 ) {
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_ERROR , " QUERY SQL %s \n " , sql ) ;
}
2010-02-06 03:38:24 +00:00
2010-01-09 00:34:17 +00:00
sofia_glue_execute_sql_now ( profile , & sql , SWITCH_TRUE ) ;
2010-01-07 06:09:35 +00:00
}
}
}
}
2010-02-06 03:38:24 +00:00
if ( ( status = = 180 | | status = = 183 | | status = = 200 ) ) {
2009-10-21 18:48:28 +00:00
const char * x_freeswitch_support ;
2009-10-08 15:07:12 +00:00
2009-10-14 19:26:10 +00:00
switch_channel_set_flag ( channel , CF_MEDIA_ACK ) ;
2009-10-21 18:48:28 +00:00
if ( ( x_freeswitch_support = sofia_glue_get_unknown_header ( sip , " X-FS-Support " ) ) ) {
tech_pvt - > x_freeswitch_support_remote = switch_core_session_strdup ( session , x_freeswitch_support ) ;
2009-10-08 15:07:12 +00:00
}
2008-07-24 16:31:47 +00:00
if ( sip - > sip_user_agent & & sip - > sip_user_agent - > g_string ) {
switch_channel_set_variable ( channel , " sip_user_agent " , sip - > sip_user_agent - > g_string ) ;
} else if ( sip - > sip_server & & sip - > sip_server - > g_string ) {
switch_channel_set_variable ( channel , " sip_user_agent " , sip - > sip_server - > g_string ) ;
}
2010-02-06 03:38:24 +00:00
2009-08-11 00:54:39 +00:00
sofia_glue_set_extra_headers ( channel , sip , SOFIA_SIP_PROGRESS_HEADER_PREFIX ) ;
2009-10-07 22:35:21 +00:00
2009-11-21 04:39:38 +00:00
sofia_update_callee_id ( session , profile , sip , SWITCH_FALSE ) ;
2009-11-21 06:54:16 +00:00
if ( sofia_test_pflag ( tech_pvt - > profile , PFLAG_AUTOFIX_TIMING ) ) {
tech_pvt - > check_frames = 0 ;
2009-12-03 22:51:50 +00:00
tech_pvt - > last_ts = 0 ;
2009-11-21 06:54:16 +00:00
}
2008-07-24 16:31:47 +00:00
}
2010-02-06 03:38:24 +00:00
2009-07-23 15:42:12 +00:00
if ( channel & & sip & & ( status = = 300 | | status = = 302 | | status = = 305 ) & & switch_channel_test_flag ( channel , CF_OUTBOUND ) ) {
2010-02-06 03:38:24 +00:00
sip_contact_t * p_contact = sip - > sip_contact ;
2008-07-08 22:50:35 +00:00
int i = 0 ;
2010-02-06 03:38:24 +00:00
char var_name [ 80 ] ;
2009-06-09 19:05:11 +00:00
const char * diversion_header ;
char * full_contact = NULL ;
char * invite_contact ;
const char * br ;
2010-02-06 03:38:24 +00:00
2009-09-23 13:17:36 +00:00
if ( ! p_contact ) {
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( session ) , SWITCH_LOG_ERROR , " Missing contact header in redirect request \n " ) ;
2010-01-07 06:09:35 +00:00
goto end ;
2009-12-24 05:44:23 +00:00
}
2009-06-09 19:05:11 +00:00
if ( ( br = switch_channel_get_variable ( channel , SWITCH_SIGNAL_BOND_VARIABLE ) ) ) {
switch_xml_t root = NULL , domain = NULL ;
switch_core_session_t * a_session ;
switch_channel_t * a_channel ;
2009-05-20 21:32:11 +00:00
2009-06-09 19:05:11 +00:00
const char * sip_redirect_profile , * sip_redirect_context , * sip_redirect_dialplan , * sip_redirect_fork ;
2010-02-06 03:38:24 +00:00
if ( ( a_session = switch_core_session_locate ( br ) ) & & ( a_channel = switch_core_session_get_channel ( a_session ) ) ) {
2009-06-09 19:05:11 +00:00
switch_stream_handle_t stream = { 0 } ;
char separator [ 2 ] = " | " ;
char * redirect_dialstring ;
su_home_t * home = su_home_new ( sizeof ( * home ) ) ;
switch_assert ( home ! = NULL ) ;
SWITCH_STANDARD_STREAM ( stream ) ;
if ( ! ( sip_redirect_profile = switch_channel_get_variable ( channel , " sip_redirect_profile " ) ) ) {
sip_redirect_profile = profile - > name ;
}
if ( ! ( sip_redirect_context = switch_channel_get_variable ( channel , " sip_redirect_context " ) ) ) {
sip_redirect_context = " redirected " ;
}
if ( ! ( sip_redirect_dialplan = switch_channel_get_variable ( channel , " sip_redirect_dialplan " ) ) ) {
sip_redirect_dialplan = " XML " ;
}
2009-05-20 20:51:35 +00:00
2009-06-09 19:05:11 +00:00
sip_redirect_fork = switch_channel_get_variable ( channel , " sip_redirect_fork " ) ;
2010-02-06 03:38:24 +00:00
2009-06-09 19:05:11 +00:00
if ( switch_true ( sip_redirect_fork ) ) {
* separator = ' , ' ;
2008-07-08 22:50:35 +00:00
}
2009-06-09 19:05:11 +00:00
for ( p_contact = sip - > sip_contact ; p_contact ; p_contact = p_contact - > m_next ) {
if ( p_contact - > m_url ) {
2009-12-17 23:22:58 +00:00
full_contact = sip_header_as_string ( home , ( void * ) p_contact ) ;
2009-06-09 19:05:11 +00:00
invite_contact = sofia_glue_strip_uri ( full_contact ) ;
2010-02-06 03:38:24 +00:00
2009-06-09 19:05:11 +00:00
switch_snprintf ( var_name , sizeof ( var_name ) , " sip_redirect_contact_%d " , i ) ;
switch_channel_set_variable ( a_channel , var_name , full_contact ) ;
2010-02-06 03:38:24 +00:00
2009-06-09 19:05:11 +00:00
if ( i = = 0 ) {
switch_channel_set_variable ( channel , " sip_redirected_to " , full_contact ) ;
switch_channel_set_variable ( a_channel , " sip_redirected_to " , full_contact ) ;
}
2010-02-06 03:38:24 +00:00
2009-06-09 19:05:11 +00:00
if ( p_contact - > m_url - > url_user ) {
switch_snprintf ( var_name , sizeof ( var_name ) , " sip_redirect_contact_user_%d " , i ) ;
switch_channel_set_variable ( channel , var_name , p_contact - > m_url - > url_user ) ;
switch_channel_set_variable ( a_channel , var_name , p_contact - > m_url - > url_user ) ;
}
if ( p_contact - > m_url - > url_host ) {
switch_snprintf ( var_name , sizeof ( var_name ) , " sip_redirect_contact_host_%d " , i ) ;
switch_channel_set_variable ( channel , var_name , p_contact - > m_url - > url_host ) ;
switch_channel_set_variable ( a_channel , var_name , p_contact - > m_url - > url_host ) ;
}
if ( p_contact - > m_url - > url_params ) {
switch_snprintf ( var_name , sizeof ( var_name ) , " sip_redirect_contact_params_%d " , i ) ;
switch_channel_set_variable ( channel , var_name , p_contact - > m_url - > url_params ) ;
switch_channel_set_variable ( a_channel , var_name , p_contact - > m_url - > url_params ) ;
}
2010-02-06 03:38:24 +00:00
2009-06-09 19:05:11 +00:00
switch_snprintf ( var_name , sizeof ( var_name ) , " sip_redirect_dialstring_%d " , i ) ;
switch_channel_set_variable_printf ( channel , var_name , " sofia/%s/%s " , sip_redirect_profile , invite_contact ) ;
switch_channel_set_variable_printf ( a_channel , var_name , " sofia/%s/%s " , sip_redirect_profile , invite_contact ) ;
stream . write_function ( & stream , " %ssofia/%s/%s " , i ? separator : " " , sip_redirect_profile , invite_contact ) ;
free ( invite_contact ) ;
i + + ;
}
2008-07-08 22:50:35 +00:00
}
2010-02-06 03:38:24 +00:00
2009-06-09 19:05:11 +00:00
redirect_dialstring = stream . data ;
2010-02-06 03:38:24 +00:00
2009-06-09 19:05:11 +00:00
switch_channel_set_variable ( channel , " sip_redirect_dialstring " , redirect_dialstring ) ;
switch_channel_set_variable ( a_channel , " sip_redirect_dialstring " , redirect_dialstring ) ;
2010-02-06 03:38:24 +00:00
2009-06-09 19:05:11 +00:00
p_contact = sip - > sip_contact ;
full_contact = sip_header_as_string ( home , ( void * ) sip - > sip_contact ) ;
2010-02-06 03:38:24 +00:00
2009-06-09 19:05:11 +00:00
if ( ( diversion_header = sofia_glue_get_unknown_header ( sip , " diversion " ) ) ) {
switch_channel_set_variable ( channel , " sip_redirected_by " , diversion_header ) ;
switch_channel_set_variable ( a_channel , " sip_redirected_by " , diversion_header ) ;
2009-05-10 17:12:29 +00:00
}
2010-02-06 03:38:24 +00:00
2009-06-09 19:05:11 +00:00
if ( sofia_test_pflag ( profile , PFLAG_MANUAL_REDIRECT ) ) {
2010-02-06 03:38:24 +00:00
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( session ) , SWITCH_LOG_DEBUG , " Redirect: Transfering to %s %s %s \n " ,
2009-06-09 19:05:11 +00:00
p_contact - > m_url - > url_user , sip_redirect_dialplan , sip_redirect_context ) ;
2010-02-06 03:38:24 +00:00
switch_ivr_session_transfer ( a_session , p_contact - > m_url - > url_user , sip_redirect_dialplan , sip_redirect_context ) ;
2009-06-09 19:05:11 +00:00
} else if ( ( ! strcmp ( profile - > sipip , p_contact - > m_url - > url_host ) )
2009-06-24 16:04:05 +00:00
| | ( profile - > extsipip & & ! strcmp ( profile - > extsipip , p_contact - > m_url - > url_host ) )
2009-06-09 19:05:11 +00:00
| | ( switch_xml_locate_domain ( p_contact - > m_url - > url_host , NULL , & root , & domain ) = = SWITCH_STATUS_SUCCESS ) ) {
2010-02-06 03:38:24 +00:00
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( session ) , SWITCH_LOG_DEBUG , " Redirect: Transfering to %s \n " ,
p_contact - > m_url - > url_user ) ;
2009-06-09 19:05:11 +00:00
switch_ivr_session_transfer ( a_session , p_contact - > m_url - > url_user , NULL , NULL ) ;
2009-06-29 17:30:55 +00:00
switch_xml_free ( root ) ;
2009-06-09 19:05:11 +00:00
} else {
invite_contact = sofia_glue_strip_uri ( full_contact ) ;
tech_pvt - > redirected = switch_core_session_strdup ( session , invite_contact ) ;
free ( invite_contact ) ;
}
2010-02-06 03:38:24 +00:00
2009-06-09 19:05:11 +00:00
if ( home ) {
su_home_unref ( home ) ;
home = NULL ;
}
free ( stream . data ) ;
switch_core_session_rwunlock ( a_session ) ;
}
} else {
su_home_t * home = su_home_new ( sizeof ( * home ) ) ;
switch_assert ( home ! = NULL ) ;
full_contact = sip_header_as_string ( home , ( void * ) sip - > sip_contact ) ;
invite_contact = sofia_glue_strip_uri ( full_contact ) ;
2009-10-15 13:52:57 +00:00
switch_channel_set_variable ( channel , " sip_redirected_to " , invite_contact ) ;
2009-06-09 19:05:11 +00:00
tech_pvt - > redirected = switch_core_session_strdup ( session , invite_contact ) ;
free ( invite_contact ) ;
if ( home ) {
su_home_unref ( home ) ;
home = NULL ;
2008-07-08 22:50:35 +00:00
}
}
}
2009-08-16 19:01:35 +00:00
if ( switch_channel_test_flag ( channel , CF_PROXY_MODE ) | | switch_channel_test_flag ( channel , CF_PROXY_MEDIA ) ) {
2010-02-06 03:38:24 +00:00
if ( sofia_test_flag ( tech_pvt , TFLAG_SENT_UPDATE ) ) {
sofia_clear_flag_locked ( tech_pvt , TFLAG_SENT_UPDATE ) ;
2009-08-16 19:01:35 +00:00
2010-02-06 03:38:24 +00:00
if ( ( uuid = switch_channel_get_variable ( channel , SWITCH_SIGNAL_BOND_VARIABLE ) ) & & ( other_session = switch_core_session_locate ( uuid ) ) ) {
const char * r_sdp = NULL ;
switch_core_session_message_t * msg ;
2009-08-16 19:01:35 +00:00
2010-02-06 03:38:24 +00:00
if ( sip - > sip_payload & & sip - > sip_payload - > pl_data & &
sip - > sip_content_type & & sip - > sip_content_type - > c_subtype & & switch_stristr ( " sdp " , sip - > sip_content_type - > c_subtype ) ) {
tech_pvt - > remote_sdp_str = switch_core_session_strdup ( tech_pvt - > session , sip - > sip_payload - > pl_data ) ;
r_sdp = tech_pvt - > remote_sdp_str ;
sofia_glue_tech_proxy_remote_addr ( tech_pvt ) ;
}
2009-08-16 19:01:35 +00:00
2010-02-06 03:38:24 +00:00
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( session ) , SWITCH_LOG_DEBUG , " Passing %d %s to other leg \n " , status , phrase ) ;
2009-08-16 19:01:35 +00:00
2010-02-06 03:38:24 +00:00
msg = switch_core_session_alloc ( other_session , sizeof ( * msg ) ) ;
msg - > message_id = SWITCH_MESSAGE_INDICATE_RESPOND ;
msg - > from = __FILE__ ;
msg - > numeric_arg = status ;
msg - > string_arg = switch_core_session_strdup ( other_session , phrase ) ;
if ( r_sdp ) {
msg - > pointer_arg = switch_core_session_strdup ( other_session , r_sdp ) ;
msg - > pointer_arg_size = strlen ( r_sdp ) ;
}
2009-08-16 19:01:35 +00:00
2010-02-06 03:38:24 +00:00
switch_core_session_queue_message ( other_session , msg ) ;
switch_core_session_rwunlock ( other_session ) ;
2009-08-16 19:01:35 +00:00
}
2010-02-06 03:38:24 +00:00
goto end ;
2009-08-16 19:01:35 +00:00
}
}
if ( ( status = = 180 | | status = = 183 | | status = = 200 ) ) {
const char * astate = " early " ;
url_t * from = NULL , * to = NULL , * contact = NULL ;
if ( sip - > sip_to ) {
to = sip - > sip_to - > a_url ;
}
if ( sip - > sip_from ) {
from = sip - > sip_from - > a_url ;
}
if ( sip - > sip_contact ) {
contact = sip - > sip_contact - > m_url ;
}
if ( status = = 200 ) {
astate = " confirmed " ;
}
if ( ! switch_channel_test_flag ( channel , CF_EARLY_MEDIA ) & & ! switch_channel_test_flag ( channel , CF_ANSWERED ) & &
! switch_channel_test_flag ( channel , CF_RING_READY ) ) {
const char * from_user = " " , * from_host = " " , * to_user = " " , * to_host = " " , * contact_user = " " , * contact_host = " " ;
const char * user_agent = " " , * call_id = " " ;
char * sql = NULL ;
2010-02-06 03:38:24 +00:00
2009-08-16 19:01:35 +00:00
if ( sip - > sip_user_agent ) {
user_agent = switch_str_nil ( sip - > sip_user_agent - > g_string ) ;
}
if ( sip - > sip_call_id ) {
call_id = switch_str_nil ( sip - > sip_call_id - > i_id ) ;
}
if ( to ) {
from_user = switch_str_nil ( to - > url_user ) ;
}
if ( from ) {
from_host = switch_str_nil ( from - > url_host ) ;
to_user = switch_str_nil ( from - > url_user ) ;
to_host = switch_str_nil ( from - > url_host ) ;
}
if ( contact ) {
contact_user = switch_str_nil ( contact - > url_user ) ;
contact_host = switch_str_nil ( contact - > url_host ) ;
}
if ( profile - > pres_type ) {
2009-11-11 02:10:41 +00:00
const char * presence_data = switch_channel_get_variable ( channel , " presence_data " ) ;
const char * presence_id = switch_channel_get_variable ( channel , " presence_id " ) ;
char * full_contact = " " ;
2010-01-07 06:09:35 +00:00
char * p = NULL ;
2009-11-11 02:10:41 +00:00
if ( sip - > sip_contact ) {
full_contact = sip_header_as_string ( nua_handle_home ( tech_pvt - > nh ) , ( void * ) sip - > sip_contact ) ;
}
2010-01-07 06:09:35 +00:00
if ( call_info & & ( p = strchr ( call_info , ' ; ' ) ) ) {
p + + ;
}
2009-08-16 19:01:35 +00:00
sql = switch_mprintf ( " insert into sip_dialogs "
" (call_id,uuid,sip_to_user,sip_to_host,sip_from_user,sip_from_host,contact_user, "
2009-12-24 05:44:23 +00:00
" contact_host,state,direction,user_agent,profile_name,hostname,contact,presence_id,presence_data,call_info) "
" values('%q','%q','%q','%q','%q','%q','%q','%q','%q','%q','%q','%q','%q','%q','%q','%q','%q') " ,
2009-08-16 19:01:35 +00:00
call_id ,
switch_core_session_get_uuid ( session ) ,
2010-02-06 03:38:24 +00:00
to_user , to_host , from_user , from_host , contact_user ,
2009-08-16 19:01:35 +00:00
contact_host , astate , " outbound " , user_agent ,
2009-11-11 02:10:41 +00:00
profile - > name , mod_sofia_globals . hostname , switch_str_nil ( full_contact ) ,
2010-01-07 06:09:35 +00:00
switch_str_nil ( presence_id ) , switch_str_nil ( presence_data ) , switch_str_nil ( p ) ) ;
2010-02-06 03:38:24 +00:00
2009-08-16 19:01:35 +00:00
switch_assert ( sql ) ;
2010-01-09 00:34:17 +00:00
sofia_glue_actually_execute_sql ( profile , sql , profile - > ireg_mutex ) ;
switch_safe_free ( sql ) ;
2009-11-11 02:10:41 +00:00
2010-02-06 03:38:24 +00:00
}
2009-08-16 19:01:35 +00:00
} else if ( status = = 200 & & ( profile - > pres_type ) ) {
char * sql = NULL ;
2009-11-11 02:10:41 +00:00
const char * presence_data = switch_channel_get_variable ( channel , " presence_data " ) ;
const char * presence_id = switch_channel_get_variable ( channel , " presence_id " ) ;
sql = switch_mprintf ( " update sip_dialogs set state='%q',presence_id='%q',presence_data='%q' "
2010-02-06 03:38:24 +00:00
" where uuid='%s'; \n " , astate , switch_str_nil ( presence_id ) , switch_str_nil ( presence_data ) ,
2009-11-11 02:10:41 +00:00
switch_core_session_get_uuid ( session ) ) ;
2009-08-16 19:01:35 +00:00
switch_assert ( sql ) ;
2010-01-09 00:34:17 +00:00
sofia_glue_execute_sql_now ( profile , & sql , SWITCH_TRUE ) ;
2009-08-16 19:01:35 +00:00
}
2010-02-06 03:38:24 +00:00
extract_header_vars ( profile , sip , session ) ;
extract_vars ( profile , sip , session ) ;
sofia_glue_tech_track ( tech_pvt - > profile , session ) ;
sofia_clear_flag ( tech_pvt , TFLAG_RECOVERING ) ;
2009-08-16 19:01:35 +00:00
}
2007-03-31 19:01:33 +00:00
}
2008-10-10 22:22:41 +00:00
2010-02-06 03:38:24 +00:00
end :
2010-01-07 06:09:35 +00:00
if ( call_info ) {
su_free ( nua_handle_home ( nh ) , call_info ) ;
}
2008-10-10 22:22:41 +00:00
if ( ! session & & ( status = = 180 | | status = = 183 | | status = = 200 ) ) {
2008-11-19 16:48:32 +00:00
/* nevermind */
nua_handle_bind ( nh , NULL ) ;
nua_handle_destroy ( nh ) ;
2008-10-10 22:22:41 +00:00
}
2007-03-31 19:01:33 +00:00
}
2008-09-18 21:50:18 +00:00
/* Pure black magic, if you can't understand this code you are lucky.........*/
void * SWITCH_THREAD_FUNC media_on_hold_thread_run ( switch_thread_t * thread , void * obj )
{
switch_core_session_t * other_session = NULL , * session = ( switch_core_session_t * ) obj ;
const char * uuid ;
2010-02-06 03:38:24 +00:00
2008-09-18 21:50:18 +00:00
if ( switch_core_session_read_lock ( session ) = = SWITCH_STATUS_SUCCESS ) {
switch_channel_t * channel = switch_core_session_get_channel ( session ) ;
private_object_t * tech_pvt = switch_core_session_get_private ( session ) ;
2010-02-06 03:38:24 +00:00
2008-09-18 21:50:18 +00:00
if ( ( uuid = switch_channel_get_variable ( channel , SWITCH_SIGNAL_BOND_VARIABLE ) ) & & ( other_session = switch_core_session_locate ( uuid ) ) ) {
if ( switch_core_session_compare ( session , other_session ) ) {
2009-02-09 17:56:38 +00:00
sofia_set_flag_locked ( tech_pvt , TFLAG_HOLD_LOCK ) ;
2008-09-18 21:50:18 +00:00
switch_ivr_media ( switch_core_session_get_uuid ( other_session ) , SMF_REBRIDGE ) ;
2010-02-06 03:38:24 +00:00
2008-09-18 21:50:18 +00:00
if ( tech_pvt - > rtp_session ) {
switch_rtp_clear_flag ( tech_pvt - > rtp_session , SWITCH_RTP_FLAG_AUTOADJ ) ;
}
sofia_glue_toggle_hold ( tech_pvt , 1 ) ;
}
2009-04-23 05:00:47 +00:00
switch_core_session_rwunlock ( other_session ) ;
2008-09-18 21:50:18 +00:00
}
switch_core_session_rwunlock ( session ) ;
}
2010-02-06 03:38:24 +00:00
2008-09-18 21:50:18 +00:00
return NULL ;
}
static void launch_media_on_hold ( switch_core_session_t * session )
{
switch_thread_t * thread ;
switch_threadattr_t * thd_attr = NULL ;
switch_threadattr_create ( & thd_attr , switch_core_session_get_pool ( session ) ) ;
switch_threadattr_detach_set ( thd_attr , 1 ) ;
switch_threadattr_stacksize_set ( thd_attr , SWITCH_THREAD_STACKSIZE ) ;
switch_threadattr_priority_increase ( thd_attr ) ;
switch_thread_create ( & thread , thd_attr , media_on_hold_thread_run , session , switch_core_session_get_pool ( session ) ) ;
}
2007-04-17 06:08:39 +00:00
static void sofia_handle_sip_i_state ( switch_core_session_t * session , int status ,
char const * phrase ,
2008-05-27 04:54:52 +00:00
nua_t * nua , sofia_profile_t * profile , nua_handle_t * nh , sofia_private_t * sofia_private , sip_t const * sip ,
tagi_t tags [ ] )
2007-03-31 19:01:33 +00:00
{
const char * l_sdp = NULL , * r_sdp = NULL ;
int offer_recv = 0 , answer_recv = 0 , offer_sent = 0 , answer_sent = 0 ;
int ss_state = nua_callstate_init ;
switch_channel_t * channel = NULL ;
2009-08-16 18:05:35 +00:00
private_object_t * tech_pvt = NULL ;
2007-03-31 19:01:33 +00:00
const char * replaces_str = NULL ;
2007-11-01 11:28:26 +00:00
const char * uuid ;
2007-03-31 19:01:33 +00:00
switch_core_session_t * other_session = NULL ;
switch_channel_t * other_channel = NULL ;
char st [ 80 ] = " " ;
2009-10-21 23:01:37 +00:00
int is_dup_sdp = 0 ;
2009-10-23 13:27:00 +00:00
switch_event_t * s_event = NULL ;
2009-12-19 17:43:05 +00:00
char * p ;
2007-03-31 19:01:33 +00:00
tl_gets ( tags ,
NUTAG_CALLSTATE_REF ( ss_state ) ,
NUTAG_OFFER_RECV_REF ( offer_recv ) ,
NUTAG_ANSWER_RECV_REF ( answer_recv ) ,
NUTAG_OFFER_SENT_REF ( offer_sent ) ,
NUTAG_ANSWER_SENT_REF ( answer_sent ) ,
SIPTAG_REPLACES_STR_REF ( replaces_str ) , SOATAG_LOCAL_SDP_STR_REF ( l_sdp ) , SOATAG_REMOTE_SDP_STR_REF ( r_sdp ) , TAG_END ( ) ) ;
2010-01-12 00:05:11 +00:00
if ( session ) {
channel = switch_core_session_get_channel ( session ) ;
tech_pvt = switch_core_session_get_private ( session ) ;
if ( ! tech_pvt | | ! tech_pvt - > nh ) {
goto done ;
}
}
if ( status > 100 & & status < 300 & & tech_pvt & & ! sofia_use_soa ( tech_pvt ) & & ! r_sdp & & tech_pvt - > last_sdp_str ) {
r_sdp = tech_pvt - > last_sdp_str ;
}
2010-02-06 03:38:24 +00:00
if ( ( channel & & ( switch_channel_test_flag ( channel , CF_PROXY_MODE ) | | switch_channel_test_flag ( channel , CF_PROXY_MEDIA ) ) ) | |
2010-01-22 22:17:17 +00:00
( sofia_test_flag ( profile , TFLAG_INB_NOMEDIA ) | | sofia_test_flag ( profile , TFLAG_PROXY_MEDIA ) ) ) {
2010-02-06 03:38:24 +00:00
/* This marr in our code brought to you by people who can't read........ */
2010-01-22 22:17:17 +00:00
if ( profile - > ndlb & PFLAG_NDLB_ALLOW_BAD_IANANAME & & r_sdp & & ( p = ( char * ) switch_stristr ( " g729a/8000 " , r_sdp ) ) ) {
p + = 4 ;
* p + + = ' / ' ;
* p + + = ' 8 ' ;
* p + + = ' 0 ' ;
* p + + = ' 0 ' ;
* p + + = ' 0 ' ;
* p + + = ' ' ;
}
2009-12-19 17:43:05 +00:00
}
2009-10-27 20:52:12 +00:00
2010-01-22 22:17:17 +00:00
2008-06-23 21:07:55 +00:00
if ( ss_state = = nua_callstate_terminated ) {
2009-06-09 19:05:11 +00:00
2009-07-23 15:42:12 +00:00
if ( ( status = = 300 | | status = = 302 | | status = = 305 ) & & session ) {
2009-06-09 19:05:11 +00:00
channel = switch_core_session_get_channel ( session ) ;
tech_pvt = switch_core_session_get_private ( session ) ;
2010-02-06 03:38:24 +00:00
2009-06-09 19:05:11 +00:00
if ( ! tech_pvt | | ! tech_pvt - > nh ) {
goto done ;
}
2010-02-06 03:38:24 +00:00
2009-06-09 19:05:11 +00:00
if ( tech_pvt - > redirected ) {
sofia_glue_do_invite ( session ) ;
goto done ;
}
}
2008-06-23 21:07:55 +00:00
if ( sofia_private ) {
sofia_private - > destroy_me = 1 ;
}
}
2007-03-31 19:01:33 +00:00
if ( session ) {
2010-02-06 03:38:24 +00:00
if ( ( switch_channel_test_flag ( channel , CF_EARLY_MEDIA ) | | switch_channel_test_flag ( channel , CF_ANSWERED ) ) & & ( status = = 180 | | status = = 183 ) ) {
2009-10-27 20:52:12 +00:00
/* Must you send 180 after 183 w/sdp ? sheesh */
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( session ) , SWITCH_LOG_DEBUG , " Channel %s skipping state [%s][%d] \n " ,
switch_channel_get_name ( channel ) , nua_callstate_name ( ss_state ) , status ) ;
goto done ;
}
2009-08-13 20:35:02 +00:00
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( session ) , SWITCH_LOG_DEBUG , " Channel %s entering state [%s][%d] \n " ,
2009-03-20 01:52:53 +00:00
switch_channel_get_name ( channel ) , nua_callstate_name ( ss_state ) , status ) ;
2010-02-06 03:38:24 +00:00
2007-03-31 19:01:33 +00:00
if ( r_sdp ) {
2009-04-08 06:05:56 +00:00
sdp_parser_t * parser ;
sdp_session_t * sdp ;
2010-02-06 03:38:24 +00:00
2009-10-23 16:03:42 +00:00
if ( ! zstr ( tech_pvt - > remote_sdp_str ) & & ! strcmp ( tech_pvt - > remote_sdp_str , r_sdp ) ) {
2009-10-21 23:01:37 +00:00
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( session ) , SWITCH_LOG_DEBUG , " Duplicate SDP \n %s \n " , r_sdp ) ;
is_dup_sdp = 1 ;
} else {
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( session ) , SWITCH_LOG_DEBUG , " Remote SDP: \n %s \n " , r_sdp ) ;
tech_pvt - > remote_sdp_str = switch_core_session_strdup ( session , r_sdp ) ;
switch_channel_set_variable ( channel , SWITCH_R_SDP_VARIABLE , r_sdp ) ;
2009-04-08 06:05:56 +00:00
2009-10-21 23:01:37 +00:00
if ( sofia_test_flag ( tech_pvt , TFLAG_LATE_NEGOTIATION ) & & ( parser = sdp_parse ( NULL , r_sdp , ( int ) strlen ( r_sdp ) , 0 ) ) ) {
if ( ( sdp = sdp_session ( parser ) ) ) {
2009-11-24 18:52:57 +00:00
sofia_glue_set_r_sdp_codec_string ( session , sofia_glue_get_codec_string ( tech_pvt ) , sdp ) ;
2009-10-21 23:01:37 +00:00
}
sdp_parser_free ( parser ) ;
2009-04-08 06:05:56 +00:00
}
2009-10-21 23:01:37 +00:00
sofia_glue_pass_sdp ( tech_pvt , ( char * ) r_sdp ) ;
2009-04-08 06:05:56 +00:00
}
2007-03-31 19:01:33 +00:00
}
}
if ( status = = 988 ) {
goto done ;
}
2007-10-05 17:05:31 +00:00
2008-02-15 19:48:16 +00:00
if ( status = = 183 & & ! r_sdp ) {
status = 180 ;
2010-02-06 03:38:24 +00:00
}
2008-09-16 21:52:12 +00:00
if ( status = = 180 & & r_sdp ) {
status = 183 ;
2008-02-15 19:48:16 +00:00
}
2010-02-06 03:38:24 +00:00
2007-10-05 18:00:33 +00:00
if ( channel & & ( status = = 180 | | status = = 183 ) & & switch_channel_test_flag ( channel , CF_OUTBOUND ) ) {
2007-11-01 11:28:26 +00:00
const char * val ;
2007-10-05 17:05:31 +00:00
if ( ( val = switch_channel_get_variable ( channel , " sip_auto_answer " ) ) & & switch_true ( val ) ) {
nua_notify ( nh , NUTAG_NEWSUB ( 1 ) , NUTAG_SUBSTATE ( nua_substate_active ) , SIPTAG_EVENT_STR ( " talk " ) , TAG_END ( ) ) ;
}
}
2008-05-27 04:54:52 +00:00
state_process :
2008-11-19 19:21:54 +00:00
switch ( ( enum nua_callstate ) ss_state ) {
case nua_callstate_terminated :
case nua_callstate_terminating :
case nua_callstate_ready :
case nua_callstate_completed :
case nua_callstate_received :
2008-12-03 19:55:05 +00:00
case nua_callstate_proceeding :
2009-12-11 00:28:54 +00:00
case nua_callstate_completing :
2010-02-06 03:38:24 +00:00
if ( ! ( session & & channel & & tech_pvt ) )
goto done ;
2008-11-19 19:21:54 +00:00
default :
break ;
}
2007-03-31 19:01:33 +00:00
switch ( ( enum nua_callstate ) ss_state ) {
case nua_callstate_init :
break ;
case nua_callstate_authenticating :
break ;
case nua_callstate_calling :
break ;
case nua_callstate_proceeding :
2008-11-19 19:21:54 +00:00
if ( status = = 180 ) {
switch_channel_mark_ring_ready ( channel ) ;
}
2010-02-06 03:38:24 +00:00
2008-11-19 19:21:54 +00:00
if ( r_sdp ) {
if ( switch_channel_test_flag ( channel , CF_PROXY_MODE ) | | switch_channel_test_flag ( channel , CF_PROXY_MEDIA ) ) {
2009-03-17 20:56:28 +00:00
if ( switch_channel_test_flag ( channel , CF_PROXY_MEDIA ) & & ! switch_channel_test_flag ( tech_pvt - > channel , CF_OUTBOUND ) ) {
switch_channel_set_variable ( channel , SWITCH_ENDPOINT_DISPOSITION_VARIABLE , " PROXY MEDIA " ) ;
}
2009-02-09 17:56:38 +00:00
sofia_set_flag_locked ( tech_pvt , TFLAG_EARLY_MEDIA ) ;
2008-11-19 19:21:54 +00:00
switch_channel_mark_pre_answered ( channel ) ;
2009-02-09 17:56:38 +00:00
sofia_set_flag ( tech_pvt , TFLAG_SDP ) ;
2008-11-19 19:21:54 +00:00
if ( switch_channel_test_flag ( channel , CF_PROXY_MEDIA ) ) {
if ( sofia_glue_activate_rtp ( tech_pvt , 0 ) ! = SWITCH_STATUS_SUCCESS ) {
goto done ;
2008-02-21 17:48:41 +00:00
}
2008-11-19 19:21:54 +00:00
}
2009-10-12 22:23:55 +00:00
if ( ( uuid = switch_channel_get_variable ( channel , SWITCH_SIGNAL_BOND_VARIABLE ) )
2008-11-19 19:21:54 +00:00
& & ( other_session = switch_core_session_locate ( uuid ) ) ) {
other_channel = switch_core_session_get_channel ( other_session ) ;
if ( ! switch_channel_get_variable ( other_channel , SWITCH_B_SDP_VARIABLE ) ) {
switch_channel_set_variable ( other_channel , SWITCH_B_SDP_VARIABLE , r_sdp ) ;
2007-03-31 19:01:33 +00:00
}
2008-11-19 19:21:54 +00:00
switch_channel_pre_answer ( other_channel ) ;
switch_core_session_rwunlock ( other_session ) ;
}
goto done ;
} else {
2009-03-17 20:56:28 +00:00
if ( sofia_test_flag ( tech_pvt , TFLAG_LATE_NEGOTIATION ) & & ! switch_channel_test_flag ( tech_pvt - > channel , CF_OUTBOUND ) ) {
2008-11-19 19:21:54 +00:00
switch_channel_set_variable ( channel , SWITCH_ENDPOINT_DISPOSITION_VARIABLE , " DELAYED NEGOTIATION " ) ;
2007-03-31 19:01:33 +00:00
} else {
2008-11-19 19:21:54 +00:00
if ( sofia_glue_tech_media ( tech_pvt , ( char * ) r_sdp ) ! = SWITCH_STATUS_SUCCESS ) {
switch_channel_set_variable ( channel , SWITCH_ENDPOINT_DISPOSITION_VARIABLE , " CODEC NEGOTIATION ERROR " ) ;
nua_respond ( nh , SIP_488_NOT_ACCEPTABLE , TAG_END ( ) ) ;
switch_channel_hangup ( channel , SWITCH_CAUSE_INCOMPATIBLE_DESTINATION ) ;
2007-03-31 19:01:33 +00:00
}
}
2008-11-19 19:21:54 +00:00
goto done ;
2007-03-31 19:01:33 +00:00
}
}
break ;
case nua_callstate_completing :
2010-02-06 03:38:24 +00:00
nua_ack ( nh , TAG_IF ( ! zstr ( tech_pvt - > user_via ) , SIPTAG_VIA_STR ( tech_pvt - > user_via ) ) , TAG_END ( ) ) ;
2009-12-11 00:28:54 +00:00
goto done ;
2007-03-31 19:01:33 +00:00
case nua_callstate_received :
2009-02-09 17:56:38 +00:00
if ( ! sofia_test_flag ( tech_pvt , TFLAG_SDP ) ) {
if ( r_sdp & & ! sofia_test_flag ( tech_pvt , TFLAG_SDP ) ) {
2008-02-21 17:48:41 +00:00
if ( switch_channel_test_flag ( channel , CF_PROXY_MODE ) ) {
2007-03-31 19:01:33 +00:00
switch_channel_set_variable ( channel , SWITCH_ENDPOINT_DISPOSITION_VARIABLE , " RECEIVED_NOMEDIA " ) ;
2009-02-09 17:56:38 +00:00
sofia_set_flag_locked ( tech_pvt , TFLAG_READY ) ;
2008-01-26 01:53:42 +00:00
if ( switch_channel_get_state ( channel ) = = CS_NEW ) {
switch_channel_set_state ( channel , CS_INIT ) ;
}
2009-02-09 17:56:38 +00:00
sofia_set_flag ( tech_pvt , TFLAG_SDP ) ;
2007-03-31 19:01:33 +00:00
goto done ;
2008-02-21 17:48:41 +00:00
} else if ( switch_channel_test_flag ( tech_pvt - > channel , CF_PROXY_MEDIA ) ) {
2008-05-27 04:54:52 +00:00
switch_channel_set_variable ( channel , SWITCH_ENDPOINT_DISPOSITION_VARIABLE , " PROXY MEDIA " ) ;
2009-02-09 17:56:38 +00:00
sofia_set_flag_locked ( tech_pvt , TFLAG_READY ) ;
2008-05-27 04:54:52 +00:00
if ( switch_channel_get_state ( channel ) = = CS_NEW ) {
switch_channel_set_state ( channel , CS_INIT ) ;
}
2009-02-09 17:56:38 +00:00
} else if ( sofia_test_flag ( tech_pvt , TFLAG_LATE_NEGOTIATION ) ) {
2008-05-27 04:54:52 +00:00
switch_channel_set_variable ( channel , SWITCH_ENDPOINT_DISPOSITION_VARIABLE , " DELAYED NEGOTIATION " ) ;
2009-02-09 17:56:38 +00:00
sofia_set_flag_locked ( tech_pvt , TFLAG_READY ) ;
2008-05-27 04:54:52 +00:00
if ( switch_channel_get_state ( channel ) = = CS_NEW ) {
switch_channel_set_state ( channel , CS_INIT ) ;
}
} else {
2007-04-17 06:08:39 +00:00
sdp_parser_t * parser ;
2007-03-31 19:01:33 +00:00
sdp_session_t * sdp ;
uint8_t match = 0 ;
if ( tech_pvt - > num_codecs ) {
2007-04-17 06:08:39 +00:00
if ( ( parser = sdp_parse ( NULL , r_sdp , ( int ) strlen ( r_sdp ) , 0 ) ) ) {
if ( ( sdp = sdp_session ( parser ) ) ) {
match = sofia_glue_negotiate_sdp ( session , sdp ) ;
}
sdp_parser_free ( parser ) ;
2007-03-31 19:01:33 +00:00
}
}
2008-05-27 04:54:52 +00:00
2007-03-31 19:01:33 +00:00
if ( match ) {
nua_handle_t * bnh ;
sip_replaces_t * replaces ;
2007-09-29 01:06:08 +00:00
su_home_t * home = NULL ;
2007-03-31 19:01:33 +00:00
switch_channel_set_variable ( channel , SWITCH_ENDPOINT_DISPOSITION_VARIABLE , " RECEIVED " ) ;
2009-02-09 17:56:38 +00:00
sofia_set_flag_locked ( tech_pvt , TFLAG_READY ) ;
2008-01-26 01:53:42 +00:00
if ( switch_channel_get_state ( channel ) = = CS_NEW ) {
switch_channel_set_state ( channel , CS_INIT ) ;
}
2009-02-09 17:56:38 +00:00
sofia_set_flag ( tech_pvt , TFLAG_SDP ) ;
2007-09-29 01:06:08 +00:00
if ( replaces_str ) {
home = su_home_new ( sizeof ( * home ) ) ;
2007-12-12 23:21:45 +00:00
switch_assert ( home ! = NULL ) ;
2007-09-29 01:06:08 +00:00
if ( ( replaces = sip_replaces_make ( home , replaces_str ) )
& & ( bnh = nua_handle_by_replaces ( nua , replaces ) ) ) {
sofia_private_t * b_private ;
2007-03-31 19:01:33 +00:00
2009-08-13 20:35:02 +00:00
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( session ) , SWITCH_LOG_DEBUG , " Processing Replaces Attended Transfer \n " ) ;
2007-09-29 01:06:08 +00:00
while ( switch_channel_get_state ( channel ) < CS_EXECUTE ) {
switch_yield ( 10000 ) ;
}
2008-05-27 04:54:52 +00:00
2007-09-29 01:06:08 +00:00
if ( ( b_private = nua_handle_magic ( bnh ) ) ) {
2007-11-01 11:28:26 +00:00
const char * br_b = switch_channel_get_variable ( channel , SWITCH_SIGNAL_BOND_VARIABLE ) ;
2007-09-29 01:06:08 +00:00
char * br_a = b_private - > uuid ;
2008-05-27 04:54:52 +00:00
2007-09-29 01:06:08 +00:00
if ( br_b ) {
switch_ivr_uuid_bridge ( br_a , br_b ) ;
switch_channel_set_variable ( channel , SWITCH_ENDPOINT_DISPOSITION_VARIABLE , " ATTENDED_TRANSFER " ) ;
2009-02-09 17:56:38 +00:00
sofia_clear_flag_locked ( tech_pvt , TFLAG_SIP_HOLD ) ;
2009-11-24 18:18:09 +00:00
switch_channel_clear_flag ( channel , CF_LEG_HOLDING ) ;
2009-02-09 17:56:38 +00:00
sofia_clear_flag_locked ( tech_pvt , TFLAG_HOLD_LOCK ) ;
2007-09-29 01:06:08 +00:00
switch_channel_hangup ( channel , SWITCH_CAUSE_ATTENDED_TRANSFER ) ;
} else {
switch_channel_set_variable ( channel , SWITCH_ENDPOINT_DISPOSITION_VARIABLE , " ATTENDED_TRANSFER_ERROR " ) ;
switch_channel_hangup ( channel , SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER ) ;
}
2007-03-31 19:01:33 +00:00
} else {
switch_channel_set_variable ( channel , SWITCH_ENDPOINT_DISPOSITION_VARIABLE , " ATTENDED_TRANSFER_ERROR " ) ;
switch_channel_hangup ( channel , SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER ) ;
}
2007-09-29 01:06:08 +00:00
nua_handle_unref ( bnh ) ;
2007-03-31 19:01:33 +00:00
}
2007-09-29 01:06:08 +00:00
su_home_unref ( home ) ;
home = NULL ;
2007-03-31 19:01:33 +00:00
}
2007-09-29 01:06:08 +00:00
2007-03-31 19:01:33 +00:00
goto done ;
}
switch_channel_set_variable ( channel , SWITCH_ENDPOINT_DISPOSITION_VARIABLE , " NO CODECS " ) ;
2007-04-17 18:53:18 +00:00
switch_channel_hangup ( channel , SWITCH_CAUSE_INCOMPATIBLE_DESTINATION ) ;
2007-03-31 19:01:33 +00:00
}
} else {
2008-02-21 17:48:41 +00:00
if ( switch_channel_test_flag ( channel , CF_PROXY_MODE ) | | switch_channel_test_flag ( channel , CF_PROXY_MEDIA ) ) {
2007-04-05 17:52:35 +00:00
goto done ;
} else {
2009-02-09 17:56:38 +00:00
if ( sofia_test_pflag ( profile , PFLAG_3PCC ) ) {
2008-05-29 20:02:06 +00:00
switch_channel_set_variable ( channel , SWITCH_ENDPOINT_DISPOSITION_VARIABLE , " RECEIVED_NOSDP " ) ;
sofia_glue_tech_choose_port ( tech_pvt , 0 ) ;
sofia_glue_set_local_sdp ( tech_pvt , NULL , 0 , NULL , 0 ) ;
2009-02-09 17:56:38 +00:00
sofia_set_flag_locked ( tech_pvt , TFLAG_3PCC ) ;
2008-05-29 20:02:06 +00:00
switch_channel_set_state ( channel , CS_HIBERNATE ) ;
2009-12-19 17:43:05 +00:00
if ( sofia_use_soa ( tech_pvt ) ) {
nua_respond ( tech_pvt - > nh , SIP_200_OK ,
SIPTAG_CONTACT_STR ( tech_pvt - > profile - > url ) ,
SOATAG_USER_SDP_STR ( tech_pvt - > local_sdp_str ) ,
SOATAG_REUSE_REJECTED ( 1 ) ,
2010-02-06 03:38:24 +00:00
SOATAG_ORDERED_USER ( 1 ) , SOATAG_AUDIO_AUX ( " cn telephone-event " ) ,
2009-12-19 17:43:05 +00:00
TAG_IF ( sofia_test_pflag ( profile , PFLAG_DISABLE_100REL ) , NUTAG_INCLUDE_EXTRA_SDP ( 1 ) ) , TAG_END ( ) ) ;
} else {
nua_respond ( tech_pvt - > nh , SIP_200_OK ,
NUTAG_MEDIA_ENABLE ( 0 ) ,
SIPTAG_CONTACT_STR ( tech_pvt - > profile - > url ) ,
2010-02-06 03:38:24 +00:00
SIPTAG_CONTENT_TYPE_STR ( " application/sdp " ) , SIPTAG_PAYLOAD_STR ( tech_pvt - > local_sdp_str ) , TAG_END ( ) ) ;
2009-12-19 17:43:05 +00:00
}
2009-02-09 17:56:38 +00:00
} else if ( sofia_test_pflag ( profile , PFLAG_3PCC_PROXY ) ) {
2008-10-10 16:15:45 +00:00
//3PCC proxy mode delays the 200 OK until the call is answered
switch_channel_set_variable ( channel , SWITCH_ENDPOINT_DISPOSITION_VARIABLE , " RECEIVED_NOSDP " ) ;
2009-02-09 17:56:38 +00:00
sofia_set_flag_locked ( tech_pvt , TFLAG_3PCC ) ;
2009-10-26 17:03:05 +00:00
//sofia_glue_tech_choose_port(tech_pvt, 0);
//sofia_glue_set_local_sdp(tech_pvt, NULL, 0, NULL, 0);
2008-10-10 16:15:45 +00:00
switch_channel_set_flag ( channel , TFLAG_LATE_NEGOTIATION ) ;
//Moves into CS_INIT so call moves forward into the dialplan
switch_channel_set_state ( channel , CS_INIT ) ;
2008-05-29 20:02:06 +00:00
} else {
2009-10-12 19:09:34 +00:00
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( session ) , SWITCH_LOG_INFO , " No SDP in INVITE and 3pcc not enabled, hanging up. \n " ) ;
2008-05-29 20:02:06 +00:00
switch_channel_set_variable ( channel , SWITCH_ENDPOINT_DISPOSITION_VARIABLE , " 3PCC DISABLED " ) ;
switch_channel_hangup ( channel , SWITCH_CAUSE_MANDATORY_IE_MISSING ) ;
}
2007-04-05 17:52:35 +00:00
goto done ;
}
2007-03-31 19:01:33 +00:00
}
2008-01-03 00:50:53 +00:00
2009-02-09 17:56:38 +00:00
} else if ( tech_pvt & & sofia_test_flag ( tech_pvt , TFLAG_SDP ) & & ! r_sdp ) {
2008-11-16 18:45:21 +00:00
nua_respond ( tech_pvt - > nh , SIP_200_OK , TAG_END ( ) ) ;
2009-02-09 17:56:38 +00:00
sofia_set_flag_locked ( tech_pvt , TFLAG_NOSDP_REINVITE ) ;
2008-11-03 19:56:48 +00:00
goto done ;
2008-01-03 00:50:53 +00:00
} else {
ss_state = nua_callstate_completed ;
goto state_process ;
2007-03-31 19:01:33 +00:00
}
break ;
case nua_callstate_early :
break ;
case nua_callstate_completed :
2008-11-19 19:21:54 +00:00
if ( r_sdp ) {
2008-05-27 04:54:52 +00:00
sdp_parser_t * parser ;
2007-05-09 19:30:41 +00:00
sdp_session_t * sdp ;
2009-10-21 19:58:11 +00:00
uint8_t match = 0 , is_ok = 1 , is_t38 = 0 ;
2008-09-18 21:50:18 +00:00
tech_pvt - > hold_laps = 0 ;
2007-05-09 19:30:41 +00:00
2008-05-27 04:54:52 +00:00
if ( r_sdp ) {
2008-09-23 23:43:40 +00:00
const char * var ;
2010-02-06 03:38:24 +00:00
2008-09-23 23:43:40 +00:00
if ( ( var = switch_channel_get_variable ( channel , " sip_ignore_reinvites " ) ) & & switch_true ( var ) ) {
2009-08-13 20:35:02 +00:00
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( session ) , SWITCH_LOG_DEBUG , " Ignoring Re-invite \n " ) ;
2008-09-23 23:43:40 +00:00
nua_respond ( tech_pvt - > nh , SIP_200_OK , TAG_END ( ) ) ;
goto done ;
}
2009-10-21 19:58:11 +00:00
if ( switch_stristr ( " m=image " , r_sdp ) ) {
is_t38 = 1 ;
}
2008-02-21 17:48:41 +00:00
if ( switch_channel_test_flag ( channel , CF_PROXY_MODE ) | | switch_channel_test_flag ( channel , CF_PROXY_MEDIA ) ) {
2007-09-19 18:24:47 +00:00
if ( ( uuid = switch_channel_get_variable ( channel , SWITCH_SIGNAL_BOND_VARIABLE ) )
& & ( other_session = switch_core_session_locate ( uuid ) ) ) {
2009-10-12 22:23:55 +00:00
switch_core_session_message_t * msg ;
2010-02-06 03:38:24 +00:00
2009-10-21 19:58:11 +00:00
if ( switch_channel_test_flag ( channel , CF_PROXY_MODE ) & & ! is_t38 & & profile - > media_options & MEDIA_OPT_MEDIA_ON_HOLD ) {
2008-09-18 21:50:18 +00:00
tech_pvt - > hold_laps = 1 ;
switch_channel_set_variable ( channel , SWITCH_R_SDP_VARIABLE , r_sdp ) ;
switch_channel_clear_flag ( channel , CF_PROXY_MODE ) ;
2009-03-20 01:52:53 +00:00
sofia_glue_tech_set_local_sdp ( tech_pvt , NULL , SWITCH_FALSE ) ;
2010-02-06 03:38:24 +00:00
2008-09-18 21:50:18 +00:00
if ( ! switch_channel_media_ready ( channel ) ) {
if ( ! switch_channel_test_flag ( tech_pvt - > channel , CF_OUTBOUND ) ) {
//const char *r_sdp = switch_channel_get_variable(channel, SWITCH_R_SDP_VARIABLE);
tech_pvt - > num_codecs = 0 ;
sofia_glue_tech_prepare_codecs ( tech_pvt ) ;
if ( sofia_glue_tech_media ( tech_pvt , r_sdp ) ! = SWITCH_STATUS_SUCCESS ) {
switch_channel_set_variable ( channel , SWITCH_ENDPOINT_DISPOSITION_VARIABLE , " CODEC NEGOTIATION ERROR " ) ;
status = SWITCH_STATUS_FALSE ;
2010-01-22 00:51:32 +00:00
switch_core_session_rwunlock ( other_session ) ;
2008-09-18 21:50:18 +00:00
goto done ;
}
}
}
if ( ! switch_rtp_ready ( tech_pvt - > rtp_session ) ) {
sofia_glue_tech_prepare_codecs ( tech_pvt ) ;
if ( ( status = sofia_glue_tech_choose_port ( tech_pvt , 0 ) ) ! = SWITCH_STATUS_SUCCESS ) {
switch_channel_hangup ( channel , SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER ) ;
2010-01-22 00:51:32 +00:00
switch_core_session_rwunlock ( other_session ) ;
2008-09-18 21:50:18 +00:00
goto done ;
}
}
sofia_glue_set_local_sdp ( tech_pvt , NULL , 0 , NULL , 1 ) ;
2010-02-06 03:38:24 +00:00
2009-12-19 17:43:05 +00:00
if ( sofia_use_soa ( tech_pvt ) ) {
nua_respond ( tech_pvt - > nh , SIP_200_OK ,
SIPTAG_CONTACT_STR ( tech_pvt - > reply_contact ) ,
SOATAG_USER_SDP_STR ( tech_pvt - > local_sdp_str ) ,
SOATAG_REUSE_REJECTED ( 1 ) ,
2010-02-06 03:38:24 +00:00
SOATAG_ORDERED_USER ( 1 ) , SOATAG_AUDIO_AUX ( " cn telephone-event " ) ,
2009-12-19 17:43:05 +00:00
TAG_IF ( sofia_test_pflag ( profile , PFLAG_DISABLE_100REL ) , NUTAG_INCLUDE_EXTRA_SDP ( 1 ) ) , TAG_END ( ) ) ;
} else {
nua_respond ( tech_pvt - > nh , SIP_200_OK ,
NUTAG_MEDIA_ENABLE ( 0 ) ,
SIPTAG_CONTACT_STR ( tech_pvt - > reply_contact ) ,
2010-02-06 03:38:24 +00:00
SIPTAG_CONTENT_TYPE_STR ( " application/sdp " ) , SIPTAG_PAYLOAD_STR ( tech_pvt - > local_sdp_str ) , TAG_END ( ) ) ;
2009-12-19 17:43:05 +00:00
}
2008-09-18 21:50:18 +00:00
launch_media_on_hold ( session ) ;
2010-02-06 03:38:24 +00:00
2008-09-18 21:50:18 +00:00
switch_core_session_rwunlock ( other_session ) ;
goto done ;
}
2010-02-06 03:38:24 +00:00
2009-10-12 22:23:55 +00:00
msg = switch_core_session_alloc ( other_session , sizeof ( * msg ) ) ;
msg - > message_id = SWITCH_MESSAGE_INDICATE_MEDIA_REDIRECT ;
msg - > from = __FILE__ ;
msg - > string_arg = switch_core_session_strdup ( other_session , r_sdp ) ;
2009-08-13 20:35:02 +00:00
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( session ) , SWITCH_LOG_DEBUG , " Passing SDP to other leg. \n %s \n " , r_sdp ) ;
2010-02-06 03:38:24 +00:00
2009-02-09 17:56:38 +00:00
if ( sofia_test_flag ( tech_pvt , TFLAG_SIP_HOLD ) ) {
2008-05-29 20:25:58 +00:00
if ( ! switch_stristr ( " sendonly " , r_sdp ) ) {
2009-02-09 17:56:38 +00:00
sofia_clear_flag_locked ( tech_pvt , TFLAG_SIP_HOLD ) ;
2009-11-24 18:18:09 +00:00
switch_channel_clear_flag ( channel , CF_LEG_HOLDING ) ;
2008-08-25 16:30:28 +00:00
switch_channel_presence ( tech_pvt - > channel , " unknown " , " unhold " , NULL ) ;
2008-05-29 20:25:58 +00:00
}
} else if ( switch_stristr ( " sendonly " , r_sdp ) ) {
2010-01-13 01:40:11 +00:00
const char * msg = " hold " ;
2010-02-06 03:38:24 +00:00
2010-01-13 01:40:11 +00:00
if ( sofia_test_pflag ( profile , PFLAG_MANAGE_SHARED_APPEARANCE ) ) {
const char * info = switch_channel_get_variable ( channel , " presence_call_info " ) ;
if ( info ) {
if ( switch_stristr ( " private " , info ) ) {
msg = " hold-private " ;
}
}
}
2009-02-09 17:56:38 +00:00
sofia_set_flag_locked ( tech_pvt , TFLAG_SIP_HOLD ) ;
2009-11-24 18:18:09 +00:00
switch_channel_set_flag ( channel , CF_LEG_HOLDING ) ;
2010-01-13 01:40:11 +00:00
switch_channel_presence ( tech_pvt - > channel , " unknown " , msg , NULL ) ;
2008-05-29 20:25:58 +00:00
}
2010-02-06 03:38:24 +00:00
2009-10-12 22:23:55 +00:00
switch_core_session_queue_message ( other_session , msg ) ;
2008-05-29 20:25:58 +00:00
2007-09-19 18:24:47 +00:00
switch_core_session_rwunlock ( other_session ) ;
} else {
2010-02-06 03:38:24 +00:00
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( session ) , SWITCH_LOG_WARNING ,
2009-10-12 22:23:55 +00:00
" Re-INVITE to a no-media channel that is not in a bridge. \n " ) ;
2008-09-05 20:34:18 +00:00
is_ok = 0 ;
2008-03-07 00:34:26 +00:00
switch_channel_hangup ( channel , SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER ) ;
2007-09-19 18:24:47 +00:00
}
2007-03-31 19:01:33 +00:00
goto done ;
} else {
2009-10-21 23:01:37 +00:00
sofia_set_flag_locked ( tech_pvt , TFLAG_REINVITE ) ;
2010-02-06 03:38:24 +00:00
2007-03-31 19:01:33 +00:00
if ( tech_pvt - > num_codecs ) {
2007-04-17 06:08:39 +00:00
if ( ( parser = sdp_parse ( NULL , r_sdp , ( int ) strlen ( r_sdp ) , 0 ) ) ) {
if ( ( sdp = sdp_session ( parser ) ) ) {
match = sofia_glue_negotiate_sdp ( session , sdp ) ;
}
sdp_parser_free ( parser ) ;
2007-03-31 19:01:33 +00:00
}
}
if ( match ) {
2008-02-21 17:48:41 +00:00
if ( sofia_glue_tech_choose_port ( tech_pvt , 0 ) ! = SWITCH_STATUS_SUCCESS ) {
2007-03-31 19:01:33 +00:00
goto done ;
}
sofia_glue_set_local_sdp ( tech_pvt , NULL , 0 , NULL , 0 ) ;
2010-02-06 03:38:24 +00:00
2007-10-25 18:36:40 +00:00
if ( sofia_glue_activate_rtp ( tech_pvt , 0 ) ! = SWITCH_STATUS_SUCCESS ) {
2009-08-13 20:35:02 +00:00
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( session ) , SWITCH_LOG_ERROR , " Reinvite RTP Error! \n " ) ;
2008-09-05 20:34:18 +00:00
is_ok = 0 ;
2007-04-17 06:08:39 +00:00
switch_channel_hangup ( channel , SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER ) ;
2007-03-31 19:01:33 +00:00
}
2009-10-21 23:01:37 +00:00
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( session ) , SWITCH_LOG_DEBUG , " Processing updated SDP \n " ) ;
2007-04-17 06:08:39 +00:00
} else {
2009-10-21 23:01:37 +00:00
sofia_clear_flag_locked ( tech_pvt , TFLAG_REINVITE ) ;
2009-08-13 20:35:02 +00:00
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( session ) , SWITCH_LOG_ERROR , " Reinvite Codec Error! \n " ) ;
2008-09-05 20:34:18 +00:00
is_ok = 0 ;
2007-03-31 19:01:33 +00:00
}
}
2010-02-06 03:38:24 +00:00
2008-09-05 20:34:18 +00:00
if ( is_ok ) {
2009-05-14 00:15:06 +00:00
if ( tech_pvt - > local_crypto_key ) {
sofia_glue_set_local_sdp ( tech_pvt , NULL , 0 , NULL , 0 ) ;
}
2009-12-19 17:43:05 +00:00
if ( sofia_use_soa ( tech_pvt ) ) {
nua_respond ( tech_pvt - > nh , SIP_200_OK ,
SIPTAG_CONTACT_STR ( tech_pvt - > reply_contact ) ,
SOATAG_USER_SDP_STR ( tech_pvt - > local_sdp_str ) ,
SOATAG_REUSE_REJECTED ( 1 ) ,
2010-02-06 03:38:24 +00:00
SOATAG_ORDERED_USER ( 1 ) , SOATAG_AUDIO_AUX ( " cn telephone-event " ) ,
2009-12-19 17:43:05 +00:00
TAG_IF ( sofia_test_pflag ( profile , PFLAG_DISABLE_100REL ) , NUTAG_INCLUDE_EXTRA_SDP ( 1 ) ) , TAG_END ( ) ) ;
} else {
nua_respond ( tech_pvt - > nh , SIP_200_OK ,
NUTAG_MEDIA_ENABLE ( 0 ) ,
SIPTAG_CONTACT_STR ( tech_pvt - > reply_contact ) ,
2010-02-06 03:38:24 +00:00
SIPTAG_CONTENT_TYPE_STR ( " application/sdp " ) , SIPTAG_PAYLOAD_STR ( tech_pvt - > local_sdp_str ) , TAG_END ( ) ) ;
2009-12-19 17:43:05 +00:00
}
2009-10-23 13:27:00 +00:00
if ( switch_event_create_subclass ( & s_event , SWITCH_EVENT_CUSTOM , MY_EVENT_REINVITE ) = = SWITCH_STATUS_SUCCESS ) {
switch_event_add_header_string ( s_event , SWITCH_STACK_BOTTOM , " Unique-ID " , switch_core_session_get_uuid ( session ) ) ;
switch_event_fire ( & s_event ) ;
}
2008-09-05 20:34:18 +00:00
} else {
nua_respond ( tech_pvt - > nh , SIP_488_NOT_ACCEPTABLE , TAG_END ( ) ) ;
}
2007-03-31 19:01:33 +00:00
}
}
break ;
case nua_callstate_ready :
2009-10-21 23:01:37 +00:00
if ( r_sdp & & ! is_dup_sdp & & switch_rtp_ready ( tech_pvt - > rtp_session ) ) {
2009-10-27 20:52:12 +00:00
/* sdp changed since 18X w sdp, we're supposed to ignore it but we, of course, were pressured into supporting it */
sdp_parser_t * parser ;
sdp_session_t * sdp ;
uint8_t match = 0 ;
sofia_set_flag_locked ( tech_pvt , TFLAG_REINVITE ) ;
2010-02-06 03:38:24 +00:00
2009-10-27 20:52:12 +00:00
if ( tech_pvt - > num_codecs ) {
if ( ( parser = sdp_parse ( NULL , r_sdp , ( int ) strlen ( r_sdp ) , 0 ) ) ) {
if ( ( sdp = sdp_session ( parser ) ) ) {
match = sofia_glue_negotiate_sdp ( session , sdp ) ;
}
sdp_parser_free ( parser ) ;
}
}
if ( match ) {
if ( sofia_glue_tech_choose_port ( tech_pvt , 0 ) ! = SWITCH_STATUS_SUCCESS ) {
goto done ;
}
sofia_glue_set_local_sdp ( tech_pvt , NULL , 0 , NULL , 0 ) ;
2010-02-06 03:38:24 +00:00
2009-11-18 19:22:45 +00:00
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( session ) , SWITCH_LOG_DEBUG , " Processing updated SDP \n " ) ;
2009-10-27 20:52:12 +00:00
if ( sofia_glue_activate_rtp ( tech_pvt , 0 ) ! = SWITCH_STATUS_SUCCESS ) {
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( session ) , SWITCH_LOG_ERROR , " RTP Error! \n " ) ;
switch_channel_hangup ( channel , SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER ) ;
2009-11-05 17:22:15 +00:00
goto done ;
2009-10-27 20:52:12 +00:00
}
} else {
sofia_clear_flag_locked ( tech_pvt , TFLAG_REINVITE ) ;
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( session ) , SWITCH_LOG_ERROR , " Codec Error! \n " ) ;
goto done ;
}
2009-10-21 23:01:37 +00:00
}
2008-11-16 18:45:21 +00:00
2009-02-09 17:56:38 +00:00
if ( r_sdp & & sofia_test_flag ( tech_pvt , TFLAG_NOSDP_REINVITE ) ) {
2008-11-16 18:45:21 +00:00
sdp_parser_t * parser ;
sdp_session_t * sdp ;
uint8_t match = 0 ;
int is_ok = 1 ;
2009-06-09 19:05:11 +00:00
2009-02-09 17:56:38 +00:00
sofia_clear_flag_locked ( tech_pvt , TFLAG_NOSDP_REINVITE ) ;
2008-11-16 18:45:21 +00:00
if ( tech_pvt - > num_codecs ) {
if ( ( parser = sdp_parse ( NULL , r_sdp , ( int ) strlen ( r_sdp ) , 0 ) ) ) {
if ( ( sdp = sdp_session ( parser ) ) ) {
match = sofia_glue_negotiate_sdp ( session , sdp ) ;
}
sdp_parser_free ( parser ) ;
}
}
if ( match ) {
2009-02-09 17:56:38 +00:00
sofia_set_flag_locked ( tech_pvt , TFLAG_REINVITE ) ;
2008-11-16 18:45:21 +00:00
if ( sofia_glue_activate_rtp ( tech_pvt , 0 ) ! = SWITCH_STATUS_SUCCESS ) {
2009-08-13 20:35:02 +00:00
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( session ) , SWITCH_LOG_ERROR , " RTP Error! \n " ) ;
2008-11-16 18:45:21 +00:00
switch_channel_set_variable ( tech_pvt - > channel , SWITCH_ENDPOINT_DISPOSITION_VARIABLE , " RTP ERROR " ) ;
is_ok = 0 ;
}
2009-02-09 17:56:38 +00:00
sofia_clear_flag_locked ( tech_pvt , TFLAG_REINVITE ) ;
2008-11-16 18:45:21 +00:00
} else {
switch_channel_set_variable ( tech_pvt - > channel , SWITCH_ENDPOINT_DISPOSITION_VARIABLE , " CODEC NEGOTIATION ERROR " ) ;
is_ok = 0 ;
}
if ( ! is_ok ) {
nua_respond ( nh , SIP_488_NOT_ACCEPTABLE , TAG_END ( ) ) ;
switch_channel_hangup ( tech_pvt - > channel , SWITCH_CAUSE_INCOMPATIBLE_DESTINATION ) ;
}
goto done ;
}
2008-03-25 18:48:20 +00:00
if ( channel ) {
switch_channel_clear_flag ( channel , CF_REQ_MEDIA ) ;
}
2007-03-31 19:01:33 +00:00
if ( tech_pvt & & nh = = tech_pvt - > nh2 ) {
2009-08-13 20:35:02 +00:00
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( session ) , SWITCH_LOG_DEBUG , " Cheater Reinvite! \n " ) ;
2009-02-09 17:56:38 +00:00
sofia_set_flag_locked ( tech_pvt , TFLAG_REINVITE ) ;
2007-03-31 19:01:33 +00:00
tech_pvt - > nh = tech_pvt - > nh2 ;
tech_pvt - > nh2 = NULL ;
2008-02-21 17:48:41 +00:00
if ( sofia_glue_tech_choose_port ( tech_pvt , 0 ) = = SWITCH_STATUS_SUCCESS ) {
2007-10-25 18:36:40 +00:00
if ( sofia_glue_activate_rtp ( tech_pvt , 0 ) ! = SWITCH_STATUS_SUCCESS ) {
2009-08-13 20:35:02 +00:00
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( session ) , SWITCH_LOG_ERROR , " Cheater Reinvite RTP Error! \n " ) ;
2007-04-17 06:08:39 +00:00
switch_channel_hangup ( channel , SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER ) ;
}
2007-03-31 19:01:33 +00:00
}
goto done ;
}
2010-02-06 03:38:24 +00:00
2007-03-31 19:01:33 +00:00
if ( channel ) {
2010-02-06 03:38:24 +00:00
if ( sofia_test_flag ( tech_pvt , TFLAG_EARLY_MEDIA ) ) {
sofia_set_flag_locked ( tech_pvt , TFLAG_ANS ) ;
sofia_set_flag ( tech_pvt , TFLAG_SDP ) ;
switch_channel_mark_answered ( channel ) ;
2008-09-16 21:52:12 +00:00
if ( switch_channel_test_flag ( channel , CF_PROXY_MODE ) | | switch_channel_test_flag ( channel , CF_PROXY_MEDIA ) ) {
if ( ( uuid = switch_channel_get_variable ( channel , SWITCH_SIGNAL_BOND_VARIABLE ) )
& & ( other_session = switch_core_session_locate ( uuid ) ) ) {
other_channel = switch_core_session_get_channel ( other_session ) ;
switch_channel_answer ( other_channel ) ;
switch_core_session_rwunlock ( other_session ) ;
}
2007-03-31 19:01:33 +00:00
}
2010-02-06 03:38:24 +00:00
goto done ;
}
2009-02-09 17:56:38 +00:00
if ( ! r_sdp & & ! sofia_test_flag ( tech_pvt , TFLAG_SDP ) ) {
2007-03-31 19:01:33 +00:00
r_sdp = ( const char * ) switch_channel_get_variable ( channel , SWITCH_R_SDP_VARIABLE ) ;
}
2008-09-16 21:52:12 +00:00
2009-02-09 17:56:38 +00:00
if ( r_sdp & & ! sofia_test_flag ( tech_pvt , TFLAG_SDP ) ) {
2008-02-21 17:48:41 +00:00
if ( switch_channel_test_flag ( channel , CF_PROXY_MODE ) | | switch_channel_test_flag ( channel , CF_PROXY_MEDIA ) ) {
2009-02-09 17:56:38 +00:00
sofia_set_flag_locked ( tech_pvt , TFLAG_ANS ) ;
sofia_set_flag_locked ( tech_pvt , TFLAG_SDP ) ;
2007-03-31 19:01:33 +00:00
switch_channel_mark_answered ( channel ) ;
2008-02-21 17:48:41 +00:00
if ( switch_channel_test_flag ( channel , CF_PROXY_MEDIA ) ) {
if ( sofia_glue_activate_rtp ( tech_pvt , 0 ) ! = SWITCH_STATUS_SUCCESS ) {
goto done ;
}
}
2008-05-24 01:27:19 +00:00
2007-03-31 19:01:33 +00:00
if ( ( uuid = switch_channel_get_variable ( channel , SWITCH_SIGNAL_BOND_VARIABLE ) )
& & ( other_session = switch_core_session_locate ( uuid ) ) ) {
other_channel = switch_core_session_get_channel ( other_session ) ;
if ( ! switch_channel_get_variable ( other_channel , SWITCH_B_SDP_VARIABLE ) ) {
switch_channel_set_variable ( other_channel , SWITCH_B_SDP_VARIABLE , r_sdp ) ;
}
switch_channel_answer ( other_channel ) ;
switch_core_session_rwunlock ( other_session ) ;
}
goto done ;
} else {
2007-04-17 06:08:39 +00:00
sdp_parser_t * parser ;
2007-03-31 19:01:33 +00:00
sdp_session_t * sdp ;
uint8_t match = 0 ;
if ( tech_pvt - > num_codecs ) {
2007-04-17 06:08:39 +00:00
if ( ( parser = sdp_parse ( NULL , r_sdp , ( int ) strlen ( r_sdp ) , 0 ) ) ) {
if ( ( sdp = sdp_session ( parser ) ) ) {
match = sofia_glue_negotiate_sdp ( session , sdp ) ;
}
sdp_parser_free ( parser ) ;
2007-03-31 19:01:33 +00:00
}
}
2009-12-07 03:32:56 +00:00
sofia_set_flag_locked ( tech_pvt , TFLAG_ANS ) ;
2007-03-31 19:01:33 +00:00
if ( match ) {
2008-02-21 17:48:41 +00:00
if ( sofia_glue_tech_choose_port ( tech_pvt , 0 ) = = SWITCH_STATUS_SUCCESS ) {
2007-10-25 18:36:40 +00:00
if ( sofia_glue_activate_rtp ( tech_pvt , 0 ) = = SWITCH_STATUS_SUCCESS ) {
2007-04-17 06:08:39 +00:00
switch_channel_mark_answered ( channel ) ;
} else {
2009-08-13 20:35:02 +00:00
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( session ) , SWITCH_LOG_ERROR , " RTP Error! \n " ) ;
2007-04-17 06:08:39 +00:00
switch_channel_hangup ( channel , SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER ) ;
}
2008-10-10 16:15:45 +00:00
2009-02-09 17:56:38 +00:00
if ( sofia_test_flag ( tech_pvt , TFLAG_3PCC ) ) {
2008-10-10 16:15:45 +00:00
/* Check if we are in 3PCC proxy mode, if so then set the flag to indicate we received the ack */
2010-02-06 03:38:24 +00:00
if ( sofia_test_pflag ( profile , PFLAG_3PCC_PROXY ) ) {
2009-08-13 20:35:02 +00:00
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( session ) , SWITCH_LOG_DEBUG , " 3PCC-PROXY, Got my ACK \n " ) ;
2009-02-09 17:56:38 +00:00
sofia_set_flag ( tech_pvt , TFLAG_3PCC_HAS_ACK ) ;
2008-10-10 16:15:45 +00:00
} else if ( switch_channel_get_state ( channel ) = = CS_HIBERNATE ) {
2009-02-09 17:56:38 +00:00
sofia_set_flag_locked ( tech_pvt , TFLAG_READY ) ;
2008-10-10 16:15:45 +00:00
switch_channel_set_state ( channel , CS_INIT ) ;
2009-02-09 17:56:38 +00:00
sofia_set_flag ( tech_pvt , TFLAG_SDP ) ;
2008-10-10 16:15:45 +00:00
}
2007-10-05 15:47:48 +00:00
}
2007-03-31 19:01:33 +00:00
goto done ;
}
}
switch_channel_set_variable ( channel , SWITCH_ENDPOINT_DISPOSITION_VARIABLE , " NO CODECS " ) ;
2007-04-17 18:53:18 +00:00
switch_channel_hangup ( channel , SWITCH_CAUSE_INCOMPATIBLE_DESTINATION ) ;
2007-03-31 19:01:33 +00:00
}
}
}
break ;
case nua_callstate_terminating :
2008-11-19 19:21:54 +00:00
if ( status = = 488 | | switch_channel_get_state ( channel ) = = CS_HIBERNATE ) {
tech_pvt - > q850_cause = SWITCH_CAUSE_MANDATORY_IE_MISSING ;
2008-03-08 02:11:21 +00:00
}
2007-03-31 19:01:33 +00:00
case nua_callstate_terminated :
2009-03-20 17:03:46 +00:00
sofia_set_flag_locked ( tech_pvt , TFLAG_BYE ) ;
2009-03-20 01:52:53 +00:00
if ( sofia_test_flag ( tech_pvt , TFLAG_NOHUP ) ) {
sofia_clear_flag_locked ( tech_pvt , TFLAG_NOHUP ) ;
} else if ( switch_channel_up ( channel ) ) {
int cause ;
if ( tech_pvt - > q850_cause ) {
cause = tech_pvt - > q850_cause ;
2008-11-19 19:21:54 +00:00
} else {
2009-03-20 01:52:53 +00:00
cause = sofia_glue_sip_cause_to_freeswitch ( status ) ;
}
if ( status ) {
switch_snprintf ( st , sizeof ( st ) , " %d " , status ) ;
switch_channel_set_variable ( channel , " sip_term_status " , st ) ;
switch_snprintf ( st , sizeof ( st ) , " sip:%d " , status ) ;
switch_channel_set_variable_partner ( channel , SWITCH_PROTO_SPECIFIC_HANGUP_CAUSE_VARIABLE , st ) ;
switch_channel_set_variable ( channel , SWITCH_PROTO_SPECIFIC_HANGUP_CAUSE_VARIABLE , st ) ;
if ( phrase ) {
switch_channel_set_variable_partner ( channel , " sip_hangup_phrase " , phrase ) ;
2007-03-31 19:01:33 +00:00
}
2009-08-11 00:54:39 +00:00
sofia_glue_set_extra_headers ( channel , sip , SOFIA_SIP_BYE_HEADER_PREFIX ) ;
2007-03-31 19:01:33 +00:00
}
2009-03-20 01:52:53 +00:00
switch_snprintf ( st , sizeof ( st ) , " %d " , cause ) ;
switch_channel_set_variable ( channel , " sip_term_cause " , st ) ;
switch_channel_hangup ( channel , cause ) ;
2008-11-19 19:21:54 +00:00
}
2010-02-06 03:38:24 +00:00
2009-03-20 01:52:53 +00:00
2009-03-03 20:16:05 +00:00
if ( ss_state = = nua_callstate_terminated ) {
if ( tech_pvt - > sofia_private ) {
tech_pvt - > sofia_private = NULL ;
}
2010-02-06 03:38:24 +00:00
2009-03-03 20:16:05 +00:00
tech_pvt - > nh = NULL ;
2010-02-06 03:38:24 +00:00
2009-03-03 20:16:05 +00:00
if ( nh ) {
nua_handle_bind ( nh , NULL ) ;
nua_handle_destroy ( nh ) ;
}
2007-03-31 19:01:33 +00:00
}
2010-02-06 03:38:24 +00:00
2007-03-31 19:01:33 +00:00
break ;
}
done :
2007-04-17 06:08:39 +00:00
return ;
2007-03-31 19:01:33 +00:00
}
2008-09-11 23:40:57 +00:00
typedef struct {
char * exten ;
2010-02-03 19:14:12 +00:00
char * exten_with_params ;
2008-09-11 23:40:57 +00:00
char * event ;
char * reply_uuid ;
char * bridge_to_uuid ;
2009-11-15 04:13:39 +00:00
switch_event_t * vars ;
2008-09-11 23:40:57 +00:00
switch_memory_pool_t * pool ;
} nightmare_xfer_helper_t ;
void * SWITCH_THREAD_FUNC nightmare_xfer_thread_run ( switch_thread_t * thread , void * obj )
{
nightmare_xfer_helper_t * nhelper = ( nightmare_xfer_helper_t * ) obj ;
switch_memory_pool_t * pool ;
2009-11-25 00:03:00 +00:00
switch_status_t status = SWITCH_STATUS_FALSE ;
2008-09-11 23:40:57 +00:00
switch_core_session_t * session , * a_session ;
2010-02-06 03:38:24 +00:00
2008-09-11 23:40:57 +00:00
if ( ( a_session = switch_core_session_locate ( nhelper - > bridge_to_uuid ) ) ) {
2009-11-25 00:03:00 +00:00
switch_core_session_t * tsession = NULL ;
2008-09-11 23:40:57 +00:00
switch_call_cause_t cause = SWITCH_CAUSE_NORMAL_CLEARING ;
uint32_t timeout = 60 ;
char * tuuid_str ;
if ( ( session = switch_core_session_locate ( nhelper - > reply_uuid ) ) ) {
private_object_t * tech_pvt = switch_core_session_get_private ( session ) ;
switch_channel_t * channel_a = switch_core_session_get_channel ( session ) ;
2010-02-03 19:14:12 +00:00
if ( ( status = switch_ivr_originate ( NULL , & tsession , & cause , nhelper - > exten_with_params , timeout , NULL , NULL , NULL ,
2010-02-06 03:38:24 +00:00
switch_channel_get_caller_profile ( channel_a ) , nhelper - > vars , SOF_NONE , NULL ) ) = = SWITCH_STATUS_SUCCESS ) {
2009-11-25 00:03:00 +00:00
if ( switch_channel_up ( channel_a ) ) {
2008-09-12 00:05:09 +00:00
tuuid_str = switch_core_session_get_uuid ( tsession ) ;
switch_ivr_uuid_bridge ( nhelper - > bridge_to_uuid , tuuid_str ) ;
switch_channel_set_variable ( channel_a , SWITCH_ENDPOINT_DISPOSITION_VARIABLE , " ATTENDED_TRANSFER " ) ;
2009-02-09 17:56:38 +00:00
sofia_set_flag_locked ( tech_pvt , TFLAG_BYE ) ;
2009-11-25 00:03:00 +00:00
} else {
switch_channel_hangup ( switch_core_session_get_channel ( tsession ) , SWITCH_CAUSE_ORIGINATOR_CANCEL ) ;
status = SWITCH_STATUS_FALSE ;
2008-09-12 00:05:09 +00:00
}
2009-11-25 00:03:00 +00:00
switch_core_session_rwunlock ( tsession ) ;
}
if ( status = = SWITCH_STATUS_SUCCESS ) {
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( session ) , SWITCH_LOG_DEBUG , " The nightmare is over..... \n " ) ;
2009-11-15 04:13:39 +00:00
} else {
2009-11-25 00:03:00 +00:00
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( session ) , SWITCH_LOG_DEBUG , " 1 .. 2 .. Freddie's commin' for you... \n " ) ;
2008-09-11 23:40:57 +00:00
}
2009-11-25 00:03:00 +00:00
2010-01-25 22:23:30 +00:00
nua_notify ( tech_pvt - > nh , NUTAG_NEWSUB ( 1 ) , SIPTAG_CONTENT_TYPE_STR ( " message/sipfrag " ) ,
2009-11-25 00:03:00 +00:00
NUTAG_SUBSTATE ( nua_substate_terminated ) ,
2010-02-06 03:38:24 +00:00
SIPTAG_PAYLOAD_STR ( status = = SWITCH_STATUS_SUCCESS ? " SIP/2.0 200 OK \r \n " :
2010-01-22 00:51:32 +00:00
" SIP/2.0 403 Forbidden \r \n " ) , SIPTAG_EVENT_STR ( nhelper - > event ) , TAG_END ( ) ) ;
2009-11-25 00:03:00 +00:00
2008-09-11 23:40:57 +00:00
switch_core_session_rwunlock ( session ) ;
}
switch_core_session_rwunlock ( a_session ) ;
}
2009-11-15 04:13:39 +00:00
switch_event_destroy ( & nhelper - > vars ) ;
2008-09-11 23:40:57 +00:00
pool = nhelper - > pool ;
switch_core_destroy_memory_pool ( & pool ) ;
return NULL ;
}
static void launch_nightmare_xfer ( nightmare_xfer_helper_t * nhelper )
{
switch_thread_t * thread ;
switch_threadattr_t * thd_attr = NULL ;
switch_threadattr_create ( & thd_attr , nhelper - > pool ) ;
switch_threadattr_detach_set ( thd_attr , 1 ) ;
switch_threadattr_stacksize_set ( thd_attr , SWITCH_THREAD_STACKSIZE ) ;
switch_threadattr_priority_increase ( thd_attr ) ;
switch_thread_create ( & thread , thd_attr , nightmare_xfer_thread_run , nhelper , nhelper - > pool ) ;
}
2007-03-31 19:01:33 +00:00
/*---------------------------------------*/
2008-11-20 02:07:59 +00:00
2009-10-09 22:28:31 +00:00
static switch_status_t xfer_hanguphook ( switch_core_session_t * session )
{
switch_channel_t * channel = switch_core_session_get_channel ( session ) ;
switch_channel_state_t state = switch_channel_get_state ( channel ) ;
if ( state = = CS_HANGUP ) {
switch_core_session_t * ksession ;
const char * uuid = switch_channel_get_variable ( channel , " att_xfer_kill_uuid " ) ;
2010-02-06 03:38:24 +00:00
2009-10-09 22:28:31 +00:00
if ( uuid & & ( ksession = switch_core_session_force_locate ( uuid ) ) ) {
switch_channel_t * kchannel = switch_core_session_get_channel ( ksession ) ;
2010-02-06 03:38:24 +00:00
2009-10-09 22:28:31 +00:00
switch_channel_clear_flag ( kchannel , CF_XFER_ZOMBIE ) ;
switch_channel_clear_flag ( kchannel , CF_TRANSFER ) ;
if ( switch_channel_up ( kchannel ) ) {
switch_channel_hangup ( kchannel , SWITCH_CAUSE_NORMAL_CLEARING ) ;
}
switch_core_session_rwunlock ( ksession ) ;
}
switch_core_event_hook_remove_state_change ( session , xfer_hanguphook ) ;
}
return SWITCH_STATUS_SUCCESS ;
}
2010-01-20 19:20:11 +00:00
nua_handle_t * sofia_global_nua_handle_by_replaces ( sip_replaces_t * replaces )
{
nua_handle_t * nh = NULL ;
switch_hash_index_t * hi ;
const void * var ;
2010-02-06 03:38:24 +00:00
void * val ;
sofia_profile_t * profile ;
2010-01-20 19:20:11 +00:00
switch_xml_t xml_root ;
const char * err ;
if ( ( xml_root = switch_xml_open_root ( 1 , & err ) ) ) {
switch_xml_free ( xml_root ) ;
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_NOTICE , " Reload XML [%s] \n " , err ) ;
}
switch_mutex_lock ( mod_sofia_globals . hash_mutex ) ;
if ( mod_sofia_globals . profile_hash ) {
2010-02-06 03:38:24 +00:00
for ( hi = switch_hash_first ( NULL , mod_sofia_globals . profile_hash ) ; hi ; hi = switch_hash_next ( hi ) ) {
2010-01-20 19:20:11 +00:00
switch_hash_this ( hi , & var , NULL , & val ) ;
2010-02-06 03:38:24 +00:00
if ( ( profile = ( sofia_profile_t * ) val ) ) {
2010-01-20 19:20:11 +00:00
if ( ! ( nh = nua_handle_by_replaces ( profile - > nua , replaces ) ) ) {
nh = nua_handle_by_call_id ( profile - > nua , replaces - > rp_call_id ) ;
}
2010-02-06 03:38:24 +00:00
if ( nh )
break ;
2010-01-20 19:20:11 +00:00
}
}
}
switch_mutex_unlock ( mod_sofia_globals . hash_mutex ) ;
2010-02-06 03:38:24 +00:00
2010-01-20 19:20:11 +00:00
return nh ;
}
2007-04-13 22:15:58 +00:00
void sofia_handle_sip_i_refer ( nua_t * nua , sofia_profile_t * profile , nua_handle_t * nh , switch_core_session_t * session , sip_t const * sip , tagi_t tags [ ] )
2007-03-31 19:01:33 +00:00
{
/* Incoming refer */
sip_from_t const * from ;
sip_to_t const * to ;
sip_refer_to_t const * refer_to ;
2008-01-28 07:26:10 +00:00
private_object_t * tech_pvt = switch_core_session_get_private ( session ) ;
2007-03-31 19:01:33 +00:00
char * etmp = NULL , * exten = NULL ;
2008-01-28 07:26:10 +00:00
switch_channel_t * channel_a = switch_core_session_get_channel ( session ) ;
switch_channel_t * channel_b = NULL ;
2007-09-29 01:06:08 +00:00
su_home_t * home = NULL ;
2007-12-28 18:54:43 +00:00
char * full_ref_by = NULL ;
2007-12-28 22:53:04 +00:00
char * full_ref_to = NULL ;
2008-09-11 23:40:57 +00:00
nightmare_xfer_helper_t * nightmare_xfer_helper ;
switch_memory_pool_t * npool ;
2007-03-31 19:01:33 +00:00
2008-03-08 04:26:02 +00:00
if ( ! ( profile - > mflags & MFLAG_REFER ) ) {
2008-03-07 14:36:08 +00:00
nua_respond ( nh , SIP_403_FORBIDDEN , NUTAG_WITH_THIS ( nua ) , TAG_END ( ) ) ;
goto done ;
}
2007-03-31 19:01:33 +00:00
if ( ! sip - > sip_cseq | | ! ( etmp = switch_mprintf ( " refer;id=%u " , sip - > sip_cseq - > cs_seq ) ) ) {
2009-08-13 20:35:02 +00:00
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( session ) , SWITCH_LOG_ERROR , " Memory Error! \n " ) ;
2007-03-31 19:01:33 +00:00
goto done ;
}
from = sip - > sip_from ;
to = sip - > sip_to ;
2008-05-27 04:54:52 +00:00
2007-12-28 22:53:04 +00:00
home = su_home_new ( sizeof ( * home ) ) ;
switch_assert ( home ! = NULL ) ;
2007-12-28 18:54:43 +00:00
2010-02-06 03:38:24 +00:00
nua_respond ( nh , SIP_202_ACCEPTED , NUTAG_WITH_THIS ( nua ) , SIPTAG_EXPIRES_STR ( " 60 " ) , TAG_END ( ) ) ;
2009-10-02 21:10:27 +00:00
2008-05-27 04:54:52 +00:00
if ( sip - > sip_referred_by ) {
2007-12-28 18:54:43 +00:00
full_ref_by = sip_header_as_string ( home , ( void * ) sip - > sip_referred_by ) ;
}
2007-03-31 19:01:33 +00:00
if ( ( refer_to = sip - > sip_refer_to ) ) {
2008-12-01 19:40:53 +00:00
char * rep ;
2007-12-28 22:53:04 +00:00
full_ref_to = sip_header_as_string ( home , ( void * ) sip - > sip_refer_to ) ;
2009-02-09 17:56:38 +00:00
if ( sofia_test_pflag ( profile , PFLAG_FULL_ID ) ) {
2008-09-11 23:40:57 +00:00
exten = switch_core_session_sprintf ( session , " %s@%s " , ( char * ) refer_to - > r_url - > url_user , ( char * ) refer_to - > r_url - > url_host ) ;
2007-03-31 19:01:33 +00:00
} else {
exten = ( char * ) refer_to - > r_url - > url_user ;
}
2009-08-13 20:35:02 +00:00
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( session ) , SWITCH_LOG_DEBUG , " Process REFER to [%s@%s] \n " , exten , ( char * ) refer_to - > r_url - > url_host ) ;
2007-03-31 19:01:33 +00:00
2010-02-06 03:38:24 +00:00
if ( refer_to - > r_url - > url_headers & & ( rep = ( char * ) switch_stristr ( " Replaces= " , refer_to - > r_url - > url_headers ) ) ) {
2007-03-31 19:01:33 +00:00
sip_replaces_t * replaces ;
2010-01-20 19:20:11 +00:00
nua_handle_t * bnh = NULL ;
2010-02-06 03:38:24 +00:00
2008-12-01 19:40:53 +00:00
if ( rep ) {
2007-11-01 11:28:26 +00:00
const char * br_a = NULL , * br_b = NULL ;
2007-03-31 19:01:33 +00:00
char * buf ;
2008-12-01 19:40:53 +00:00
char * p ;
2007-03-31 19:01:33 +00:00
2008-12-01 19:40:53 +00:00
rep = switch_core_session_strdup ( session , rep + 9 ) ;
2007-03-31 19:01:33 +00:00
2008-12-01 19:40:53 +00:00
if ( ( p = strchr ( rep , ' ; ' ) ) ) {
* p = ' \0 ' ;
}
2010-02-06 03:38:24 +00:00
2007-03-31 19:01:33 +00:00
if ( ( buf = switch_core_session_alloc ( session , strlen ( rep ) + 1 ) ) ) {
rep = url_unescape ( buf , ( const char * ) rep ) ;
2009-08-13 20:35:02 +00:00
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( session ) , SWITCH_LOG_DEBUG , " Replaces: [%s] \n " , rep ) ;
2007-03-31 19:01:33 +00:00
} else {
2009-08-13 20:35:02 +00:00
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( session ) , SWITCH_LOG_ERROR , " Memory Error! \n " ) ;
2007-03-31 19:01:33 +00:00
goto done ;
}
2010-02-06 03:38:24 +00:00
2010-01-20 19:20:11 +00:00
if ( ( replaces = sip_replaces_make ( home , rep ) ) ) {
if ( ! ( bnh = nua_handle_by_replaces ( nua , replaces ) ) ) {
if ( ! ( bnh = nua_handle_by_call_id ( nua , replaces - > rp_call_id ) ) ) {
bnh = sofia_global_nua_handle_by_replaces ( replaces ) ;
}
}
}
2007-12-28 18:54:43 +00:00
2010-01-20 19:20:11 +00:00
if ( bnh ) {
2007-03-31 19:01:33 +00:00
sofia_private_t * b_private = NULL ;
private_object_t * b_tech_pvt = NULL ;
switch_core_session_t * b_session = NULL ;
2008-05-27 04:54:52 +00:00
2007-03-31 19:01:33 +00:00
switch_channel_set_variable ( channel_a , SOFIA_REPLACES_HEADER , rep ) ;
if ( ( b_private = nua_handle_magic ( bnh ) ) ) {
if ( ! ( b_session = switch_core_session_locate ( b_private - > uuid ) ) ) {
goto done ;
}
b_tech_pvt = ( private_object_t * ) switch_core_session_get_private ( b_session ) ;
channel_b = switch_core_session_get_channel ( b_session ) ;
br_a = switch_channel_get_variable ( channel_a , SWITCH_SIGNAL_BOND_VARIABLE ) ;
br_b = switch_channel_get_variable ( channel_b , SWITCH_SIGNAL_BOND_VARIABLE ) ;
2010-02-06 03:38:24 +00:00
2009-10-08 18:09:06 +00:00
if ( ! switch_ivr_uuid_exists ( br_a ) ) {
br_a = NULL ;
}
if ( ! switch_ivr_uuid_exists ( br_b ) ) {
br_b = NULL ;
}
2010-02-06 03:38:24 +00:00
2009-10-07 04:30:19 +00:00
if ( switch_channel_test_flag ( channel_b , CF_ORIGINATOR ) ) {
switch_core_session_t * a_session ;
2010-02-06 03:38:24 +00:00
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( session ) , SWITCH_LOG_NOTICE ,
2009-10-07 04:30:19 +00:00
" Attended Transfer on originating session %s \n " , switch_core_session_get_uuid ( b_session ) ) ;
2010-02-06 03:38:24 +00:00
2009-10-07 04:30:19 +00:00
switch_channel_set_variable ( channel_b , SWITCH_ENDPOINT_DISPOSITION_VARIABLE , " ATTENDED_TRANSFER " ) ;
2010-02-06 03:38:24 +00:00
2009-10-07 04:30:19 +00:00
sofia_clear_flag_locked ( b_tech_pvt , TFLAG_SIP_HOLD ) ;
2009-11-24 18:18:09 +00:00
switch_channel_clear_flag ( channel_b , CF_LEG_HOLDING ) ;
2009-10-07 04:30:19 +00:00
sofia_clear_flag_locked ( tech_pvt , TFLAG_HOLD_LOCK ) ;
switch_channel_set_variable ( channel_b , SWITCH_HOLDING_UUID_VARIABLE , br_a ) ;
switch_channel_set_flag ( channel_b , CF_XFER_ZOMBIE ) ;
2009-10-09 00:52:25 +00:00
switch_channel_set_flag ( channel_b , CF_TRANSFER ) ;
2010-02-06 03:38:24 +00:00
2009-10-07 04:30:19 +00:00
if ( ( a_session = switch_core_session_locate ( br_a ) ) ) {
const char * moh = profile - > hold_music ;
switch_channel_t * a_channel = switch_core_session_get_channel ( a_session ) ;
const char * tmp ;
2009-10-09 22:28:31 +00:00
switch_core_event_hook_add_state_change ( a_session , xfer_hanguphook ) ;
switch_channel_set_variable ( a_channel , " att_xfer_kill_uuid " , switch_core_session_get_uuid ( b_session ) ) ;
2009-10-07 04:30:19 +00:00
if ( ( tmp = switch_channel_get_variable ( a_channel , SWITCH_HOLD_MUSIC_VARIABLE ) ) ) {
moh = tmp ;
}
2010-02-06 03:38:24 +00:00
2009-11-02 23:31:08 +00:00
if ( ! zstr ( moh ) & & ! strcasecmp ( moh , " silence " ) ) {
2009-10-07 22:38:11 +00:00
moh = NULL ;
}
2010-02-06 03:38:24 +00:00
2009-10-07 22:35:21 +00:00
if ( moh ) {
2009-10-09 00:52:25 +00:00
char * xdest ;
xdest = switch_core_session_sprintf ( a_session , " endless_playback:%s,park " , moh ) ;
switch_ivr_session_transfer ( a_session , xdest , " inline " , NULL ) ;
2009-10-07 22:35:21 +00:00
} else {
2009-10-09 00:52:25 +00:00
switch_ivr_session_transfer ( a_session , " park " , " inline " , NULL ) ;
2009-10-07 22:35:21 +00:00
}
2010-02-06 03:38:24 +00:00
2009-10-07 04:30:19 +00:00
switch_core_session_rwunlock ( a_session ) ;
2010-01-22 00:51:32 +00:00
nua_notify ( tech_pvt - > nh , NUTAG_NEWSUB ( 1 ) , SIPTAG_CONTENT_TYPE_STR ( " message/sipfrag;version=2.0 " ) ,
2010-02-06 03:38:24 +00:00
NUTAG_SUBSTATE ( nua_substate_terminated ) , SIPTAG_PAYLOAD_STR ( " SIP/2.0 200 OK \r \n " ) , SIPTAG_EVENT_STR ( etmp ) ,
TAG_END ( ) ) ;
2010-01-21 02:51:04 +00:00
if ( b_tech_pvt & & ! sofia_test_flag ( b_tech_pvt , TFLAG_BYE ) ) {
2010-02-06 03:38:24 +00:00
char * q850 = NULL ;
const char * val = NULL ;
2010-01-21 02:51:04 +00:00
2009-10-09 00:52:25 +00:00
sofia_set_flag_locked ( b_tech_pvt , TFLAG_BYE ) ;
2009-12-08 21:23:13 +00:00
val = switch_channel_get_variable ( tech_pvt - > channel , " disable_q850_reason " ) ;
2009-12-11 01:20:26 +00:00
if ( ! val | | switch_true ( val ) ) {
2009-12-08 21:23:13 +00:00
q850 = switch_core_session_sprintf ( a_session , " Q.850;cause=16;text= \" normal_clearing \" " ) ;
2010-02-06 03:38:24 +00:00
}
nua_bye ( b_tech_pvt - > nh ,
2009-12-08 21:23:13 +00:00
TAG_IF ( ! zstr ( q850 ) , SIPTAG_REASON_STR ( q850 ) ) ,
2010-02-06 03:38:24 +00:00
TAG_IF ( ! zstr ( tech_pvt - > user_via ) , SIPTAG_VIA_STR ( tech_pvt - > user_via ) ) , TAG_END ( ) ) ;
2009-10-09 00:52:25 +00:00
}
} else {
2010-01-22 00:51:32 +00:00
nua_notify ( tech_pvt - > nh , NUTAG_NEWSUB ( 1 ) , SIPTAG_CONTENT_TYPE_STR ( " message/sipfrag;version=2.0 " ) ,
2009-10-09 00:52:25 +00:00
NUTAG_SUBSTATE ( nua_substate_terminated ) ,
2010-01-22 00:51:32 +00:00
SIPTAG_PAYLOAD_STR ( " SIP/2.0 403 Forbidden \r \n " ) , SIPTAG_EVENT_STR ( etmp ) , TAG_END ( ) ) ;
2009-10-09 00:52:25 +00:00
}
2009-10-07 04:30:19 +00:00
} else if ( br_a & & br_b ) {
2009-10-07 22:35:21 +00:00
switch_core_session_t * tmp = NULL ;
2010-02-06 03:38:24 +00:00
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( session ) , SWITCH_LOG_NOTICE , " Attended Transfer [%s][%s] \n " ,
switch_str_nil ( br_a ) , switch_str_nil ( br_b ) ) ;
2008-09-29 15:15:53 +00:00
2008-09-18 21:50:18 +00:00
if ( ( profile - > media_options & MEDIA_OPT_BYPASS_AFTER_ATT_XFER ) & & ( tmp = switch_core_session_locate ( br_b ) ) ) {
switch_channel_t * tchannel = switch_core_session_get_channel ( tmp ) ;
2009-11-09 23:49:35 +00:00
switch_channel_set_flag ( tchannel , CF_BYPASS_MEDIA_AFTER_BRIDGE ) ;
2008-09-18 21:50:18 +00:00
switch_core_session_rwunlock ( tmp ) ;
}
2010-02-06 03:38:24 +00:00
2007-10-25 18:36:40 +00:00
switch_ivr_uuid_bridge ( br_b , br_a ) ;
2007-03-31 19:01:33 +00:00
switch_channel_set_variable ( channel_b , SWITCH_ENDPOINT_DISPOSITION_VARIABLE , " ATTENDED_TRANSFER " ) ;
2010-01-22 00:51:32 +00:00
nua_notify ( tech_pvt - > nh , NUTAG_NEWSUB ( 1 ) , SIPTAG_CONTENT_TYPE_STR ( " message/sipfrag;version=2.0 " ) ,
2010-02-06 03:38:24 +00:00
NUTAG_SUBSTATE ( nua_substate_terminated ) , SIPTAG_PAYLOAD_STR ( " SIP/2.0 200 OK \r \n " ) , SIPTAG_EVENT_STR ( etmp ) ,
TAG_END ( ) ) ;
2007-03-31 19:01:33 +00:00
2009-02-09 17:56:38 +00:00
sofia_clear_flag_locked ( b_tech_pvt , TFLAG_SIP_HOLD ) ;
2009-11-24 18:18:09 +00:00
switch_channel_clear_flag ( channel_b , CF_LEG_HOLDING ) ;
2009-02-09 17:56:38 +00:00
sofia_clear_flag_locked ( tech_pvt , TFLAG_HOLD_LOCK ) ;
2009-10-07 04:30:19 +00:00
switch_channel_set_variable ( channel_b , " park_timeout " , " 2 " ) ;
switch_channel_set_state ( channel_b , CS_PARK ) ;
2010-02-06 03:38:24 +00:00
2007-03-31 19:01:33 +00:00
} else {
if ( ! br_a & & ! br_b ) {
2010-02-06 03:38:24 +00:00
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( session ) , SWITCH_LOG_WARNING ,
" Cannot transfer channels that are not in a bridge. \n " ) ;
2010-01-22 00:51:32 +00:00
nua_notify ( tech_pvt - > nh , NUTAG_NEWSUB ( 1 ) , SIPTAG_CONTENT_TYPE_STR ( " message/sipfrag;version=2.0 " ) ,
2010-02-06 03:38:24 +00:00
NUTAG_SUBSTATE ( nua_substate_terminated ) , SIPTAG_PAYLOAD_STR ( " SIP/2.0 403 Forbidden \r \n " ) ,
SIPTAG_EVENT_STR ( etmp ) , TAG_END ( ) ) ;
2007-10-25 18:36:40 +00:00
} else {
switch_core_session_t * t_session ;
switch_channel_t * hup_channel ;
2007-11-01 11:28:26 +00:00
const char * ext ;
2007-03-31 19:01:33 +00:00
2007-10-25 18:36:40 +00:00
if ( br_a & & ! br_b ) {
t_session = switch_core_session_locate ( br_a ) ;
hup_channel = channel_b ;
} else {
2007-12-24 18:26:39 +00:00
private_object_t * h_tech_pvt = ( private_object_t * ) switch_core_session_get_private ( b_session ) ;
2007-10-25 18:36:40 +00:00
t_session = switch_core_session_locate ( br_b ) ;
hup_channel = channel_a ;
2009-02-09 17:56:38 +00:00
sofia_clear_flag_locked ( tech_pvt , TFLAG_SIP_HOLD ) ;
2009-11-24 18:18:09 +00:00
switch_channel_clear_flag ( tech_pvt - > channel , CF_LEG_HOLDING ) ;
2009-02-09 17:56:38 +00:00
sofia_clear_flag_locked ( h_tech_pvt , TFLAG_SIP_HOLD ) ;
2009-11-24 18:18:09 +00:00
switch_channel_clear_flag ( h_tech_pvt - > channel , CF_LEG_HOLDING ) ;
2007-10-25 18:36:40 +00:00
switch_channel_hangup ( channel_b , SWITCH_CAUSE_ATTENDED_TRANSFER ) ;
}
2007-03-31 19:01:33 +00:00
2007-10-25 18:36:40 +00:00
if ( t_session ) {
2007-12-28 18:54:43 +00:00
switch_channel_t * t_channel = switch_core_session_get_channel ( t_session ) ;
2009-10-09 02:09:49 +00:00
const char * idest = switch_channel_get_variable ( hup_channel , " inline_destination " ) ;
2007-10-25 18:36:40 +00:00
ext = switch_channel_get_variable ( hup_channel , " destination_number " ) ;
2007-03-31 19:01:33 +00:00
2009-10-23 16:03:42 +00:00
if ( ! zstr ( full_ref_by ) ) {
2007-12-28 18:54:43 +00:00
switch_channel_set_variable ( t_channel , SOFIA_SIP_HEADER_PREFIX " Referred-By " , full_ref_by ) ;
}
2009-10-23 16:03:42 +00:00
if ( ! zstr ( full_ref_to ) ) {
2007-12-28 22:53:04 +00:00
switch_channel_set_variable ( t_channel , SOFIA_REFER_TO_VARIABLE , full_ref_to ) ;
}
2010-02-06 03:38:24 +00:00
2009-10-09 02:09:49 +00:00
if ( idest ) {
switch_ivr_session_transfer ( t_session , idest , " inline " , NULL ) ;
} else {
switch_ivr_session_transfer ( t_session , ext , NULL , NULL ) ;
}
2010-02-06 03:38:24 +00:00
2007-11-20 01:09:39 +00:00
nua_notify ( tech_pvt - > nh ,
2008-05-27 04:54:52 +00:00
NUTAG_NEWSUB ( 1 ) ,
2010-01-22 00:51:32 +00:00
SIPTAG_CONTENT_TYPE_STR ( " message/sipfrag;version=2.0 " ) ,
2008-05-27 04:54:52 +00:00
NUTAG_SUBSTATE ( nua_substate_terminated ) ,
2010-01-22 00:51:32 +00:00
SIPTAG_PAYLOAD_STR ( " SIP/2.0 200 OK \r \n " ) , SIPTAG_EVENT_STR ( etmp ) , TAG_END ( ) ) ;
2007-10-25 18:36:40 +00:00
switch_core_session_rwunlock ( t_session ) ;
switch_channel_hangup ( hup_channel , SWITCH_CAUSE_ATTENDED_TRANSFER ) ;
} else {
2009-08-13 20:35:02 +00:00
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( session ) , SWITCH_LOG_DEBUG , " Session to transfer to not found. \n " ) ;
2010-01-22 00:51:32 +00:00
nua_notify ( tech_pvt - > nh , NUTAG_NEWSUB ( 1 ) , SIPTAG_CONTENT_TYPE_STR ( " message/sipfrag;version=2.0 " ) ,
2007-10-25 18:36:40 +00:00
NUTAG_SUBSTATE ( nua_substate_terminated ) ,
2010-01-22 00:51:32 +00:00
SIPTAG_PAYLOAD_STR ( " SIP/2.0 403 Forbidden \r \n " ) , SIPTAG_EVENT_STR ( etmp ) , TAG_END ( ) ) ;
2007-03-31 19:01:33 +00:00
}
}
}
if ( b_session ) {
switch_core_session_rwunlock ( b_session ) ;
}
}
nua_handle_unref ( bnh ) ;
} else { /* the other channel is on a different box, we have to go find them */
if ( exten & & ( br_a = switch_channel_get_variable ( channel_a , SWITCH_SIGNAL_BOND_VARIABLE ) ) ) {
switch_core_session_t * a_session ;
switch_channel_t * channel = switch_core_session_get_channel ( session ) ;
if ( ( a_session = switch_core_session_locate ( br_a ) ) ) {
2007-12-19 03:34:37 +00:00
const char * port = NULL ;
2010-02-03 19:14:12 +00:00
const char * rep_h = NULL ;
2008-03-06 19:51:11 +00:00
2007-12-19 03:34:37 +00:00
if ( refer_to & & refer_to - > r_url & & refer_to - > r_url - > url_port ) {
port = refer_to - > r_url - > url_port ;
}
2007-03-31 19:01:33 +00:00
2008-09-11 23:40:57 +00:00
channel = switch_core_session_get_channel ( a_session ) ;
2010-02-06 03:38:24 +00:00
exten = switch_core_session_sprintf ( session , " sofia/%s/sip:%s@%s%s%s " ,
profile - > name , refer_to - > r_url - > url_user ,
refer_to - > r_url - > url_host , port ? " : " : " " , port ? port : " " ) ;
2008-09-12 14:57:44 +00:00
2008-09-11 23:40:57 +00:00
switch_core_new_memory_pool ( & npool ) ;
nightmare_xfer_helper = switch_core_alloc ( npool , sizeof ( * nightmare_xfer_helper ) ) ;
nightmare_xfer_helper - > exten = switch_core_strdup ( npool , exten ) ;
2010-02-03 19:14:12 +00:00
2010-02-06 03:38:24 +00:00
if ( refer_to - > r_url & & ( refer_to - > r_url - > url_params | | refer_to - > r_url - > url_headers ) ) {
2010-02-03 19:14:12 +00:00
if ( refer_to - > r_url - > url_headers ) {
2010-02-06 03:38:24 +00:00
nightmare_xfer_helper - > exten_with_params = switch_core_sprintf ( npool ,
" {sip_invite_params=%s?%s}%s " ,
refer_to - > r_url - > url_params ? refer_to - > r_url - >
url_params : " " , refer_to - > r_url - > url_headers , exten ) ;
2010-02-03 19:14:12 +00:00
} else {
2010-02-06 03:38:24 +00:00
nightmare_xfer_helper - > exten_with_params = switch_core_sprintf ( npool ,
" {sip_invite_params=%s}%s " , refer_to - > r_url - > url_params ,
exten ) ;
2010-02-03 19:14:12 +00:00
}
2010-02-06 03:38:24 +00:00
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_DEBUG , " INVITE RURI '%s' \n " , nightmare_xfer_helper - > exten_with_params ) ;
2010-02-03 19:14:12 +00:00
} else {
nightmare_xfer_helper - > exten_with_params = nightmare_xfer_helper - > exten ;
}
2008-09-11 23:40:57 +00:00
nightmare_xfer_helper - > event = switch_core_strdup ( npool , etmp ) ;
nightmare_xfer_helper - > reply_uuid = switch_core_strdup ( npool , switch_core_session_get_uuid ( session ) ) ;
nightmare_xfer_helper - > bridge_to_uuid = switch_core_strdup ( npool , br_a ) ;
nightmare_xfer_helper - > pool = npool ;
2010-02-03 19:14:12 +00:00
if ( refer_to - > r_url & & refer_to - > r_url - > url_headers ) {
char * h , * v , * hp ;
p = switch_core_session_strdup ( session , refer_to - > r_url - > url_headers ) ;
while ( p & & * p ) {
2010-02-06 03:38:24 +00:00
h = p ;
2010-02-03 19:14:12 +00:00
if ( ( p = strchr ( p , ' = ' ) ) ) {
* p + + = ' \0 ' ;
v = p ;
if ( ( p = strchr ( p , ' & ' ) ) ) {
* p + + = ' \0 ' ;
}
2010-02-06 03:38:24 +00:00
url_unescape ( h , ( const char * ) h ) ;
url_unescape ( v , ( const char * ) v ) ;
if ( strcasecmp ( " Replaces " , h ) ) {
2010-02-03 19:14:12 +00:00
hp = switch_core_session_sprintf ( session , " %s%s " , SOFIA_SIP_HEADER_PREFIX , h ) ;
switch_channel_set_variable ( channel , hp , v ) ;
} else {
// use this one instead of rep value from above to keep all parameters
switch_channel_set_variable ( channel , SOFIA_REPLACES_HEADER , v ) ;
}
2010-02-06 03:38:24 +00:00
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( session ) , SWITCH_LOG_DEBUG , " Exporting replaces URL header [%s:%s] \n " ,
h , v ) ;
}
2010-02-03 19:14:12 +00:00
}
}
2009-11-15 04:13:39 +00:00
switch_event_create ( & nightmare_xfer_helper - > vars , SWITCH_EVENT_CHANNEL_DATA ) ;
2008-05-27 04:54:52 +00:00
2010-02-03 19:14:12 +00:00
rep_h = switch_channel_get_variable ( channel , SOFIA_REPLACES_HEADER ) ;
if ( rep_h ) {
switch_event_add_header_string ( nightmare_xfer_helper - > vars , SWITCH_STACK_BOTTOM , SOFIA_REPLACES_HEADER , rep_h ) ;
} else {
switch_event_add_header_string ( nightmare_xfer_helper - > vars , SWITCH_STACK_BOTTOM , SOFIA_REPLACES_HEADER , rep ) ;
}
2010-02-06 03:38:24 +00:00
2009-10-23 16:03:42 +00:00
if ( ! zstr ( full_ref_by ) ) {
2009-11-15 04:13:39 +00:00
switch_event_add_header_string ( nightmare_xfer_helper - > vars , SWITCH_STACK_BOTTOM , " Referred-By " , full_ref_by ) ;
2007-12-28 18:54:43 +00:00
}
2008-09-11 23:40:57 +00:00
2009-10-23 16:03:42 +00:00
if ( ! zstr ( full_ref_to ) ) {
2009-11-15 04:13:39 +00:00
switch_event_add_header_string ( nightmare_xfer_helper - > vars , SWITCH_STACK_BOTTOM , SOFIA_REFER_TO_VARIABLE , full_ref_to ) ;
2007-12-28 22:53:04 +00:00
}
2008-05-27 04:54:52 +00:00
2009-08-13 20:35:02 +00:00
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( session ) , SWITCH_LOG_DEBUG , " Good Luck, you'll need it...... \n " ) ;
2008-09-11 23:40:57 +00:00
launch_nightmare_xfer ( nightmare_xfer_helper ) ;
2010-02-06 03:38:24 +00:00
2007-03-31 19:01:33 +00:00
switch_core_session_rwunlock ( a_session ) ;
2008-03-06 19:51:11 +00:00
2007-03-31 19:01:33 +00:00
} else {
goto error ;
}
} else {
error :
2009-08-13 20:35:02 +00:00
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( session ) , SWITCH_LOG_ERROR , " Invalid Transfer! [%s] \n " , br_a ) ;
2007-03-31 19:01:33 +00:00
switch_channel_set_variable ( channel_a , SWITCH_ENDPOINT_DISPOSITION_VARIABLE , " ATTENDED_TRANSFER_ERROR " ) ;
2010-01-22 00:51:32 +00:00
nua_notify ( tech_pvt - > nh , NUTAG_NEWSUB ( 1 ) , SIPTAG_CONTENT_TYPE_STR ( " message/sipfrag;version=2.0 " ) ,
NUTAG_SUBSTATE ( nua_substate_terminated ) , SIPTAG_PAYLOAD_STR ( " SIP/2.0 403 Forbidden \r \n " ) , SIPTAG_EVENT_STR ( etmp ) ,
2007-03-31 19:01:33 +00:00
TAG_END ( ) ) ;
}
}
} else {
2009-08-13 20:35:02 +00:00
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( session ) , SWITCH_LOG_ERROR , " Cannot parse Replaces! \n " ) ;
2007-03-31 19:01:33 +00:00
}
goto done ;
}
} else {
2009-08-13 20:35:02 +00:00
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( session ) , SWITCH_LOG_ERROR , " Missing Refer-To \n " ) ;
2007-03-31 19:01:33 +00:00
goto done ;
}
if ( exten ) {
switch_channel_t * channel = switch_core_session_get_channel ( session ) ;
2007-11-01 11:28:26 +00:00
const char * br ;
2007-03-31 19:01:33 +00:00
if ( ( br = switch_channel_get_variable ( channel , SWITCH_SIGNAL_BOND_VARIABLE ) ) ) {
switch_core_session_t * b_session ;
2008-05-27 04:54:52 +00:00
2007-03-31 19:01:33 +00:00
if ( ( b_session = switch_core_session_locate ( br ) ) ) {
2007-12-28 18:54:43 +00:00
switch_channel_t * b_channel = switch_core_session_get_channel ( b_session ) ;
2007-12-20 02:55:36 +00:00
switch_channel_set_variable ( channel , " transfer_fallback_extension " , from - > a_user ) ;
2009-10-23 16:03:42 +00:00
if ( ! zstr ( full_ref_by ) ) {
2007-12-28 18:54:43 +00:00
switch_channel_set_variable ( b_channel , SOFIA_SIP_HEADER_PREFIX " Referred-By " , full_ref_by ) ;
}
2009-10-23 16:03:42 +00:00
if ( ! zstr ( full_ref_to ) ) {
2007-12-28 22:53:04 +00:00
switch_channel_set_variable ( b_channel , SOFIA_REFER_TO_VARIABLE , full_ref_to ) ;
}
2008-05-09 19:59:42 +00:00
2007-12-19 00:27:40 +00:00
switch_ivr_session_transfer ( b_session , exten , NULL , NULL ) ;
2007-03-31 19:01:33 +00:00
switch_core_session_rwunlock ( b_session ) ;
}
switch_channel_set_variable ( channel , SWITCH_ENDPOINT_DISPOSITION_VARIABLE , " BLIND_TRANSFER " ) ;
2010-01-22 00:51:32 +00:00
nua_notify ( tech_pvt - > nh , NUTAG_NEWSUB ( 1 ) , SIPTAG_CONTENT_TYPE_STR ( " message/sipfrag;version=2.0 " ) ,
NUTAG_SUBSTATE ( nua_substate_terminated ) , SIPTAG_PAYLOAD_STR ( " SIP/2.0 200 OK \r \n " ) , SIPTAG_EVENT_STR ( etmp ) , TAG_END ( ) ) ;
2008-05-27 04:54:52 +00:00
2007-03-31 19:01:33 +00:00
} else {
2009-08-13 20:35:02 +00:00
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( session ) , SWITCH_LOG_ERROR , " Cannot Blind Transfer 1 Legged calls \n " ) ;
2007-10-25 18:36:40 +00:00
switch_channel_set_variable ( channel_a , SWITCH_ENDPOINT_DISPOSITION_VARIABLE , " ATTENDED_TRANSFER_ERROR " ) ;
2010-01-22 00:51:32 +00:00
nua_notify ( tech_pvt - > nh , NUTAG_NEWSUB ( 1 ) , SIPTAG_CONTENT_TYPE_STR ( " message/sipfrag;version=2.0 " ) ,
NUTAG_SUBSTATE ( nua_substate_terminated ) , SIPTAG_PAYLOAD_STR ( " SIP/2.0 403 Forbidden \r \n " ) , SIPTAG_EVENT_STR ( etmp ) , TAG_END ( ) ) ;
2007-03-31 19:01:33 +00:00
}
}
done :
2007-09-29 01:06:08 +00:00
if ( home ) {
su_home_unref ( home ) ;
home = NULL ;
}
2007-03-31 19:01:33 +00:00
if ( etmp ) {
switch_safe_free ( etmp ) ;
}
}
2007-04-13 22:15:58 +00:00
void sofia_handle_sip_i_info ( nua_t * nua , sofia_profile_t * profile , nua_handle_t * nh , switch_core_session_t * session , sip_t const * sip , tagi_t tags [ ] )
2007-03-31 19:01:33 +00:00
{
2007-11-20 01:09:39 +00:00
/* placeholder for string searching */
2007-12-24 18:26:39 +00:00
const char * signal_ptr ;
2007-12-22 00:32:20 +00:00
const char * rec_header ;
2007-12-26 22:33:46 +00:00
const char * clientcode_header ;
2008-04-18 17:03:34 +00:00
switch_dtmf_t dtmf = { 0 , switch_core_default_dtmf_duration ( 0 ) } ;
2009-04-20 17:07:54 +00:00
switch_event_t * event ;
2008-05-27 04:54:52 +00:00
2007-12-22 00:32:20 +00:00
if ( session ) {
/* Get the channel */
2008-01-28 07:26:10 +00:00
switch_channel_t * channel = switch_core_session_get_channel ( session ) ;
2008-03-20 00:27:04 +00:00
/* Barf if we didn't get our private */
assert ( switch_core_session_get_private ( session ) ) ;
2007-03-31 19:01:33 +00:00
2008-05-27 04:54:52 +00:00
if ( sip & & sip - > sip_content_type & & sip - > sip_content_type - > c_type & & sip - > sip_content_type - > c_subtype & &
2007-12-24 18:26:39 +00:00
sip - > sip_payload & & sip - > sip_payload - > pl_data ) {
2008-01-13 20:08:12 +00:00
if ( ! strncasecmp ( sip - > sip_content_type - > c_type , " application " , 11 ) & & ! strcasecmp ( sip - > sip_content_type - > c_subtype , " dtmf-relay " ) ) {
2007-12-24 18:26:39 +00:00
/* Try and find signal information in the payload */
if ( ( signal_ptr = switch_stristr ( " Signal= " , sip - > sip_payload - > pl_data ) ) ) {
2008-09-07 02:56:56 +00:00
int tmp ;
2007-12-24 18:26:39 +00:00
/* move signal_ptr where we need it (right past Signal=) */
signal_ptr = signal_ptr + 7 ;
2009-05-29 18:08:05 +00:00
/* handle broken devices with spaces after the = (cough) VegaStream (cough) */
2010-02-06 03:38:24 +00:00
while ( * signal_ptr & & * signal_ptr = = ' ' )
signal_ptr + + ;
2009-05-29 18:08:05 +00:00
2010-02-06 03:38:24 +00:00
if ( * signal_ptr
& & ( * signal_ptr = = ' * ' | | * signal_ptr = = ' # ' | | * signal_ptr = = ' A ' | | * signal_ptr = = ' B ' | | * signal_ptr = = ' C '
| | * signal_ptr = = ' D ' ) ) {
2008-11-18 22:46:40 +00:00
dtmf . digit = * signal_ptr ;
} else {
tmp = atoi ( signal_ptr ) ;
dtmf . digit = switch_rfc2833_to_char ( tmp ) ;
}
2007-12-24 18:26:39 +00:00
} else {
2009-08-13 20:35:02 +00:00
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( session ) , SWITCH_LOG_DEBUG , " Bad signal \n " ) ;
2009-04-20 19:00:39 +00:00
goto end ;
2007-12-24 18:26:39 +00:00
}
2007-03-31 19:01:33 +00:00
2007-12-24 18:26:39 +00:00
if ( ( signal_ptr = switch_stristr ( " Duration= " , sip - > sip_payload - > pl_data ) ) ) {
int tmp ;
2008-01-13 20:08:12 +00:00
signal_ptr + = 9 ;
2009-05-29 18:08:05 +00:00
/* handle broken devices with spaces after the = (cough) VegaStream (cough) */
2010-02-06 03:38:24 +00:00
while ( * signal_ptr & & * signal_ptr = = ' ' )
signal_ptr + + ;
2008-01-13 20:08:12 +00:00
if ( ( tmp = atoi ( signal_ptr ) ) < = 0 ) {
2008-04-18 17:03:34 +00:00
tmp = switch_core_default_dtmf_duration ( 0 ) ;
2008-05-27 04:54:52 +00:00
}
2008-01-13 20:08:12 +00:00
dtmf . duration = tmp * 8 ;
2007-12-24 18:26:39 +00:00
}
2008-01-13 20:08:12 +00:00
} else if ( ! strncasecmp ( sip - > sip_content_type - > c_type , " application " , 11 ) & & ! strcasecmp ( sip - > sip_content_type - > c_subtype , " dtmf " ) ) {
2008-09-07 02:56:56 +00:00
int tmp = atoi ( sip - > sip_payload - > pl_data ) ;
dtmf . digit = switch_rfc2833_to_char ( tmp ) ;
2009-10-21 18:48:28 +00:00
} else if ( ! strncasecmp ( sip - > sip_content_type - > c_type , " message " , 11 ) & & ! strcasecmp ( sip - > sip_content_type - > c_subtype , " update_display " ) ) {
sofia_update_callee_id ( session , profile , sip , SWITCH_TRUE ) ;
2007-12-22 00:32:20 +00:00
} else {
2009-04-20 19:00:39 +00:00
goto end ;
2007-12-22 00:32:20 +00:00
}
2008-05-27 04:54:52 +00:00
2007-12-24 18:26:39 +00:00
if ( dtmf . digit ) {
/* queue it up */
switch_channel_queue_dtmf ( channel , & dtmf ) ;
2007-12-22 00:32:20 +00:00
2007-12-24 18:26:39 +00:00
/* print debug info */
2009-08-13 20:35:02 +00:00
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( session ) , SWITCH_LOG_DEBUG , " INFO DTMF(%c) \n " , dtmf . digit ) ;
2010-02-06 03:38:24 +00:00
2009-01-06 21:07:58 +00:00
if ( switch_channel_test_flag ( channel , CF_PROXY_MODE ) ) {
const char * uuid ;
switch_core_session_t * session_b ;
2010-02-06 03:38:24 +00:00
2009-01-06 21:07:58 +00:00
if ( ( uuid = switch_channel_get_variable ( channel , SWITCH_SIGNAL_BOND_VARIABLE ) ) & & ( session_b = switch_core_session_locate ( uuid ) ) ) {
while ( switch_channel_has_dtmf ( channel ) ) {
switch_dtmf_t idtmf = { 0 , 0 } ;
if ( switch_channel_dequeue_dtmf ( channel , & idtmf ) = = SWITCH_STATUS_SUCCESS ) {
switch_core_session_send_dtmf ( session_b , & idtmf ) ;
}
}
switch_core_session_rwunlock ( session_b ) ;
}
}
2007-03-31 19:01:33 +00:00
2007-12-24 18:26:39 +00:00
/* Send 200 OK response */
nua_respond ( nh , SIP_200_OK , NUTAG_WITH_THIS ( nua ) , TAG_END ( ) ) ;
}
2009-04-20 19:00:39 +00:00
goto end ;
2007-12-22 00:32:20 +00:00
}
2007-03-31 19:01:33 +00:00
2007-12-26 22:33:46 +00:00
if ( ( clientcode_header = sofia_glue_get_unknown_header ( sip , " x-clientcode " ) ) ) {
2009-10-23 16:03:42 +00:00
if ( ! zstr ( clientcode_header ) ) {
2007-12-26 22:33:46 +00:00
switch_channel_set_variable ( channel , " call_clientcode " , clientcode_header ) ;
2009-08-13 20:35:02 +00:00
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( session ) , SWITCH_LOG_NOTICE , " Setting CMC to %s \n " , clientcode_header ) ;
2007-12-26 22:33:46 +00:00
nua_respond ( nh , SIP_200_OK , NUTAG_WITH_THIS ( nua ) , TAG_END ( ) ) ;
}
2009-04-20 17:07:54 +00:00
goto end ;
2007-12-26 22:33:46 +00:00
}
2007-12-22 00:32:20 +00:00
if ( ( rec_header = sofia_glue_get_unknown_header ( sip , " record " ) ) ) {
2009-10-23 16:03:42 +00:00
if ( zstr ( profile - > record_template ) ) {
2009-08-13 20:35:02 +00:00
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( session ) , SWITCH_LOG_WARNING , " Record attempted but no template defined. \n " ) ;
2007-12-22 00:32:20 +00:00
nua_respond ( nh , 488 , " Recording not enabled " , NUTAG_WITH_THIS ( nua ) , TAG_END ( ) ) ;
} else {
if ( ! strcasecmp ( rec_header , " on " ) ) {
2009-10-23 15:07:52 +00:00
char * file = NULL , * tmp = NULL ;
2007-12-22 00:32:20 +00:00
2010-01-11 03:20:42 +00:00
tmp = switch_mprintf ( " %s%s%s " , profile - > record_path ? profile - > record_path : " ${recordings_dir} " ,
2009-10-23 15:07:52 +00:00
SWITCH_PATH_SEPARATOR , profile - > record_template ) ;
file = switch_channel_expand_variables ( channel , tmp ) ;
2007-12-22 00:32:20 +00:00
switch_ivr_record_session ( session , file , 0 , NULL ) ;
switch_channel_set_variable ( channel , " sofia_record_file " , file ) ;
2010-02-06 03:38:24 +00:00
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( session ) , SWITCH_LOG_NOTICE , " Recording %s to %s \n " , switch_channel_get_name ( channel ) ,
file ) ;
2009-10-23 15:07:52 +00:00
switch_safe_free ( tmp ) ;
2007-12-22 00:32:20 +00:00
nua_respond ( nh , SIP_200_OK , NUTAG_WITH_THIS ( nua ) , TAG_END ( ) ) ;
if ( file ! = profile - > record_template ) {
free ( file ) ;
file = NULL ;
}
} else {
const char * file ;
if ( ( file = switch_channel_get_variable ( channel , " sofia_record_file " ) ) ) {
2010-02-06 03:38:24 +00:00
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( session ) , SWITCH_LOG_NOTICE , " Done recording %s to %s \n " ,
switch_channel_get_name ( channel ) , file ) ;
2007-12-22 00:32:20 +00:00
switch_ivr_stop_record_session ( session , file ) ;
nua_respond ( nh , SIP_200_OK , NUTAG_WITH_THIS ( nua ) , TAG_END ( ) ) ;
} else {
nua_respond ( nh , 488 , " Nothing to stop " , NUTAG_WITH_THIS ( nua ) , TAG_END ( ) ) ;
}
}
}
}
}
2009-04-20 17:07:54 +00:00
2010-02-06 03:38:24 +00:00
end :
2009-04-20 17:07:54 +00:00
2009-05-11 22:28:02 +00:00
if ( sip & & switch_event_create ( & event , SWITCH_EVENT_RECV_INFO ) = = SWITCH_STATUS_SUCCESS ) {
2009-04-27 23:36:03 +00:00
sip_alert_info_t * alert_info = sip_alert_info ( sip ) ;
2009-04-23 20:05:45 +00:00
if ( sip & & sip - > sip_content_type ) {
2009-04-21 00:54:50 +00:00
switch_event_add_header_string ( event , SWITCH_STACK_BOTTOM , " SIP-Content-Type " , sip - > sip_content_type - > c_type ) ;
2009-04-20 17:07:54 +00:00
}
if ( sip - > sip_from & & sip - > sip_from - > a_url ) {
if ( sip - > sip_from - > a_url - > url_user ) {
2009-04-21 00:54:50 +00:00
switch_event_add_header_string ( event , SWITCH_STACK_BOTTOM , " SIP-From-User " , sip - > sip_from - > a_url - > url_user ) ;
2009-04-20 17:07:54 +00:00
}
if ( sip - > sip_from - > a_url - > url_host ) {
2009-04-21 00:54:50 +00:00
switch_event_add_header_string ( event , SWITCH_STACK_BOTTOM , " SIP-From-Host " , sip - > sip_from - > a_url - > url_host ) ;
2009-04-20 17:07:54 +00:00
}
}
if ( sip - > sip_to & & sip - > sip_to - > a_url ) {
if ( sip - > sip_to - > a_url - > url_user ) {
2009-04-21 00:54:50 +00:00
switch_event_add_header_string ( event , SWITCH_STACK_BOTTOM , " SIP-To-User " , sip - > sip_to - > a_url - > url_user ) ;
2009-04-20 17:07:54 +00:00
}
if ( sip - > sip_to - > a_url - > url_host ) {
2009-04-21 00:54:50 +00:00
switch_event_add_header_string ( event , SWITCH_STACK_BOTTOM , " SIP-To-Host " , sip - > sip_to - > a_url - > url_host ) ;
2009-04-20 17:07:54 +00:00
}
}
if ( sip - > sip_contact & & sip - > sip_contact - > m_url ) {
if ( sip - > sip_contact - > m_url - > url_user ) {
2009-04-21 00:54:50 +00:00
switch_event_add_header_string ( event , SWITCH_STACK_BOTTOM , " SIP-Contact-User " , sip - > sip_contact - > m_url - > url_user ) ;
2009-04-20 17:07:54 +00:00
}
if ( sip - > sip_contact - > m_url - > url_host ) {
2009-04-21 00:54:50 +00:00
switch_event_add_header_string ( event , SWITCH_STACK_BOTTOM , " SIP-Contact-Host " , sip - > sip_contact - > m_url - > url_host ) ;
2009-04-20 17:07:54 +00:00
}
}
2009-04-27 23:36:03 +00:00
if ( sip - > sip_call_info ) {
2010-02-06 03:38:24 +00:00
switch_event_add_header_string ( event , SWITCH_STACK_BOTTOM , " Call-Info " ,
sip_header_as_string ( nua_handle_home ( nh ) , ( void * ) sip - > sip_call_info ) ) ;
2009-04-27 23:36:03 +00:00
}
if ( alert_info ) {
switch_event_add_header_string ( event , SWITCH_STACK_BOTTOM , " Alert-Info " , sip_header_as_string ( nua_handle_home ( nh ) , ( void * ) alert_info ) ) ;
}
2009-04-20 19:00:39 +00:00
if ( sip - > sip_payload & & sip - > sip_payload - > pl_data ) {
2009-04-20 17:07:54 +00:00
switch_event_add_body ( event , " %s " , sip - > sip_payload - > pl_data ) ;
}
switch_event_fire ( & event ) ;
2009-08-13 20:35:02 +00:00
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( session ) , SWITCH_LOG_DEBUG , " dispatched freeswitch event for INFO \n " ) ;
2009-04-20 17:07:54 +00:00
}
2009-04-20 19:00:39 +00:00
nua_respond ( nh , SIP_200_OK , NUTAG_WITH_THIS ( nua ) , TAG_END ( ) ) ;
2009-04-20 17:07:54 +00:00
return ;
2007-03-31 19:01:33 +00:00
}
2010-02-06 03:38:24 +00:00
void sofia_handle_sip_i_reinvite ( switch_core_session_t * session ,
nua_t * nua , sofia_profile_t * profile , nua_handle_t * nh , sofia_private_t * sofia_private , sip_t const * sip ,
tagi_t tags [ ] )
2010-01-15 00:31:43 +00:00
{
char * call_info = NULL ;
if ( sofia_test_pflag ( profile , PFLAG_MANAGE_SHARED_APPEARANCE ) ) {
switch_channel_t * channel = switch_core_session_get_channel ( session ) ;
if ( channel & & sip - > sip_call_info ) {
char * p ;
if ( ( call_info = sip_header_as_string ( nua_handle_home ( nh ) , ( void * ) sip - > sip_call_info ) ) ) {
2010-01-28 20:52:28 +00:00
if ( switch_stristr ( " appearance " , call_info ) ) {
2010-01-28 20:35:17 +00:00
switch_channel_set_variable ( channel , " presence_call_info_full " , call_info ) ;
if ( ( p = strchr ( call_info , ' ; ' ) ) ) {
2010-02-06 03:38:24 +00:00
switch_channel_set_variable ( channel , " presence_call_info " , p + 1 ) ;
2010-01-28 20:35:17 +00:00
}
2010-01-15 00:31:43 +00:00
}
su_free ( nua_handle_home ( nh ) , call_info ) ;
}
}
}
}
2007-04-13 22:15:58 +00:00
void sofia_handle_sip_i_invite ( nua_t * nua , sofia_profile_t * profile , nua_handle_t * nh , sofia_private_t * sofia_private , sip_t const * sip , tagi_t tags [ ] )
2007-03-31 19:01:33 +00:00
{
switch_core_session_t * session = NULL ;
char key [ 128 ] = " " ;
sip_unknown_t * un ;
2007-11-19 21:34:27 +00:00
sip_remote_party_id_t * rpid = NULL ;
2008-01-07 20:27:48 +00:00
sip_p_asserted_identity_t * passerted = NULL ;
sip_p_preferred_identity_t * ppreferred = NULL ;
2008-10-21 20:01:48 +00:00
sip_privacy_t * privacy = NULL ;
2007-11-19 23:29:32 +00:00
sip_alert_info_t * alert_info = NULL ;
2009-04-09 22:34:59 +00:00
sip_call_info_t * call_info = NULL ;
2007-03-31 19:01:33 +00:00
private_object_t * tech_pvt = NULL ;
switch_channel_t * channel = NULL ;
const char * channel_name = NULL ;
const char * displayname = NULL ;
const char * destination_number = NULL ;
const char * from_user = NULL , * from_host = NULL ;
2008-01-12 19:53:12 +00:00
const char * referred_by_user = NULL , * referred_by_host = NULL ;
2007-03-31 19:01:33 +00:00
const char * context = NULL ;
2007-10-31 22:26:54 +00:00
const char * dialplan = NULL ;
2007-03-31 19:01:33 +00:00
char network_ip [ 80 ] ;
2009-09-08 22:16:45 +00:00
char proxied_client_ip [ 80 ] ;
2007-04-30 16:26:44 +00:00
switch_event_t * v_event = NULL ;
2007-05-11 00:27:55 +00:00
uint32_t sess_count = switch_core_session_count ( ) ;
uint32_t sess_max = switch_core_session_limit ( 0 ) ;
2008-01-03 23:42:15 +00:00
int is_auth = 0 , calling_myself = 0 ;
2008-05-13 23:22:21 +00:00
int network_port = 0 ;
2008-05-21 16:46:48 +00:00
char * is_nat = NULL ;
2009-11-21 06:40:38 +00:00
char * aniii = NULL ;
2009-03-20 22:03:43 +00:00
char acl_token [ 512 ] = " " ;
2009-06-03 21:08:34 +00:00
sofia_transport_t transport ;
2009-10-16 19:51:32 +00:00
const char * gw_name = NULL ;
2009-12-24 05:44:23 +00:00
char * call_info_str = NULL ;
nua_handle_t * bnh = NULL ;
2008-03-04 23:53:23 +00:00
2009-04-21 17:47:22 +00:00
profile - > ib_calls + + ;
2009-02-09 17:56:38 +00:00
if ( sess_count > = sess_max | | ! sofia_test_pflag ( profile , PFLAG_RUNNING ) ) {
2008-04-07 17:06:44 +00:00
nua_respond ( nh , 503 , " Maximum Calls In Progress " , SIPTAG_RETRY_AFTER_STR ( " 300 " ) , TAG_END ( ) ) ;
2009-04-21 17:47:22 +00:00
goto fail ;
2007-05-11 00:27:55 +00:00
}
2007-03-31 19:01:33 +00:00
if ( ! sip | | ! sip - > sip_request | | ! sip - > sip_request - > rq_method_name ) {
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_ERROR , " Received an invalid packet! \n " ) ;
2007-05-11 00:27:55 +00:00
nua_respond ( nh , SIP_503_SERVICE_UNAVAILABLE , TAG_END ( ) ) ;
2009-04-21 17:47:22 +00:00
goto fail ;
2007-03-31 19:01:33 +00:00
}
2008-05-27 04:54:52 +00:00
2009-01-23 16:22:50 +00:00
if ( ! ( sip - > sip_contact & & sip - > sip_contact - > m_url ) ) {
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_ERROR , " NO CONTACT! \n " ) ;
nua_respond ( nh , 400 , " Missing Contact Header " , TAG_END ( ) ) ;
2009-04-21 17:47:22 +00:00
goto fail ;
2009-01-23 16:22:50 +00:00
}
2010-02-06 03:38:24 +00:00
sofia_glue_get_addr ( nua_current_request ( nua ) , network_ip , sizeof ( network_ip ) , & network_port ) ;
2008-05-21 16:46:48 +00:00
2009-02-09 17:56:38 +00:00
if ( sofia_test_pflag ( profile , PFLAG_AGGRESSIVE_NAT_DETECTION ) ) {
2008-05-21 16:46:48 +00:00
if ( sip & & sip - > sip_via ) {
const char * port = sip - > sip_via - > v_port ;
const char * host = sip - > sip_via - > v_host ;
2008-05-27 04:54:52 +00:00
2008-05-21 21:49:27 +00:00
if ( host & & sip - > sip_via - > v_received ) {
is_nat = " via received " ;
} else if ( host & & strcmp ( network_ip , host ) ) {
2008-05-21 16:46:48 +00:00
is_nat = " via host " ;
} else if ( port & & atoi ( port ) ! = network_port ) {
is_nat = " via port " ;
}
}
}
if ( ! is_nat & & profile - > nat_acl_count ) {
2008-05-20 16:41:57 +00:00
uint32_t x = 0 ;
int ok = 1 ;
char * last_acl = NULL ;
const char * contact_host = NULL ;
if ( sip & & sip - > sip_contact & & sip - > sip_contact - > m_url ) {
contact_host = sip - > sip_contact - > m_url - > url_host ;
}
2009-10-23 16:03:42 +00:00
if ( ! zstr ( contact_host ) ) {
2008-05-27 04:54:52 +00:00
for ( x = 0 ; x < profile - > nat_acl_count ; x + + ) {
2008-05-20 16:41:57 +00:00
last_acl = profile - > nat_acl [ x ] ;
if ( ! ( ok = switch_check_network_list_ip ( contact_host , last_acl ) ) ) {
break ;
}
}
2008-05-27 04:54:52 +00:00
2008-05-20 16:41:57 +00:00
if ( ok ) {
is_nat = last_acl ;
}
}
}
2010-02-06 03:38:24 +00:00
2008-03-26 22:14:09 +00:00
if ( profile - > acl_count ) {
2008-03-31 16:05:32 +00:00
uint32_t x = 0 ;
2008-05-13 20:58:38 +00:00
int ok = 1 ;
char * last_acl = NULL ;
2008-07-16 20:00:23 +00:00
const char * token = NULL ;
2008-05-13 20:58:38 +00:00
2008-05-27 04:54:52 +00:00
for ( x = 0 ; x < profile - > acl_count ; x + + ) {
2008-05-13 20:58:38 +00:00
last_acl = profile - > acl [ x ] ;
2008-07-16 17:44:54 +00:00
if ( ! ( ok = switch_check_network_list_ip_token ( network_ip , last_acl , & token ) ) ) {
2008-05-13 20:58:38 +00:00
break ;
}
}
2008-05-15 01:10:52 +00:00
if ( ok ) {
2008-07-16 17:44:54 +00:00
if ( token ) {
2009-03-20 22:03:43 +00:00
switch_set_string ( acl_token , token ) ;
2008-07-16 17:44:54 +00:00
}
2009-02-09 17:56:38 +00:00
if ( sofia_test_pflag ( profile , PFLAG_AUTH_CALLS ) ) {
2008-11-02 20:14:12 +00:00
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_DEBUG , " IP %s Approved by acl \" %s[%s] \" . Access Granted. \n " ,
2009-03-20 22:03:43 +00:00
network_ip , switch_str_nil ( last_acl ) , acl_token ) ;
2008-05-15 01:10:52 +00:00
is_auth = 1 ;
}
} else {
2009-09-08 22:16:45 +00:00
int network_ip_is_proxy = 0 ;
/* Check if network_ip is a proxy allowed to send us calls */
2010-01-12 01:23:19 +00:00
if ( profile - > proxy_acl_count ) {
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_DEBUG , " %d acls to check for proxy \n " , profile - > proxy_acl_count ) ;
}
2010-02-06 03:38:24 +00:00
2009-09-08 22:16:45 +00:00
for ( x = 0 ; x < profile - > proxy_acl_count ; x + + ) {
last_acl = profile - > proxy_acl [ x ] ;
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_DEBUG , " checking %s against acl %s \n " , network_ip , last_acl ) ;
if ( switch_check_network_list_ip_token ( network_ip , last_acl , & token ) ) {
2010-02-06 03:38:24 +00:00
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_INFO , " %s is a proxy according to the %s acl \n " , network_ip , last_acl ) ;
2009-09-08 22:16:45 +00:00
network_ip_is_proxy = 1 ;
break ;
}
}
/*
* if network_ip is a proxy allowed to send calls , check for auth
* ip header and see if it matches against the inbound acl
*/
if ( network_ip_is_proxy ) {
2010-01-12 01:23:19 +00:00
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_DEBUG , " network ip is a proxy \n " ) ;
2010-02-06 03:38:24 +00:00
2009-09-08 22:16:45 +00:00
for ( un = sip - > sip_unknown ; un ; un = un - > un_next ) {
if ( ! strcasecmp ( un - > un_name , " X-AUTH-IP " ) ) {
2010-02-06 03:38:24 +00:00
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_DEBUG , " found auth ip [%s] header of [%s] \n " , un - > un_name , un - > un_value ) ;
2009-10-23 16:03:42 +00:00
if ( ! zstr ( un - > un_value ) ) {
2009-09-08 22:16:45 +00:00
for ( x = 0 ; x < profile - > acl_count ; x + + ) {
last_acl = profile - > acl [ x ] ;
if ( ( ok = switch_check_network_list_ip_token ( un - > un_value , last_acl , & token ) ) ) {
2010-02-06 03:38:24 +00:00
switch_copy_string ( proxied_client_ip , un - > un_value , sizeof ( proxied_client_ip ) ) ;
2009-09-08 22:16:45 +00:00
break ;
}
}
}
}
}
}
2010-02-06 03:38:24 +00:00
2009-09-08 22:16:45 +00:00
if ( ! ok ) {
if ( ! sofia_test_pflag ( profile , PFLAG_AUTH_CALLS ) ) {
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_WARNING , " IP %s Rejected by acl \" %s \" \n " , network_ip , switch_str_nil ( last_acl ) ) ;
nua_respond ( nh , SIP_403_FORBIDDEN , TAG_END ( ) ) ;
goto fail ;
} else {
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_DEBUG , " IP %s Rejected by acl \" %s \" . Falling back to Digest auth. \n " ,
network_ip , switch_str_nil ( last_acl ) ) ;
}
2008-05-13 20:58:38 +00:00
} else {
2009-09-08 22:16:45 +00:00
if ( token ) {
switch_set_string ( acl_token , token ) ;
}
if ( sofia_test_pflag ( profile , PFLAG_AUTH_CALLS ) ) {
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_DEBUG , " IP %s Approved by acl \" %s[%s] \" . Access Granted. \n " ,
proxied_client_ip , switch_str_nil ( last_acl ) , acl_token ) ;
is_auth = 1 ;
}
2008-03-26 22:14:09 +00:00
}
}
}
2008-05-27 04:54:52 +00:00
if ( ! is_auth & &
2010-02-06 03:38:24 +00:00
( sofia_test_pflag ( profile , PFLAG_AUTH_CALLS )
| | ( ! sofia_test_pflag ( profile , PFLAG_BLIND_AUTH ) & & ( sip - > sip_proxy_authorization | | sip - > sip_authorization ) ) ) ) {
2008-05-13 23:22:21 +00:00
if ( ! strcmp ( network_ip , profile - > sipip ) & & network_port = = profile - > sip_port ) {
2008-04-30 20:03:20 +00:00
calling_myself + + ;
} else {
2008-05-21 21:49:27 +00:00
if ( sofia_reg_handle_register ( nua , profile , nh , sip , REG_INVITE , key , sizeof ( key ) , & v_event , NULL ) ) {
2008-01-03 23:42:15 +00:00
if ( v_event ) {
switch_event_destroy ( & v_event ) ;
}
2010-02-06 03:38:24 +00:00
2009-04-21 17:47:22 +00:00
if ( sip - > sip_authorization | | sip - > sip_proxy_authorization ) {
goto fail ;
}
2008-01-03 23:42:15 +00:00
return ;
2007-04-30 16:26:44 +00:00
}
2007-03-31 19:01:33 +00:00
}
2007-06-08 23:12:57 +00:00
is_auth + + ;
2007-03-31 19:01:33 +00:00
}
2008-02-22 15:02:16 +00:00
2008-11-15 17:44:27 +00:00
if ( sofia_endpoint_interface ) {
2009-02-09 17:56:38 +00:00
if ( sofia_test_pflag ( profile , PFLAG_CALLID_AS_UUID ) ) {
2009-02-23 16:31:59 +00:00
session = switch_core_session_request_uuid ( sofia_endpoint_interface , SWITCH_CALL_DIRECTION_INBOUND , NULL , sip - > sip_call_id - > i_id ) ;
2008-11-15 17:44:27 +00:00
} else {
2009-02-23 16:31:59 +00:00
session = switch_core_session_request ( sofia_endpoint_interface , SWITCH_CALL_DIRECTION_INBOUND , NULL ) ;
2008-11-15 17:44:27 +00:00
}
}
if ( ! session ) {
2008-04-07 17:06:44 +00:00
nua_respond ( nh , 503 , " Maximum Calls In Progress " , SIPTAG_RETRY_AFTER_STR ( " 300 " ) , TAG_END ( ) ) ;
2009-04-21 17:47:22 +00:00
goto fail ;
2007-03-31 19:01:33 +00:00
}
if ( ! ( tech_pvt = ( private_object_t * ) switch_core_session_alloc ( session , sizeof ( private_object_t ) ) ) ) {
2009-08-13 20:35:02 +00:00
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( session ) , SWITCH_LOG_CRIT , " Hey where is my memory pool? \n " ) ;
2007-03-31 19:01:33 +00:00
nua_respond ( nh , SIP_503_SERVICE_UNAVAILABLE , TAG_END ( ) ) ;
2007-04-17 18:53:18 +00:00
switch_core_session_destroy ( & session ) ;
2009-04-21 17:47:22 +00:00
goto fail ;
2007-03-31 19:01:33 +00:00
}
2008-05-21 16:46:48 +00:00
2007-04-13 22:15:58 +00:00
switch_mutex_init ( & tech_pvt - > flag_mutex , SWITCH_MUTEX_NESTED , switch_core_session_get_pool ( session ) ) ;
2008-10-30 22:40:39 +00:00
switch_mutex_init ( & tech_pvt - > sofia_mutex , SWITCH_MUTEX_NESTED , switch_core_session_get_pool ( session ) ) ;
2007-03-31 19:01:33 +00:00
2008-05-13 23:22:21 +00:00
tech_pvt - > remote_ip = switch_core_session_strdup ( session , network_ip ) ;
tech_pvt - > remote_port = network_port ;
2008-05-14 14:22:04 +00:00
channel = tech_pvt - > channel = switch_core_session_get_channel ( session ) ;
2010-02-06 03:38:24 +00:00
switch_channel_set_variable_printf ( channel , " sip_network_ip " , " %s " , network_ip ) ;
switch_channel_set_variable_printf ( channel , " sip_network_port " , " %d " , network_port ) ;
2009-03-20 22:03:43 +00:00
if ( * acl_token ) {
2008-07-16 17:44:54 +00:00
switch_channel_set_variable ( channel , " acl_token " , acl_token ) ;
if ( strchr ( acl_token , ' @ ' ) ) {
if ( switch_ivr_set_user ( session , acl_token ) = = SWITCH_STATUS_SUCCESS ) {
2009-08-13 20:35:02 +00:00
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( session ) , SWITCH_LOG_DEBUG , " Authenticating user %s \n " , acl_token ) ;
2008-07-16 17:44:54 +00:00
} else {
2009-08-13 20:35:02 +00:00
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( session ) , SWITCH_LOG_WARNING , " Error Authenticating user %s \n " , acl_token ) ;
2008-07-16 17:44:54 +00:00
}
}
}
2008-05-13 23:22:21 +00:00
if ( sip - > sip_contact & & sip - > sip_contact - > m_url ) {
2008-05-14 14:13:40 +00:00
char tmp [ 35 ] = " " ;
2008-07-03 18:50:15 +00:00
const char * ipv6 = strchr ( tech_pvt - > remote_ip , ' : ' ) ;
2009-06-03 21:08:34 +00:00
transport = sofia_glue_url2transport ( sip - > sip_contact - > m_url ) ;
2008-07-03 18:50:15 +00:00
tech_pvt - > record_route =
switch_core_session_sprintf ( session ,
2010-02-06 03:38:24 +00:00
" sip:%s@%s%s%s:%d;transport=%s " ,
sip - > sip_contact - > m_url - > url_user ,
ipv6 ? " [ " : " " , tech_pvt - > remote_ip , ipv6 ? " ] " : " " , tech_pvt - > remote_port , sofia_glue_transport2str ( transport ) ) ;
2008-07-03 18:50:15 +00:00
2008-05-14 14:13:40 +00:00
switch_channel_set_variable ( channel , " sip_received_ip " , tech_pvt - > remote_ip ) ;
2008-05-16 15:05:54 +00:00
snprintf ( tmp , sizeof ( tmp ) , " %d " , tech_pvt - > remote_port ) ;
2008-05-14 14:13:40 +00:00
switch_channel_set_variable ( channel , " sip_received_port " , tmp ) ;
2008-05-13 23:22:21 +00:00
}
2008-10-10 01:06:03 +00:00
if ( sip - > sip_via ) {
switch_channel_set_variable ( channel , " sip_via_protocol " , sofia_glue_transport2str ( sofia_glue_via2transport ( sip - > sip_via ) ) ) ;
}
2007-08-03 21:29:01 +00:00
if ( * key ! = ' \0 ' ) {
2007-03-31 19:01:33 +00:00
tech_pvt - > key = switch_core_session_strdup ( session , key ) ;
}
2008-05-27 04:54:52 +00:00
2007-06-08 23:12:57 +00:00
if ( is_auth ) {
switch_channel_set_variable ( channel , " sip_authorized " , " true " ) ;
}
2007-06-08 22:28:32 +00:00
2008-01-03 23:42:15 +00:00
if ( calling_myself ) {
switch_channel_set_variable ( channel , " sip_looped_call " , " true " ) ;
}
2007-04-30 16:26:44 +00:00
if ( v_event ) {
switch_event_header_t * hp ;
2008-05-27 04:54:52 +00:00
for ( hp = v_event - > headers ; hp ; hp = hp - > next ) {
2007-04-30 16:26:44 +00:00
switch_channel_set_variable ( channel , hp - > name , hp - > value ) ;
}
switch_event_destroy ( & v_event ) ;
}
2007-03-31 19:01:33 +00:00
if ( sip - > sip_from & & sip - > sip_from - > a_url ) {
2010-02-06 03:38:24 +00:00
char * tmp ;
2007-03-31 19:01:33 +00:00
from_user = sip - > sip_from - > a_url - > url_user ;
from_host = sip - > sip_from - > a_url - > url_host ;
channel_name = url_set_chanvars ( session , sip - > sip_from - > a_url , sip_from ) ;
2010-01-21 02:51:04 +00:00
2009-11-21 06:40:38 +00:00
if ( sip - > sip_from - > a_url - > url_params & & ( tmp = sofia_glue_find_parameter ( sip - > sip_from - > a_url - > url_params , " isup-oli= " ) ) ) {
aniii = switch_core_session_strdup ( session , tmp + 9 ) ;
if ( ( tmp = strchr ( aniii , ' ; ' ) ) ) {
tmp = ' \0 ' ;
}
}
2007-03-31 19:01:33 +00:00
2009-10-23 16:03:42 +00:00
if ( ! zstr ( from_user ) ) {
2007-03-31 19:01:33 +00:00
if ( * from_user = = ' + ' ) {
switch_channel_set_variable ( channel , " sip_from_user_stripped " , ( const char * ) ( from_user + 1 ) ) ;
} else {
switch_channel_set_variable ( channel , " sip_from_user_stripped " , from_user ) ;
}
}
2008-01-12 19:53:12 +00:00
switch_channel_set_variable ( channel , " sip_from_comment " , sip - > sip_from - > a_comment ) ;
2008-01-12 19:56:47 +00:00
if ( sip - > sip_from - > a_params ) {
2008-01-12 19:53:12 +00:00
set_variable_sip_param ( channel , " from " , sip - > sip_from - > a_params ) ;
2008-01-12 19:56:47 +00:00
}
2008-01-12 19:53:12 +00:00
2007-09-21 19:20:15 +00:00
switch_channel_set_variable ( channel , " sofia_profile_name " , profile - > name ) ;
2008-01-21 20:14:53 +00:00
switch_channel_set_variable ( channel , " sofia_profile_domain_name " , profile - > domain_name ) ;
2007-09-21 19:20:15 +00:00
2009-10-23 16:03:42 +00:00
if ( ! zstr ( sip - > sip_from - > a_display ) ) {
2007-11-19 23:29:32 +00:00
displayname = sip - > sip_from - > a_display ;
2007-03-31 19:01:33 +00:00
} else {
2009-10-23 16:03:42 +00:00
displayname = zstr ( from_user ) ? " unknown " : from_user ;
2007-03-31 19:01:33 +00:00
}
}
2007-11-19 23:29:32 +00:00
if ( ( rpid = sip_remote_party_id ( sip ) ) ) {
if ( rpid - > rpid_url & & rpid - > rpid_url - > url_user ) {
2010-02-06 03:38:24 +00:00
char * full_rpid_header = sip_header_as_string ( nh - > nh_home , ( void * ) rpid ) ;
2007-11-19 23:29:32 +00:00
from_user = rpid - > rpid_url - > url_user ;
2009-10-23 16:03:42 +00:00
if ( ! zstr ( full_rpid_header ) ) {
2009-07-01 15:02:27 +00:00
switch_channel_set_variable ( channel , " sip_Remote-Party-ID " , full_rpid_header ) ;
}
2009-06-26 17:33:19 +00:00
2007-11-19 23:29:32 +00:00
}
2009-10-23 16:03:42 +00:00
if ( ! zstr ( rpid - > rpid_display ) ) {
2007-11-19 23:29:32 +00:00
displayname = rpid - > rpid_display ;
}
2009-03-04 23:03:25 +00:00
switch_channel_set_variable ( channel , " sip_cid_type " , " rpid " ) ;
2009-11-15 02:16:10 +00:00
tech_pvt - > cid_type = CID_TYPE_RPID ;
2007-11-19 23:29:32 +00:00
}
2008-01-07 20:27:48 +00:00
if ( ( passerted = sip_p_asserted_identity ( sip ) ) ) {
if ( passerted - > paid_url & & passerted - > paid_url - > url_user ) {
2009-07-01 15:02:27 +00:00
char * full_paid_header = sip_header_as_string ( nh - > nh_home , ( void * ) passerted ) ;
2008-01-07 20:27:48 +00:00
from_user = passerted - > paid_url - > url_user ;
2009-10-23 16:03:42 +00:00
if ( ! zstr ( full_paid_header ) ) {
2009-07-01 15:02:27 +00:00
switch_channel_set_variable ( channel , " sip_P-Asserted-Identity " , from_user ) ;
}
2008-01-07 20:27:48 +00:00
}
2009-10-23 16:03:42 +00:00
if ( ! zstr ( passerted - > paid_display ) ) {
2008-01-07 20:27:48 +00:00
displayname = passerted - > paid_display ;
}
2009-03-04 23:03:25 +00:00
switch_channel_set_variable ( channel , " sip_cid_type " , " pid " ) ;
2009-11-15 02:16:10 +00:00
tech_pvt - > cid_type = CID_TYPE_PID ;
2008-01-07 20:27:48 +00:00
}
if ( ( ppreferred = sip_p_preferred_identity ( sip ) ) ) {
if ( ppreferred - > ppid_url & & ppreferred - > ppid_url - > url_user ) {
2009-07-01 15:02:27 +00:00
char * full_ppid_header = sip_header_as_string ( nh - > nh_home , ( void * ) ppreferred ) ;
2008-01-07 20:27:48 +00:00
from_user = ppreferred - > ppid_url - > url_user ;
2009-10-23 16:03:42 +00:00
if ( ! zstr ( full_ppid_header ) ) {
2009-07-01 15:02:27 +00:00
switch_channel_set_variable ( channel , " sip_P-Preferred-Identity " , full_ppid_header ) ;
}
2010-02-06 03:38:24 +00:00
2008-01-07 20:27:48 +00:00
}
2009-10-23 16:03:42 +00:00
if ( ! zstr ( ppreferred - > ppid_display ) ) {
2008-01-07 20:27:48 +00:00
displayname = ppreferred - > ppid_display ;
}
2009-03-04 23:03:25 +00:00
switch_channel_set_variable ( channel , " sip_cid_type " , " pid " ) ;
2009-11-15 02:16:10 +00:00
tech_pvt - > cid_type = CID_TYPE_PID ;
2008-01-07 20:27:48 +00:00
}
if ( from_user ) {
check_decode ( from_user , session ) ;
}
2010-02-06 03:38:24 +00:00
extract_header_vars ( profile , sip , session ) ;
2007-03-31 19:01:33 +00:00
if ( sip - > sip_request - > rq_url ) {
const char * req_uri = url_set_chanvars ( session , sip - > sip_request - > rq_url , sip_req ) ;
2009-02-09 17:56:38 +00:00
if ( sofia_test_pflag ( profile , PFLAG_FULL_ID ) ) {
2007-03-31 19:01:33 +00:00
destination_number = req_uri ;
} else {
destination_number = sip - > sip_request - > rq_url - > url_user ;
}
2009-07-13 15:50:05 +00:00
if ( sip - > sip_request - > rq_url - > url_params & & ( sofia_glue_find_parameter ( sip - > sip_request - > rq_url - > url_params , " intercom=true " ) ) ) {
switch_channel_set_variable ( channel , " sip_auto_answer_detected " , " true " ) ;
}
2007-03-31 19:01:33 +00:00
}
2009-02-04 20:25:46 +00:00
if ( ! destination_number & & sip - > sip_to & & sip - > sip_to - > a_url ) {
destination_number = sip - > sip_to - > a_url - > url_user ;
}
2010-01-13 01:40:11 +00:00
/* The human network, OH THE HUMANITY!!! lets send invites with no number! */
if ( ! destination_number & & sip - > sip_from & & sip - > sip_from - > a_url ) {
destination_number = sip - > sip_from - > a_url - > url_user ;
}
2010-02-06 03:38:24 +00:00
2009-02-04 20:25:46 +00:00
if ( destination_number ) {
check_decode ( destination_number , session ) ;
} else {
destination_number = " service " ;
}
2010-02-06 03:38:24 +00:00
2007-03-31 19:01:33 +00:00
if ( sip - > sip_to & & sip - > sip_to - > a_url ) {
2007-12-18 19:12:45 +00:00
const char * host , * user ;
int port ;
2008-03-13 23:19:55 +00:00
url_t * transport_url ;
if ( sip - > sip_record_route & & sip - > sip_record_route - > r_url ) {
transport_url = sip - > sip_record_route - > r_url ;
} else {
transport_url = sip - > sip_contact - > m_url ;
}
2008-04-09 19:16:14 +00:00
transport = sofia_glue_url2transport ( transport_url ) ;
tech_pvt - > transport = transport ;
2007-12-18 19:12:45 +00:00
2007-03-31 19:01:33 +00:00
url_set_chanvars ( session , sip - > sip_to - > a_url , sip_to ) ;
2007-12-18 19:12:45 +00:00
if ( switch_channel_get_variable ( channel , " sip_to_uri " ) ) {
2008-07-03 18:50:15 +00:00
const char * ipv6 ;
2009-07-10 19:22:39 +00:00
const char * tmp , * at , * url = NULL ;
2010-02-06 03:38:24 +00:00
2007-12-18 19:12:45 +00:00
host = switch_channel_get_variable ( channel , " sip_to_host " ) ;
user = switch_channel_get_variable ( channel , " sip_to_user " ) ;
2008-05-27 04:54:52 +00:00
2008-01-12 19:53:12 +00:00
switch_channel_set_variable ( channel , " sip_to_comment " , sip - > sip_to - > a_comment ) ;
2008-01-12 19:56:47 +00:00
if ( sip - > sip_to - > a_params ) {
2008-01-12 19:53:12 +00:00
set_variable_sip_param ( channel , " to " , sip - > sip_to - > a_params ) ;
2008-01-12 19:56:47 +00:00
}
2007-12-18 19:12:45 +00:00
if ( sip - > sip_contact - > m_url - > url_port ) {
port = atoi ( sip - > sip_contact - > m_url - > url_port ) ;
} else {
port = sofia_glue_transport_has_tls ( transport ) ? profile - > tls_sip_port : profile - > sip_port ;
}
2008-07-03 18:50:15 +00:00
ipv6 = strchr ( host , ' : ' ) ;
tech_pvt - > to_uri =
switch_core_session_sprintf ( session ,
2010-02-06 03:38:24 +00:00
" sip:%s@%s%s%s:%d;transport=%s " ,
user , ipv6 ? " [ " : " " , host , ipv6 ? " ] " : " " , port , sofia_glue_transport2str ( transport ) ) ;
2007-12-18 19:12:45 +00:00
2009-06-11 17:17:52 +00:00
if ( sofia_glue_check_nat ( profile , tech_pvt - > remote_ip ) ) {
url = ( sofia_glue_transport_has_tls ( transport ) ) ? profile - > tls_public_url : profile - > public_url ;
2010-02-06 03:38:24 +00:00
} else {
2009-06-11 17:17:52 +00:00
url = ( sofia_glue_transport_has_tls ( transport ) ) ? profile - > tls_url : profile - > url ;
2010-02-06 03:38:24 +00:00
}
2009-07-10 19:22:39 +00:00
tmp = sofia_overcome_sip_uri_weakness ( session , url , transport , SWITCH_TRUE , NULL ) ;
2010-02-06 03:38:24 +00:00
2009-07-10 19:22:39 +00:00
if ( ( at = strchr ( tmp , ' @ ' ) ) ) {
url = switch_core_session_sprintf ( session , " sip:%s%s " , user , at ) ;
2009-06-11 17:17:52 +00:00
}
if ( url ) {
2009-07-14 19:49:34 +00:00
const char * brackets = NULL ;
const char * proto = NULL ;
2010-02-06 03:38:24 +00:00
2009-07-14 19:49:34 +00:00
brackets = strchr ( url , ' > ' ) ;
proto = switch_stristr ( " transport= " , url ) ;
tech_pvt - > reply_contact = switch_core_session_sprintf ( session , " %s%s%s%s%s " ,
brackets ? " " : " < " , url ,
proto ? " " : " ;transport= " ,
2010-02-06 03:38:24 +00:00
proto ? " " : sofia_glue_transport2str ( transport ) , brackets ? " " : " > " ) ;
2009-06-11 17:17:52 +00:00
} else {
switch_channel_hangup ( tech_pvt - > channel , SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER ) ;
2007-05-29 14:59:03 +00:00
}
2010-02-06 03:38:24 +00:00
2007-05-21 21:44:35 +00:00
} else {
2009-06-03 21:08:34 +00:00
const char * url = NULL ;
if ( sofia_glue_check_nat ( profile , tech_pvt - > remote_ip ) ) {
2010-02-06 03:38:24 +00:00
url = ( sofia_glue_transport_has_tls ( transport ) ) ? profile - > tls_public_url : profile - > public_url ;
} else {
2009-06-03 21:08:34 +00:00
url = ( sofia_glue_transport_has_tls ( transport ) ) ? profile - > tls_url : profile - > url ;
2010-02-06 03:38:24 +00:00
}
2009-06-03 21:08:34 +00:00
if ( url ) {
2009-07-14 19:49:34 +00:00
const char * brackets = NULL ;
const char * proto = NULL ;
2010-02-06 03:38:24 +00:00
2009-07-14 19:49:34 +00:00
brackets = strchr ( url , ' > ' ) ;
proto = switch_stristr ( " transport= " , url ) ;
tech_pvt - > reply_contact = switch_core_session_sprintf ( session , " %s%s%s%s%s " ,
brackets ? " " : " < " , url ,
proto ? " " : " ;transport= " ,
2010-02-06 03:38:24 +00:00
proto ? " " : sofia_glue_transport2str ( transport ) , brackets ? " " : " > " ) ;
2007-10-24 00:06:33 +00:00
} else {
2008-01-18 15:43:57 +00:00
switch_channel_hangup ( tech_pvt - > channel , SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER ) ;
2007-10-24 00:06:33 +00:00
}
2007-05-21 21:44:35 +00:00
}
2007-03-31 19:01:33 +00:00
}
2010-02-06 03:38:24 +00:00
2009-06-03 21:08:34 +00:00
if ( sofia_glue_check_nat ( profile , tech_pvt - > remote_ip ) ) {
tech_pvt - > user_via = sofia_glue_create_external_via ( session , profile , tech_pvt - > transport ) ;
}
2007-03-31 19:01:33 +00:00
if ( sip - > sip_contact & & sip - > sip_contact - > m_url ) {
const char * contact_uri = url_set_chanvars ( session , sip - > sip_contact - > m_url , sip_contact ) ;
if ( ! channel_name ) {
channel_name = contact_uri ;
}
}
2008-01-12 19:53:12 +00:00
if ( sip - > sip_referred_by ) {
referred_by_user = sip - > sip_referred_by - > b_url - > url_user ;
referred_by_host = sip - > sip_referred_by - > b_url - > url_host ;
channel_name = url_set_chanvars ( session , sip - > sip_referred_by - > b_url , sip_referred_by ) ;
check_decode ( referred_by_user , session ) ;
2009-10-23 16:03:42 +00:00
if ( ! zstr ( referred_by_user ) ) {
2008-01-12 19:53:12 +00:00
if ( * referred_by_user = = ' + ' ) {
switch_channel_set_variable ( channel , " sip_referred_by_user_stripped " , ( const char * ) ( referred_by_user + 1 ) ) ;
} else {
switch_channel_set_variable ( channel , " sip_referred_by_user_stripped " , referred_by_user ) ;
}
}
switch_channel_set_variable ( channel , " sip_referred_by_cid " , sip - > sip_referred_by - > b_cid ) ;
2008-01-12 19:56:47 +00:00
if ( sip - > sip_referred_by - > b_params ) {
2008-01-12 19:53:12 +00:00
set_variable_sip_param ( channel , " referred_by " , sip - > sip_referred_by - > b_params ) ;
2008-01-12 19:56:47 +00:00
}
2008-01-12 19:53:12 +00:00
}
2007-03-31 19:01:33 +00:00
sofia_glue_attach_private ( session , profile , tech_pvt , channel_name ) ;
2007-04-17 06:08:39 +00:00
sofia_glue_tech_prepare_codecs ( tech_pvt ) ;
2007-03-31 19:01:33 +00:00
switch_channel_set_variable ( channel , SWITCH_ENDPOINT_DISPOSITION_VARIABLE , " INBOUND CALL " ) ;
2009-02-09 17:56:38 +00:00
if ( sofia_test_flag ( tech_pvt , TFLAG_INB_NOMEDIA ) ) {
2008-02-21 17:48:41 +00:00
switch_channel_set_flag ( channel , CF_PROXY_MODE ) ;
}
2009-02-09 17:56:38 +00:00
if ( sofia_test_flag ( tech_pvt , TFLAG_PROXY_MEDIA ) ) {
2008-02-21 17:48:41 +00:00
switch_channel_set_flag ( channel , CF_PROXY_MEDIA ) ;
2007-03-31 19:01:33 +00:00
}
if ( ! tech_pvt - > call_id & & sip - > sip_call_id & & sip - > sip_call_id - > i_id ) {
tech_pvt - > call_id = switch_core_session_strdup ( session , sip - > sip_call_id - > i_id ) ;
switch_channel_set_variable ( channel , " sip_call_id " , tech_pvt - > call_id ) ;
}
2007-05-04 22:38:24 +00:00
if ( sip - > sip_subject & & sip - > sip_subject - > g_string ) {
switch_channel_set_variable ( channel , " sip_subject " , sip - > sip_subject - > g_string ) ;
}
2008-05-27 04:54:52 +00:00
2009-10-23 16:03:42 +00:00
if ( sip - > sip_user_agent & & ! zstr ( sip - > sip_user_agent - > g_string ) ) {
2007-12-22 20:51:57 +00:00
switch_channel_set_variable ( channel , " sip_user_agent " , sip - > sip_user_agent - > g_string ) ;
}
2007-05-04 22:38:24 +00:00
2007-03-31 19:01:33 +00:00
if ( sip - > sip_via ) {
if ( sip - > sip_via - > v_host ) {
switch_channel_set_variable ( channel , " sip_via_host " , sip - > sip_via - > v_host ) ;
}
if ( sip - > sip_via - > v_port ) {
switch_channel_set_variable ( channel , " sip_via_port " , sip - > sip_via - > v_port ) ;
}
if ( sip - > sip_via - > v_rport ) {
switch_channel_set_variable ( channel , " sip_via_rport " , sip - > sip_via - > v_rport ) ;
}
}
if ( sip - > sip_max_forwards ) {
char max_forwards [ 32 ] ;
2007-12-12 21:53:32 +00:00
switch_snprintf ( max_forwards , sizeof ( max_forwards ) , " %lu " , sip - > sip_max_forwards - > mf_count ) ;
2007-03-31 19:01:33 +00:00
switch_channel_set_variable ( channel , SWITCH_MAX_FORWARDS_VARIABLE , max_forwards ) ;
}
2007-10-31 22:26:54 +00:00
if ( ! context ) {
2007-12-11 15:38:07 +00:00
context = switch_channel_get_variable ( channel , " user_context " ) ;
2007-10-31 22:26:54 +00:00
}
2007-03-31 19:01:33 +00:00
if ( ! context ) {
if ( profile - > context & & ! strcasecmp ( profile - > context , " _domain_ " ) ) {
context = from_host ;
} else {
context = profile - > context ;
}
}
2007-10-31 22:26:54 +00:00
if ( ! ( dialplan = switch_channel_get_variable ( channel , " inbound_dialplan " ) ) ) {
dialplan = profile - > dialplan ;
}
2007-11-19 23:29:32 +00:00
if ( ( alert_info = sip_alert_info ( sip ) ) ) {
2007-11-20 03:24:55 +00:00
char * tmp = sip_header_as_string ( profile - > home , ( void * ) alert_info ) ;
switch_channel_set_variable ( channel , " alert_info " , tmp ) ;
su_free ( profile - > home , tmp ) ;
2007-11-19 23:29:32 +00:00
}
2007-11-19 21:34:27 +00:00
2009-04-09 22:34:59 +00:00
if ( ( call_info = sip_call_info ( sip ) ) ) {
2010-02-06 03:38:24 +00:00
call_info_str = sip_header_as_string ( nh - > nh_home , ( void * ) call_info ) ;
if ( call_info - > ci_params & & ( msg_params_find ( call_info - > ci_params , " answer-after=0 " ) ) ) {
2009-07-13 15:50:05 +00:00
switch_channel_set_variable ( channel , " sip_auto_answer_detected " , " true " ) ;
}
2009-12-24 05:44:23 +00:00
switch_channel_set_variable ( channel , " sip_call_info " , call_info_str ) ;
2009-04-09 22:34:59 +00:00
}
2008-09-18 00:01:03 +00:00
if ( profile - > pres_type ) {
2007-12-18 01:12:50 +00:00
const char * user = switch_str_nil ( sip - > sip_from - > a_url - > url_user ) ;
const char * host = switch_str_nil ( sip - > sip_from - > a_url - > url_host ) ;
char * tmp = switch_mprintf ( " %s@%s " , user , host ) ;
2007-12-15 18:26:10 +00:00
switch_assert ( tmp ) ;
switch_channel_set_variable ( channel , " presence_id " , tmp ) ;
free ( tmp ) ;
}
2010-02-06 03:38:24 +00:00
2009-10-16 19:51:32 +00:00
if ( sip - > sip_request - > rq_url - > url_params ) {
gw_name = sofia_glue_find_parameter ( sip - > sip_request - > rq_url - > url_params , " gw= " ) ;
}
2009-01-23 20:33:30 +00:00
if ( strstr ( destination_number , " gw+ " ) ) {
2009-10-16 19:51:32 +00:00
gw_name = destination_number + 3 ;
}
if ( gw_name ) {
2009-01-23 20:33:30 +00:00
sofia_gateway_t * gateway ;
if ( gw_name & & ( gateway = sofia_reg_find_gateway ( gw_name ) ) ) {
context = switch_core_session_strdup ( session , gateway - > register_context ) ;
switch_channel_set_variable ( channel , " sip_gateway " , gateway - > name ) ;
if ( gateway - > extension ) {
2009-09-29 02:07:17 +00:00
if ( ! strcasecmp ( gateway - > extension , " auto_to_user " ) ) {
destination_number = sip - > sip_to - > a_url - > url_user ;
} else {
destination_number = switch_core_session_strdup ( session , gateway - > extension ) ;
}
} else {
destination_number = sip - > sip_to - > a_url - > url_user ;
2009-01-23 20:33:30 +00:00
}
gateway - > ib_calls + + ;
if ( gateway - > ib_vars ) {
switch_event_header_t * hp ;
2010-02-06 03:38:24 +00:00
for ( hp = gateway - > ib_vars - > headers ; hp ; hp = hp - > next ) {
2009-08-13 20:35:02 +00:00
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( session ) , SWITCH_LOG_DEBUG , " %s setting variable [%s]=[%s] \n " ,
2009-01-23 20:33:30 +00:00
switch_channel_get_name ( channel ) , hp - > name , hp - > value ) ;
switch_channel_set_variable ( channel , hp - > name , hp - > value ) ;
}
}
sofia_reg_release_gateway ( gateway ) ;
}
}
2009-12-24 05:44:23 +00:00
if ( call_info_str ) {
char * sql ;
char cid [ 512 ] = " " ;
char * str ;
2010-01-07 06:09:35 +00:00
char * p = NULL ;
2010-01-13 01:40:11 +00:00
const char * user = NULL , * host = NULL ;
2010-02-06 03:38:24 +00:00
2010-01-13 01:40:11 +00:00
if ( sip - > sip_to & & sip - > sip_to - > a_url ) {
user = sip - > sip_to - > a_url - > url_user ;
host = sip - > sip_to - > a_url - > url_host ;
}
2010-01-07 06:09:35 +00:00
2010-01-13 01:40:11 +00:00
if ( ! user | | ! host ) {
if ( sip - > sip_from & & sip - > sip_from - > a_url ) {
2010-02-06 03:38:24 +00:00
if ( ! user )
user = sip - > sip_from - > a_url - > url_user ;
if ( ! host )
host = sip - > sip_from - > a_url - > url_host ;
2010-01-13 01:40:11 +00:00
}
}
2009-12-24 05:44:23 +00:00
2010-01-13 01:40:11 +00:00
if ( user & & host ) {
2010-01-07 06:09:35 +00:00
if ( ( p = strchr ( call_info_str , ' ; ' ) ) ) {
p + + ;
}
2010-02-06 03:38:24 +00:00
sql =
switch_mprintf
( " select call_id from sip_dialogs where call_info='%q' and sip_from_user='%q' and sip_from_host='%q' and call_id is not null " ,
switch_str_nil ( p ) , user , host ) ;
2010-01-13 01:40:11 +00:00
2009-12-24 05:44:23 +00:00
if ( ( str = sofia_glue_execute_sql2str ( profile , profile - > ireg_mutex , sql , cid , sizeof ( cid ) ) ) ) {
bnh = nua_handle_by_call_id ( nua , str ) ;
}
2010-01-13 01:40:11 +00:00
if ( mod_sofia_globals . debug_sla > 1 ) {
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_ERROR , " PICK SQL %s [%s] [%s] %d \n " , sql , str , cid , ! ! bnh ) ;
}
2010-02-06 03:38:24 +00:00
2009-12-24 05:44:23 +00:00
free ( sql ) ;
}
}
2010-01-20 19:20:11 +00:00
if ( ! bnh & & sip - > sip_replaces ) {
if ( ! ( bnh = nua_handle_by_replaces ( nua , sip - > sip_replaces ) ) ) {
if ( ! ( bnh = nua_handle_by_call_id ( nua , sip - > sip_replaces - > rp_call_id ) ) ) {
bnh = sofia_global_nua_handle_by_replaces ( sip - > sip_replaces ) ;
}
}
2009-12-24 05:44:23 +00:00
}
2009-01-30 16:46:37 +00:00
2009-12-24 05:44:23 +00:00
if ( bnh ) {
sofia_private_t * b_private = NULL ;
if ( ( b_private = nua_handle_magic ( bnh ) ) ) {
switch_core_session_t * b_session = NULL ;
2009-01-30 16:46:37 +00:00
2009-12-24 05:44:23 +00:00
if ( ( b_session = switch_core_session_locate ( b_private - > uuid ) ) ) {
switch_channel_t * b_channel = switch_core_session_get_channel ( b_session ) ;
const char * uuid ;
int one_leg = 1 ;
private_object_t * b_tech_pvt = NULL ;
const char * app = switch_channel_get_variable ( b_channel , SWITCH_CURRENT_APPLICATION_VARIABLE ) ;
const char * data = switch_channel_get_variable ( b_channel , SWITCH_CURRENT_APPLICATION_DATA_VARIABLE ) ;
2010-01-13 01:40:11 +00:00
2009-12-24 05:44:23 +00:00
if ( app & & data & & ! strcasecmp ( app , " conference " ) ) {
destination_number = switch_core_session_sprintf ( b_session , " answer,conference:%s " , data ) ;
dialplan = " inline " ;
} else {
if ( switch_core_session_check_interface ( b_session , sofia_endpoint_interface ) ) {
b_tech_pvt = switch_core_session_get_private ( b_session ) ;
}
2010-02-06 03:38:24 +00:00
2009-12-24 05:44:23 +00:00
if ( ( uuid = switch_channel_get_variable ( b_channel , SWITCH_SIGNAL_BOND_VARIABLE ) ) ) {
2010-01-07 06:09:35 +00:00
switch_channel_set_variable ( b_channel , " presence_call_info " , NULL ) ;
2010-01-28 20:35:17 +00:00
switch_channel_set_variable ( b_channel , " presence_call_info_full " , NULL ) ;
2009-12-24 05:44:23 +00:00
one_leg = 0 ;
} else {
uuid = switch_core_session_get_uuid ( b_session ) ;
}
2010-02-06 03:38:24 +00:00
2009-12-24 05:44:23 +00:00
if ( uuid ) {
switch_core_session_t * c_session = NULL ;
2010-02-06 03:38:24 +00:00
int do_conf = 0 ;
2009-12-24 05:44:23 +00:00
uuid = switch_core_session_strdup ( b_session , uuid ) ;
if ( ( c_session = switch_core_session_locate ( uuid ) ) ) {
switch_channel_t * c_channel = switch_core_session_get_channel ( c_session ) ;
private_object_t * c_tech_pvt = NULL ;
if ( switch_core_session_check_interface ( c_session , sofia_endpoint_interface ) ) {
c_tech_pvt = switch_core_session_get_private ( c_session ) ;
}
2009-01-23 20:33:30 +00:00
2010-02-06 03:38:24 +00:00
if ( ! one_leg & &
( ! b_tech_pvt | | ! sofia_test_flag ( b_tech_pvt , TFLAG_SIP_HOLD ) ) & &
2009-12-24 05:44:23 +00:00
( ! c_tech_pvt | | ! sofia_test_flag ( c_tech_pvt , TFLAG_SIP_HOLD ) ) ) {
2010-01-07 06:09:35 +00:00
char * ext = switch_core_session_sprintf ( b_session , " answer,conference:%s@sla+flags{mintwo} " , uuid ) ;
2010-02-06 03:38:24 +00:00
2009-12-24 05:44:23 +00:00
switch_channel_set_flag ( c_channel , CF_REDIRECT ) ;
switch_ivr_session_transfer ( b_session , ext , " inline " , NULL ) ;
switch_ivr_session_transfer ( c_session , ext , " inline " , NULL ) ;
switch_channel_clear_flag ( c_channel , CF_REDIRECT ) ;
do_conf = 1 ;
2009-01-30 16:46:37 +00:00
}
2009-12-24 05:44:23 +00:00
switch_core_session_rwunlock ( c_session ) ;
}
2010-02-06 03:38:24 +00:00
2009-12-24 05:44:23 +00:00
if ( do_conf ) {
destination_number = switch_core_session_sprintf ( b_session , " answer,conference:%s@sla+flags{mintwo} " , uuid ) ;
} else {
destination_number = switch_core_session_sprintf ( b_session , " answer,intercept:%s " , uuid ) ;
2009-01-30 16:46:37 +00:00
}
2009-12-24 05:44:23 +00:00
dialplan = " inline " ;
2009-01-30 16:46:37 +00:00
}
}
2009-12-24 05:44:23 +00:00
switch_core_session_rwunlock ( b_session ) ;
2009-01-30 16:46:37 +00:00
}
}
2009-12-24 05:44:23 +00:00
nua_handle_unref ( bnh ) ;
2009-01-30 16:46:37 +00:00
}
2009-01-23 20:33:30 +00:00
2007-11-10 00:47:09 +00:00
check_decode ( displayname , session ) ;
2007-03-31 19:01:33 +00:00
tech_pvt - > caller_profile = switch_caller_profile_new ( switch_core_session_get_pool ( session ) ,
from_user ,
2007-10-31 22:26:54 +00:00
dialplan ,
2009-11-21 06:40:38 +00:00
displayname , from_user , network_ip , from_user , aniii , NULL , MODNAME , context , destination_number ) ;
2007-03-31 19:01:33 +00:00
if ( tech_pvt - > caller_profile ) {
2007-11-19 23:29:32 +00:00
if ( rpid ) {
if ( rpid - > rpid_privacy ) {
if ( ! strcasecmp ( rpid - > rpid_privacy , " yes " ) ) {
2009-02-11 20:49:45 +00:00
switch_set_flag ( tech_pvt - > caller_profile , SWITCH_CPF_HIDE_NAME | SWITCH_CPF_HIDE_NUMBER ) ;
2007-11-19 23:29:32 +00:00
} else if ( ! strcasecmp ( rpid - > rpid_privacy , " full " ) ) {
2009-02-11 20:49:45 +00:00
switch_set_flag ( tech_pvt - > caller_profile , SWITCH_CPF_HIDE_NAME | SWITCH_CPF_HIDE_NUMBER ) ;
2007-11-19 23:29:32 +00:00
} else if ( ! strcasecmp ( rpid - > rpid_privacy , " name " ) ) {
2009-02-11 20:49:45 +00:00
switch_set_flag ( tech_pvt - > caller_profile , SWITCH_CPF_HIDE_NAME ) ;
2007-11-19 23:29:32 +00:00
} else if ( ! strcasecmp ( rpid - > rpid_privacy , " number " ) ) {
2009-02-11 20:49:45 +00:00
switch_set_flag ( tech_pvt - > caller_profile , SWITCH_CPF_HIDE_NUMBER ) ;
2007-11-19 23:29:32 +00:00
} else {
switch_clear_flag ( tech_pvt - > caller_profile , SWITCH_CPF_HIDE_NAME ) ;
switch_clear_flag ( tech_pvt - > caller_profile , SWITCH_CPF_HIDE_NUMBER ) ;
}
2008-05-27 04:54:52 +00:00
}
2007-11-19 23:29:32 +00:00
if ( rpid - > rpid_screen & & ! strcasecmp ( rpid - > rpid_screen , " no " ) ) {
switch_clear_flag ( tech_pvt - > caller_profile , SWITCH_CPF_SCREEN ) ;
}
}
2007-11-20 01:09:39 +00:00
2008-10-21 20:01:48 +00:00
if ( ( privacy = sip_privacy ( sip ) ) ) {
2010-02-06 03:38:24 +00:00
char * full_priv_header = sip_header_as_string ( nh - > nh_home , ( void * ) privacy ) ;
2009-10-23 16:03:42 +00:00
if ( ! zstr ( full_priv_header ) ) {
2009-07-01 15:02:27 +00:00
switch_channel_set_variable ( channel , " sip_Privacy " , full_priv_header ) ;
2009-06-26 17:33:19 +00:00
}
2009-02-13 22:27:05 +00:00
if ( msg_params_find ( privacy - > priv_values , " id " ) ) {
2009-02-11 20:49:45 +00:00
switch_set_flag ( tech_pvt - > caller_profile , SWITCH_CPF_HIDE_NAME | SWITCH_CPF_HIDE_NUMBER ) ;
2008-10-21 20:01:48 +00:00
}
}
2007-03-31 19:01:33 +00:00
/* Loop thru unknown Headers Here so we can do something with them */
for ( un = sip - > sip_unknown ; un ; un = un - > un_next ) {
2007-11-19 23:29:32 +00:00
if ( ! strncasecmp ( un - > un_name , " Diversion " , 9 ) ) {
2007-11-20 01:09:39 +00:00
/* Basic Diversion Support for Diversion Indication in SIP */
/* draft-levy-sip-diversion-08 */
2009-10-23 16:03:42 +00:00
if ( ! zstr ( un - > un_value ) ) {
2007-09-21 16:27:41 +00:00
char * tmp_name ;
if ( ( tmp_name = switch_mprintf ( " %s%s " , SOFIA_SIP_HEADER_PREFIX , un - > un_name ) ) ) {
switch_channel_set_variable ( channel , tmp_name , un - > un_value ) ;
free ( tmp_name ) ;
}
}
2008-12-11 20:42:34 +00:00
} else if ( ! strncasecmp ( un - > un_name , " History-Info " , 12 ) ) {
switch_channel_set_variable ( channel , " sip_history_info " , un - > un_value ) ;
2009-10-21 18:48:28 +00:00
} else if ( ! strcasecmp ( un - > un_name , " X-FS-Support " ) ) {
tech_pvt - > x_freeswitch_support_remote = switch_core_session_strdup ( session , un - > un_value ) ;
2007-05-25 16:14:12 +00:00
} else if ( ! strncasecmp ( un - > un_name , " X- " , 2 ) | | ! strncasecmp ( un - > un_name , " P- " , 2 ) ) {
2009-10-23 16:03:42 +00:00
if ( ! zstr ( un - > un_value ) ) {
2008-09-28 21:36:39 +00:00
char new_name [ 512 ] = " " ;
2010-02-06 03:38:24 +00:00
int reps = 0 ;
for ( ; ; ) {
2008-09-28 21:36:39 +00:00
char postfix [ 25 ] = " " ;
if ( reps > 0 ) {
switch_snprintf ( postfix , sizeof ( postfix ) , " -%d " , reps ) ;
}
reps + + ;
switch_snprintf ( new_name , sizeof ( new_name ) , " %s%s%s " , SOFIA_SIP_HEADER_PREFIX , un - > un_name , postfix ) ;
if ( switch_channel_get_variable ( channel , new_name ) ) {
continue ;
}
2007-03-31 19:01:33 +00:00
switch_channel_set_variable ( channel , new_name , un - > un_value ) ;
2008-09-28 21:36:39 +00:00
break ;
2007-03-31 19:01:33 +00:00
}
}
}
}
2010-02-06 03:38:24 +00:00
2007-03-31 19:01:33 +00:00
switch_channel_set_caller_profile ( channel , tech_pvt - > caller_profile ) ;
}
2010-02-06 03:38:24 +00:00
2007-10-03 23:42:40 +00:00
if ( ! ( sofia_private = malloc ( sizeof ( * sofia_private ) ) ) ) {
2007-03-31 19:01:33 +00:00
abort ( ) ;
}
2008-06-23 21:07:55 +00:00
2007-10-03 23:42:40 +00:00
memset ( sofia_private , 0 , sizeof ( * sofia_private ) ) ;
2008-07-29 17:54:42 +00:00
sofia_private - > is_call + + ;
2007-10-03 23:42:40 +00:00
tech_pvt - > sofia_private = sofia_private ;
2010-02-06 03:38:24 +00:00
2008-09-18 00:01:03 +00:00
if ( ( profile - > pres_type ) ) {
2007-09-29 01:06:08 +00:00
sofia_presence_set_chat_hash ( tech_pvt , sip ) ;
}
2007-03-31 19:01:33 +00:00
switch_copy_string ( tech_pvt - > sofia_private - > uuid , switch_core_session_get_uuid ( session ) , sizeof ( tech_pvt - > sofia_private - > uuid ) ) ;
nua_handle_bind ( nh , tech_pvt - > sofia_private ) ;
tech_pvt - > nh = nh ;
2007-05-11 00:27:55 +00:00
2007-12-18 20:34:19 +00:00
if ( sip & & switch_core_session_thread_launch ( session ) = = SWITCH_STATUS_SUCCESS ) {
const char * dialog_from_user = " " , * dialog_from_host = " " , * to_user = " " , * to_host = " " , * contact_user = " " , * contact_host = " " ;
const char * user_agent = " " , * call_id = " " ;
url_t * from = NULL , * to = NULL , * contact = NULL ;
2007-12-18 01:12:50 +00:00
char * sql = NULL ;
2007-12-18 20:34:19 +00:00
if ( sip - > sip_to ) {
to = sip - > sip_to - > a_url ;
}
if ( sip - > sip_from ) {
from = sip - > sip_from - > a_url ;
}
if ( sip - > sip_contact ) {
contact = sip - > sip_contact - > m_url ;
}
if ( sip - > sip_user_agent ) {
user_agent = switch_str_nil ( sip - > sip_user_agent - > g_string ) ;
}
if ( sip - > sip_call_id ) {
call_id = switch_str_nil ( sip - > sip_call_id - > i_id ) ;
}
if ( to ) {
to_user = switch_str_nil ( to - > url_user ) ;
to_host = switch_str_nil ( to - > url_host ) ;
}
if ( from ) {
dialog_from_user = switch_str_nil ( from - > url_user ) ;
dialog_from_host = switch_str_nil ( from - > url_host ) ;
}
if ( contact ) {
contact_user = switch_str_nil ( contact - > url_user ) ;
contact_host = switch_str_nil ( contact - > url_host ) ;
}
2008-09-18 00:01:03 +00:00
if ( profile - > pres_type ) {
2009-11-11 02:10:41 +00:00
const char * presence_data = switch_channel_get_variable ( channel , " presence_data " ) ;
const char * presence_id = switch_channel_get_variable ( channel , " presence_id " ) ;
char * full_contact = " " ;
2010-01-07 06:09:35 +00:00
char * p = NULL ;
2009-11-11 02:10:41 +00:00
if ( sip - > sip_contact ) {
full_contact = sip_header_as_string ( nua_handle_home ( tech_pvt - > nh ) , ( void * ) sip - > sip_contact ) ;
}
2010-02-06 03:38:24 +00:00
2010-01-28 20:52:28 +00:00
if ( call_info_str & & switch_stristr ( " appearance " , call_info_str ) ) {
2010-01-28 20:35:17 +00:00
switch_channel_set_variable ( channel , " presence_call_info_full " , call_info_str ) ;
2010-01-07 06:09:35 +00:00
if ( ( p = strchr ( call_info_str , ' ; ' ) ) ) {
p + + ;
switch_channel_set_variable ( channel , " presence_call_info " , p ) ;
}
2009-12-24 05:44:23 +00:00
}
2008-09-18 00:01:03 +00:00
sql = switch_mprintf ( " insert into sip_dialogs "
" (call_id,uuid,sip_to_user,sip_to_host,sip_from_user,sip_from_host,contact_user, "
2009-12-24 05:44:23 +00:00
" contact_host,state,direction,user_agent,profile_name,hostname,contact,presence_id,presence_data,call_info) "
" values('%q','%q','%q','%q','%q','%q','%q','%q','%q','%q','%q','%q','%q','%q','%q','%q','%q') " ,
2008-03-04 23:53:23 +00:00
call_id ,
tech_pvt - > sofia_private - > uuid ,
2010-02-06 03:38:24 +00:00
to_user , to_host , dialog_from_user , dialog_from_host ,
2008-09-18 00:01:03 +00:00
contact_user , contact_host , " confirmed " , " inbound " , user_agent ,
2010-02-06 03:38:24 +00:00
profile - > name , mod_sofia_globals . hostname , switch_str_nil ( full_contact ) ,
2010-01-07 06:09:35 +00:00
switch_str_nil ( presence_id ) , switch_str_nil ( presence_data ) , switch_str_nil ( p ) ) ;
2009-11-11 02:10:41 +00:00
2008-03-04 23:53:23 +00:00
switch_assert ( sql ) ;
2010-02-06 03:38:24 +00:00
2010-01-09 00:34:17 +00:00
sofia_glue_actually_execute_sql ( profile , sql , profile - > ireg_mutex ) ;
switch_safe_free ( sql ) ;
2010-02-06 03:38:24 +00:00
2008-03-04 23:53:23 +00:00
}
2008-05-13 23:22:21 +00:00
2008-05-20 16:41:57 +00:00
if ( is_nat ) {
2009-02-09 17:56:38 +00:00
sofia_set_flag ( tech_pvt , TFLAG_NAT ) ;
2009-08-13 20:35:02 +00:00
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( session ) , SWITCH_LOG_DEBUG , " Setting NAT mode based on %s \n " , is_nat ) ;
2008-05-20 16:41:57 +00:00
switch_channel_set_variable ( channel , " sip_nat_detected " , " true " ) ;
2008-05-13 23:22:21 +00:00
}
2007-05-11 00:27:55 +00:00
return ;
}
2007-11-12 16:51:33 +00:00
if ( sess_count > 110 ) {
switch_mutex_lock ( profile - > flag_mutex ) ;
switch_core_session_limit ( sess_count - 10 ) ;
2009-08-13 20:35:02 +00:00
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( session ) , SWITCH_LOG_CRIT , " LUKE: I'm hit, but not bad. \n " ) ;
2010-02-06 03:38:24 +00:00
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( session ) , SWITCH_LOG_CRIT ,
" LUKE'S VOICE: Artoo, see what you can do with it. Hang on back there.... \n "
2007-11-12 16:51:33 +00:00
" Green laserfire moves past the beeping little robot as his head turns. "
" After a few beeps and a twist of his mechanical arm, \n "
2008-06-14 18:54:09 +00:00
" Artoo reduces the max sessions to %d thus, saving the switch from certain doom. \n " , sess_count - 10 ) ;
2007-11-12 16:51:33 +00:00
switch_mutex_unlock ( profile - > flag_mutex ) ;
}
2007-05-11 00:27:55 +00:00
if ( tech_pvt - > hash_key ) {
2008-09-16 20:04:33 +00:00
switch_mutex_lock ( tech_pvt - > profile - > flag_mutex ) ;
2007-05-11 00:27:55 +00:00
switch_core_hash_delete ( tech_pvt - > profile - > chat_hash , tech_pvt - > hash_key ) ;
2008-09-16 20:04:33 +00:00
switch_mutex_unlock ( tech_pvt - > profile - > flag_mutex ) ;
2007-05-11 00:27:55 +00:00
}
nua_handle_bind ( nh , NULL ) ;
2009-03-22 05:15:17 +00:00
sofia_private_free ( sofia_private ) ;
2007-05-11 00:27:55 +00:00
switch_core_session_destroy ( & session ) ;
2008-04-07 17:06:44 +00:00
nua_respond ( nh , 503 , " Maximum Calls In Progress " , SIPTAG_RETRY_AFTER_STR ( " 300 " ) , TAG_END ( ) ) ;
2009-04-21 17:47:22 +00:00
return ;
2010-02-06 03:38:24 +00:00
fail :
2009-04-21 17:47:22 +00:00
profile - > ib_failed_calls + + ;
return ;
2007-03-31 19:01:33 +00:00
}
void sofia_handle_sip_i_options ( int status ,
2008-05-27 04:54:52 +00:00
char const * phrase ,
2010-02-06 03:38:24 +00:00
nua_t * nua , sofia_profile_t * profile , nua_handle_t * nh , sofia_private_t * sofia_private , sip_t const * sip ,
tagi_t tags [ ] )
2007-03-31 19:01:33 +00:00
{
2008-05-27 04:54:52 +00:00
nua_respond ( nh , SIP_200_OK , NUTAG_WITH_THIS ( nua ) , TAG_END ( ) ) ;
2007-03-31 19:01:33 +00:00
}
2008-01-02 17:06:07 +00:00
2009-10-07 22:35:21 +00:00
void sofia_info_send_sipfrag ( switch_core_session_t * aleg , switch_core_session_t * bleg )
2008-01-02 17:06:07 +00:00
{
private_object_t * b_tech_pvt = NULL , * a_tech_pvt = NULL ;
char message [ 256 ] = " " ;
2008-04-16 22:49:36 +00:00
if ( aleg & & bleg & & switch_core_session_compare ( aleg , bleg ) ) {
2008-07-23 21:11:42 +00:00
switch_channel_t * channel = switch_core_session_get_channel ( bleg ) ;
const char * ua = switch_channel_get_variable ( channel , " sip_user_agent " ) ;
2010-02-06 03:38:24 +00:00
2008-01-02 17:06:07 +00:00
a_tech_pvt = ( private_object_t * ) switch_core_session_get_private ( aleg ) ;
b_tech_pvt = ( private_object_t * ) switch_core_session_get_private ( bleg ) ;
2008-05-27 04:54:52 +00:00
2008-01-02 17:06:07 +00:00
if ( b_tech_pvt & & a_tech_pvt & & a_tech_pvt - > caller_profile ) {
switch_caller_profile_t * acp = a_tech_pvt - > caller_profile ;
2010-02-06 03:38:24 +00:00
2009-05-28 22:46:17 +00:00
if ( ua & & switch_stristr ( " snom " , ua ) ) {
2009-10-23 16:03:42 +00:00
if ( zstr ( acp - > caller_id_name ) ) {
2009-05-28 22:46:17 +00:00
snprintf ( message , sizeof ( message ) , " From: \r \n To: %s \r \n " , acp - > caller_id_number ) ;
} else {
snprintf ( message , sizeof ( message ) , " From: \r \n To: \" %s \" %s \r \n " , acp - > caller_id_name , acp - > caller_id_number ) ;
}
2009-10-07 22:35:21 +00:00
nua_info ( b_tech_pvt - > nh ,
2010-01-22 00:51:32 +00:00
SIPTAG_CONTENT_TYPE_STR ( " message/sipfrag;version=2.0 " ) ,
2010-02-06 03:38:24 +00:00
TAG_IF ( ! zstr ( b_tech_pvt - > user_via ) , SIPTAG_VIA_STR ( b_tech_pvt - > user_via ) ) , SIPTAG_PAYLOAD_STR ( message ) , TAG_END ( ) ) ;
2009-06-01 13:45:50 +00:00
} else if ( ua & & switch_stristr ( " polycom " , ua ) ) {
2009-10-23 16:03:42 +00:00
if ( zstr ( acp - > caller_id_name ) ) {
2009-05-28 22:46:17 +00:00
snprintf ( message , sizeof ( message ) , " P-Asserted-Identity: \" %s \" <%s> " , acp - > caller_id_number , acp - > caller_id_number ) ;
} else {
snprintf ( message , sizeof ( message ) , " P-Asserted-Identity: \" %s \" <%s> " , acp - > caller_id_name , acp - > caller_id_number ) ;
}
2009-12-08 21:30:49 +00:00
if ( b_tech_pvt - > local_crypto_key ) {
sofia_glue_set_local_sdp ( b_tech_pvt , NULL , 0 , NULL , 0 ) ;
}
2009-12-19 17:43:05 +00:00
if ( sofia_use_soa ( b_tech_pvt ) ) {
nua_update ( b_tech_pvt - > nh ,
SIPTAG_CONTACT_STR ( b_tech_pvt - > reply_contact ) ,
SOATAG_USER_SDP_STR ( b_tech_pvt - > local_sdp_str ) ,
SOATAG_REUSE_REJECTED ( 1 ) ,
SOATAG_ORDERED_USER ( 1 ) , SOATAG_AUDIO_AUX ( " cn telephone-event " ) ,
TAG_IF ( ! zstr_buf ( message ) , SIPTAG_HEADER_STR ( message ) ) ,
2010-02-06 03:38:24 +00:00
TAG_IF ( ! zstr ( b_tech_pvt - > user_via ) , SIPTAG_VIA_STR ( b_tech_pvt - > user_via ) ) , TAG_END ( ) ) ;
2009-12-19 17:43:05 +00:00
} else {
nua_update ( b_tech_pvt - > nh ,
NUTAG_MEDIA_ENABLE ( 0 ) ,
SIPTAG_CONTACT_STR ( b_tech_pvt - > reply_contact ) ,
SIPTAG_CONTENT_TYPE_STR ( " application/sdp " ) ,
2010-01-07 05:22:02 +00:00
SIPTAG_PAYLOAD_STR ( b_tech_pvt - > local_sdp_str ) ,
2009-12-19 17:43:05 +00:00
TAG_IF ( ! zstr_buf ( message ) , SIPTAG_HEADER_STR ( message ) ) ,
2010-02-06 03:38:24 +00:00
TAG_IF ( ! zstr ( b_tech_pvt - > user_via ) , SIPTAG_VIA_STR ( b_tech_pvt - > user_via ) ) , TAG_END ( ) ) ;
2009-12-19 17:43:05 +00:00
}
2008-01-02 17:06:07 +00:00
}
2009-10-08 16:52:55 +00:00
2008-01-02 17:06:07 +00:00
}
}
}
2009-01-24 02:34:55 +00:00
2008-01-12 19:53:12 +00:00
/*
* This subroutine will take the a_params of a sip_addr_s structure and spin through them .
* Each param will be used to create a channel variable .
* In the SIP RFC ' s , this data is called generic - param .
* Note that the tag - param is also included in the a_params list .
*
* From : " John Doe " < sip : 5551212 @ 1.2 .3 .4 > ; tag = ed23266b52cbb17eo2 ; ref = 101 ; mbid = 201
*
* For example , the header above will produce an a_params list with three entries
* tag = ed23266b52cbb17eo2
* ref = 101
* mbid = 201
*
* The a_params list is parsed and the lvalue is used to create the channel variable name while the
* rvalue is used to create the channel variable value .
*
* If no equal ( = ) sign is found during parsing , a channel variable name is created with the param and
* the value is set to NULL .
*
* Pointers are used for copying the sip_header_name for performance reasons . There are no calls to
* any string functions and no memory is allocated / dealocated . The only limiter is the size of the
* sip_header_name array .
*/
static void set_variable_sip_param ( switch_channel_t * channel , char * header_type , sip_param_t const * params )
{
char sip_header_name [ 128 ] = " " ;
char var1 [ ] = " sip_ " ;
char * cp , * sh , * sh_end , * sh_save ;
2008-05-27 04:54:52 +00:00
/* Build the static part of the sip_header_name variable from */
/* the header_type. If the header type is "referred_by" then */
2008-10-07 04:42:35 +00:00
/* sip_header_name = "sip_referred_by_". */
2008-01-12 19:53:12 +00:00
sh = sip_header_name ;
sh_end = sh + sizeof ( sip_header_name ) - 1 ;
2008-05-27 04:54:52 +00:00
for ( cp = var1 ; * cp ; cp + + , sh + + ) {
2008-01-12 19:53:12 +00:00
* sh = * cp ;
}
* sh = ' \0 ' ;
2008-05-27 04:54:52 +00:00
/* Copy the header_type to the sip_header_name. Before copying */
2008-01-12 19:53:12 +00:00
/* each character, check that we aren't going to overflow the */
2008-10-07 04:42:35 +00:00
/* the sip_header_name buffer. We have to account for the */
2008-05-27 04:54:52 +00:00
/* trailing underscore and NULL that will be added to the end. */
for ( cp = header_type ; ( * cp & & ( sh < ( sh_end - 1 ) ) ) ; cp + + , sh + + ) {
2008-01-12 19:53:12 +00:00
* sh = * cp ;
}
* sh + + = ' _ ' ;
* sh = ' \0 ' ;
2008-05-27 04:54:52 +00:00
/* sh now points to the NULL at the end of the partially built */
2008-01-12 19:53:12 +00:00
/* sip_header_name variable. This is also the start of the */
/* variable part of the sip_header_name built from the lvalue */
2008-10-07 04:42:35 +00:00
/* of the params data. */
2008-01-12 19:53:12 +00:00
sh_save = sh ;
while ( params & & params [ 0 ] ) {
2008-05-27 04:54:52 +00:00
/* Copy the params data to the sip_header_name variable until */
/* the end of the params string is reached, an '=' is detected */
2008-10-07 04:42:35 +00:00
/* or until the sip_header_name buffer has been exhausted. */
2008-05-27 04:54:52 +00:00
for ( cp = ( char * ) ( * params ) ; ( ( * cp ! = ' = ' ) & & * cp & & ( sh < sh_end ) ) ; cp + + , sh + + ) {
2008-01-12 19:53:12 +00:00
* sh = * cp ;
}
2008-10-07 04:42:35 +00:00
/* cp now points to either the end of the params data or the */
/* equal (=) sign separating the lvalue and rvalue. */
2008-01-12 19:53:12 +00:00
if ( * cp = = ' = ' )
2008-05-27 04:54:52 +00:00
cp + + ;
2008-01-12 19:53:12 +00:00
* sh = ' \0 ' ;
switch_channel_set_variable ( channel , sip_header_name , cp ) ;
2008-10-07 04:42:35 +00:00
/* Bump pointer to next param in the list. Also reset the */
2008-01-12 19:53:12 +00:00
/* sip_header_name pointer to the beginning of the dynamic area */
params + + ;
sh = sh_save ;
}
}
2008-01-27 05:02:52 +00:00
/* For Emacs:
* Local Variables :
* mode : c
2008-02-03 22:14:57 +00:00
* indent - tabs - mode : t
2008-01-27 05:02:52 +00:00
* tab - width : 4
* c - basic - offset : 4
* End :
* For VIM :
2008-07-03 19:12:26 +00:00
* vim : set softtabstop = 4 shiftwidth = 4 tabstop = 4 :
2008-01-27 05:02:52 +00:00
*/