]> git.ipfire.org Git - thirdparty/freeswitch.git/commitdiff
[mod_kazoo] maintenance
authorlazedo <luis.azedo@factorlusitano.com>
Thu, 12 Mar 2020 21:44:19 +0000 (21:44 +0000)
committerGitHub <noreply@github.com>
Thu, 12 Mar 2020 21:44:19 +0000 (01:44 +0400)
* [mod_kazoo] add kz_eval api

* [mod_kazoo] use session if available in first-of

* [mod_kazoo] handle bridge variables

* [mod_kazoo] allow time for erlang node to initialize

* [mod_kazoo] add kz_moh

* tries to start moh from previous unhold

src/mod/event_handlers/mod_kazoo/kazoo_commands.c
src/mod/event_handlers/mod_kazoo/kazoo_dptools.c
src/mod/event_handlers/mod_kazoo/kazoo_ei_utils.c
src/mod/event_handlers/mod_kazoo/kazoo_tweaks.c

index bf191127c2fd309ebb9af776e57d62a19e000e16..c1ac69f62002ad09be589d8f47cbc2cc55d1522e 100644 (file)
@@ -54,12 +54,18 @@ SWITCH_STANDARD_API(kz_first_of)
        char *mycmd = NULL, *mycmd_dup = NULL, *argv[MAX_FIRST_OF] = { 0 };
        int n, argc = 0;
        switch_event_header_t *header = NULL;
+       switch_channel_t *channel = NULL;
 
        if (zstr(cmd)) {
                switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "invalid arg\n");
                return SWITCH_STATUS_GENERR;
        }
 
+       if ( session ) {
+               channel = switch_core_session_get_channel(session);
+               switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG1, "GOT CHANNEL\n");
+       }
+
        mycmd_dup = mycmd = strdup(cmd);
        switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG1, "FIRST-OF %s\n", mycmd);
        if (!zstr(mycmd) && *mycmd == '^' && *(mycmd+1) == '^') {
@@ -77,6 +83,24 @@ SWITCH_STANDARD_API(kz_first_of)
                        }
                } else {
                        switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG1, "CHECKING %s\n", item);
+                       if (channel) {
+                               const char *var = switch_channel_get_variable_dup(channel, item, SWITCH_FALSE, -1);
+                               switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG1, "CHECKING CHANNEL %s\n", item);
+                               if (var) {
+                                       switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG1, "GOT FROM CHANNEL %s => %s\n", item, var);
+                                       stream->write_function(stream, var);
+                                       break;
+                               }
+                               if (!strncmp(item, "variable_", 9)) {
+                                       switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG1, "CHECKING CHANNEL %s\n", item+9);
+                                       var = switch_channel_get_variable_dup(channel, item+9, SWITCH_FALSE, -1);
+                                       if (var) {
+                                               switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG1, "GOT FROM CHANNEL %s => %s\n", item+9, var);
+                                               stream->write_function(stream, var);
+                                               break;
+                                       }
+                               }
+                       }
                        header = switch_event_get_header_ptr(stream->param_event, item);
                        if(header) {
                                switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG1, "RETURNING %s : %s\n", item, header->value);
@@ -440,6 +464,61 @@ SWITCH_STANDARD_API(kz_expand_api)
        return SWITCH_STATUS_SUCCESS;
 }
 
