[Freeswitch-svn] [commit] r11255 - in freeswitch/trunk: libs/esl src/mod/event_handlers/mod_event_socket

FreeSWITCH SVN anthm at freeswitch.org
Fri Jan 16 07:32:10 PST 2009


Author: anthm
Date: Fri Jan 16 09:32:10 2009
New Revision: 11255

Log:
add linger event_socket command to make outbound socket notify channel disconnect and wait for you to terminate

Modified:
   freeswitch/trunk/libs/esl/testserver.c
   freeswitch/trunk/src/mod/event_handlers/mod_event_socket/mod_event_socket.c

Modified: freeswitch/trunk/libs/esl/testserver.c
==============================================================================
--- freeswitch/trunk/libs/esl/testserver.c	(original)
+++ freeswitch/trunk/libs/esl/testserver.c	Fri Jan 16 09:32:10 2009
@@ -5,7 +5,10 @@
 static void mycallback(esl_socket_t server_sock, esl_socket_t client_sock, struct sockaddr_in addr)
 {
 	esl_handle_t handle = {{0}};
-	
+	int done = 0;
+	esl_status_t status;
+	time_t exp = 0;
+
 	if (fork()) {
 		close(client_sock);
 		return;
@@ -13,17 +16,37 @@
 
 	esl_attach_handle(&handle, client_sock, addr);
 
-	printf("Connected! %d\n", handle.sock);
+	esl_log(ESL_LOG_INFO, "Connected! %d\n", handle.sock);
 
 	esl_filter(&handle, "unique-id", esl_event_get_header(handle.info_event, "caller-unique-id"));
 	esl_events(&handle, ESL_EVENT_TYPE_PLAIN, "SESSION_HEARTBEAT CHANNEL_ANSWER CHANNEL_ORIGINATE CHANNEL_PROGRESS CHANNEL_HANGUP "
 			   "CHANNEL_BRIDGE CHANNEL_UNBRIDGE CHANNEL_OUTGOING CHANNEL_EXECUTE CHANNEL_EXECUTE_COMPLETE DTMF CUSTOM conference::maintenance");
 
+	esl_send_recv(&handle, "linger");
+
 	esl_execute(&handle, "answer", NULL, NULL);
 	esl_execute(&handle, "conference", "3000 at default", NULL);
 	
-	while(esl_recv(&handle) == ESL_SUCCESS);
-
+	while((status = esl_recv_timed(&handle, 1000)) != ESL_FAIL) {
+		if (done) {
+			if (time(NULL) >= exp) {
+				break;
+			}
+		} else if (status == ESL_SUCCESS) {
+			const char *type = esl_event_get_header(handle.last_event, "content-type");
+			if (type && !strcasecmp(type, "text/disconnect-notice")) {
+				const char *dispo = esl_event_get_header(handle.last_event, "content-disposition");
+				esl_log(ESL_LOG_INFO, "Got a disconnection notice dispostion: [%s]\n", dispo ? dispo : "");
+				if (!strcmp(dispo, "linger")) {
+					done = 1;
+					esl_log(ESL_LOG_INFO, "Waiting 5 seconds for any remaining events.\n");
+					exp = time(NULL) + 5;
+				}
+			}
+		}
+	}
+	
+	esl_log(ESL_LOG_INFO, "Disconnected! %d\n", handle.sock);
 	esl_disconnect(&handle);
 }
 

Modified: freeswitch/trunk/src/mod/event_handlers/mod_event_socket/mod_event_socket.c
==============================================================================
--- freeswitch/trunk/src/mod/event_handlers/mod_event_socket/mod_event_socket.c	(original)
+++ freeswitch/trunk/src/mod/event_handlers/mod_event_socket/mod_event_socket.c	Fri Jan 16 09:32:10 2009
@@ -49,7 +49,9 @@
 	LFLAG_SESSION = (1 << 6),
 	LFLAG_ASYNC = (1 << 7),
 	LFLAG_STATEFUL = (1 << 8),
-	LFLAG_OUTBOUND = (1 << 9)
+	LFLAG_OUTBOUND = (1 << 9),
+	LFLAG_LINGER = (1 << 10),
+	LFLAG_HANDLE_DISCO = (1 << 11)
 } event_flag_t;
 
 typedef enum {
@@ -1045,22 +1047,21 @@
 											if (!SWITCH_STATUS_IS_BREAK(status) && status != SWITCH_STATUS_SUCCESS) {
 												return SWITCH_STATUS_FALSE;
 											}
-				
+											
+											/*
 											if (channel && !switch_channel_ready(channel)) {
 												status = SWITCH_STATUS_FALSE;
 												break;
 											}
+											*/
 
 											clen -= (int) mlen;
 											p += mlen;
 										}
