[Freeswitch-svn] [commit] r2270 - freeswitch/branches/bennylp/src/mod/endpoints/mod_pjsip

Freeswitch SVN bennylp at freeswitch.org
Sat Aug 12 09:56:55 EDT 2006


Author: bennylp
Date: Sat Aug 12 09:56:55 2006
New Revision: 2270

Modified:
   freeswitch/branches/bennylp/src/mod/endpoints/mod_pjsip/mod_pjsip.c

Log:
mod_pjsip looks okay, but there is deadlock in switch_channel_hangup()

Modified: freeswitch/branches/bennylp/src/mod/endpoints/mod_pjsip/mod_pjsip.c
==============================================================================
--- freeswitch/branches/bennylp/src/mod/endpoints/mod_pjsip/mod_pjsip.c	(original)
+++ freeswitch/branches/bennylp/src/mod/endpoints/mod_pjsip/mod_pjsip.c	Sat Aug 12 09:56:55 2006
@@ -42,11 +42,7 @@
 #define MOD_PJSIP_CFG	"pjsip.conf"
 #define THIS_FILE		pj_thread_get_name(pj_thread_this())
 
-#if 0
-#define TRACE_(x)		PJ_LOG(4,x) 
-#else
-#define TRACE_(x)
-#endif
+#define TRACE_(x)		PJ_LOG(6,x) 
 
 static switch_memory_pool_t *module_pool = NULL;
 static pj_caching_pool cp;
@@ -195,16 +191,20 @@
 
 void log_func(int level, const char *data, int len)
 {
-#if 1
-	switch_log_printf( SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, (char *) data);
-#else
-	static FILE *pjsip_log;
-	if (pjsip_log == NULL)
-		pjsip_log = fopen("/tmp/pjsip-fs.log", "w");
+	char msg[1024];
+	pj_ansi_snprintf(msg, sizeof(msg), "[%s] %s", THIS_FILE, data);
+	switch_log_printf( SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, msg);
 
-	if (pjsip_log != NULL) {
-		fwrite(data, len, 1, pjsip_log);
-		fflush(pjsip_log);
+#if PJ_LOG_MAX_LEVEL >= 6
+	{
+		static FILE *pjsip_log;
+		if (pjsip_log == NULL)
+			pjsip_log = fopen("/tmp/pjsip-fs.log", "w");
+
+		if (pjsip_log != NULL) {
+			fwrite(data, len, 1, pjsip_log);
+			fflush(pjsip_log);
+		}
 	}
 #endif
 }
@@ -406,7 +406,7 @@
 	assert( profile != NULL );
 
 	PJ_LOG(4,(THIS_FILE, "Hangup call %s dialog=%s", tech_pvt->call_id, 
-			  tech_pvt->sip_invite->dlg->obj_name));
+			     (tech_pvt->sip_invite ? tech_pvt->sip_invite->dlg->obj_name : "none")));
 
 	/* remove call from hash */
 	switch_core_hash_delete( profile->call_hash, tech_pvt->call_id );
@@ -416,18 +416,19 @@
 
 	stop_rtp( tech_pvt );
 