+SWITCH_STANDARD_API(kz_eval_api)
+{
+       char *p = NULL, *input = NULL;
+       char *uuid = NULL, *mycmd;
+       switch_core_session_t *nsession = NULL;
+       switch_channel_t *channel = NULL;
+
+
+       if (zstr(cmd)) {
+               stream->write_function(stream, "-ERR invalid input");
+               return SWITCH_STATUS_GENERR;
+       }
+
+       if (!(mycmd = strdup(cmd))) {
+               stream->write_function(stream, "-ERR no memory");
+               return SWITCH_STATUS_GENERR;
+       }
+
+       if (!strncasecmp(mycmd, "uuid:", 5)) {
+               uuid = mycmd + 5;
+               if ((input = strchr(uuid, ' ')) != NULL) {
+                       *input++ = '\0';
+                       if ((nsession = switch_core_session_locate(uuid)) != NULL) {
+                               channel = switch_core_session_get_channel(nsession);
+                       } else {
+                               stream->write_function(stream, "-ERR invalid session");
+                               switch_safe_free(mycmd);
+                               return SWITCH_STATUS_GENERR;
+                       }
+               } else {
+                       stream->write_function(stream, "-ERR invalid argument");
+                       switch_safe_free(mycmd);
+                       return SWITCH_STATUS_GENERR;
+               }
+       } else if (session == NULL) {
+               stream->write_function(stream, "-ERR invalid argument");
+               switch_safe_free(mycmd);
+               return SWITCH_STATUS_GENERR;
+       } else {
+               channel = switch_core_session_get_channel(session);
+               input = mycmd;
+       }
+
+       p = switch_channel_expand_variables_check(channel, input, NULL, NULL, 0);
+       stream->write_function(stream, "+OK %s", p);
+       if (p != input) {
+               switch_safe_free(p);
+       }
+       switch_safe_free(mycmd);
+       if (nsession) {
+               switch_core_session_rwunlock(nsession);
+       }
+       return SWITCH_STATUS_SUCCESS;
+}
+
 void add_kz_commands(switch_loadable_module_interface_t **module_interface) {
        switch_api_interface_t *api_interface = NULL;
        SWITCH_ADD_API(api_interface, "kz_uuid_setvar_multi", UUID_SET_DESC, uuid_setvar_multi_function, UUID_MULTISET_SYNTAX);
@@ -453,5 +532,6 @@ void add_kz_commands(switch_loadable_module_interface_t **module_interface) {
        SWITCH_ADD_API(api_interface, "kz_http_put", KZ_HTTP_PUT_DESC, kz_http_put, KZ_HTTP_PUT_SYNTAX);
        SWITCH_ADD_API(api_interface, "first-of", KZ_FIRST_OF_DESC, kz_first_of, KZ_FIRST_OF_SYNTAX);
        SWITCH_ADD_API(api_interface, "kz_expand", KZ_FIRST_OF_DESC, kz_expand_api, KZ_FIRST_OF_SYNTAX);
+       SWITCH_ADD_API(api_interface, "kz_eval", KZ_FIRST_OF_DESC, kz_eval_api, KZ_FIRST_OF_SYNTAX);
 }
 
index d5bd64fa9a01c2de21c05aea53da3eee3f3b48b9..073986e1ee8128427a6b85e67061ab9e39d14a1f 100644 (file)
@@ -443,6 +443,60 @@ SWITCH_STANDARD_APP(kz_endless_playback_function)
 
 }
 
