[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