]> git.ipfire.org Git - thirdparty/freeswitch.git/commitdiff
add linger event_socket command to make outbound socket notify channel disconnect...
authorAnthony Minessale <anthony.minessale@gmail.com>
Fri, 16 Jan 2009 15:32:10 +0000 (15:32 +0000)
committerAnthony Minessale <anthony.minessale@gmail.com>
Fri, 16 Jan 2009 15:32:10 +0000 (15:32 +0000)
git-svn-id: http://svn.freeswitch.org/svn/freeswitch/trunk@11255 d0543943-73ff-0310-b7d9-9358b9ac24b2

libs/esl/testserver.c
src/mod/event_handlers/mod_event_socket/mod_event_socket.c

index c3e24f4ce0c4f4bcd26339aaa7641caf2e03922a..3e1a8a519b0d687a59b2943d97694933a1270465 100644 (file)
@@ -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 @@ static void mycallback(esl_socket_t server_sock, esl_socket_t client_sock, struc
 
        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@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);
 }
 
index c586161ba26dbec730252baaddaa9e140e160504..f5953e09688fbf56711186b18eb91f22b3971702 100644 (file)
@@ -49,7 +49,9 @@ typedef enum {
        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 @@ static switch_status_t read_packet(listener_t *listener, switch_event_t **event,
                                                                                        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 @@ static switch_status_t read_packet(listener_t *listener, switch_event_t **event,
                        }
                }
 
-               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 @@ static switch_status_t parse_command(listener_t *listener, switch_event_t **even
                } 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 @@ static void *SWITCH_THREAD_FUNC listener_run(switch_thread_t *thread, void *obj)
                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 {