-	//PJ_TODO(should_we_clear_dlg_data_here);
+	/* Hangup PJSIP call */
+	if (tech_pvt->sip_invite && tech_pvt->sip_invite->state < PJSIP_INV_STATE_DISCONNECTED) {
+		status = pjsip_inv_end_session( tech_pvt->sip_invite, 200, NULL, &txdata );
+		if( status == PJ_SUCCESS ) {
+			add_server_header(txdata);
+			status = pjsip_inv_send_msg( tech_pvt->sip_invite, txdata );
+		}
 
-	status = pjsip_inv_end_session( tech_pvt->sip_invite, 200, NULL, &txdata );
-	if( status == PJ_SUCCESS ) {
-		add_server_header(txdata);
-		status = pjsip_inv_send_msg( tech_pvt->sip_invite, txdata );
+		if (status != PJ_SUCCESS) {
+			perror_(tech_pvt->sip_invite->dlg->obj_name, "Unable to hangup", status);
+		}
 	}
 
-	if (status != PJ_SUCCESS) {
-		perror_(tech_pvt->sip_invite->dlg->obj_name, "Unable to hangup", status);
-	}
-
 	if (switch_test_flag( tech_pvt, TFLAG_USING_CODEC ) ) {
 		switch_core_codec_destroy( &tech_pvt->read_codec );
 		switch_core_codec_destroy( &tech_pvt->write_codec );
@@ -442,6 +443,8 @@
 	struct private_object *tech_pvt;
 	switch_channel_t *channel;
 
+	TRACE_((THIS_FILE, "ENTER pjsip_on_loopback"));
+
 	channel = switch_core_session_get_channel( session );
 	assert( channel != NULL );
 
@@ -450,6 +453,7 @@
 
 	/* do nothing */
 
+	TRACE_((THIS_FILE, "LEAVE pjsip_on_loopback"));
 	return SWITCH_STATUS_SUCCESS;
 } 
 
@@ -458,6 +462,8 @@
 	struct private_object *tech_pvt;
 	switch_channel_t *channel;
 
+	TRACE_((THIS_FILE, "ENTER pjsip_on_transmit"));
+
 	assert( session != NULL );
 
 	channel = switch_core_session_get_channel( session );
@@ -468,6 +474,7 @@
 
 	/* do nothing */
 
+	TRACE_((THIS_FILE, "LEAVE pjsip_on_transmit"));
 	return SWITCH_STATUS_SUCCESS;
 } 
 
@@ -763,6 +770,7 @@
 	switch_clear_flag_locked(tech_pvt, TFLAG_READING);
 
 	if (switch_test_flag(tech_pvt, TFLAG_BYE)) {
+		TRACE_((THIS_FILE, "switch_channel_hangup(%x) called by pjsip_read_frame()", channel));
 		switch_channel_hangup(channel, SWITCH_CAUSE_NORMAL_CLEARING);
 		return SWITCH_STATUS_FALSE;
 	}
@@ -793,6 +801,7 @@
 	}
 
 	if (switch_test_flag(tech_pvt, TFLAG_BYE)) {
+		TRACE_((THIS_FILE, "switch_channel_hangup(%x) called by pjsip_write_frame()", channel));
 		switch_channel_hangup(channel, SWITCH_CAUSE_NORMAL_CLEARING);
 		return SWITCH_STATUS_FALSE;
 	}
@@ -1146,7 +1155,7 @@
     }
 	
     /* Add Server header */
-	add_server_header(tdata);
+		add_server_header(tdata);
 	
     /* TODO: it would be nice if we could add SDP body here (dunno how) */
 	//PJ_TODO(ADD_SDP_TO_OPTIONS_RESPONSE);
