]> git.ipfire.org Git - thirdparty/freeswitch.git/commitdiff
[core] Add switch_core_session_set_external_id() which lets you define an additional...
authorChris Rienzo <chris@signalwire.com>
Tue, 23 Jun 2020 21:50:18 +0000 (17:50 -0400)
committerAndrey Volk <andywolk@gmail.com>
Sat, 23 Oct 2021 19:00:26 +0000 (22:00 +0300)
src/include/private/switch_core_pvt.h
src/include/switch_core.h
src/switch_channel.c
src/switch_core_session.c
tests/unit/Makefile.am
tests/unit/switch_core_session.c [new file with mode: 0644]
tests/unit/switch_ivr_originate.c

index a69c3173cc9c51c8c190b08ca2ace6798a1cb025..aece2e7e173e6e55b27355b68387e2d3fd8d25f3 100644 (file)
@@ -189,6 +189,7 @@ struct switch_core_session {
        switch_buffer_t *text_buffer;
        switch_buffer_t *text_line_buffer;
        switch_mutex_t *text_mutex;
+       const char *external_id;
 };
 
 struct switch_media_bug {
index 263c1f7ff7ced6c5438ef7183aca6354d5edb4b0..e4c615941d96b9a5274479501efba32830d6e2ef 100644 (file)
@@ -1,6 +1,6 @@
 /*
  * FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
- * Copyright (C) 2005-2014, Anthony Minessale II <anthm@freeswitch.org>
+ * Copyright (C) 2005-2020, Anthony Minessale II <anthm@freeswitch.org>
  *
  * Version: MPL 1.1
  *
@@ -804,6 +804,8 @@ SWITCH_DECLARE(switch_core_session_t *) switch_core_session_request_uuid(_In_ sw
 
 SWITCH_DECLARE(switch_status_t) switch_core_session_set_uuid(_In_ switch_core_session_t *session, _In_z_ const char *use_uuid);
 
+SWITCH_DECLARE(switch_status_t) switch_core_session_set_external_id(_In_ switch_core_session_t *session, _In_z_ const char *use_external_id);
+
 SWITCH_DECLARE(void) switch_core_session_perform_destroy(_Inout_ switch_core_session_t **session,
                                                                                                                 _In_z_ const char *file, _In_z_ const char *func, _In_ int line);
 
@@ -875,6 +877,13 @@ SWITCH_DECLARE(void) switch_core_session_signal_state_change(_In_ switch_core_se
 */
 SWITCH_DECLARE(char *) switch_core_session_get_uuid(_In_ switch_core_session_t *session);
 
+/*!
+  \brief Retrieve the unique external identifier from a session
+  \param session the session to retrieve the uuid from
+  \return a string representing the uuid
+*/
+SWITCH_DECLARE(const char *) switch_core_session_get_external_id(_In_ switch_core_session_t *session);
+
 
 /*!
   \brief Sets the log level for a session
index d2b10ed15d850d43a51f5c9083a385089512c161..d6c0e6488391db92dce166621b6722a038ad1558 100644 (file)
@@ -1,6 +1,6 @@
 /*
  * FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
- * Copyright (C) 2005-2014, Anthony Minessale II <anthm@freeswitch.org>
+ * Copyright (C) 2005-2020, Anthony Minessale II <anthm@freeswitch.org>
  *
  * Version: MPL 1.1
  *
@@ -2655,6 +2655,7 @@ SWITCH_DECLARE(void) switch_channel_event_set_basic_data(switch_channel_t *chann
        switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Channel-State-Number", state_num);
        switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Channel-Name", switch_channel_get_name(channel));
        switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Unique-ID", switch_core_session_get_uuid(channel->session));
+       switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Session-External-ID", switch_core_session_get_external_id(channel->session));
 
        switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Call-Direction",
                                                                   channel->direction == SWITCH_CALL_DIRECTION_OUTBOUND ? "outbound" : "inbound");
index 4440da639d5b5ca42236fde93d8721ae61437d17..23c787fb23f3f46ba4448aa1220e3c59ae79ecf7 100644 (file)
@@ -625,6 +625,7 @@ SWITCH_DECLARE(switch_call_cause_t) switch_core_session_outgoing_channel(switch_
                switch_event_t *event;
                switch_channel_t *peer_channel = switch_core_session_get_channel(*new_session);
                const char *use_uuid;
+               const char *use_external_id;
                switch_core_session_t *other_session = NULL;
 
                switch_assert(peer_channel);
@@ -646,6 +647,17 @@ SWITCH_DECLARE(switch_call_cause_t) switch_core_session_outgoing_channel(switch_
                        }
                }
 
+               if ((use_external_id = switch_event_get_header(var_event, "origination_external_id"))) {
+                       if (switch_core_session_set_external_id(*new_session, use_external_id) == SWITCH_STATUS_SUCCESS) {
+                               switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(*new_session), SWITCH_LOG_DEBUG, "%s set external_id=%s\n", switch_channel_get_name(peer_channel),
+                                                                 use_external_id);
+                               switch_event_del_header(var_event, "origination_external_id");
+                       } else {
+                               switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(*new_session), SWITCH_LOG_CRIT, "%s set external_id=%s FAILED\n",
+                                                                 switch_channel_get_name(peer_channel), use_external_id);
+                       }
+               }
+
                if (!channel && var_event) {
                        const char *other_uuid;
 
@@ -1558,6 +1570,9 @@ SWITCH_DECLARE(void) switch_core_session_perform_destroy(switch_core_session_t *
 
        switch_mutex_lock(runtime.session_hash_mutex);
        switch_core_hash_delete(session_manager.session_table, (*session)->uuid_str);
+       if ((*session)->external_id) {
+               switch_core_hash_delete(session_manager.session_table, (*session)->external_id);
+       }
        if (session_manager.session_count) {
                session_manager.session_count--;
                if (session_manager.session_count == 0) {
@@ -2055,6 +2070,34 @@ SWITCH_DECLARE(switch_status_t) switch_core_session_set_uuid(switch_core_session
        return SWITCH_STATUS_SUCCESS;
 }
 
+SWITCH_DECLARE(switch_status_t) switch_core_session_set_external_id(switch_core_session_t *session, const char *use_external_id)
+{
+       switch_assert(use_external_id);
+
+       if (session->external_id && !strcmp(use_external_id, session->external_id)) {
+               return SWITCH_STATUS_SUCCESS;
+       }
+
+
+       switch_mutex_lock(runtime.session_hash_mutex);
+       if (switch_core_hash_find(session_manager.session_table, use_external_id)) {
+               switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_WARNING, "Duplicate External ID!\n");
+               switch_mutex_unlock(runtime.session_hash_mutex);
+               return SWITCH_STATUS_FALSE;
+       }
+
+       switch_channel_set_variable(session->channel, "session_external_id", use_external_id);
+
+       if (session->external_id) {
+               switch_core_hash_delete(session_manager.session_table, session->external_id);
+       }
+       session->external_id = switch_core_session_strdup(session, use_external_id);
+       switch_core_hash_insert(session_manager.session_table, session->external_id, session);
+       switch_mutex_unlock(runtime.session_hash_mutex);
+
+       return SWITCH_STATUS_SUCCESS;
+}
+
 static char *xml_find_var(switch_xml_t vars, const char *name)
 {
        switch_xml_t var;
@@ -2540,6 +2583,11 @@ SWITCH_DECLARE(char *) switch_core_session_get_uuid(switch_core_session_t *sessi
        return session->uuid_str;
 }
 
+SWITCH_DECLARE(const char *) switch_core_session_get_external_id(switch_core_session_t *session)
+{
+       if (!session) return NULL;
+       return session->external_id;
+}
 
 SWITCH_DECLARE(uint32_t) switch_core_session_limit(uint32_t new_limit)
 {
index 212c54b2bf0dab42a9a579949b5fa4386f5a9448..10660c7dbd7028274b9a1e78e314b71ac0f9ab57 100644 (file)
@@ -2,7 +2,7 @@ include $(top_srcdir)/build/modmake.rulesam
 
 noinst_PROGRAMS = switch_event switch_hash switch_ivr_originate switch_utils switch_core switch_console switch_vpx switch_core_file \
                           switch_ivr_play_say switch_core_codec switch_rtp switch_xml
-noinst_PROGRAMS += switch_core_video switch_core_db switch_vad switch_packetizer test_sofia switch_core_asr
+noinst_PROGRAMS += switch_core_video switch_core_db switch_vad switch_packetizer test_sofia switch_core_asr switch_core_session
 
 AM_LDFLAGS += -avoid-version -no-undefined $(SWITCH_AM_LDFLAGS) $(openssl_LIBS)
 AM_LDFLAGS += $(FREESWITCH_LIBS) $(switch_builddir)/libfreeswitch.la $(CORE_LIBS) $(APR_LIBS)
diff --git a/tests/unit/switch_core_session.c b/tests/unit/switch_core_session.c
new file mode 100644 (file)
index 0000000..0319683
--- /dev/null
@@ -0,0 +1,75 @@
+/*
+ * FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
+ * Copyright (C) 2005-2020, Anthony Minessale II <anthm@freeswitch.org>
+ *
+ * Version: MPL 1.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
+ *
+ * The Initial Developer of the Original Code is
+ * Anthony Minessale II <anthm@freeswitch.org>
+ * Portions created by the Initial Developer are Copyright (C)
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Chris Rienzo <chris@signalwire.com>
+ *
+ *
+ * switch_core_session.c -- tests sessions
+ *
+ */
+#include <switch.h>
+#include <test/switch_test.h>
+
+
+FST_CORE_BEGIN("./conf")
+{
+       FST_SUITE_BEGIN(switch_core_session)
+       {
+               FST_SETUP_BEGIN()
+               {
+               }
+               FST_SETUP_END()
+
+               FST_TEARDOWN_BEGIN()
+               {
+               }
+               FST_TEARDOWN_END()
+
+               FST_SESSION_BEGIN(session_external_id)
+               {
+                       fst_check(switch_core_session_set_external_id(fst_session, switch_core_session_get_uuid(fst_session)) != SWITCH_STATUS_SUCCESS);
+                       fst_check(switch_core_session_set_external_id(fst_session, "foo") == SWITCH_STATUS_SUCCESS);
+                       switch_core_session_t *session = switch_core_session_locate("foo");
+                       fst_requires(session);
+                       fst_check_string_equals(switch_core_session_get_uuid(session), switch_core_session_get_uuid(fst_session));
+                       fst_check_string_equals(switch_core_session_get_external_id(session), "foo");
+                       fst_check(switch_core_session_set_external_id(fst_session, "bar") == SWITCH_STATUS_SUCCESS);
+                       fst_check_string_equals(switch_core_session_get_external_id(session), "bar");
+                       fst_requires(switch_core_session_locate("foo") == NULL);
+                       switch_core_session_rwunlock(session);
+                       session = switch_core_session_locate("bar");
+                       fst_requires(session);
+                       switch_core_session_rwunlock(session);
+                       session = switch_core_session_locate(switch_core_session_get_uuid(fst_session));
+                       fst_requires(session);
+                       switch_core_session_rwunlock(session);
+                       switch_channel_hangup(fst_channel, SWITCH_CAUSE_NORMAL_CLEARING);
+                       session = switch_core_session_locate("bar");
+                       fst_check(session == NULL);
+               }
+               FST_SESSION_END()
+       }
+       FST_SUITE_END()
+}
+FST_CORE_END()
index 6c34fcc1e873630303b98945952cf5cac1600a9c..b6ffe7cf513ecea202ace2602a8b26ba1eb83156 100644 (file)
@@ -55,6 +55,20 @@ static switch_status_t my_on_destroy(switch_core_session_t *session)
        return SWITCH_STATUS_SUCCESS;
 }
 
