2009-01-30 16:46:37 +00:00
/*
* FreeSWITCH Modular Media Switching Software Library / Soft - Switch Application
2011-01-05 10:08:55 -06:00
* Copyright ( C ) 2005 - 2011 , Anthony Minessale II < anthm @ freeswitch . org >
2009-01-30 16:46:37 +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 >
2009-01-30 16:46:37 +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 >
2009-01-30 16:46:37 +00:00
* Ken Rice , Asteria Solutions Group , Inc < ken @ asteriasgi . com >
* Paul D . Tinsley < pdt at jackhammer . org >
* Bret McDanel < trixter AT 0xdecafbad . com >
2009-05-14 15:44:43 +00:00
* Brian West < brian @ freeswitch . org >
2009-01-30 16:46:37 +00:00
*
* sofia_sla . c - - SOFIA SIP Endpoint ( support for shared line appearance )
* This file ( and calls into it ) developed by Matthew T Kaufman < matthew @ matthew . at >
*
*/
# include "mod_sofia.h"
static int sofia_sla_sub_callback ( void * pArg , int argc , char * * argv , char * * columnNames ) ;
2009-03-22 05:15:17 +00:00
struct sla_helper {
char call_id [ 1024 ] ;
} ;
static int get_call_id_callback ( void * pArg , int argc , char * * argv , char * * columnNames )
2009-01-30 16:46:37 +00:00
{
2009-03-22 05:15:17 +00:00
struct sla_helper * sh = ( struct sla_helper * ) pArg ;
2009-01-30 16:46:37 +00:00
2009-03-22 05:15:17 +00:00
switch_set_string ( sh - > call_id , argv [ 0 ] ) ;
return 0 ;
}
2009-01-30 16:46:37 +00:00
2009-11-12 03:52:07 +00:00
int sofia_sla_supported ( sip_t const * sip )
{
if ( sip & & sip - > sip_user_agent & & sip - > sip_user_agent - > g_string ) {
const char * ua = sip - > sip_user_agent - > g_string ;
if ( switch_stristr ( " polycom " , ua ) ) {
return 1 ;
}
if ( switch_stristr ( " snom " , ua ) ) {
return 1 ;
}
}
return 0 ;
}
2011-06-16 14:37:22 -05:00
void sofia_sla_handle_register ( nua_t * nua , sofia_profile_t * profile , sip_t const * sip ,
sofia_dispatch_event_t * de , long exptime , const char * full_contact )
2009-03-22 05:15:17 +00:00
{
nua_handle_t * nh = NULL ;
char exp_str [ 256 ] = " " ;
char my_contact [ 256 ] = " " ;
char * sql ;
2010-02-06 03:38:24 +00:00
struct sla_helper sh = { { 0 } } ;
2009-06-09 16:33:33 +00:00
char * contact_str = sofia_glue_strip_uri ( full_contact ) ;
2009-05-14 15:44:43 +00:00
sofia_transport_t transport = sofia_glue_url2transport ( sip - > sip_contact - > m_url ) ;
2009-06-03 21:08:34 +00:00
char network_ip [ 80 ] ;
int network_port = 0 ;
2009-11-12 03:52:07 +00:00
sofia_destination_t * dst ;
char * route_uri = NULL ;
char port_str [ 25 ] = " " ;
2011-07-16 01:02:22 -05:00
nua_handle_t * fnh = NULL ;
2009-06-03 21:08:34 +00:00
2011-06-16 14:37:22 -05:00
sofia_glue_get_addr ( de - > data - > e_msg , network_ip , sizeof ( network_ip ) , & network_port ) ;
2009-03-22 05:15:17 +00:00
2010-02-06 03:38:24 +00:00
sql = switch_mprintf ( " select call_id from sip_shared_appearance_dialogs where hostname='%q' and profile_name='%q' and contact_str='%q' " ,
2009-03-22 05:15:17 +00:00
mod_sofia_globals . hostname , profile - > name , contact_str ) ;
2009-11-12 03:52:07 +00:00
sofia_glue_execute_sql_callback ( profile , profile - > ireg_mutex , sql , get_call_id_callback , & sh ) ;
2009-03-22 05:15:17 +00:00
free ( sql ) ;
2010-02-06 03:38:24 +00:00
2009-03-22 05:15:17 +00:00
if ( * sh . call_id ) {
2011-07-16 01:02:22 -05:00
if ( ( nh = nua_handle_by_call_id ( profile - > nua , sh . call_id ) ) ) {
fnh = nh ;
} else {
2010-02-06 03:38:24 +00:00
if ( ( sql = switch_mprintf ( " delete from sip_shared_appearance_dialogs where hostname='%q' and profile_name='%q' and contact_str='%q' " ,
2009-03-22 05:15:17 +00:00
mod_sofia_globals . hostname , profile - > name , contact_str ) ) ) {
sofia_glue_execute_sql ( profile , & sql , SWITCH_TRUE ) ;
}
}
}
if ( ! nh ) {
nh = nua_handle ( nua , NULL , NUTAG_URL ( sip - > sip_contact - > m_url ) , TAG_NULL ( ) ) ;
}
2009-01-30 16:46:37 +00:00
nua_handle_bind ( nh , & mod_sofia_globals . keep_private ) ;
2009-03-22 05:15:17 +00:00
switch_snprintf ( exp_str , sizeof ( exp_str ) , " %ld " , exptime + 30 ) ;
2009-11-12 03:52:07 +00:00
switch_snprintf ( port_str , sizeof ( port_str ) , " :%ld " , sofia_glue_transport_has_tls ( transport ) ? profile - > tls_sip_port : profile - > sip_port ) ;
2010-02-06 03:38:24 +00:00
if ( sofia_glue_check_nat ( profile , network_ip ) ) {
switch_snprintf ( my_contact , sizeof ( my_contact ) , " <sip:%s@%s%s;transport=%s>;expires=%s " , profile - > sla_contact ,
2009-11-12 03:52:07 +00:00
profile - > extsipip , port_str , sofia_glue_transport2str ( transport ) , exp_str ) ;
2009-06-03 21:08:34 +00:00
} else {
2010-02-06 03:38:24 +00:00
switch_snprintf ( my_contact , sizeof ( my_contact ) , " <sip:%s@%s%s;transport=%s>;expires=%s " , profile - > sla_contact ,
2009-11-12 03:52:07 +00:00
profile - > sipip , port_str , sofia_glue_transport2str ( transport ) , exp_str ) ;
2009-06-03 21:08:34 +00:00
}
2009-11-12 03:52:07 +00:00
2010-02-06 03:38:24 +00:00
dst = sofia_glue_get_destination ( ( char * ) full_contact ) ;
2009-11-12 03:52:07 +00:00
2009-12-11 01:20:26 +00:00
if ( dst - > route_uri ) {
2009-11-12 03:52:07 +00:00
route_uri = sofia_glue_strip_uri ( dst - > route_uri ) ;
}
2009-01-30 16:46:37 +00:00
nua_subscribe ( nh ,
2009-11-12 03:52:07 +00:00
TAG_IF ( dst - > route_uri , NUTAG_PROXY ( route_uri ) ) , TAG_IF ( dst - > route , SIPTAG_ROUTE_STR ( dst - > route ) ) ,
2009-03-22 05:15:17 +00:00
SIPTAG_TO ( sip - > sip_to ) ,
2009-05-14 15:44:43 +00:00
SIPTAG_FROM ( sip - > sip_to ) ,
2009-03-22 05:15:17 +00:00
SIPTAG_CONTACT_STR ( my_contact ) ,
SIPTAG_EXPIRES_STR ( exp_str ) ,
2010-02-06 03:38:24 +00:00
SIPTAG_EVENT_STR ( " dialog;sla;include-session-description " ) , SIPTAG_ACCEPT_STR ( " application/dialog-info+xml " ) , TAG_NULL ( ) ) ;
2009-03-22 05:15:17 +00:00
2011-07-16 01:02:22 -05:00
if ( fnh ) {
nua_handle_unref ( fnh ) ;
}
2009-11-12 03:52:07 +00:00
sofia_glue_free_destination ( dst ) ;
2009-03-22 05:15:17 +00:00
free ( contact_str ) ;
2009-01-30 16:46:37 +00:00
}
2011-06-16 14:37:22 -05:00
void sofia_sla_handle_sip_i_publish ( nua_t * nua , sofia_profile_t * profile , nua_handle_t * nh , sip_t const * sip ,
sofia_dispatch_event_t * de , tagi_t tags [ ] )
2009-01-30 16:46:37 +00:00
{
/* at present there's no SLA versions that we deal with that do publish. to be safe, we say "OK" */
2011-06-16 14:37:22 -05:00
nua_respond ( nh , SIP_200_OK , NUTAG_WITH_THIS_MSG ( de - > data - > e_msg ) , TAG_END ( ) ) ;
2009-01-30 16:46:37 +00:00
}
2011-06-16 14:37:22 -05:00
void sofia_sla_handle_sip_i_subscribe ( nua_t * nua , const char * contact_str , sofia_profile_t * profile , nua_handle_t * nh , sip_t const * sip ,
sofia_dispatch_event_t * de , tagi_t tags [ ] )
2009-01-30 16:46:37 +00:00
{
char * aor = NULL ;
char * subscriber = NULL ;
char * sql = NULL ;
2009-02-01 00:06:46 +00:00
char * route_uri = NULL ;
2009-05-14 15:44:43 +00:00
char * sla_contact = NULL ;
2009-06-03 21:08:34 +00:00
char network_ip [ 80 ] ;
int network_port = 0 ;
2009-11-12 15:25:13 +00:00
char port_str [ 25 ] = " " ;
2009-05-14 15:44:43 +00:00
sofia_transport_t transport = sofia_glue_url2transport ( sip - > sip_contact - > m_url ) ;
2011-06-16 14:37:22 -05:00
sofia_glue_get_addr ( de - > data - > e_msg , network_ip , sizeof ( network_ip ) , & network_port ) ;
2009-01-30 16:46:37 +00:00
/*
* XXX MTK FIXME - we don ' t look at the tag to see if NUTAG_SUBSTATE ( nua_substate_terminated ) or
* a Subscription - State header with state " terminated " and / or expiration of 0. So we never forget
* about them here .
* likewise , we also don ' t have a hook against nua_r_notify events , so we can ' t see nua_substate_terminated there .
2010-02-06 03:38:24 +00:00
*/
2009-01-30 16:46:37 +00:00
/*
* extracting AOR is weird . . .
* the From is the main extension , not the third - party one . . .
* and the contact has the phone ' s own network address , not the AOR address
* so we do what openser ' s pua_bla does and . . .
*/
2009-06-03 21:08:34 +00:00
/* We always store the AOR as the sipip and not the request so SLA works with NAT inside out */
2009-06-09 16:10:12 +00:00
aor = switch_mprintf ( " sip:%s@%s " , sip - > sip_contact - > m_url - > url_user , profile - > sipip ) ;
2009-01-30 16:46:37 +00:00
/*
* ok , and now that we HAVE the AOR , we REALLY should go check in the XML config and see if this particular
* extension is set up to have shared appearances managed . right now it is all - or - nothing on the profile ,
* which won ' t be sufficient for real life . FIXME XXX MTK
2010-02-06 03:38:24 +00:00
*/
2009-01-30 16:46:37 +00:00
/* then the subscriber is the user at their network location... this is arguably the wrong way, but works so far... */
2009-05-14 15:44:43 +00:00
subscriber = switch_mprintf ( " sip:%s@%s;transport=%s " , sip - > sip_from - > a_url - > url_user ,
sip - > sip_contact - > m_url - > url_host , sofia_glue_transport2str ( transport ) ) ;
2010-02-06 03:38:24 +00:00
2009-01-30 16:46:37 +00:00
if ( ( sql =
2010-02-06 03:38:24 +00:00
switch_mprintf ( " delete from sip_shared_appearance_subscriptions where subscriber='%q' and profile_name='%q' and hostname='%q' " ,
subscriber , profile - > name , mod_sofia_globals . hostname ) ) ) {
2009-01-30 16:46:37 +00:00
sofia_glue_execute_sql ( profile , & sql , SWITCH_TRUE ) ;
}
if ( ( sql =
2009-06-03 21:08:34 +00:00
switch_mprintf ( " insert into sip_shared_appearance_subscriptions (subscriber, call_id, aor, profile_name, hostname, contact_str, network_ip) "
2010-02-06 03:38:24 +00:00
" values ('%q','%q','%q','%q','%q','%q','%q') " ,
subscriber , sip - > sip_call_id - > i_id , aor , profile - > name , mod_sofia_globals . hostname , contact_str , network_ip ) ) ) {
2009-01-30 16:46:37 +00:00
sofia_glue_execute_sql ( profile , & sql , SWITCH_TRUE ) ;
}
2009-02-01 00:06:46 +00:00
if ( strstr ( contact_str , " ;fs_nat " ) ) {
char * p ;
2010-02-06 03:38:24 +00:00
route_uri = sofia_glue_get_url_from_contact ( ( char * ) contact_str , 1 ) ;
2009-02-01 00:06:46 +00:00
if ( ( p = strstr ( contact_str , " ;fs_ " ) ) ) {
* p = ' \0 ' ;
}
}
if ( route_uri ) {
char * p ;
while ( route_uri & & * route_uri & & ( * route_uri = = ' < ' | | * route_uri = = ' ' ) ) {
route_uri + + ;
}
if ( ( p = strchr ( route_uri , ' > ' ) ) ) {
* p + + = ' \0 ' ;
}
}
2009-11-12 15:25:13 +00:00
switch_snprintf ( port_str , sizeof ( port_str ) , " :%ld " , sofia_glue_transport_has_tls ( transport ) ? profile - > tls_sip_port : profile - > sip_port ) ;
2010-02-06 03:38:24 +00:00
if ( sofia_glue_check_nat ( profile , network_ip ) ) {
sla_contact = switch_mprintf ( " <sip:%s@%s%s;transport=%s> " , profile - > sla_contact , profile - > extsipip , port_str , sofia_glue_transport2str ( transport ) ) ;
2009-06-03 21:08:34 +00:00
} else {
2010-02-06 03:38:24 +00:00
sla_contact = switch_mprintf ( " <sip:%s@%s%s;transport=%s> " , profile - > sla_contact , profile - > sipip , port_str , sofia_glue_transport2str ( transport ) ) ;
2009-06-03 21:08:34 +00:00
}
2009-05-14 15:44:43 +00:00
2011-06-16 14:37:22 -05:00
nua_respond ( nh , SIP_202_ACCEPTED , SIPTAG_CONTACT_STR ( sla_contact ) , NUTAG_WITH_THIS_MSG ( de - > data - > e_msg ) , TAG_IF ( route_uri , NUTAG_PROXY ( route_uri ) ) , SIPTAG_SUBSCRIPTION_STATE_STR ( " active;expires=300 " ) , /* you thought the OTHER time was fake... need delta here FIXME XXX MTK */
2010-02-06 03:38:24 +00:00
SIPTAG_EXPIRES_STR ( " 300 " ) , /* likewise, totally fake - FIXME XXX MTK */
2009-05-14 15:44:43 +00:00
/* sofia_presence says something about needing TAG_IF(sticky, NUTAG_PROXY(sticky)) for NAT stuff? */
TAG_END ( ) ) ;
2010-02-06 03:38:24 +00:00
2009-01-30 16:46:37 +00:00
switch_safe_free ( aor ) ;
switch_safe_free ( subscriber ) ;
2009-02-01 00:06:46 +00:00
switch_safe_free ( route_uri ) ;
2009-05-14 15:44:43 +00:00
switch_safe_free ( sla_contact ) ;
2009-01-30 16:46:37 +00:00
switch_safe_free ( sql ) ;
}
struct sla_notify_helper {
sofia_profile_t * profile ;
char * payload ;
} ;
2009-03-22 05:15:17 +00:00
void sofia_sla_handle_sip_r_subscribe ( int status ,
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 ,
2011-06-16 14:37:22 -05:00
sofia_dispatch_event_t * de ,
2010-02-06 03:38:24 +00:00
tagi_t tags [ ] )
2009-01-30 16:46:37 +00:00
{
2009-03-22 05:15:17 +00:00
if ( status > = 300 ) {
nua_handle_destroy ( nh ) ;
sofia_private_free ( sofia_private ) ;
} else {
2009-03-24 17:57:00 +00:00
char * full_contact = sip_header_as_string ( nua_handle_home ( nh ) , ( void * ) sip - > sip_contact ) ;
2009-03-22 05:15:17 +00:00
time_t expires = switch_epoch_time_now ( NULL ) ;
char * sql ;
2009-06-09 16:33:33 +00:00
char * contact_str = sofia_glue_strip_uri ( full_contact ) ;
2009-03-22 05:15:17 +00:00
if ( sip & & sip - > sip_expires ) {
expires + = sip - > sip_expires - > ex_delta + 30 ;
}
2009-06-04 04:10:40 +00:00
if ( ( sql = switch_mprintf ( " insert into sip_shared_appearance_dialogs (profile_name, hostname, contact_str, call_id, expires) "
2010-02-06 03:38:24 +00:00
" values ('%q','%q','%q','%q','%ld') " ,
profile - > name , mod_sofia_globals . hostname , contact_str , sip - > sip_call_id - > i_id , ( long ) expires ) ) ) {
2009-03-22 05:15:17 +00:00
sofia_glue_execute_sql ( profile , & sql , SWITCH_TRUE ) ;
}
free ( contact_str ) ;
}
2009-01-30 16:46:37 +00:00
}
2011-06-16 14:37:22 -05:00
void sofia_sla_handle_sip_i_notify ( nua_t * nua , sofia_profile_t * profile , nua_handle_t * nh , sip_t const * sip ,
sofia_dispatch_event_t * de , tagi_t tags [ ] )
2009-01-30 16:46:37 +00:00
{
char * sql = NULL ;
struct sla_notify_helper helper ;
char * aor = NULL ;
char * contact = NULL ;
2009-05-14 15:44:43 +00:00
sofia_transport_t transport = sofia_glue_url2transport ( sip - > sip_contact - > m_url ) ;
2009-01-30 16:46:37 +00:00
/*
* things we know we don ' t do :
* draft - anil - sipping - bla says we should look and see if the specific appearance is in use and if it is
* return an error for the i_notify , to handle the initial line - seize for dialing out case .
* to do that we would need to really track all the appearances * and * override sofia ' s autoresponder for i_notify
* because at this point , it already sent the 200 for us .
* and we simply don ' t track all the appearance status by decoding the XML payload out and recording that in
* an SQL line appearance database yet . we ' ll need to do that in order to do the above , and in order to make
* interoperation possible between devices that disagree on the dialog xml payload OR don ' t even do it that
* way and instead use things like call - info / line - seize events like the old Broadsoft spec .
* instead we cheat and just reflect the entire payload back to the subscribers ( who , because we don ' t
* yet check each AOR as it comes in to see if it is to be managed , is more subscribers than we probably
* should have ) . for the current prototype stage , this works ok anyway .
* and because we don ' t parse the XML , we even reflect it right back to the notifier / sender ( which is called
2010-02-06 03:38:24 +00:00
* " target " in the payload XML , of course ) .
2009-01-30 16:46:37 +00:00
* also because we don ' t track on a per - appearance basis , there IS NOT a hook back from sofia_glue to add
* an appearance index to the outbound invite for the " next free appearance " . this can lead to race
* conditions where a call shows up on slightly different line key numbers at different phones , making
* " pick up on line X " meaningless if such a race occurs . again , it is a prototype . we can fix it later .
2010-02-06 03:38:24 +00:00
*/
2009-01-30 16:46:37 +00:00
/* the dispatcher calls us just because it is aimed at us, so check to see if it is dialog;sla at the very least... */
2010-02-06 03:38:24 +00:00
if ( ( ! sip - > sip_event )
| | ( strcasecmp ( sip - > sip_event - > o_type , " dialog " ) )
| | ! msg_params_find ( sip - > sip_event - > o_params , " sla " ) ) {
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_WARNING , " sent to sla-agent but not dialog;sla \n " ) ;
2009-01-30 16:46:37 +00:00
return ;
}
/* calculate the AOR we're trying to tell people about. should probably double-check before derferencing XXX MTK */
2009-06-03 21:08:34 +00:00
/* We always store the AOR as the sipip and not the request so SLA works with NAT inside out */
2009-06-09 16:10:12 +00:00
aor = switch_mprintf ( " sip:%s@%s " , sip - > sip_to - > a_url - > url_user , profile - > sipip ) ;
2009-01-30 16:46:37 +00:00
/* this isn't sufficient because on things like the polycom, the subscriber is the 'main' ext number, but the
* ' main ' ext number isn ' t in ANY of the headers they send us in the notify . of course .
* as a side effect , the subscriber < > ' % q ' below isn ' t sufficient to prevent reflecting the event back
* at a phone that has the ext # ! = third - party # . see above , can only fix by parsing the XML for the ' target '
* so we don ' t reflect it back at anyone who is the " boss " config , but we do reflect it back at the " secretary "
* config . if that breaks the phone , just set them all up as the " boss " config where ext # = = third - party #
*/
2010-02-06 03:38:24 +00:00
contact = switch_mprintf ( " sip:%s@%s;transport=%s " , sip - > sip_contact - > m_url - > url_user ,
2009-05-14 15:44:43 +00:00
sip - > sip_contact - > m_url - > url_host , sofia_glue_transport2str ( transport ) ) ;
2009-01-30 16:46:37 +00:00
2009-02-13 22:27:05 +00:00
if ( sip - > sip_payload & & sip - > sip_payload - > pl_data ) {
2009-06-03 21:08:34 +00:00
sql = switch_mprintf ( " select subscriber,call_id,aor,profile_name,hostname,contact_str,network_ip from sip_shared_appearance_subscriptions where "
2010-02-06 03:38:24 +00:00
" aor='%q' and profile_name='%q' and hostname='%q' " , aor , profile - > name , mod_sofia_globals . hostname ) ;
2009-01-30 16:46:37 +00:00
helper . profile = profile ;
2010-02-06 03:38:24 +00:00
helper . payload = sip - > sip_payload - > pl_data ; /* could just send the WHOLE payload. you'd get the type that way. */
2009-01-30 16:46:37 +00:00
/* which mutex if any is correct to hold in this callback? XXX MTK FIXME */
2009-11-12 03:52:07 +00:00
sofia_glue_execute_sql_callback ( profile , profile - > ireg_mutex , sql , sofia_sla_sub_callback , & helper ) ;
2009-01-30 16:46:37 +00:00
switch_safe_free ( sql ) ;
switch_safe_free ( aor ) ;
switch_safe_free ( contact ) ;
}
}
static int sofia_sla_sub_callback ( void * pArg , int argc , char * * argv , char * * columnNames )
{
struct sla_notify_helper * helper = pArg ;
/* char *subscriber = argv[0]; */
char * call_id = argv [ 1 ] ;
/* char *aor = argv[2]; */
/* char *profile_name = argv[3]; */
/* char *hostname = argv[4]; */
2009-02-01 00:06:46 +00:00
char * contact_str = argv [ 5 ] ;
2009-06-03 21:08:34 +00:00
char * network_ip = argv [ 6 ] ;
2009-01-30 16:46:37 +00:00
nua_handle_t * nh ;
2009-02-01 00:06:46 +00:00
char * route_uri = NULL ;
2009-06-03 21:08:34 +00:00
char * xml_fixup = NULL ;
char * fixup = NULL ;
2010-02-06 03:38:24 +00:00
nh = nua_handle_by_call_id ( helper - > profile - > nua , call_id ) ; /* that's all you need to find the subscription's nh */
2009-01-30 16:46:37 +00:00
2009-02-13 22:27:05 +00:00
if ( nh ) {
2009-02-01 00:06:46 +00:00
if ( strstr ( contact_str , " ;fs_nat " ) ) {
char * p ;
2009-02-01 00:49:06 +00:00
route_uri = sofia_glue_get_url_from_contact ( contact_str , 1 ) ;
2009-02-01 00:06:46 +00:00
if ( ( p = strstr ( contact_str , " ;fs_ " ) ) ) {
* p = ' \0 ' ;
}
}
if ( route_uri ) {
char * p ;
while ( route_uri & & * route_uri & & ( * route_uri = = ' < ' | | * route_uri = = ' ' ) ) {
route_uri + + ;
}
if ( ( p = strchr ( route_uri , ' > ' ) ) ) {
* p + + = ' \0 ' ;
}
}
2009-12-02 18:46:17 +00:00
if ( helper - > profile - > extsipip ) {
2010-02-06 03:38:24 +00:00
if ( sofia_glue_check_nat ( helper - > profile , network_ip ) ) {
2009-06-03 21:08:34 +00:00
fixup = switch_string_replace ( helper - > payload , helper - > profile - > sipip , helper - > profile - > extsipip ) ;
2010-02-06 03:38:24 +00:00
} else {
2009-06-03 21:08:34 +00:00
fixup = switch_string_replace ( helper - > payload , helper - > profile - > extsipip , helper - > profile - > sipip ) ;
}
xml_fixup = fixup ;
} else {
xml_fixup = helper - > payload ;
}
2010-02-06 03:38:24 +00:00
nua_notify ( nh , SIPTAG_SUBSCRIPTION_STATE_STR ( " active;expires=300 " ) , /* XXX MTK FIXME - this is totally fake calculation */
TAG_IF ( route_uri , NUTAG_PROXY ( route_uri ) ) , SIPTAG_CONTENT_TYPE_STR ( " application/dialog-info+xml " ) , /* could've just kept the type from the payload */
SIPTAG_PAYLOAD_STR ( xml_fixup ) , TAG_END ( ) ) ;
2009-02-01 00:06:46 +00:00
switch_safe_free ( route_uri ) ;
2010-02-06 03:38:24 +00:00
if ( fixup & & fixup ! = helper - > payload ) {
2009-06-03 21:08:34 +00:00
free ( fixup ) ;
}
2011-07-16 01:02:22 -05:00
nua_handle_unref ( nh ) ;
2009-01-30 16:46:37 +00:00
}
return 0 ;
}