+SWITCH_STANDARD_APP(kz_moh_function)
+{
+       switch_channel_t *channel = switch_core_session_get_channel(session);
+       switch_status_t status = SWITCH_STATUS_SUCCESS;
+       switch_file_handle_t fh = { 0 };
+       const char *var_samples = switch_channel_get_variable_dup(channel, "moh_playback_samples", SWITCH_FALSE, -1);
+       unsigned int samples =  0;
+
+       if (var_samples) {
+               fh.samples = samples = atoi(var_samples);
+               switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG1, "SETTING SAMPLES %d\n", samples);
+       }
+
+       switch_channel_set_variable(channel, SWITCH_PLAYBACK_TERMINATOR_USED, "");
+
+       status = switch_ivr_play_file(session, &fh, data, NULL);
+       switch_assert(!(fh.flags & SWITCH_FILE_OPEN));
+
+       switch (status) {
+       case SWITCH_STATUS_SUCCESS:
+               switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG1, "MOH PLAYED SUCCESS\n");
+               switch_channel_set_variable(channel, SWITCH_CURRENT_APPLICATION_RESPONSE_VARIABLE, "MOH FILE PLAYED");
+               switch_channel_set_variable(channel, "moh_playback_samples", "0");
+               break;
+       case SWITCH_STATUS_BREAK:
+               switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG1, "MOH PLAYED BREAK\n");
+               switch_channel_set_variable(channel, SWITCH_CURRENT_APPLICATION_RESPONSE_VARIABLE, "MOH FILE PLAYED");
+               if ((var_samples = switch_channel_get_variable_dup(channel, "playback_samples", SWITCH_FALSE, -1)) != NULL) {
+                       samples += atoi(var_samples);
+                       if (samples >= fh.samples) {
+                               samples = 0;
+                       }
+                       switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG1, "SETTING MOH SAMPLES %d\n", samples);
+                       switch_channel_set_variable_printf(channel, "moh_playback_samples", "%d", samples);
+               }
+               break;
+       case SWITCH_STATUS_NOTFOUND:
+               switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG1, "MOH PLAYED NOT FOUND\n");
+               switch_channel_set_variable(channel, SWITCH_CURRENT_APPLICATION_RESPONSE_VARIABLE, "MOH FILE NOT FOUND");
+               break;
+       default:
+               switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "MOH PLAYED DEFAULT\n");
+               switch_channel_set_variable(channel, SWITCH_CURRENT_APPLICATION_RESPONSE_VARIABLE, "MOH PLAYBACK ERROR");
+               break;
+       }
+
+       switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG1, "MOH duration %ld\n", fh.duration);
+       switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG1, "MOH offset_pos %d\n", fh.offset_pos);
+       switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG1, "MOH pos %ld\n", fh.pos);
+       switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG1, "MOH sample_count %ld\n", fh.sample_count);
+       switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG1, "MOH samples %d\n", fh.samples);
+
+}
+
 SWITCH_STANDARD_APP(noop_function)
 {
        switch_channel_t *channel = switch_core_session_get_channel(session);
@@ -907,4 +961,5 @@ void add_kz_dptools(switch_loadable_module_interface_t **module_interface) {
        SWITCH_ADD_APP(app_interface, "kz_bridge", "Bridge Audio", "Bridge the audio between two sessions", kz_audio_bridge_function, "<channel_url>", SAF_SUPPORT_NOMEDIA|SAF_SUPPORT_TEXT_ONLY);
        SWITCH_ADD_APP(app_interface, "kz_bridge_uuid", "Bridge Audio", "Bridge the audio between two sessions", kz_audio_bridge_uuid_function, "<channel_url>", SAF_SUPPORT_NOMEDIA|SAF_SUPPORT_TEXT_ONLY);
        SWITCH_ADD_APP(app_interface, "kz_att_xfer", "Attended Transfer", "Attended Transfer", kz_att_xfer_function, "<channel_url>", SAF_NONE);
+       SWITCH_ADD_APP(app_interface, "kz_moh", "Kazoo MOH Playback", "Kazoo MOH Playback", kz_moh_function, "", SAF_NONE);
 }
index 416098b97269a866cf2afd6911626bf82eac09d4..a5e59b99787c8820ecd85de0ed8be46b5e2bd865 100644 (file)
@@ -922,6 +922,10 @@ static void fetch_config_handlers(switch_memory_pool_t *pool)
 static void *SWITCH_THREAD_FUNC fetch_config_exec(switch_thread_t *thread, void *obj)
 {
        switch_memory_pool_t *pool = (switch_memory_pool_t *) obj;
+
+       // give some time for node initialization
+       switch_sleep(10000);
+
        fetch_config_filters(pool);
        fetch_config_handlers(pool);
 
index 8b1d19d89c24a347dcc0650488bc304fca846e27..bb7c792b889b6c89c6bd229f581a600d311d7f7a 100644 (file)
@@ -64,7 +64,7 @@ static switch_status_t kz_tweaks_signal_bridge_on_hangup(switch_core_session_t *
 
        const char *peer_uuid = switch_channel_get_variable(channel, "Bridge-B-Unique-ID");
 
-       switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "tweak signal bridge on hangup: %s , %s\n", switch_core_session_get_uuid(session), peer_uuid);
+       switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "tweak signal bridge on hangup: %s , %s\n", switch_core_session_get_uuid(session), peer_uuid);
 
        if (switch_event_create(&my_event, SWITCH_EVENT_CHANNEL_UNBRIDGE) == SWITCH_STATUS_SUCCESS) {
                switch_event_add_header_string(my_event, SWITCH_STACK_BOTTOM, "Bridge-A-Unique-ID", switch_core_session_get_uuid(session));
@@ -96,88 +96,38 @@ static void kz_tweaks_handle_bridge_variables(switch_event_t *event)
        switch_core_session_t *a_session = NULL, *b_session = NULL;
        const char *a_leg = switch_event_get_header(event, "Bridge-A-Unique-ID");
        const char *b_leg = switch_event_get_header(event, "Bridge-B-Unique-ID");
+       const char *reentry = switch_event_get_header(event, "Bridge-Event-Processed");
        int i;
 
        if (!kz_test_tweak(KZ_TWEAK_BRIDGE_VARIABLES)) return;
 
-       switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "tweak bridge event handler: variables : %s , %s\n", a_leg, b_leg);
+       if(reentry) return;
+
+       switch_log_printf(SWITCH_CHANNEL_UUID_LOG(a_leg), SWITCH_LOG_DEBUG, "tweak bridge event handler: variables : %s , %s\n", a_leg, b_leg);
 
        if (a_leg && (a_session = switch_core_session_locate(a_leg)) != NULL) {
                switch_channel_t *a_channel = switch_core_session_get_channel(a_session);
-               if(switch_channel_get_variable_dup(a_channel, bridge_variables[0], SWITCH_FALSE, -1) == NULL) {
-                       if(b_leg && (b_session = switch_core_session_locate(b_leg)) != NULL) {
-                               switch_channel_t *b_channel = switch_core_session_get_channel(b_session);
+               switch_channel_timetable_t *a_times = switch_channel_get_timetable(a_channel);
+               if(b_leg && (b_session = switch_core_session_locate(b_leg)) != NULL) {
+                       switch_channel_t *b_channel = switch_core_session_get_channel(b_session);
+                       switch_channel_timetable_t *b_times = switch_channel_get_timetable(b_channel);
+                       if (a_times->created <= b_times->created) {
+                               for(i = 0; bridge_variables[i] != NULL; i++) {
+                                       const char *val = switch_channel_get_variable_dup(a_channel, bridge_variables[i], SWITCH_FALSE, -1);
+                                       switch_channel_set_variable(b_channel, bridge_variables[i], val);
+                               }
+                       } else {
                                for(i = 0; bridge_variables[i] != NULL; i++) {
                                        const char *val = switch_channel_get_variable_dup(b_channel, bridge_variables[i], SWITCH_FALSE, -1);
                                        switch_channel_set_variable(a_channel, bridge_variables[i], val);
                                }
-                               switch_core_session_rwunlock(b_session);
-                       }
-               } else {
-                       if(b_leg && (b_session = switch_core_session_locate(b_leg)) != NULL) {
-                               switch_channel_t *b_channel = switch_core_session_get_channel(b_session);
-                               if(switch_channel_get_variable_dup(b_channel, bridge_variables[0], SWITCH_FALSE, -1) == NULL) {
-                                       for(i = 0; bridge_variables[i] != NULL; i++) {
-                                               const char *val = switch_channel_get_variable_dup(a_channel, bridge_variables[i], SWITCH_FALSE, -1);
-                                               switch_channel_set_variable(b_channel, bridge_variables[i], val);
-                                       }
-                               }
-                               switch_core_session_rwunlock(b_session);
                        }
+                       switch_core_session_rwunlock(b_session);
                }
                switch_core_session_rwunlock(a_session);
        } else {
-               switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG1, "NOT FOUND : %s\n", a_leg);
-       }
-
-}
-
-static void kz_tweaks_handle_bridge_replaces_aleg(switch_event_t *event)
-{
-       switch_event_t *my_event;
-
-       const char *replaced_call_id =  switch_event_get_header(event, "variable_sip_replaces_call_id");
-       const char *a_leg_call_id =     switch_event_get_header(event, "variable_sip_replaces_a-leg");
-       const char *peer_uuid = switch_event_get_header(event, "Unique-ID");
-       int processed = 0;
-
-       if (!kz_test_tweak(KZ_TWEAK_BRIDGE_REPLACES_ALEG)) return;
-
-
-       if(a_leg_call_id && replaced_call_id) {
-               const char *call_id = switch_event_get_header(event, "Bridge-B-Unique-ID");
-               switch_core_session_t *session = NULL;
-               if ((session = switch_core_session_locate(peer_uuid)) != NULL) {
-                       switch_channel_t *channel = switch_core_session_get_channel(session);
-                       processed = switch_true(switch_channel_get_variable_dup(channel, "Bridge-Event-Processed", SWITCH_FALSE, -1));
-                       switch_channel_set_variable(channel, "Bridge-Event-Processed", "true");
-                       switch_core_session_rwunlock(session);
-               }
-
-               if(processed) {
-                       if(call_id) {
-                               if((session = switch_core_session_locate(call_id)) != NULL) {
-                                       switch_channel_t *channel = switch_core_session_get_channel(session);
-                                       switch_channel_set_variable(channel, "Bridge-Event-Processed", "true");
-                                       switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "creating channel_bridge event A - %s , B - %s\n", switch_core_session_get_uuid(session), peer_uuid);
-                                       if (switch_event_create(&my_event, SWITCH_EVENT_CHANNEL_BRIDGE) == SWITCH_STATUS_SUCCESS) {
-                                               switch_event_add_header_string(my_event, SWITCH_STACK_BOTTOM, "Bridge-A-Unique-ID", switch_core_session_get_uuid(session));
-                                               switch_event_add_header_string(my_event, SWITCH_STACK_BOTTOM, "Bridge-B-Unique-ID", peer_uuid);
-                                               switch_channel_event_set_data(channel, my_event);
-                                               switch_event_fire(&my_event);
-                                       }
-                                       switch_channel_set_variable(channel, "Bridge-B-Unique-ID", peer_uuid);
-                                       switch_channel_add_state_handler(channel, &kz_tweaks_signal_bridge_state_handlers);
-                                       switch_core_session_rwunlock(session);
-                               } else {
-                                       switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "invalid session : %s\n", call_id);
-                                       DUMP_EVENT(event);
-                               }
-                       }
-               }
-
+               switch_log_printf(SWITCH_CHANNEL_UUID_LOG(a_leg), SWITCH_LOG_DEBUG1, "NOT FOUND : %s\n", a_leg);
        }