@@ -1170,8 +1179,6 @@
 { 
 	pj_str_t reason;
 
-	PJ_LOG(4,(THIS_FILE,"%s: received new request", __FUNCTION__ ));
-
 	switch( rxdata->msg_info.msg->line.req.method.id ) {
 		case PJSIP_INVITE_METHOD:
 			on_incoming_call( rxdata );
@@ -1241,7 +1248,10 @@
 	switch_core_session_t *session;
 	switch_channel_t *channel;
 
+	/* evt may be NULL if invite is terminated by pjsip_inv_terminate()
 	assert ( evt != NULL);
+	 */
+
 	assert ( inv != NULL );
 	
 	if (!(tech_pvt = inv->mod_data[globals.mod_app.id])) {
@@ -1271,28 +1281,35 @@
 	switch( inv->state )
 	{
 	case PJSIP_INV_STATE_DISCONNECTED:
+		/* Remove association between PJSIP call and channel, to prevent
+     * other channels from re-entering PJSIP for the context of this INVITE
+     * (which is guaranteed to cause deadlock!) 
+     */
+		pjsip_dlg_inc_lock(inv->dlg);
+
+		switch_mutex_lock(tech_pvt->flag_mutex);
 		inv->mod_data[globals.mod_app.id] = NULL;
+		tech_pvt->sip_invite = NULL;
+		tech_pvt->sip_dialog = NULL;
+	  switch_mutex_unlock(tech_pvt->flag_mutex);
+
 		PJ_LOG(4,(THIS_FILE, "* Call %s (%s) has been disconnected", tech_pvt->call_id,
 									switch_channel_get_name( channel ) ));
 
 		if( !switch_test_flag( tech_pvt, TFLAG_BYE ) ) {
 			switch_call_cause_t cause;
 
-			switch( evt->body.rx_msg.rdata->msg_info.msg->line.status.code )
+			switch( inv->cause )
 			{
 			default:
-				/* bennylp: we can get the INVITE disconnect cause from inv->cause.
-				 *          and the reason in inv->cause_text.
-				 *          But how do we map it to switch cause?
-				 */
-				//PJ_TODO(MAP_SIP_STATUS_CODE_TO_SWITCH_CAUSE_CODE);
 				cause = SWITCH_CAUSE_NORMAL_CLEARING;
 			}
-			TRACE_((THIS_FILE, "LOOK HERE!!! Entering switch_channel_hangup for dialog %s",
-				    inv->dlg->obj_name));
+			TRACE_((THIS_FILE, "LOOK HERE!!! Entering switch_channel_hangup(%x) for dialog %s",
+				    channel, inv->dlg->obj_name));
 			switch_channel_hangup( channel, cause );
 			TRACE_((THIS_FILE, "LOOK HERE!!! Leaving switch_channel_hangup"));
 		}
+		pjsip_dlg_dec_lock(inv->dlg);
 		break;
 	case PJSIP_INV_STATE_CONFIRMED:
 		PJ_LOG(4,(THIS_FILE, "* Call %s (%s) has been connected", tech_pvt->call_id,
@@ -1392,7 +1409,7 @@
 	}
 
 	if( status != PJ_SUCCESS ) {
-		char tmp[1024];
+		char tmp[PJ_ERR_MSG_SIZE];
 		pj_strerror( status, tmp, sizeof(tmp) );
 		PJ_LOG(1,(THIS_FILE, "SDP negotiation failed for call %s, reason: %s", tech_pvt->call_id, tmp ));
 		switch_channel_hangup( channel, SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER );
@@ -1775,7 +1792,7 @@
 	       ( switch_test_flag( tech_pvt, TFLAG_READING ) ||
 		 switch_test_flag( tech_pvt, TFLAG_WRITING ) ) )
 	{
-		switch_yield( 1000 );
+		switch_yield( 10 );
 		loop++;
 	}
 
@@ -2124,10 +2141,15 @@
 			 */
 			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: %s [%s:%d]\n", profile->name, profile->sip_ip, profile->sip_port );
+	 			PJ_LOG( 1, (THIS_FILE, "Failed to create UDP transport: %s [%s:%d]", 
+									  profile->name, profile->sip_ip, profile->sip_port ));
 				return SWITCH_STATUS_TERM;
 			}
 
+			PJ_LOG(3,(THIS_FILE, "UDP transport created, listening on %.*s:%d",
+					      (int)transport->local_name.host.slen, transport->local_name.host.ptr, 
+							  transport->local_name.port));
+
 			/* add transports name to hash */
 			switch_core_hash_insert( globals.transport_hash, transport->obj_name, profile );
 		}
@@ -2212,8 +2234,6 @@
 		return SWITCH_STATUS_TERM;
 	}
 
-	switch_log_printf( SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Monitor thread running\n" );
-
 	globals.running = 1;
 
 	/* Create PJSIP from worker threads */
@@ -2225,9 +2245,11 @@
 		}
 	}
 
+	switch_log_printf( SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Monitor thread running\n" );
+
 	/* Another worker */
 	while ( globals.running > 0 ) {
-		pj_time_val timeout = { 1, 0 };
+		pj_time_val timeout = { 0, 100 };
 		TRACE_((THIS_FILE, "ENTER pjsip_endpt_handle_events"));
 		pjsip_endpt_handle_events( globals.sip_endpt, &timeout );
 		TRACE_((THIS_FILE, "LEAVE pjsip_endpt_handle_events"));



More information about the Freeswitch-svn mailing list