+
+const char *external_id_to_match = NULL;
+static int got_external_id_in_event = 0;
+
+static void on_hangup_event(switch_event_t *event)
+{
+       if (external_id_to_match) {
+               const char *external_id = switch_event_get_header(event, "Session-External-ID");
+               if (external_id && !strcmp(external_id_to_match, external_id)) {
+                       got_external_id_in_event = 1;
+               }
+       }
+}
+
 static switch_state_handler_table_t state_handlers = {
        /*.on_init */ NULL,
        /*.on_routing */ NULL,
@@ -89,6 +103,8 @@ FST_CORE_BEGIN("./conf")
                {
                        fst_requires_module("mod_loopback");
                        application_hit = 0;
+                       external_id_to_match = NULL;
+                       got_external_id_in_event = 0;
                }
                FST_SETUP_END()
 
@@ -97,6 +113,37 @@ FST_CORE_BEGIN("./conf")
                }
                FST_TEARDOWN_END()
 
+               FST_TEST_BEGIN(originate_test_external_id)
+               {
+                       switch_core_session_t *session = NULL;
+                       switch_channel_t *channel = NULL;
+                       switch_status_t status;
+                       switch_call_cause_t cause;
+                       switch_event_t *ovars = NULL;
+                       switch_event_create(&ovars, SWITCH_EVENT_CLONE);
+                       switch_event_add_header_string(ovars, SWITCH_STACK_BOTTOM, "origination_external_id", "zzzz");
+                       status = switch_ivr_originate(NULL, &session, &cause, "null/+15553334444", 2, NULL, NULL, NULL, NULL, ovars, SOF_NONE, NULL, NULL);
+                       fst_requires(session);
+                       fst_check(status == SWITCH_STATUS_SUCCESS);
+                       switch_event_destroy(&ovars);
+                       switch_core_session_rwunlock(session);
+
+                       session = switch_core_session_locate("zzzz");
+                       fst_requires(session);
+
+                       channel = switch_core_session_get_channel(session);
+                       fst_requires(channel);
+
+                       external_id_to_match = "zzzz";
+                       switch_event_bind("originate_test_external_id", SWITCH_EVENT_CHANNEL_HANGUP, SWITCH_EVENT_SUBCLASS_ANY, on_hangup_event, NULL);
+                       switch_channel_hangup(channel, SWITCH_CAUSE_NORMAL_CLEARING);
+                       switch_core_session_rwunlock(session);
+                       switch_yield(1000 * 1000);
+                       fst_check(got_external_id_in_event == 1);
+                       switch_event_unbind_callback(on_hangup_event);
+               }
+               FST_TEST_END()
+
                FST_TEST_BEGIN(originate_test_early_state_handler)
                {
                        switch_core_session_t *session = NULL;