-
 }
 
 static void kz_tweaks_handle_bridge_replaces_call_id(switch_event_t *event)
@@ -185,12 +135,14 @@ static void kz_tweaks_handle_bridge_replaces_call_id(switch_event_t *event)
        switch_event_t *my_event;
 
        const char *replaced_call_id =  switch_event_get_header(event, "variable_sip_replaces_call_id");
-       const char *a_leg_call_id =     switch_event_get_header(event, "variable_sip_replaces_a-leg");
        const char *peer_uuid = switch_event_get_header(event, "Unique-ID");
+       const char *reentry = switch_event_get_header(event, "Bridge-Event-Processed");
 
        if (!kz_test_tweak(KZ_TWEAK_BRIDGE_REPLACES_CALL_ID)) return;
 
-       if(a_leg_call_id && replaced_call_id) {
+       if(reentry) return;
+
+       if(replaced_call_id) {
                switch_core_session_t *call_session = NULL;
                const char *call_id = switch_event_get_header(event, "Bridge-B-Unique-ID");
                if (call_id && (call_session = switch_core_session_locate(call_id)) != NULL) {
@@ -198,6 +150,7 @@ static void kz_tweaks_handle_bridge_replaces_call_id(switch_event_t *event)
                        if (switch_event_create(&my_event, SWITCH_EVENT_CHANNEL_BRIDGE) == SWITCH_STATUS_SUCCESS) {
                                switch_event_add_header_string(my_event, SWITCH_STACK_BOTTOM, "Bridge-A-Unique-ID", switch_core_session_get_uuid(call_session));
                                switch_event_add_header_string(my_event, SWITCH_STACK_BOTTOM, "Bridge-B-Unique-ID", peer_uuid);
+                               switch_event_add_header_string(my_event, SWITCH_STACK_BOTTOM, "Bridge-Event-Processed", "true");
                                switch_channel_event_set_data(call_channel, my_event);
                                switch_event_fire(&my_event);
                        }
@@ -208,7 +161,6 @@ static void kz_tweaks_handle_bridge_replaces_call_id(switch_event_t *event)
                        switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG1, "NOT FOUND : %s\n", call_id);
                }
        }
-
 }
 
 static void kz_tweaks_channel_bridge_event_handler(switch_event_t *event)
@@ -216,7 +168,6 @@ static void kz_tweaks_channel_bridge_event_handler(switch_event_t *event)
        if (!kz_test_tweak(KZ_TWEAK_BRIDGE)) return;
 
        kz_tweaks_handle_bridge_replaces_call_id(event);
-       kz_tweaks_handle_bridge_replaces_aleg(event);
        kz_tweaks_handle_bridge_variables(event);
 }
 
@@ -482,7 +433,7 @@ static switch_status_t kz_tweaks_handle_replaces_call_id(switch_core_session_t *
                const char *replaced_call_id = switch_channel_get_variable(channel, "sip_replaces_call_id");
                const char *core_uuid = switch_channel_get_variable(channel, "sip_h_X-FS-From-Core-UUID");
                if((!core_uuid) && replaced_call_id) {
-                       switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "checking replaces header tweak for %s\n", replaced_call_id);
+                       switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_INFO, "checking replaces header tweak for %s\n", replaced_call_id);
                        if ((replace_call_session = switch_core_session_locate(replaced_call_id))) {
                                switch_channel_t *replaced_call_channel = switch_core_session_get_channel(replace_call_session);
                                int i;