]> git.ipfire.org Git - thirdparty/freeswitch.git/commitdiff
signalling refactoring for media etc
authorAnthony Minessale <anthony.minessale@gmail.com>
Wed, 25 Oct 2006 04:28:49 +0000 (04:28 +0000)
committerAnthony Minessale <anthony.minessale@gmail.com>
Wed, 25 Oct 2006 04:28:49 +0000 (04:28 +0000)
git-svn-id: http://svn.freeswitch.org/svn/freeswitch/trunk@3192 d0543943-73ff-0310-b7d9-9358b9ac24b2

src/include/switch_channel.h
src/include/switch_types.h
src/mod/applications/mod_dptools/mod_dptools.c
src/mod/endpoints/mod_sofia/mod_sofia.c
src/switch_channel.c
src/switch_ivr.c

index fc31b29461e0b607001dc9bd274b096228fb2633..dd22ca9f2e5176bbe12560c78c47e477e9dc2dc7 100644 (file)
@@ -281,6 +281,17 @@ SWITCH_DECLARE(switch_status_t) switch_channel_perform_answer(switch_channel_t *
 #define switch_channel_answer(channel) switch_channel_perform_answer(channel, __FILE__, __FUNCTION__, __LINE__)
 
 
+SWITCH_DECLARE(switch_status_t) switch_channel_perform_ringback(switch_channel_t *channel,
+                                                                                                                               const char *file,
+                                                                                                                               const char *func,
+                                                                                                                               int line);
+/*!
+  \brief Send Ringing message to a channel
+  \param channel channel to ring
+  \return SWITCH_STATUS_SUCCESS if successful
+*/
+#define switch_channel_ringback(channel) switch_channel_perform_ringback(channel, __FILE__, __FUNCTION__, __LINE__)
+
 
 SWITCH_DECLARE(switch_status_t) switch_channel_perform_pre_answer(switch_channel_t *channel,
                                                                                                                                const char *file,
index a9f0b43c33406f4c6b7198222217b962703b3c79..39c45936f226f32c406fc3e9c144ef92f98ca690 100644 (file)
@@ -720,6 +720,7 @@ typedef enum {
        SWITCH_CAUSE_MANDATORY_IE_LENGTH_ERROR = 103,
        SWITCH_CAUSE_PROTOCOL_ERROR = 111,
        SWITCH_CAUSE_INTERWORKING = 127,
+       SWITCH_CAUSE_ORIGINATOR_CANCEL = 487,
        SWITCH_CAUSE_CRASH = 500,
        SWITCH_CAUSE_SYSTEM_SHUTDOWN = 501,
        SWITCH_CAUSE_LOSE_RACE = 502,
index 7b6f9dc51df132b5ba58b706c25f166ace217597..7722c8aff9a3e58d0fd39990d83994c048269e77 100644 (file)
 
 static const char modname[] = "mod_dptools";
 
+
+static void ringback_function(switch_core_session_t *session, char *data)
+{
+       switch_channel_t *channel;
+       channel = switch_core_session_get_channel(session);
+    assert(channel != NULL);
+       switch_channel_ringback(channel);
+}
+
 static void transfer_function(switch_core_session_t *session, char *data)
 {
        int argc;
@@ -253,13 +262,24 @@ static switch_api_interface_t presence_api_interface = {
        /*.next */ &dptools_api_interface
 };
 
+
+static const switch_application_interface_t ringback_application_interface = {
+       /*.interface_name */ "ringback",
+       /*.application_function */ ringback_function,
+       /* long_desc */ "Indicate Ringback on a channel.",
+       /* short_desc */ "Indicate Ringback",
+       /* syntax */ "",
+       /*.next */ NULL
+
+};
+
 static const switch_application_interface_t set_application_interface = {
        /*.interface_name */ "set",
        /*.application_function */ set_function,
        /* long_desc */ "Set a channel varaible for the channel calling the application.",
        /* short_desc */ "Set a channel varaible",
        /* syntax */ "<varname>=[<value>|_UNDEF_]",
-       /*.next */ NULL
+       /*.next */ &ringback_application_interface
 };
 
 static const switch_application_interface_t answer_application_interface = {
index 93d4f7a8ce2c6cbbcb2255f0eb46279de5f47429..804efd7213d39e59583072ce87d3ac1ddb0284aa 100644 (file)
@@ -1078,53 +1078,55 @@ static switch_status_t sofia_on_execute(switch_core_session_t *session)
 // map QSIG cause codes to SIP from RFC4497 section 8.4.1
 static int hangup_cause_to_sip(switch_call_cause_t cause) {
        switch (cause) {
-               case SWITCH_CAUSE_UNALLOCATED: 
-               case SWITCH_CAUSE_NO_ROUTE_TRANSIT_NET:
-               case SWITCH_CAUSE_NO_ROUTE_DESTINATION:
-                       return 404;
-               case SWITCH_CAUSE_USER_BUSY:
-                       return 486;
-               case SWITCH_CAUSE_NO_USER_RESPONSE:
-                       return 408;
-               case SWITCH_CAUSE_NO_ANSWER:
-                       return 480;
-               case SWITCH_CAUSE_SUBSCRIBER_ABSENT:
-                       return 480;
-               case SWITCH_CAUSE_CALL_REJECTED:
-                       return 603;
-               case SWITCH_CAUSE_NUMBER_CHANGED:
-               case SWITCH_CAUSE_REDIRECTION_TO_NEW_DESTINATION:
-                       return 410;
-               case SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER:
-                       return 502;
-               case SWITCH_CAUSE_INVALID_NUMBER_FORMAT:
-                       return 484;
-               case SWITCH_CAUSE_FACILITY_REJECTED:
-                       return 501;
-               case SWITCH_CAUSE_NORMAL_UNSPECIFIED:
-                       return 480;
-               case SWITCH_CAUSE_NORMAL_CIRCUIT_CONGESTION:
-               case SWITCH_CAUSE_NETWORK_OUT_OF_ORDER:
-               case SWITCH_CAUSE_NORMAL_TEMPORARY_FAILURE:
-               case SWITCH_CAUSE_SWITCH_CONGESTION:
-                       return 503;
-               case SWITCH_CAUSE_OUTGOING_CALL_BARRED:
-               case SWITCH_CAUSE_INCOMING_CALL_BARRED:
-               case SWITCH_CAUSE_BEARERCAPABILITY_NOTAUTH: 
-                       return 403;
-               case SWITCH_CAUSE_BEARERCAPABILITY_NOTAVAIL:
-                       return 503;
-               case SWITCH_CAUSE_BEARERCAPABILITY_NOTIMPL:
-                       return 488;
-               case SWITCH_CAUSE_FACILITY_NOT_IMPLEMENTED:
-               case SWITCH_CAUSE_SERVICE_NOT_IMPLEMENTED:
-                       return 501;
-               case SWITCH_CAUSE_INCOMPATIBLE_DESTINATION:
-                       return 503;
-               case SWITCH_CAUSE_RECOVERY_ON_TIMER_EXPIRE:
-                       return 504;
-               default:
-                       return 500;
+       case SWITCH_CAUSE_UNALLOCATED: 
+       case SWITCH_CAUSE_NO_ROUTE_TRANSIT_NET:
+       case SWITCH_CAUSE_NO_ROUTE_DESTINATION:
+               return 404;
+       case SWITCH_CAUSE_USER_BUSY:
+               return 486;
+       case SWITCH_CAUSE_NO_USER_RESPONSE:
+               return 408;
+       case SWITCH_CAUSE_NO_ANSWER:
+               return 480;
+       case SWITCH_CAUSE_SUBSCRIBER_ABSENT:
+               return 480;
+       case SWITCH_CAUSE_CALL_REJECTED:
+               return 603;
+       case SWITCH_CAUSE_NUMBER_CHANGED:
+       case SWITCH_CAUSE_REDIRECTION_TO_NEW_DESTINATION:
+               return 410;
+       case SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER:
+               return 502;
+       case SWITCH_CAUSE_INVALID_NUMBER_FORMAT:
+               return 484;
+       case SWITCH_CAUSE_FACILITY_REJECTED:
+               return 501;
+       case SWITCH_CAUSE_NORMAL_UNSPECIFIED:
+               return 480;
+       case SWITCH_CAUSE_NORMAL_CIRCUIT_CONGESTION:
+       case SWITCH_CAUSE_NETWORK_OUT_OF_ORDER:
+       case SWITCH_CAUSE_NORMAL_TEMPORARY_FAILURE:
+       case SWITCH_CAUSE_SWITCH_CONGESTION:
+               return 503;
+       case SWITCH_CAUSE_OUTGOING_CALL_BARRED:
+       case SWITCH_CAUSE_INCOMING_CALL_BARRED:
+       case SWITCH_CAUSE_BEARERCAPABILITY_NOTAUTH: 
+               return 403;
+       case SWITCH_CAUSE_BEARERCAPABILITY_NOTAVAIL:
+               return 503;
+       case SWITCH_CAUSE_BEARERCAPABILITY_NOTIMPL:
+               return 488;
+       case SWITCH_CAUSE_FACILITY_NOT_IMPLEMENTED:
+       case SWITCH_CAUSE_SERVICE_NOT_IMPLEMENTED:
+               return 501;
+       case SWITCH_CAUSE_INCOMPATIBLE_DESTINATION:
+               return 503;
+       case SWITCH_CAUSE_RECOVERY_ON_TIMER_EXPIRE:
+               return 504;
+       case SWITCH_CAUSE_ORIGINATOR_CANCEL:
+               return 487;
+       default:
+               return 500;
        }
 
 }
@@ -2033,60 +2035,64 @@ static uint8_t negotiate_sdp(switch_core_session_t *session, sdp_session_t *sdp)
 // map sip responses to QSIG cause codes ala RFC4497 section 8.4.4
 static switch_call_cause_t sip_cause_to_freeswitch(int status) {
        switch (status) {
-               case 200:
-                       return SWITCH_CAUSE_NORMAL_CLEARING;
-               case 401:
-               case 402: 
-               case 403:
-               case 407:
-               case 603:
-                       return SWITCH_CAUSE_CALL_REJECTED;
-               case 404:
-               case 485:
-               case 604:       
-                       return SWITCH_CAUSE_UNALLOCATED;
-               case 408: 
-               case 504:
-                       return SWITCH_CAUSE_RECOVERY_ON_TIMER_EXPIRE;
-               case 410: 
-                       return SWITCH_CAUSE_NUMBER_CHANGED;
-               case 413: 
-               case 414:
-               case 416:
-               case 420:
-               case 421:
-               case 423:
-               case 505:
-               case 513:
-                       return SWITCH_CAUSE_INTERWORKING;
-               case 480:
-                       return SWITCH_CAUSE_NO_USER_RESPONSE;
-               case 400:
-               case 481:
-               case 500:
-               case 503:
-                       return SWITCH_CAUSE_NORMAL_TEMPORARY_FAILURE;
-               case 486:
-               case 600:
-                       return SWITCH_CAUSE_USER_BUSY;
-               case 484:
-                       return SWITCH_CAUSE_INVALID_NUMBER_FORMAT;
-               case 488:
-               case 606:
-                       return SWITCH_CAUSE_BEARERCAPABILITY_NOTIMPL;
-               case 502:
-                       return SWITCH_CAUSE_NETWORK_OUT_OF_ORDER;
-               case 405:
-                       return SWITCH_CAUSE_SERVICE_UNAVAILABLE;
-               case 406:
-               case 415:
-               case 501:
-                       return SWITCH_CAUSE_SERVICE_NOT_IMPLEMENTED;
-               case 482:
-               case 483:
-                       return SWITCH_CAUSE_EXCHANGE_ROUTING_ERROR;
-               default: 
-                       return SWITCH_CAUSE_NORMAL_UNSPECIFIED;
+       case 200:
+               return SWITCH_CAUSE_NORMAL_CLEARING;
+       case 401:
+       case 402: 
+       case 403:
+       case 407:
+       case 603:
+               return SWITCH_CAUSE_CALL_REJECTED;
+       case 404:
+       case 485:
+       case 604:       
+               return SWITCH_CAUSE_UNALLOCATED;
+       case 408: 
+       case 504:
+               return SWITCH_CAUSE_RECOVERY_ON_TIMER_EXPIRE;
+       case 410: 
+               return SWITCH_CAUSE_NUMBER_CHANGED;
+       case 413: 
+       case 414:
+       case 416:
+       case 420:
+       case 421:
+       case 423:
+       case 505:
+       case 513:
+               return SWITCH_CAUSE_INTERWORKING;
+       case 480:
+               return SWITCH_CAUSE_NO_USER_RESPONSE;
+       case 400:
+       case 481:
+       case 500:
+       case 503:
+               return SWITCH_CAUSE_NORMAL_TEMPORARY_FAILURE;
+       case 486:
+       case 600:
+               return SWITCH_CAUSE_USER_BUSY;
+       case 484:
+               return SWITCH_CAUSE_INVALID_NUMBER_FORMAT;
+       case 488:
+       case 606:
+               return SWITCH_CAUSE_BEARERCAPABILITY_NOTIMPL;
+       case 502:
+               return SWITCH_CAUSE_NETWORK_OUT_OF_ORDER;
+       case 405:
+               return SWITCH_CAUSE_SERVICE_UNAVAILABLE;
+       case 406:
+       case 415:
+       case 501:
+               return SWITCH_CAUSE_SERVICE_NOT_IMPLEMENTED;
+       case 482:
+       case 483:
+               return SWITCH_CAUSE_EXCHANGE_ROUTING_ERROR;
+       case 487:
+               return SWITCH_CAUSE_ORIGINATOR_CANCEL;
+
+       default: 
+               return SWITCH_CAUSE_NORMAL_UNSPECIFIED;
+
        }
 }
 
@@ -2280,7 +2286,9 @@ static void sip_i_state(int status,
        char *uuid;
        switch_core_session_t *other_session = NULL;
        switch_channel_t *other_channel = NULL;
+       char st[80] = "";
 
+       
        tl_gets(tags, 
                        NUTAG_CALLSTATE_REF(ss_state),
                        NUTAG_OFFER_RECV_REF(offer_recv),
@@ -2560,6 +2568,8 @@ static void sip_i_state(int status,
                                        nua_handle_destroy(tech_pvt->nh);
                                        tech_pvt->nh = NULL;
                                } else {
+                                       snprintf(st, sizeof(st), "%d", status);
+                                       switch_channel_set_variable(channel, "sip_term_status", st);
                                        terminate_session(&session, sip_cause_to_freeswitch(status), __LINE__);
                                }
                        }
index ed9b4fb0e37a3d3e4fea23f9cc0af8ac7d5afc2b..313a8bfccb9a3cad3e2796428ed1a1684ba72e47 100644 (file)
@@ -87,6 +87,7 @@ static struct switch_cause_table CAUSE_CHART[] = {
        { "MANDATORY_IE_LENGTH_ERROR", SWITCH_CAUSE_MANDATORY_IE_LENGTH_ERROR },
        { "PROTOCOL_ERROR", SWITCH_CAUSE_PROTOCOL_ERROR },
        { "INTERWORKING", SWITCH_CAUSE_INTERWORKING },
+       { "ORIGINATOR_CANCEL", SWITCH_CAUSE_ORIGINATOR_CANCEL },
        { "CRASH", SWITCH_CAUSE_CRASH },
        { "SYSTEM_SHUTDOWN", SWITCH_CAUSE_SYSTEM_SHUTDOWN },
        { "LOSE_RACE", SWITCH_CAUSE_LOSE_RACE },
@@ -1018,6 +1019,40 @@ SWITCH_DECLARE(switch_status_t) switch_channel_perform_pre_answer(switch_channel
        return status;
 }
 
+SWITCH_DECLARE(switch_status_t) switch_channel_perform_ringback(switch_channel_t *channel,
+                                                                                                                               const char *file,
+                                                                                                                               const char *func,
+                                                                                                                               int line)
+{
+       switch_core_session_message_t msg;
+       char *uuid = switch_core_session_get_uuid(channel->session);
+       switch_status_t status;
+       
+       assert(channel != NULL);
+
+       if (channel->state >= CS_HANGUP) {
+               return SWITCH_STATUS_FALSE;
+       }
+
+       if (switch_channel_test_flag(channel, CF_ANSWERED)) {
+               return SWITCH_STATUS_SUCCESS;
+       }
+
+       if (switch_channel_test_flag(channel, CF_EARLY_MEDIA)) {
+               return SWITCH_STATUS_SUCCESS;
+       }
+
+       msg.message_id = SWITCH_MESSAGE_INDICATE_RINGING;
+       msg.from = channel->name;
+       status = switch_core_session_message_send(uuid, &msg);
+
+       if (status == SWITCH_STATUS_SUCCESS) {
+               switch_log_printf(SWITCH_CHANNEL_ID_LOG, (char *) file, func, line, SWITCH_LOG_NOTICE, "Ringback %s!\n", channel->name);
+       }
+
+       return status;
+}
+
 SWITCH_DECLARE(switch_status_t) switch_channel_perform_answer(switch_channel_t *channel,
                                                                                                                                const char *file,
                                                                                                                                const char *func,
index 2a0f22c9365de3c29981a281148e1634b3ae8429..6f47ad0639ab149b31982aa153c65733b20a42f6 100644 (file)
 
 static const switch_state_handler_table_t audio_bridge_peer_state_handlers;
 
+typedef enum {
+       IDX_CANCEL = -2,
+       IDX_NADA = -1
+} abort_t;
+
 SWITCH_DECLARE(switch_status_t) switch_ivr_sleep(switch_core_session_t *session, uint32_t ms)
 {
        switch_channel_t *channel;
@@ -1715,12 +1720,13 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_originate(switch_core_session_t *sess
        switch_frame_t *read_frame = NULL;
        switch_memory_pool_t *pool = NULL;
        int r = 0, i, and_argc = 0, or_argc = 0;
-       int32_t idx = -1;
+       int32_t idx = IDX_NADA;
        switch_codec_t write_codec = {0};
        switch_frame_t write_frame = {0};
        uint8_t err = 0, fdata[1024], pass = 0;
        char *file = NULL, *key = NULL, *odata, *var;
-
+       switch_call_cause_t reason = SWITCH_CAUSE_UNALLOCATED;
+       uint8_t to = 0;
        write_frame.data = fdata;
        
        *bleg = NULL;
@@ -1785,7 +1791,8 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_originate(switch_core_session_t *sess
                file = NULL;
                key = NULL;
                var = NULL;
-               
+               to = 0;
+
                and_argc = switch_separate_string(pipe_names[r], '&', peer_names, (sizeof(peer_names) / sizeof(peer_names[0])));
        
                for (i = 0; i < and_argc; i++) {
@@ -1924,6 +1931,7 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_originate(switch_core_session_t *sess
                                }
                
                                if ((time(NULL) - start) > (time_t)timelimit_sec) {
+                                       to++;
                                        break;
                                }
                                switch_yield(1000);
@@ -1965,9 +1973,13 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_originate(switch_core_session_t *sess
                                }
                        }
                }
-
+               
                while ((!caller_channel || switch_channel_ready(caller_channel)) && 
-                          check_channel_status(peer_channels, peer_sessions, and_argc, &idx, file, key) && ((time(NULL) - start) < (time_t)timelimit_sec)) {
+                          check_channel_status(peer_channels, peer_sessions, and_argc, &idx, file, key)) {
+
+                       if ((to = ((time(NULL) - start) >= (time_t)timelimit_sec))) {
+                               break;
+                       }
 
                        if (session && or_argc == 1 && and_argc == 1) { /* when there is only 1 channel to call and bridge */
                                switch_core_session_message_t *message = NULL;
@@ -2000,7 +2012,7 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_originate(switch_core_session_t *sess
                }
 
                if (!switch_channel_ready(caller_channel)) {
-                       idx = -2;
+                       idx = IDX_CANCEL;
                }
 
                if (session && !switch_channel_test_flag(caller_channel, CF_NOMEDIA)) {
@@ -2012,12 +2024,24 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_originate(switch_core_session_t *sess
                                continue;
                        }
                        if (i != idx) {
-                               switch_channel_hangup(peer_channels[i], SWITCH_CAUSE_LOSE_RACE);
+                               if (idx == IDX_CANCEL) {
+                                       reason = SWITCH_CAUSE_ORIGINATOR_CANCEL;
+                               } else {
+                                       if (to) {
+                                               reason = SWITCH_CAUSE_NO_ANSWER;
+                                       } else if (and_argc > 1) {
+                                               reason = SWITCH_CAUSE_LOSE_RACE;
+                                       } else {
+                                               reason = SWITCH_CAUSE_NO_ANSWER;
+                                       }
+                               }
+                               
+                               switch_channel_hangup(peer_channels[i], reason);
                        }
                }
 
 
-               if (idx > -1) {
+               if (idx > IDX_NADA) {
                        peer_session = peer_sessions[idx];
                        peer_channel = peer_channels[idx];
                } else {
@@ -2068,13 +2092,13 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_originate(switch_core_session_t *sess
                        }
 
                        if (caller_channel) {
-                               if (idx == -2) {
+                               if (idx == IDX_CANCEL) {
                                        *cause = switch_channel_get_cause(caller_channel);
                                } 
                                switch_channel_set_variable(caller_channel, "originate_disposition", switch_channel_cause2str(*cause));
                                
                        }
-                       if (idx == -2) {
+                       if (idx == IDX_CANCEL) {
                                switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Originate Cancelled by originator termination Cause: %d [%s]\n",
                                                                  *cause, switch_channel_cause2str(*cause));
                        } else {