[Freeswitch-svn] [commit] r1838 - in freeswitch/branches/stkn: conf src/mod/endpoints/mod_pjsip
Freeswitch SVN
stkn at freeswitch.org
Tue Jul 11 21:46:44 EDT 2006
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;
}
More information about the Freeswitch-svn
mailing list