-
+										
 										switch_event_add_body(*event, "%s", body);
 										free(body);
 									}
-
-
-
 								}
 							}
 						}
@@ -1158,9 +1159,32 @@
 			}
 		}
 
-		if (channel && !switch_channel_ready(channel)) {
-			status = SWITCH_STATUS_FALSE;
-            break;
+		if (channel && !switch_channel_ready(channel) && !switch_test_flag(listener, LFLAG_HANDLE_DISCO)) {
+			switch_set_flag_locked(listener, LFLAG_HANDLE_DISCO);
+			if (switch_test_flag(listener, LFLAG_LINGER)) {
+				char message[128] = "";
+				int mlen;
+				switch_size_t len;
+				char disco_buf[512] = "";
+
+				switch_snprintf(message, sizeof(message), 
+								"Channel %s has disconnected, lingering by request from remote.\n", switch_channel_get_name(channel));
+				mlen = strlen(message);
+
+				switch_snprintf(disco_buf, sizeof(disco_buf), "Content-Type: text/disconnect-notice\n"
+								"Controlled-Session-UUID: %s\n"
+								"Content-Disposition: linger\n"
+								"Content-Length: %d\n\n", 
+								switch_core_session_get_uuid(listener->session), mlen);
+
+				len = strlen(disco_buf);
+				switch_socket_send(listener->sock, disco_buf, &len);
+				len = mlen;
+				switch_socket_send(listener->sock, message, &len);
+			} else {
+				status = SWITCH_STATUS_FALSE;
+				break;
+			}
 		}
 		
 		if (do_sleep) {
@@ -1580,6 +1604,20 @@
 		} else {
 			switch_snprintf(reply, reply_len, "-ERR invalid log level");
 		}
+	} else if (!strncasecmp(cmd, "linger", 6)) {
+		if (listener->session) {
+			switch_set_flag_locked(listener, LFLAG_LINGER);
+			switch_snprintf(reply, reply_len, "+OK will linger");
+		} else {
+			switch_snprintf(reply, reply_len, "-ERR not controlling a session");
+		}
+	} else if (!strncasecmp(cmd, "nolinger", 6)) {
+		if (listener->session) {
+			switch_clear_flag_locked(listener, LFLAG_LINGER);
+			switch_snprintf(reply, reply_len, "+OK will not linger");
+		} else {
+			switch_snprintf(reply, reply_len, "-ERR not controlling a session");
+		}
 	} else if (!strncasecmp(cmd, "nolog", 5)) {
 		flush_listener(listener, SWITCH_TRUE, SWITCH_FALSE);
 		if (switch_test_flag(listener, LFLAG_LOG)) {
@@ -1926,6 +1964,7 @@
 		if (listener->session) {
 			switch_snprintf(disco_buf, sizeof(disco_buf), "Content-Type: text/disconnect-notice\n"
 							"Controlled-Session-UUID: %s\n"
+							"Content-Disposition: disconnect\n"
 							"Content-Length: %d\n\n", 
 							switch_core_session_get_uuid(listener->session), mlen);
 		} else {



More information about the Freeswitch-svn mailing list