[commit] r1838 - in freeswitch/branches/stkn: conf src/mod/endpoints/mod_pjsip
Author: stkn Date: Tue Jul 11 21:46:44 2006 New Revision: 1838 Modified: freeswitch/branches/stkn/conf/freeswitch.xml freeswitch/branches/stkn/src/mod/endpoints/mod_pjsip/mod_pjsip.c freeswitch/branches/stkn/src/mod/endpoints/mod_pjsip/mod_pjsip.h freeswitch/branches/stkn/src/mod/endpoints/mod_pjsip/mod_pjsip_sdp.c Log: Add profile support to mod_pjsip and start to add configuration options; change pjsip_on_hangup() to simply terminate the call if it has not yet reached the "confirmed" state. Modified: freeswitch/branches/stkn/conf/freeswitch.xml ============================================================================== --- freeswitch/branches/stkn/conf/freeswitch.xml (original) +++ freeswitch/branches/stkn/conf/freeswitch.xml Tue Jul 11 21:46:44 2006 @@ -71,7 +71,20 @@ </modules> </configuration> - + + <configuration name="pjsip.conf" description="PJSIP Configuration"> + <profile name="default"> + <param name="port" value="5060"/> + <param name="max-calls" value="10"/> + <param name="dialplan" value="XML"/> + </profile> + <profile name="foobar"> + <param name="port" value="5061"/> + <param name="max-calls" value="10"/> + <param name="dialplan" value="XML"/> + </profile> + </configuration> + <configuration name="iax.conf" description="IAX Configuration"> <settings> <param name="debug" value="0"/> Modified: freeswitch/branches/stkn/src/mod/endpoints/mod_pjsip/mod_pjsip.c ============================================================================== --- freeswitch/branches/stkn/src/mod/endpoints/mod_pjsip/mod_pjsip.c (original) +++ freeswitch/branches/stkn/src/mod/endpoints/mod_pjsip/mod_pjsip.c Tue Jul 11 21:46:44 2006 @@ -15,7 +15,16 @@ * * 2006-06-20: added parts of sdp negotiation, started writing pjsip event handler code. * more code taken from mod_exosip for FS event handling. + * + * 2006-07-12: initial version of profiles support + * */ +/* + * TODO: + * + * Do we really need to call pj_register_thread() in monitor_thread()? + * + */ #define HAVE_APR #include <switch.h> @@ -30,7 +39,7 @@ static const char modname[] = "mod_pjsip"; -#define MAX_CALLS 1000 +#define MOD_PJSIP_CFG "pjsip.conf" static switch_memory_pool_t *module_pool = NULL; static pj_caching_pool cp; @@ -41,37 +50,50 @@ static struct { /* */ - switch_hash_t *call_hash; + switch_hash_t *profiles_hash; + switch_hash_t *transport_hash; + int running; + pjsip_endpoint *sip_endpt; + pjsip_module mod_app; +} globals; + +struct pjsip_profile { pj_str_t local_uri; pj_str_t local_contact; pj_sockaddr_in sip_addr; //<- really needed? - /* endpoints */ - pjsip_endpoint *sip_endpt; - pjsip_module mod_app; - /* */ + char name[128]; char local_addr[128]; - char dialplan[50]; + char *dialplan; + char *codec_string; + char *codec_order[SWITCH_MAX_CODECS]; + int codec_order_last; + int sip_port; - int running; -} globals; + int max_calls; + int calls; + switch_hash_t *call_hash; +}; + + enum tech_flags { TFLAG_OUTBOUND = (1 << 0), TFLAG_INBOUND = (1 << 1), TFLAG_IO = (1 << 2), TFLAG_BYE = (1 << 3), - TFLAG_RINGING = (1 << 4), // not used atm - TFLAG_ANSWERED = (1 << 5), - TFLAG_USING_CODEC = (1 << 6), + TFLAG_ANSWERED = (1 << 4), + TFLAG_USING_CODEC = (1 << 5), TFLAG_READING = (1 << 10), TFLAG_WRITING = (1 << 11), TFLAG_TIMER = (1 << 20) }; +#define set_param(ptr, val) if ( ptr ) { free( ptr ); ptr = NULL; } if ( val ) { ptr = strdup( val ); } + static switch_status_t create_sdp( pj_pool_t *pool, struct pjsip_tech_pvt *pvt, pjmedia_sdp_session **p_sdp, @@ -147,8 +169,20 @@ /*.application_interface */ NULL }; +/* */ +static int pjsip_strncpy( char *dst, const pj_str_t *src, int maxlen ) +{ + int len = maxlen > src->slen ? src->slen : maxlen; + + switch_copy_string( dst, src->ptr, len - 1 ); + dst[len] = '\0'; + + return len; +} + static switch_status_t pjsip_on_init(switch_core_session_t *session) { + struct pjsip_profile *profile; struct pjsip_tech_pvt *pvt; switch_channel_t *channel; pj_status_t status; @@ -159,6 +193,9 @@ pvt = switch_core_session_get_private( session ); assert( pvt != NULL ); + profile = pvt->profile; + assert( profile != NULL ); + /* register switch thread to pjsip core */ status = pj_thread_register( NULL, pvt->thread_desc, &pvt->thread ); if( status != PJ_SUCCESS ) { @@ -179,12 +216,12 @@ pvt->sip_ua = pjsip_ua_instance(); - switch_log_printf( SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Dst: %s, Local: %s %s\n", tmp, globals.local_uri.ptr, globals.local_contact.ptr ); + switch_log_printf( SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Dst: %s, Local: %s %s\n", tmp, pvt->profile->local_uri.ptr, pvt->profile->local_contact.ptr ); /* create new UAC dialog */ status = pjsip_dlg_create_uac( pvt->sip_ua, - &globals.local_uri, - &globals.local_contact, + &pvt->profile->local_uri, + &pvt->profile->local_contact, &dst, &dst, &pvt->sip_dialog ); @@ -258,7 +295,7 @@ switch_set_flag( pvt, TFLAG_IO ); /* add call to hash */ - switch_core_hash_insert( globals.call_hash, pvt->call_id, pvt ); + switch_core_hash_insert( profile->call_hash, pvt->call_id, pvt ); return SWITCH_STATUS_SUCCESS; } @@ -276,29 +313,6 @@ pvt = switch_core_session_get_private( session ); assert( pvt != NULL ); -#if 0 /* fix this, pjsip_inv_* is wrong here */ - if( !switch_channel_test_flag( channel, CF_OUTBOUND ) ) { - pj_status_t status; - pjsip_tx_data *txdata; - - /* start to send 180 ring every second */ - status = pjsip_inv_create_answer( pvt->sip_dialog, 180, NULL, &txdata ); - if( status != PJ_SUCCESS ) { - switch_log_printf( SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Failed to create 183 RING message" ); - status = pjsip_inv_end_session( pvt->sip_invite, 500, NULL, &txdata ); - if( status == PJ_SUCCESS ) - pjsip_inv_send_msg( pvt->sip_invite, txdata ); - else - pjsip_inv_terminate( pvt->sip_invite, 500, 1 ); - - switch_core_session_destroy( &session ); - return SWITCH_STATUS_GENERR; - } - pjsip_dlg_send_response( pvt->sip_dialog, pjsip_rdata_get_tsx(rxdata), txdata ); - switch_set_flag( pvt, TFLAG_RINGING ); - } -#endif - switch_log_printf( SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "RING %s\n", switch_channel_get_name( channel ) ); return SWITCH_STATUS_SUCCESS; @@ -306,6 +320,7 @@ static switch_status_t pjsip_on_hangup(switch_core_session_t *session) { + struct pjsip_profile *profile; struct pjsip_tech_pvt *pvt; switch_channel_t *channel; pj_status_t status; @@ -319,23 +334,29 @@ pvt = switch_core_session_get_private( session ); assert( pvt != NULL ); + profile = pvt->profile; + assert( profile != NULL ); + switch_log_printf( SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Hangup call %s\n", pvt->call_id ); /* remove call from hash */ - switch_core_hash_delete( globals.call_hash, pvt->call_id ); + switch_core_hash_delete( profile->call_hash, pvt->call_id ); switch_set_flag( pvt, TFLAG_BYE ); switch_clear_flag( pvt, TFLAG_IO ); stop_rtp( pvt ); - status = pjsip_inv_end_session( pvt->sip_invite, 200, NULL, &txdata ); - if( status != PJ_SUCCESS ) + if( pvt->sip_invite->state < PJSIP_INV_STATE_CONFIRMED ) { pjsip_inv_terminate( pvt->sip_invite, 500, PJ_TRUE ); - else - pjsip_inv_send_msg( pvt->sip_invite, txdata ); + } else { + status = pjsip_inv_end_session( pvt->sip_invite, 200, NULL, &txdata ); + if( status != PJ_SUCCESS ) + pjsip_inv_terminate( pvt->sip_invite, 500, PJ_TRUE ); + else + pjsip_inv_send_msg( pvt->sip_invite, txdata ); + } - if ( switch_test_flag( pvt, TFLAG_USING_CODEC ) ) { switch_core_codec_destroy( &pvt->read_codec ); switch_core_codec_destroy( &pvt->write_codec ); @@ -466,7 +487,28 @@ { struct pjsip_tech_pvt *pvt = NULL; switch_channel_t *channel = NULL; + struct pjsip_profile *profile = NULL; + switch_caller_profile_t *caller_profile = NULL; + char tmp[1024], *profile_name, *dest; + assert( outbound_profile != NULL ); + + switch_copy_string( tmp, outbound_profile->destination_number, sizeof(tmp) ); + profile_name = tmp; + if(( dest = strchr( tmp, '/' ) )) { + *dest++ = '\0'; + } + + if( !( profile_name && dest ) ) { + switch_log_printf( SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Malformed URL!\n" ); + return SWITCH_STATUS_GENERR; + } + + if( !( profile = (struct pjsip_profile *) switch_core_hash_find( globals.profiles_hash, profile_name ) )) { + switch_log_printf( SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Unknown profile: %s\n", profile_name ); + return SWITCH_STATUS_GENERR; + } + if ( !( *new_session = switch_core_session_request( &pjsip_endpoint_interface, pool ) ) ) { switch_log_printf( SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Failed to create new session for call\n" ); return SWITCH_STATUS_GENERR; @@ -480,32 +522,32 @@ goto err; } pj_memset( pvt, 0, sizeof(struct pjsip_tech_pvt) ); + switch_core_session_set_private( *new_session, pvt ); + channel = switch_core_session_get_channel( *new_session ); + pvt->session = *new_session; + pvt->profile = profile; /* get list of all available codecs */ pvt->num_codecs = switch_loadable_module_get_codecs( switch_core_session_get_pool(pvt->session), pvt->codecs, sizeof(pvt->codecs) / sizeof(pvt->codecs[0]) ); - if( outbound_profile ) { - switch_caller_profile_t *caller_profile = NULL; - char name[128]; + /* create channel name, copy profile and parse destination number (?) */ + snprintf( tmp, sizeof(tmp), "pjsip/%s-%04x", outbound_profile->destination_number, rand() & 0xffff ); + switch_channel_set_name( channel, tmp ); - /* create channel name, copy profile and parse destination number (?) */ - snprintf( name, sizeof(name), "pjsip/%s-%04x", outbound_profile->destination_number, rand() & 0xffff ); - switch_channel_set_name( channel, name ); + caller_profile = switch_caller_profile_clone( *new_session, outbound_profile ); + switch_channel_set_caller_profile( channel, caller_profile ); - caller_profile = switch_caller_profile_clone( *new_session, outbound_profile ); - switch_channel_set_caller_profile( channel, caller_profile ); + pvt->caller_profile = caller_profile; - pvt->caller_profile = caller_profile; + switch_channel_set_flag( channel, CF_OUTBOUND ); + switch_channel_set_state( channel, CS_INIT ); - switch_channel_set_flag( channel, CF_OUTBOUND ); - switch_channel_set_state( channel, CS_INIT ); + return SWITCH_STATUS_SUCCESS; - return SWITCH_STATUS_SUCCESS; - } err: switch_core_session_destroy(new_session); return SWITCH_STATUS_GENERR; @@ -612,31 +654,42 @@ static void on_incoming_call( pjsip_rx_data *rxdata ) { switch_core_session_t *session; + struct pjsip_profile *profile; pj_status_t status; + /* How to map rxdata / transport -> profile? */ + if( !( profile = switch_core_hash_find( globals.transport_hash, rxdata->tp_info.transport->obj_name )) ) { + switch_log_printf( SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Profile not found\n" ); + return; + } + + switch_log_printf( SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "*** New incoming call for profile %s\n", profile->name ); + /* check call limit */ -#if 0 - if( switch_core_hash_count( &globals.call_hash ) >= MAX_CALLS ) { + if( profile->max_calls && ( profile->calls + 1 ) > profile->max_calls ) { const pj_str_t reason = pj_str("Too many calls"); - pjsip_endpt_respond_stateless( app.sip_endpt, rxdata, + + pjsip_endpt_respond_stateless( globals.sip_endpt, rxdata, 500, &reason, NULL, NULL); - return; + switch_log_printf( SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Too many calls (profile: %s)\n", profile->name ); + return; } -#endif + switch_log_printf( SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "PJSIP process id %lu, thread name %s\n", pj_getpid(), pj_thread_get_name( pj_thread_this() ) ); if ((session = switch_core_session_request( &pjsip_endpoint_interface, NULL ))) { struct pjsip_tech_pvt *pvt; switch_channel_t *channel; - char name[128]; pjmedia_sdp_session *sdp; pjsip_dialog *dialog; pjsip_tx_data *txdata; pj_str_t tmp, username, host, destination; + char name[1024]; channel = switch_core_session_get_channel( session ); + /* allocate new session */ switch_core_session_add_stream( session, NULL ); if ((pvt = (struct pjsip_tech_pvt *) switch_core_session_alloc( session, sizeof(struct pjsip_tech_pvt) ))) { memset( pvt, 0, sizeof(struct pjsip_tech_pvt) ); @@ -656,6 +709,7 @@ /* need the invite data in pjsip_on_init */ pvt->sip_ua = pjsip_ua_instance(); + pvt->profile = profile; /* create UAS dialog */ status = pjsip_dlg_create_uas( pvt->sip_ua, rxdata, NULL, &dialog ); @@ -693,7 +747,7 @@ if ( (pvt->caller_profile = switch_caller_profile_new( switch_core_session_get_pool( session ), username.ptr, - globals.dialplan, + profile->dialplan, username.ptr, username.ptr, host.ptr, @@ -709,9 +763,10 @@ /* assign vars */ pvt->sip_invite->mod_data[globals.mod_app.id] = pvt; pvt->sip_dialog = dialog; + pvt->profile = profile; /* set call id */ - strncpy( pvt->call_id, dialog->call_id->id.ptr, PJ_MAX_STRLEN(pvt->call_id, dialog->call_id->id) ); + pjsip_strncpy( pvt->call_id, &dialog->call_id->id, sizeof( pvt->call_id ) ); switch_set_flag( pvt, TFLAG_INBOUND ); @@ -768,7 +823,7 @@ ;; default: reason = rxdata->msg_info.msg->line.req.method.name; - pjsip_endpt_respond_stateless( globals.sip_endpt, rxdata, + pjsip_endpt_respond_stateless( rxdata->tp_info.transport->endpt, rxdata, 500, &reason, NULL, NULL ); ;; } @@ -778,6 +833,7 @@ static void call_on_tsx_state_changed( pjsip_inv_session *inv, pjsip_transaction *tsx, pjsip_event *e ) { struct pjsip_tech_pvt *pvt; + struct pjsip_profile *profile; switch_core_session_t *session; assert( inv != NULL && tsx != NULL ); @@ -785,6 +841,9 @@ pvt = inv->mod_data[globals.mod_app.id]; assert( pvt != NULL ); + profile = pvt->profile; + assert( profile != NULL ); + session = pvt->session; assert( session != NULL ); @@ -809,6 +868,7 @@ pjsip_event *evt ) { struct pjsip_tech_pvt *pvt; + struct pjsip_profile *profile; switch_core_session_t *session; switch_channel_t *channel; @@ -817,6 +877,9 @@ pvt = inv->mod_data[globals.mod_app.id]; assert( pvt != NULL ); + profile = pvt->profile; + assert( profile != NULL ); + session = pvt->session; assert( session != NULL ); @@ -862,6 +925,7 @@ pj_status_t status ) { struct pjsip_tech_pvt *pvt; + struct pjsip_profile *profile; const pjmedia_sdp_session *remote_sdp, *local_sdp; pj_pool_t *pool; const switch_codec_implementation_t *codec, *imp; @@ -874,6 +938,9 @@ pvt = inv->mod_data[globals.mod_app.id]; assert( pvt != NULL ); + profile = pvt->profile; + assert( profile != NULL ); + pool = inv->dlg->pool; assert( pool != NULL ); @@ -1062,6 +1129,7 @@ pjmedia_sdp_session **p_sdp, pjmedia_sdp_session *ref_sdp ) { + struct pjsip_profile *profile; pjmedia_sdp_session *sdp; pjmedia_sdp_media *media; pjmedia_sdp_attr *attr, *rtpmap_attr; @@ -1071,6 +1139,9 @@ if( !pool || !pvt ) return SWITCH_STATUS_GENERR; + profile = pvt->profile; + assert( profile != NULL ); + /* allocate and initialize new SDP var */ sdp = pj_pool_zalloc( pool, sizeof(pjmedia_sdp_session) ); if( !sdp ) @@ -1086,7 +1157,7 @@ sdp->conn = pj_pool_zalloc( pool, sizeof(pjmedia_sdp_conn) ); sdp->conn->net_type = pj_str( "IN" ); sdp->conn->addr_type = pj_str( "IP4" ); - sdp->conn->addr = pj_str( globals.local_addr ); + sdp->conn->addr = pj_str( profile->local_addr ); sdp->time.start = sdp->time.stop = 0; sdp->attr_count = 0; @@ -1102,7 +1173,7 @@ media->desc.port_count = 1; media->desc.transport = pj_str( "RTP/AVP" ); - strncpy( pvt->local_sdp_audio_addr, globals.local_addr, sizeof(pvt->local_sdp_audio_addr) ); + strncpy( pvt->local_sdp_audio_addr, profile->local_addr, sizeof(pvt->local_sdp_audio_addr) ); /* codec rtpmap list */ media->desc.fmt_count = 0; @@ -1242,18 +1313,62 @@ return SWITCH_STATUS_SUCCESS; } -#if 0 // unused for now -static struct pjsip_tech_pvt * find_pvt_by_callid( char *id ) +static switch_status_t config_pjsip( void ) { - struct pjsip_tech_pvt *pvt = NULL; + char *cfgname = MOD_PJSIP_CFG; + switch_xml_t config, xml, xmlprofile, param; - assert( id != NULL ); + if( !( xml = switch_xml_open_cfg( cfgname, &config, NULL ) )) { + switch_log_printf( SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Could not open config %s\n", cfgname ); + return SWITCH_STATUS_TERM; + } - pvt = (struct pjsip_tech_pvt *) switch_core_hash_find( globals.call_hash, id ); + for( xmlprofile = switch_xml_child( config, "profile" ); xmlprofile; xmlprofile = xmlprofile->next ) + { + struct pjsip_profile *profile; + char *profile_name = (char *) switch_xml_attr_soft( xmlprofile, "name" ); - return pvt; + if( !profile_name ) { + profile_name = "noname"; + } + + if( !(profile = switch_core_alloc( module_pool, sizeof(struct pjsip_profile))) ) { + switch_log_printf( SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Failed to allocate new profile %s\n", profile_name ); + return SWITCH_STATUS_TERM; + } + memset( profile, 0, sizeof( struct pjsip_profile ) ); + + switch_copy_string( profile->name, profile_name, sizeof( profile->name ) ); + + for( param = switch_xml_child( xmlprofile, "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, "max-calls" ) ) { + profile->max_calls = atoi( val ); + } + else if ( !strcmp( var, "port" ) ) { + profile->sip_port = atoi( val ); + } + else if ( !strcmp( var, "dialplan" ) ) { + set_param( profile->dialplan, val ); + } + else if ( !strcmp( var, "codec-prefs" ) ) { + set_param( profile->codec_string, val ); + profile->codec_order_last = switch_separate_string( profile->codec_string, ',', profile->codec_order, SWITCH_MAX_CODECS ); + } + else { + switch_log_printf( SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Unknown option %s (ignored)\n", var ); + } + } + + switch_log_printf( SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Adding profile %s\n", profile->name ); + switch_core_hash_insert( globals.profiles_hash, profile->name, profile ); + } + + return SWITCH_STATUS_SUCCESS; } -#endif /* END: mid-level functions */ @@ -1272,14 +1387,14 @@ SWITCH_MOD_DECLARE(switch_status_t) switch_module_load(const switch_loadable_module_interface_t **module_interface, char *filename) { - /* NOTE: **interface is **_interface because the common lib redefines interface to struct in some situations */ if (switch_core_new_memory_pool( &module_pool ) != SWITCH_STATUS_SUCCESS ) { switch_log_printf( SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "OH OH no pool\n" ); return SWITCH_STATUS_TERM; } - switch_core_hash_init( &globals.call_hash, module_pool ); + switch_core_hash_init( &globals.profiles_hash, module_pool ); + switch_core_hash_init( &globals.transport_hash, module_pool ); /* connect my internal structure to the blank pointer passed to me */ *module_interface = &pjsip_module_interface; @@ -1290,19 +1405,9 @@ SWITCH_MOD_DECLARE(switch_status_t) switch_module_runtime(void) { + switch_hash_index_t *p_entry; pj_status_t status; - globals.sip_port = 5060; - - pj_memset( &globals.mod_app, 0, sizeof(globals.mod_app) ); - globals.mod_app.name = pj_str( "mod-pjsip" ); /* Name. */ - globals.mod_app.id = -1; /* Id */ - globals.mod_app.priority = PJSIP_MOD_PRIORITY_APPLICATION; /* Priority */ - globals.mod_app.on_rx_request = &on_rx_request; /* on_rx_request() */ - - /* Set dialplan */ - strncpy( globals.dialplan, "XML", sizeof(globals.dialplan) - 1 ); - /* init pjlib */ status = pj_init(); if ( status != PJ_SUCCESS ) { @@ -1320,6 +1425,18 @@ /* initialize pjlib pool factory */ pj_caching_pool_init( &cp, &pj_pool_factory_default_policy, 0 ); + /* global pool */ + pjsip_pool = pj_pool_create( &cp.factory, "pjsip-pool", 1024, 1024, NULL ); + if( !pjsip_pool ) { + switch_log_printf( SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Failed to initialize global pool\n" ); + return SWITCH_STATUS_TERM; + } + + if( config_pjsip( ) != SWITCH_STATUS_SUCCESS ) { + switch_log_printf( SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Failed to load configuration\n" ); + return SWITCH_STATUS_TERM; + } + /* create endpoint */ status = pjsip_endpt_create( &cp.factory, "FreeSWITCH", &globals.sip_endpt ); if ( status != PJ_SUCCESS ) { @@ -1327,18 +1444,56 @@ return SWITCH_STATUS_TERM; } - /* allocate pool for pjsip functions */ - pjsip_pool = pjsip_endpt_create_pool( globals.sip_endpt, "pjsip-pool", 1024, 1024 ); + pj_memset( &invite_cb, 0, sizeof(invite_cb) ); + invite_cb.on_state_changed = &call_on_state_changed; + invite_cb.on_new_session = &call_on_forked; + invite_cb.on_media_update = &call_on_media_update; + invite_cb.on_tsx_state_changed = &call_on_tsx_state_changed; - /* add udp transport */ - globals.sip_addr.sin_family = PJ_AF_INET; - globals.sip_addr.sin_addr.s_addr = 0; - globals.sip_addr.sin_port = pj_htons( 5060 ); + /* + * + */ + for( p_entry = switch_hash_first( module_pool, globals.profiles_hash ); p_entry; p_entry = switch_hash_next( p_entry ) ) + { + struct pjsip_profile *profile; + pjsip_transport *transport; + void *val; - status = pjsip_udp_transport_start( globals.sip_endpt, &globals.sip_addr, NULL, 1, NULL ); - if ( status != PJ_SUCCESS ) { - switch_log_printf( SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Failed to create UDP transport\n" ); - return SWITCH_STATUS_TERM; + switch_hash_this( p_entry, NULL, NULL, &val ); + profile = val; + + /* add udp transport */ + profile->sip_addr.sin_family = PJ_AF_INET; + profile->sip_addr.sin_addr.s_addr = 0; + profile->sip_addr.sin_port = pj_htons( profile->sip_port ); + + status = pjsip_udp_transport_start( globals.sip_endpt, &profile->sip_addr, NULL, 1, &transport ); + if ( status != PJ_SUCCESS ) { + switch_log_printf( SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Failed to create UDP transport\n" ); + return SWITCH_STATUS_TERM; + } + + /* */ + { + const pj_str_t *hostname; + pj_sockaddr_in tmp_addr; + char *addr; + char local_uri[64]; + + hostname = pj_gethostname(); + pj_sockaddr_in_init( &tmp_addr, hostname, 0 ); + addr = pj_inet_ntoa( tmp_addr.sin_addr ); + pj_ansi_strcpy( profile->local_addr, addr ); + pj_ansi_sprintf( local_uri, "sip:%s:%d", hostname->ptr, profile->sip_port ); + pj_strdup2( pjsip_pool, &profile->local_uri, local_uri ); + pj_strdup2( pjsip_pool, &profile->local_contact, local_uri ); + } + + /* init call hash */ + switch_core_hash_init( &profile->call_hash, module_pool ); + + /* add transports name to hash */ + switch_core_hash_insert( globals.transport_hash, transport->obj_name, profile ); } /* init transaction handling */ @@ -1355,12 +1510,6 @@ return SWITCH_STATUS_TERM; } - pj_memset( &invite_cb, 0, sizeof(invite_cb) ); - invite_cb.on_state_changed = &call_on_state_changed; - invite_cb.on_new_session = &call_on_forked; - invite_cb.on_media_update = &call_on_media_update; - invite_cb.on_tsx_state_changed = &call_on_tsx_state_changed; - /* initialize invite session module */ status = pjsip_inv_usage_init( globals.sip_endpt, &invite_cb ); if ( status != PJ_SUCCESS ) { @@ -1368,26 +1517,16 @@ return SWITCH_STATUS_TERM; } - /* */ - { - const pj_str_t *hostname; - pj_sockaddr_in tmp_addr; - char *addr; - char local_uri[64]; + pj_memset( &globals.mod_app, 0, sizeof(globals.mod_app) ); + globals.mod_app.name = pj_str( "mod_pjsip" ); /* Name. */ + globals.mod_app.id = -1; /* Id */ + globals.mod_app.priority = PJSIP_MOD_PRIORITY_APPLICATION; /* Priority */ + globals.mod_app.on_rx_request = &on_rx_request; /* on_rx_request() */ - hostname = pj_gethostname(); - pj_sockaddr_in_init( &tmp_addr, hostname, 0 ); - addr = pj_inet_ntoa( tmp_addr.sin_addr ); - pj_ansi_strcpy( globals.local_addr, addr ); - pj_ansi_sprintf( local_uri, "sip:%s:%d", hostname->ptr, globals.sip_port ); - pj_strdup2( pjsip_pool, &globals.local_uri, local_uri ); - pj_strdup2( pjsip_pool, &globals.local_contact, local_uri ); - } - /* register application to pjsip core */ status = pjsip_endpt_register_module( globals.sip_endpt, &globals.mod_app ); if ( status != PJ_SUCCESS ) { - switch_log_printf( SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Failed to register mod_pjsip application to pjsip core\n" ); + switch_log_printf( SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Failed to register mod_pjsip application to pjsip core\n" ); return SWITCH_STATUS_TERM; } @@ -1399,8 +1538,8 @@ pj_time_val timeout = { 1, 0 }; pjsip_endpt_handle_events( globals.sip_endpt, &timeout ); } - globals.running = 0; + switch_log_printf( SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Monitor thread exiting\n" ); return SWITCH_STATUS_TERM; Modified: freeswitch/branches/stkn/src/mod/endpoints/mod_pjsip/mod_pjsip.h ============================================================================== --- freeswitch/branches/stkn/src/mod/endpoints/mod_pjsip/mod_pjsip.h (original) +++ freeswitch/branches/stkn/src/mod/endpoints/mod_pjsip/mod_pjsip.h Tue Jul 11 21:46:44 2006 @@ -1,8 +1,11 @@ #ifndef _MOD_PJSIP_H_ #define _MOD_PJSIP_H_ +struct pjsip_profile; + struct pjsip_tech_pvt { /* switch */ + struct pjsip_profile *profile; switch_core_session_t *session; switch_caller_profile_t *caller_profile; char call_id[50]; Modified: freeswitch/branches/stkn/src/mod/endpoints/mod_pjsip/mod_pjsip_sdp.c ============================================================================== --- freeswitch/branches/stkn/src/mod/endpoints/mod_pjsip/mod_pjsip_sdp.c (original) +++ freeswitch/branches/stkn/src/mod/endpoints/mod_pjsip/mod_pjsip_sdp.c Tue Jul 11 21:46:44 2006 @@ -62,6 +62,8 @@ /* codec found, find implementation too */ tmp_imp = pvt->codecs[i]; + switch_log_printf( SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "--- Codec %s found\n", pvt->codecs[i]->iananame ); + while( tmp_imp != NULL ) { if ( tmp_imp->samples_per_second == clock_rate ) { *codec = pvt->codecs[i]; @@ -74,6 +76,7 @@ break; } } + switch_log_printf( SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "--- Codec not found\n", pvt->codecs[i]->iananame ); return PJ_ENOTFOUND; } @@ -111,6 +114,7 @@ if (!pj_isdigit(*local_m->desc.fmt[0].ptr) || !pj_isdigit(*rem_m->desc.fmt[0].ptr)) { + switch_log_printf( SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "--- Hmm invalid codec entries in SDP\n" ); return PJMEDIA_EINVALIDPT; } @@ -140,19 +144,24 @@ /* Build codec format info: */ if (has_rtpmap) { status = find_codec( pvt, pt, rtpmap->clock_rate, codec, imp ); - if( status != PJ_SUCCESS ) + if( status != PJ_SUCCESS ) { + switch_log_printf( SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "--- Hmm codec not found (with rtpmap)\n" ); return PJ_ENOTFOUND; + } } else { /* * No rtpmap, use default clock_rate (8000 Hz) */ status = find_codec( pvt, pt, 8000, codec, imp ); - if( status != PJ_SUCCESS ) + if( status != PJ_SUCCESS ) { + switch_log_printf( SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "--- Hmm codec not found (without rtpmap, 8KHz default)\n" ); return PJ_ENOTFOUND; + } } - } else + } else { + switch_log_printf( SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "--- Hmm payload type >96 (dynamic) not supported!\n" ); return PJ_ENOTSUP; - + } return PJ_SUCCESS; }
participants (1)
-
Freeswitch SVN