From 987e87bc0b37d5707b180d9834cdaf748a2e925d Mon Sep 17 00:00:00 2001 From: Andrey Volk Date: Fri, 22 Dec 2023 22:37:54 +0300 Subject: [PATCH 01/56] version bump --- build/next-release.txt | 2 +- configure.ac | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/build/next-release.txt b/build/next-release.txt index 63fd3adc741..a3426275e72 100644 --- a/build/next-release.txt +++ b/build/next-release.txt @@ -1 +1 @@ -1.10.11-dev +1.10.12-dev diff --git a/configure.ac b/configure.ac index 56bf86f53c1..e4ab33ae5cc 100644 --- a/configure.ac +++ b/configure.ac @@ -3,10 +3,10 @@ # Must change all of the below together # For a release, set revision for that tagged release as well and uncomment -AC_INIT([freeswitch], [1.10.11-dev], bugs@freeswitch.org) +AC_INIT([freeswitch], [1.10.12-dev], bugs@freeswitch.org) AC_SUBST(SWITCH_VERSION_MAJOR, [1]) AC_SUBST(SWITCH_VERSION_MINOR, [10]) -AC_SUBST(SWITCH_VERSION_MICRO, [11-dev]) +AC_SUBST(SWITCH_VERSION_MICRO, [12-dev]) AC_SUBST(SWITCH_VERSION_REVISION, []) AC_SUBST(SWITCH_VERSION_REVISION_HUMAN, []) From 0cea9811cd6c39604280ced6b16c0e2429c4ec6c Mon Sep 17 00:00:00 2001 From: tmancill <1195611+tmancill@users.noreply.github.com> Date: Fri, 5 Jan 2024 07:42:58 -0800 Subject: [PATCH 02/56] [Docker] Change default freeswitch UID and GID to 499 in docker/master/Dockerfile On several installs on recent Debian and Ubuntu systems, I have noticed that GID 999 is already allocated on the system running the container, making it a minor hassle to share a common freeswitch UID and GID between the Docker host and the container. The conflicting group id varies, but is typically either one of the systemd groups or polkitd, which are dynamically created when those packages are installed. The behavior stems from the range of system GIDs being between 100-999 ([see Debian Policy 9.2.2](https://www.debian.org/doc/debian-policy/ch-opersys.html#uid-and-gid-classes)) and the fact that system installation dynamically allocates from this range. I didn't track down exactly why these daemons are allocating from the top of the range, since the default behavior of `adduser` and `addgroup` ([link](https://salsa.debian.org/debian/adduser/-/blob/6c04aa701a2ca09efbff9094ab07e7dae14554fc/adduser#L1255-1269)) is to search from the bottom of the range, and the manpage for `groupadd` says that it's default is also to use the smallest id, but perhaps it was to avoid (other) conflicts. The approach taken in this PR is to default to 499, more in the middle of the range, which should reduce the chance of conflicting with an existing system UID and GID. The values are also now exposed as ARGs and so can be explicitly set during the build with `--build-arg="FREESWITCH_UID=xxx"` and `--build-arg="FREESWITCH_GID=yyy"` if desired. --- docker/master/Dockerfile | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/docker/master/Dockerfile b/docker/master/Dockerfile index 4c73ecc6e48..d036164ac7c 100644 --- a/docker/master/Dockerfile +++ b/docker/master/Dockerfile @@ -20,7 +20,9 @@ ARG FS_META_PACKAGE=freeswitch-meta-all # https://github.com/docker-library/postgres/blob/master/9.4/Dockerfile # explicitly set user/group IDs -RUN groupadd -r freeswitch --gid=999 && useradd -r -g freeswitch --uid=999 freeswitch +ARG FREESWITCH_UID=499 +ARG FREESWITCH_GID=499 +RUN groupadd -r freeswitch --gid=${FREESWITCH_GID} && useradd -r -g freeswitch --uid=${FREESWITCH_UID} freeswitch # make the "en_US.UTF-8" locale so freeswitch will be utf-8 enabled by default RUN apt-get update -qq \ From a6e219062dd30a0c6b9b53b3dc0864a83924a8d9 Mon Sep 17 00:00:00 2001 From: Visytel <59720603+Visytel@users.noreply.github.com> Date: Mon, 8 Jan 2024 20:00:28 +1100 Subject: [PATCH 03/56] [Build-System, ldns] config.h change to not define inline under Windows to avoid clash with Windows winsock2.h inline usage. Use updated ldns tarball on Windows. * [ldns] config.h change to not define inline under Windows to avoid clash with Windows winsock2.h inline usage * [Build-System] Use updated ldns tarball on Windows. --------- Co-authored-by: Andrey Volk --- libs/win32/ldns/ldns-lib/config.h | 4 +++- w32/download_LDNS.props | 2 +- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/libs/win32/ldns/ldns-lib/config.h b/libs/win32/ldns/ldns-lib/config.h index 58463456b3c..fb29bc2c7c3 100644 --- a/libs/win32/ldns/ldns-lib/config.h +++ b/libs/win32/ldns/ldns-lib/config.h @@ -260,7 +260,9 @@ /* Define to `__inline__' or `__inline' if that's what the C compiler calls it, or to nothing if 'inline' is not supported under any name. */ #ifndef __cplusplus -#define inline +#ifndef _WIN32 +#define inline /* Do not define inline for Windows to avoid warnings/errors with winsock2.h usage of inline within the latest Windows SDKs */ +#endif #endif #if _MSC_VER >= 1900 diff --git a/w32/download_LDNS.props b/w32/download_LDNS.props index 445fe9a2b94..0036e1f278c 100644 --- a/w32/download_LDNS.props +++ b/w32/download_LDNS.props @@ -29,7 +29,7 @@ Date: Wed, 10 Jan 2024 17:01:26 +0100 Subject: [PATCH 04/56] [mod_amqp] Adjusting to Appropriate Log Level for Message * [mod_amqp] Adjusting to Appropriate Log Level for Message Refined Logging Level for FreeSWITCH's mod_amqp: The logging level for the AMQP module in FreeSWITCH has been updated from 'warning' to 'debug'. This adjustment ensures a more suitable level for the log message and eliminates any potential impact on production environments. Previously, the 'warning' level would lead to unnecessary log entries for each individual message, although there was no actual warning condition. This change improves logging efficiency and appropriateness for mod_amqp's operations within FreeSWITCH. * [MOD_AMQP] Change LogLevel to DEBUG1 as it is more appropriate for this message --- src/mod/event_handlers/mod_amqp/mod_amqp_command.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/mod/event_handlers/mod_amqp/mod_amqp_command.c b/src/mod/event_handlers/mod_amqp/mod_amqp_command.c index 2789a6e2525..48cdf55ce4e 100644 --- a/src/mod/event_handlers/mod_amqp/mod_amqp_command.c +++ b/src/mod/event_handlers/mod_amqp/mod_amqp_command.c @@ -231,7 +231,7 @@ static void mod_amqp_command_response(mod_amqp_command_profile_t *profile, char } /* Construct the api response */ - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Preparing api command response: [%s]\n", (char *)stream.data); + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG1, "Preparing api command response: [%s]\n", (char *)stream.data); message = cJSON_CreateObject(); cJSON_AddItemToObject(message, "output", cJSON_CreateString((const char *) stream.data)); From d148a3e412dbe1772a0e6f8a39e9a9b480c49268 Mon Sep 17 00:00:00 2001 From: Dmitry Kunilov <38783480+dkunilov@users.noreply.github.com> Date: Wed, 24 Jan 2024 16:50:08 +0300 Subject: [PATCH 05/56] [mod_amr, mod_amrwb] Fix input data corruption * Fix input data corruption in AMR and AMRWB codecs * [amr/amrwb] Check encoded frame size before decoding * [mod_amr, mod_amrwb] Coding guidelines cleanup. --------- Co-authored-by: Dmitry Kunilov Co-authored-by: Andrey Volk --- src/mod/codecs/mod_amr/mod_amr.c | 19 ++++++++++++++++--- src/mod/codecs/mod_amrwb/mod_amrwb.c | 19 ++++++++++++++++--- 2 files changed, 32 insertions(+), 6 deletions(-) diff --git a/src/mod/codecs/mod_amr/mod_amr.c b/src/mod/codecs/mod_amr/mod_amr.c index e7c45c7aff8..0769f62f3aa 100644 --- a/src/mod/codecs/mod_amr/mod_amr.c +++ b/src/mod/codecs/mod_amr/mod_amr.c @@ -250,6 +250,7 @@ static switch_status_t switch_amr_init(switch_codec_t *codec, switch_codec_flag_ int x, i, argc, fmtptmp_pos; char *argv[10]; char fmtptmp[128]; + char *fmtp_dup = NULL; encoding = (flags & SWITCH_CODEC_FLAG_ENCODE); decoding = (flags & SWITCH_CODEC_FLAG_DECODE); @@ -283,13 +284,19 @@ static switch_status_t switch_amr_init(switch_codec_t *codec, switch_codec_flag_ switch_set_flag(context, AMR_OPT_OCTET_ALIGN); } if (codec->fmtp_in) { - argc = switch_separate_string(codec->fmtp_in, ';', argv, (sizeof(argv) / sizeof(argv[0]))); + fmtp_dup = strdup(codec->fmtp_in); + switch_assert(fmtp_dup); + + argc = switch_separate_string(fmtp_dup, ';', argv, (sizeof(argv) / sizeof(argv[0]))); + for (x = 0; x < argc; x++) { char *data = argv[x]; char *arg; + while (*data && *data == ' ') { data++; } + if ((arg = strchr(data, '='))) { *arg++ = '\0'; if (!strcasecmp(data, "octet-align")) { @@ -325,13 +332,17 @@ static switch_status_t switch_amr_init(switch_codec_t *codec, switch_codec_flag_ } else if (!strcasecmp(data, "mode-set")) { int y, m_argc; char *m_argv[SWITCH_AMR_MODES-1]; + m_argc = switch_separate_string(arg, ',', m_argv, (sizeof(m_argv) / sizeof(m_argv[0]))); + for (y = 0; y < m_argc; y++) { context->enc_modes |= (1 << atoi(m_argv[y])); } } } } + + free(fmtp_dup); } if (context->enc_modes) { @@ -475,13 +486,15 @@ static switch_status_t switch_amr_decode(switch_codec_t *codec, return SWITCH_STATUS_FALSE; #else struct amr_context *context = codec->private_info; - unsigned char *buf = encoded_data; + unsigned char buf[SWITCH_AMR_OUT_MAX_SIZE]; uint8_t tmp[SWITCH_AMR_OUT_MAX_SIZE]; - if (!context) { + if (!context || encoded_data_len > SWITCH_AMR_OUT_MAX_SIZE) { return SWITCH_STATUS_FALSE; } + memcpy(buf, encoded_data, encoded_data_len); + if (globals.debug) { switch_amr_info(codec, buf, encoded_data_len, switch_test_flag(context, AMR_OPT_OCTET_ALIGN) ? 1 : 0, "AMR decoder"); } diff --git a/src/mod/codecs/mod_amrwb/mod_amrwb.c b/src/mod/codecs/mod_amrwb/mod_amrwb.c index 8be5f4d5412..4ac3f25f37a 100644 --- a/src/mod/codecs/mod_amrwb/mod_amrwb.c +++ b/src/mod/codecs/mod_amrwb/mod_amrwb.c @@ -198,6 +198,7 @@ static switch_status_t switch_amrwb_init(switch_codec_t *codec, switch_codec_fla int x, i, argc, fmtptmp_pos; char *argv[10]; char fmtptmp[128]; + char *fmtp_dup = NULL; encoding = (flags & SWITCH_CODEC_FLAG_ENCODE); decoding = (flags & SWITCH_CODEC_FLAG_DECODE); @@ -222,13 +223,19 @@ static switch_status_t switch_amrwb_init(switch_codec_t *codec, switch_codec_fla } if (codec->fmtp_in) { - argc = switch_separate_string(codec->fmtp_in, ';', argv, (sizeof(argv) / sizeof(argv[0]))); + fmtp_dup = strdup(codec->fmtp_in); + switch_assert(fmtp_dup); + + argc = switch_separate_string(fmtp_dup, ';', argv, (sizeof(argv) / sizeof(argv[0]))); + for (x = 0; x < argc; x++) { char *data = argv[x]; char *arg; + while (*data && *data == ' ') { data++; } + if ((arg = strchr(data, '='))) { *arg++ = '\0'; if (!strcasecmp(data, "octet-align")) { @@ -264,7 +271,9 @@ static switch_status_t switch_amrwb_init(switch_codec_t *codec, switch_codec_fla } else if (!strcasecmp(data, "mode-set")) { int y, m_argc; char *m_argv[SWITCH_AMRWB_MODES-1]; /* AMRWB has 9 modes */ + m_argc = switch_separate_string(arg, ',', m_argv, (sizeof(m_argv) / sizeof(m_argv[0]))); + for (y = 0; y < m_argc; y++) { context->enc_modes |= (1 << atoi(m_argv[y])); context->enc_mode = atoi(m_argv[y]); @@ -272,6 +281,8 @@ static switch_status_t switch_amrwb_init(switch_codec_t *codec, switch_codec_fla } } } + + free(fmtp_dup); } if (context->enc_modes && !globals.mode_set_overwrite) { @@ -401,13 +412,15 @@ static switch_status_t switch_amrwb_decode(switch_codec_t *codec, return SWITCH_STATUS_FALSE; #else struct amrwb_context *context = codec->private_info; - unsigned char *buf = encoded_data; + unsigned char buf[SWITCH_AMRWB_OUT_MAX_SIZE]; uint8_t tmp[SWITCH_AMRWB_OUT_MAX_SIZE]; - if (!context) { + if (!context || encoded_data_len > SWITCH_AMRWB_OUT_MAX_SIZE) { return SWITCH_STATUS_FALSE; } + memcpy(buf, encoded_data, encoded_data_len); + if (globals.debug) { switch_amrwb_info(codec, buf, encoded_data_len, switch_test_flag(context, AMRWB_OPT_OCTET_ALIGN) ? 1 : 0, "AMRWB decoder"); } From 1c057191002b8fbcabf31d6810fb1a834a148607 Mon Sep 17 00:00:00 2001 From: wmasilva Date: Wed, 24 Jan 2024 19:04:32 +0000 Subject: [PATCH 06/56] [Core] softtimer: fix crash in timezones when reloading xml * switch_time: fix segfault null TIMEZONES_LIST.hash when reloading xml * Unbind before destroying TIMEZONES_LIST.hash. Protect TIMEZONES_LIST.hash with a mutex that's allocated in core's global runtime.memory_pool so the mutex does not die on softtimer shutdown. --------- Co-authored-by: Andrey Volk --- src/switch_time.c | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/src/switch_time.c b/src/switch_time.c index a56c5e96f1f..1ee581453a8 100644 --- a/src/switch_time.c +++ b/src/switch_time.c @@ -1384,10 +1384,13 @@ SWITCH_DECLARE(const char *) switch_lookup_timezone(const char *tz_name) return NULL; } + switch_mutex_lock(globals.mutex); if ((value = switch_core_hash_find(TIMEZONES_LIST.hash, tz_name)) == NULL) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Timezone '%s' not found!\n", tz_name); } + switch_mutex_unlock(globals.mutex); + return value; } @@ -1522,7 +1525,7 @@ SWITCH_MODULE_LOAD_FUNCTION(softtimer_load) #endif memset(&globals, 0, sizeof(globals)); - switch_mutex_init(&globals.mutex, SWITCH_MUTEX_NESTED, module_pool); + switch_mutex_init(&globals.mutex, SWITCH_MUTEX_NESTED, runtime.memory_pool); if ((switch_event_bind_removable(modname, SWITCH_EVENT_RELOADXML, NULL, event_handler, NULL, &NODE) != SWITCH_STATUS_SUCCESS)) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Couldn't bind!\n"); @@ -1599,18 +1602,21 @@ SWITCH_MODULE_SHUTDOWN_FUNCTION(softtimer_shutdown) DeleteCriticalSection(&timer_section); #endif + if (NODE) { + switch_event_unbind(&NODE); + } + + switch_mutex_lock(globals.mutex); if (TIMEZONES_LIST.hash) { switch_core_hash_destroy(&TIMEZONES_LIST.hash); } + switch_mutex_unlock(globals.mutex); + if (TIMEZONES_LIST.pool) { switch_core_destroy_memory_pool(&TIMEZONES_LIST.pool); } - if (NODE) { - switch_event_unbind(&NODE); - } - return SWITCH_STATUS_SUCCESS; } From 8b7a8c4aea5906ab3988764c4077c205151695e6 Mon Sep 17 00:00:00 2001 From: Dragos Oancea Date: Wed, 18 Oct 2023 20:24:14 +0300 Subject: [PATCH 07/56] [core] SDP: replace SIP lingo in SDP offer/answer. --- src/include/switch_types.h | 6 +- .../applications/mod_dptools/mod_dptools.c | 2 +- src/mod/endpoints/mod_loopback/mod_loopback.c | 2 +- src/mod/endpoints/mod_sofia/mod_sofia.c | 22 ++--- src/mod/endpoints/mod_sofia/sofia.c | 50 +++++------ src/mod/endpoints/mod_sofia/sofia_glue.c | 2 +- src/mod/endpoints/mod_verto/mod_verto.c | 22 ++--- src/mod/languages/mod_managed/managed/swig.cs | 4 +- src/switch_core_media.c | 88 +++++++++---------- src/switch_ivr.c | 2 +- tests/unit/switch_rtp.c | 2 +- tests/unit/switch_rtp_pcap.c | 2 +- 12 files changed, 103 insertions(+), 101 deletions(-) diff --git a/src/include/switch_types.h b/src/include/switch_types.h index 94a4c62ccac..d315e46fc8c 100644 --- a/src/include/switch_types.h +++ b/src/include/switch_types.h @@ -2656,10 +2656,12 @@ struct switch_live_array_s; typedef struct switch_live_array_s switch_live_array_t; typedef enum { - SDP_TYPE_REQUEST, - SDP_TYPE_RESPONSE + SDP_OFFER, + SDP_ANSWER } switch_sdp_type_t; +#define SDP_TYPE_REQUEST SDP_OFFER +#define SDP_TYPE_RESPONSE SDP_ANSWER typedef enum { AEAD_AES_256_GCM_8, diff --git a/src/mod/applications/mod_dptools/mod_dptools.c b/src/mod/applications/mod_dptools/mod_dptools.c index f52b1184e56..58fce5f5d36 100644 --- a/src/mod/applications/mod_dptools/mod_dptools.c +++ b/src/mod/applications/mod_dptools/mod_dptools.c @@ -593,7 +593,7 @@ SWITCH_STANDARD_APP(filter_codecs_function) r_sdp = switch_channel_get_variable(channel, SWITCH_R_SDP_VARIABLE); if (data && r_sdp) { - switch_core_media_merge_sdp_codec_string(session, r_sdp, SDP_TYPE_REQUEST, data); + switch_core_media_merge_sdp_codec_string(session, r_sdp, SDP_OFFER, data); switch_channel_set_variable(channel, "filter_codec_string", data); } else { switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Incomplete data\n"); diff --git a/src/mod/endpoints/mod_loopback/mod_loopback.c b/src/mod/endpoints/mod_loopback/mod_loopback.c index 456936562a2..f5941eae36a 100644 --- a/src/mod/endpoints/mod_loopback/mod_loopback.c +++ b/src/mod/endpoints/mod_loopback/mod_loopback.c @@ -1429,7 +1429,7 @@ static switch_status_t null_tech_init(null_private_t *tech_pvt, switch_core_sess // switch_core_media_check_video_codecs(session); // switch_core_media_choose_port(session, SWITCH_MEDIA_TYPE_AUDIO, 0); // switch_core_media_choose_port(session, SWITCH_MEDIA_TYPE_VIDEO, 0); - // switch_core_media_gen_local_sdp(session, SDP_TYPE_REQUEST, "127.0.0.1", 2000, NULL, 0); + // switch_core_media_gen_local_sdp(session, SDP_OFFER, "127.0.0.1", 2000, NULL, 0); // switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "%s\n", mparams.local_sdp_str); } diff --git a/src/mod/endpoints/mod_sofia/mod_sofia.c b/src/mod/endpoints/mod_sofia/mod_sofia.c index 458be3f875a..c5ce6e38555 100644 --- a/src/mod/endpoints/mod_sofia/mod_sofia.c +++ b/src/mod/endpoints/mod_sofia/mod_sofia.c @@ -790,7 +790,7 @@ static switch_status_t sofia_answer_channel(switch_core_session_t *session) switch_core_media_prepare_codecs(tech_pvt->session, SWITCH_TRUE); tech_pvt->mparams.local_sdp_str = NULL; switch_core_media_choose_port(tech_pvt->session, SWITCH_MEDIA_TYPE_AUDIO, 0); - switch_core_media_gen_local_sdp(session, SDP_TYPE_RESPONSE, NULL, 0, NULL, 0); + switch_core_media_gen_local_sdp(session, SDP_ANSWER, NULL, 0, NULL, 0); } else if (is_3pcc_proxy) { if (!(sofia_test_pflag(tech_pvt->profile, PFLAG_3PCC_PROXY))) { @@ -802,7 +802,7 @@ static switch_status_t sofia_answer_channel(switch_core_session_t *session) } else { switch_core_media_choose_port(tech_pvt->session, SWITCH_MEDIA_TYPE_AUDIO, 0); switch_core_media_prepare_codecs(session, 1); - switch_core_media_gen_local_sdp(session, SDP_TYPE_REQUEST, NULL, 0, NULL, 1); + switch_core_media_gen_local_sdp(session, SDP_OFFER, NULL, 0, NULL, 1); sofia_set_flag_locked(tech_pvt, TFLAG_3PCC); } @@ -889,7 +889,7 @@ static switch_status_t sofia_answer_channel(switch_core_session_t *session) switch_core_media_prepare_codecs(tech_pvt->session, SWITCH_TRUE); - if (zstr(r_sdp) || sofia_media_tech_media(tech_pvt, r_sdp, SDP_TYPE_REQUEST) != SWITCH_STATUS_SUCCESS) { + if (zstr(r_sdp) || sofia_media_tech_media(tech_pvt, r_sdp, SDP_OFFER) != SWITCH_STATUS_SUCCESS) { switch_channel_set_variable(channel, SWITCH_ENDPOINT_DISPOSITION_VARIABLE, "CODEC NEGOTIATION ERROR"); //switch_mutex_lock(tech_pvt->sofia_mutex); //nua_respond(tech_pvt->nh, SIP_488_NOT_ACCEPTABLE, TAG_END()); @@ -904,7 +904,7 @@ static switch_status_t sofia_answer_channel(switch_core_session_t *session) return status; } - switch_core_media_gen_local_sdp(session, SDP_TYPE_RESPONSE, NULL, 0, NULL, 0); + switch_core_media_gen_local_sdp(session, SDP_ANSWER, NULL, 0, NULL, 0); if (sofia_media_activate_rtp(tech_pvt) != SWITCH_STATUS_SUCCESS) { switch_channel_hangup(channel, SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER); } @@ -1598,7 +1598,7 @@ static switch_status_t sofia_receive_message(switch_core_session_t *session, swi ip = switch_channel_get_variable(channel, SWITCH_REMOTE_MEDIA_IP_VARIABLE); port = switch_channel_get_variable(channel, SWITCH_REMOTE_MEDIA_PORT_VARIABLE); if (ip && port) { - switch_core_media_gen_local_sdp(session, SDP_TYPE_REQUEST, ip, (switch_port_t)atoi(port), msg->string_arg, 1); + switch_core_media_gen_local_sdp(session, SDP_OFFER, ip, (switch_port_t)atoi(port), msg->string_arg, 1); } if (!sofia_test_flag(tech_pvt, TFLAG_BYE)) { @@ -1783,7 +1783,7 @@ static switch_status_t sofia_receive_message(switch_core_session_t *session, swi if (switch_channel_direction(tech_pvt->channel) == SWITCH_CALL_DIRECTION_INBOUND) { switch_core_media_prepare_codecs(tech_pvt->session, SWITCH_TRUE); - if (sofia_media_tech_media(tech_pvt, r_sdp, SDP_TYPE_REQUEST) != SWITCH_STATUS_SUCCESS) { + if (sofia_media_tech_media(tech_pvt, r_sdp, SDP_OFFER) != SWITCH_STATUS_SUCCESS) { switch_channel_set_variable(channel, SWITCH_ENDPOINT_DISPOSITION_VARIABLE, "CODEC NEGOTIATION ERROR"); status = SWITCH_STATUS_FALSE; goto end_lock; @@ -1793,7 +1793,7 @@ static switch_status_t sofia_receive_message(switch_core_session_t *session, swi } - switch_core_media_set_sdp_codec_string(tech_pvt->session, r_sdp, SDP_TYPE_RESPONSE); + switch_core_media_set_sdp_codec_string(tech_pvt->session, r_sdp, SDP_ANSWER); switch_channel_set_variable(tech_pvt->channel, "absolute_codec_string", switch_channel_get_variable(tech_pvt->channel, "ep_codec_string")); switch_core_media_prepare_codecs(tech_pvt->session, SWITCH_TRUE); @@ -1802,7 +1802,7 @@ static switch_status_t sofia_receive_message(switch_core_session_t *session, swi goto end_lock; } - switch_core_media_gen_local_sdp(session, SDP_TYPE_REQUEST, NULL, 0, NULL, 1); + switch_core_media_gen_local_sdp(session, SDP_OFFER, NULL, 0, NULL, 1); if (!msg->numeric_arg) { if (send_invite) { @@ -2256,7 +2256,7 @@ static switch_status_t sofia_receive_message(switch_core_session_t *session, swi switch_channel_clear_flag(tech_pvt->channel, CF_AWAITING_STREAM_CHANGE); switch_core_session_local_crypto_key(tech_pvt->session, SWITCH_MEDIA_TYPE_AUDIO); - switch_core_media_gen_local_sdp(session, SDP_TYPE_RESPONSE, NULL, 0, NULL, 0); + switch_core_media_gen_local_sdp(session, SDP_ANSWER, NULL, 0, NULL, 0); if (sofia_use_soa(tech_pvt)) { nua_respond(tech_pvt->nh, SIP_200_OK, @@ -2584,7 +2584,7 @@ static switch_status_t sofia_receive_message(switch_core_session_t *session, swi switch_core_media_prepare_codecs(tech_pvt->session, SWITCH_TRUE); - if (zstr(r_sdp) || sofia_media_tech_media(tech_pvt, r_sdp, SDP_TYPE_REQUEST) != SWITCH_STATUS_SUCCESS) { + if (zstr(r_sdp) || sofia_media_tech_media(tech_pvt, r_sdp, SDP_OFFER) != SWITCH_STATUS_SUCCESS) { switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_WARNING, "CODEC NEGOTIATION ERROR. SDP:\n%s\n", r_sdp ? r_sdp : "NO SDP!"); switch_channel_set_variable(channel, SWITCH_ENDPOINT_DISPOSITION_VARIABLE, "CODEC NEGOTIATION ERROR"); @@ -2599,7 +2599,7 @@ static switch_status_t sofia_receive_message(switch_core_session_t *session, swi switch_channel_hangup(channel, SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER); goto end_lock; } - switch_core_media_gen_local_sdp(session, SDP_TYPE_RESPONSE, NULL, 0, NULL, 0); + switch_core_media_gen_local_sdp(session, SDP_ANSWER, NULL, 0, NULL, 0); if (sofia_media_activate_rtp(tech_pvt) != SWITCH_STATUS_SUCCESS) { switch_channel_hangup(channel, SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER); } diff --git a/src/mod/endpoints/mod_sofia/sofia.c b/src/mod/endpoints/mod_sofia/sofia.c index c5b5bcc1901..311052a6198 100644 --- a/src/mod/endpoints/mod_sofia/sofia.c +++ b/src/mod/endpoints/mod_sofia/sofia.c @@ -6683,7 +6683,7 @@ static void sofia_handle_sip_r_invite(switch_core_session_t *session, int status tech_pvt->mparams.last_sdp_response = NULL; if (sip->sip_payload && sip->sip_payload->pl_data) { - switch_core_media_set_sdp_codec_string(session, sip->sip_payload->pl_data, SDP_TYPE_RESPONSE); + switch_core_media_set_sdp_codec_string(session, sip->sip_payload->pl_data, SDP_ANSWER); if (!zstr(tech_pvt->mparams.prev_sdp_response) && !strcmp(tech_pvt->mparams.prev_sdp_response, sip->sip_payload->pl_data)) { tech_pvt->mparams.last_sdp_response = tech_pvt->mparams.prev_sdp_response; @@ -7506,9 +7506,9 @@ static void sofia_handle_sip_i_state(switch_core_session_t *session, int status, switch_channel_mark_pre_answered(channel); } //if ((sofia_test_flag(tech_pvt, TFLAG_LATE_NEGOTIATION) || switch_channel_direction(channel) == SWITCH_CALL_DIRECTION_OUTBOUND)) { - // switch_core_media_set_sdp_codec_string(session, r_sdp, status < 200 ? SDP_TYPE_REQUEST : SDP_TYPE_RESPONSE); + // switch_core_media_set_sdp_codec_string(session, r_sdp, status < 200 ? SDP_OFFER : SDP_ANSWER); //} - switch_core_media_set_sdp_codec_string(session, r_sdp, SDP_TYPE_REQUEST); + switch_core_media_set_sdp_codec_string(session, r_sdp, SDP_OFFER); sofia_glue_pass_sdp(tech_pvt, (char *) r_sdp); sofia_set_flag(tech_pvt, TFLAG_NEW_SDP); @@ -7680,7 +7680,7 @@ static void sofia_handle_sip_i_state(switch_core_session_t *session, int status, } } else { - if (sofia_media_tech_media(tech_pvt, (char *) r_sdp, SDP_TYPE_REQUEST) != SWITCH_STATUS_SUCCESS) { + if (sofia_media_tech_media(tech_pvt, (char *) r_sdp, SDP_OFFER) != SWITCH_STATUS_SUCCESS) { switch_channel_set_variable(channel, SWITCH_ENDPOINT_DISPOSITION_VARIABLE, "CODEC NEGOTIATION ERROR"); nua_respond(nh, SIP_488_NOT_ACCEPTABLE, TAG_IF(!zstr(session_id_header), SIPTAG_HEADER_STR(session_id_header)),TAG_END()); @@ -7776,7 +7776,7 @@ static void sofia_handle_sip_i_state(switch_core_session_t *session, int status, switch_core_media_prepare_codecs(tech_pvt->session, SWITCH_FALSE); if (tech_pvt->mparams.num_codecs) { - match = sofia_media_negotiate_sdp(session, r_sdp, SDP_TYPE_REQUEST); + match = sofia_media_negotiate_sdp(session, r_sdp, SDP_OFFER); } if (!match) { @@ -7785,7 +7785,7 @@ static void sofia_handle_sip_i_state(switch_core_session_t *session, int status, TAG_IF(!zstr(session_id_header), SIPTAG_HEADER_STR(session_id_header)),TAG_END()); } } else { - switch_core_media_gen_local_sdp(session, SDP_TYPE_RESPONSE, NULL, 0, NULL, 0); + switch_core_media_gen_local_sdp(session, SDP_ANSWER, NULL, 0, NULL, 0); switch_channel_set_variable(channel, SWITCH_ENDPOINT_DISPOSITION_VARIABLE, "RECEIVED"); sofia_set_flag_locked(tech_pvt, TFLAG_READY); @@ -7909,7 +7909,7 @@ static void sofia_handle_sip_i_state(switch_core_session_t *session, int status, uint8_t match = 0; if (tech_pvt->mparams.num_codecs) { - match = sofia_media_negotiate_sdp(session, r_sdp, SDP_TYPE_REQUEST); + match = sofia_media_negotiate_sdp(session, r_sdp, SDP_OFFER); } if (!match) { @@ -7995,7 +7995,7 @@ static void sofia_handle_sip_i_state(switch_core_session_t *session, int status, switch_core_media_choose_port(tech_pvt->session, SWITCH_MEDIA_TYPE_AUDIO, 0); switch_core_media_prepare_codecs(session, 1); switch_channel_set_state(channel, CS_HIBERNATE); - switch_core_media_gen_local_sdp(session, SDP_TYPE_REQUEST, NULL, 0, NULL, 0); + switch_core_media_gen_local_sdp(session, SDP_OFFER, NULL, 0, NULL, 0); sofia_set_flag_locked(tech_pvt, TFLAG_3PCC); if (sofia_use_soa(tech_pvt)) { @@ -8067,10 +8067,10 @@ static void sofia_handle_sip_i_state(switch_core_session_t *session, int status, switch_channel_set_flag(channel, CF_NOSDP_REINVITE); if (switch_channel_var_true(channel, "sip_unhold_nosdp")) { - switch_core_media_gen_local_sdp(session, SDP_TYPE_RESPONSE, NULL, 0, "sendrecv", + switch_core_media_gen_local_sdp(session, SDP_ANSWER, NULL, 0, "sendrecv", zstr(tech_pvt->mparams.local_sdp_str) || !switch_channel_test_flag(channel, CF_PROXY_MODE)); } else { - switch_core_media_gen_local_sdp(session, SDP_TYPE_RESPONSE, NULL, 0, NULL, + switch_core_media_gen_local_sdp(session, SDP_ANSWER, NULL, 0, NULL, zstr(tech_pvt->mparams.local_sdp_str) || !switch_channel_test_flag(channel, CF_PROXY_MODE)); } @@ -8116,13 +8116,13 @@ static void sofia_handle_sip_i_state(switch_core_session_t *session, int status, sofia_set_flag(tech_pvt, TFLAG_SDP); - match = sofia_media_negotiate_sdp(session, r_sdp, SDP_TYPE_RESPONSE); + match = sofia_media_negotiate_sdp(session, r_sdp, SDP_ANSWER); if (match) { if (switch_core_media_choose_port(tech_pvt->session, SWITCH_MEDIA_TYPE_AUDIO, 0) != SWITCH_STATUS_SUCCESS) { goto done; } - switch_core_media_gen_local_sdp(session, SDP_TYPE_RESPONSE, NULL, 0, NULL, 0); + switch_core_media_gen_local_sdp(session, SDP_ANSWER, NULL, 0, NULL, 0); if (sofia_media_activate_rtp(tech_pvt) != SWITCH_STATUS_SUCCESS) { switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Early Media RTP Error!\n"); @@ -8191,7 +8191,7 @@ static void sofia_handle_sip_i_state(switch_core_session_t *session, int status, switch_core_media_prepare_codecs(tech_pvt->session, SWITCH_TRUE); - if (sofia_media_tech_media(tech_pvt, r_sdp, SDP_TYPE_REQUEST) != SWITCH_STATUS_SUCCESS) { + if (sofia_media_tech_media(tech_pvt, r_sdp, SDP_OFFER) != SWITCH_STATUS_SUCCESS) { switch_channel_set_variable(channel, SWITCH_ENDPOINT_DISPOSITION_VARIABLE, "CODEC NEGOTIATION ERROR"); switch_core_session_rwunlock(other_session); switch_channel_hangup(channel, SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER); @@ -8210,7 +8210,7 @@ static void sofia_handle_sip_i_state(switch_core_session_t *session, int status, } } - switch_core_media_gen_local_sdp(session, SDP_TYPE_RESPONSE, NULL, 0, NULL, 1); + switch_core_media_gen_local_sdp(session, SDP_ANSWER, NULL, 0, NULL, 1); if (sofia_use_soa(tech_pvt)) { nua_respond(tech_pvt->nh, SIP_200_OK, @@ -8320,7 +8320,7 @@ static void sofia_handle_sip_i_state(switch_core_session_t *session, int status, switch_channel_set_flag(tech_pvt->channel, CF_REINVITE); if (tech_pvt->mparams.num_codecs){ - match = sofia_media_negotiate_sdp(session, r_sdp, SDP_TYPE_REQUEST); + match = sofia_media_negotiate_sdp(session, r_sdp, SDP_OFFER); } if (!match) { @@ -8369,7 +8369,7 @@ static void sofia_handle_sip_i_state(switch_core_session_t *session, int status, - switch_core_media_gen_local_sdp(session, SDP_TYPE_RESPONSE, NULL, 0, NULL, 0); + switch_core_media_gen_local_sdp(session, SDP_ANSWER, NULL, 0, NULL, 0); if (sofia_use_soa(tech_pvt)){ nua_respond(tech_pvt->nh, SIP_200_OK, SIPTAG_CONTACT_STR(tech_pvt->reply_contact), @@ -8419,7 +8419,7 @@ static void sofia_handle_sip_i_state(switch_core_session_t *session, int status, switch_channel_set_flag(tech_pvt->channel, CF_REINVITE); if (tech_pvt->mparams.num_codecs) { - match = sofia_media_negotiate_sdp(session, r_sdp, SDP_TYPE_REQUEST); + match = sofia_media_negotiate_sdp(session, r_sdp, SDP_OFFER); } @@ -8438,7 +8438,7 @@ static void sofia_handle_sip_i_state(switch_core_session_t *session, int status, goto done; } - switch_core_media_gen_local_sdp(session, SDP_TYPE_RESPONSE, NULL, 0, NULL, 0); + switch_core_media_gen_local_sdp(session, SDP_ANSWER, NULL, 0, NULL, 0); if (sofia_media_activate_rtp(tech_pvt) != SWITCH_STATUS_SUCCESS) { switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Reinvite RTP Error!\n"); @@ -8462,7 +8462,7 @@ static void sofia_handle_sip_i_state(switch_core_session_t *session, int status, if (is_ok) { if (switch_core_session_local_crypto_key(tech_pvt->session, SWITCH_MEDIA_TYPE_AUDIO)) { - switch_core_media_gen_local_sdp(session, SDP_TYPE_RESPONSE, NULL, 0, NULL, 0); + switch_core_media_gen_local_sdp(session, SDP_ANSWER, NULL, 0, NULL, 0); } if (!switch_channel_test_flag(tech_pvt->channel, CF_AWAITING_STREAM_CHANGE)) { @@ -8507,13 +8507,13 @@ static void sofia_handle_sip_i_state(switch_core_session_t *session, int status, if (tech_pvt->mparams.num_codecs) { - match = sofia_media_negotiate_sdp(session, r_sdp, SDP_TYPE_RESPONSE); + match = sofia_media_negotiate_sdp(session, r_sdp, SDP_ANSWER); } if (match) { if (switch_core_media_choose_port(tech_pvt->session, SWITCH_MEDIA_TYPE_AUDIO, 0) != SWITCH_STATUS_SUCCESS) { goto done; } - switch_core_media_gen_local_sdp(session, SDP_TYPE_RESPONSE, NULL, 0, NULL, 0); + switch_core_media_gen_local_sdp(session, SDP_ANSWER, NULL, 0, NULL, 0); switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Processing updated SDP\n"); switch_channel_set_flag(tech_pvt->channel, CF_REINVITE); @@ -8571,9 +8571,9 @@ static void sofia_handle_sip_i_state(switch_core_session_t *session, int status, if (tech_pvt->mparams.num_codecs) { if (sofia_test_flag(tech_pvt, TFLAG_GOT_ACK)) { - match = sofia_media_negotiate_sdp(session, r_sdp, SDP_TYPE_REQUEST); + match = sofia_media_negotiate_sdp(session, r_sdp, SDP_OFFER); } else { - match = sofia_media_negotiate_sdp(session, r_sdp, SDP_TYPE_RESPONSE); + match = sofia_media_negotiate_sdp(session, r_sdp, SDP_ANSWER); } } @@ -8668,7 +8668,7 @@ static void sofia_handle_sip_i_state(switch_core_session_t *session, int status, uint8_t match = 0; - match = sofia_media_negotiate_sdp(session, r_sdp, SDP_TYPE_RESPONSE); + match = sofia_media_negotiate_sdp(session, r_sdp, SDP_ANSWER); sofia_set_flag_locked(tech_pvt, TFLAG_ANS); @@ -10466,7 +10466,7 @@ void sofia_handle_sip_i_invite(switch_core_session_t *session, nua_t *nua, sofia if (r_sdp) { - switch_core_media_set_sdp_codec_string(session, r_sdp, SDP_TYPE_REQUEST); + switch_core_media_set_sdp_codec_string(session, r_sdp, SDP_OFFER); } diff --git a/src/mod/endpoints/mod_sofia/sofia_glue.c b/src/mod/endpoints/mod_sofia/sofia_glue.c index eceae218f8d..1452a7cf0fc 100644 --- a/src/mod/endpoints/mod_sofia/sofia_glue.c +++ b/src/mod/endpoints/mod_sofia/sofia_glue.c @@ -1158,7 +1158,7 @@ switch_status_t sofia_glue_do_invite(switch_core_session_t *session) } if (!switch_channel_get_private(tech_pvt->channel, "t38_options") || zstr(tech_pvt->mparams.local_sdp_str)) { - switch_core_media_gen_local_sdp(session, SDP_TYPE_REQUEST, NULL, 0, NULL, 0); + switch_core_media_gen_local_sdp(session, SDP_OFFER, NULL, 0, NULL, 0); } sofia_set_flag_locked(tech_pvt, TFLAG_READY); diff --git a/src/mod/endpoints/mod_verto/mod_verto.c b/src/mod/endpoints/mod_verto/mod_verto.c index ac042fe626d..48c40527b56 100644 --- a/src/mod/endpoints/mod_verto/mod_verto.c +++ b/src/mod/endpoints/mod_verto/mod_verto.c @@ -1320,7 +1320,7 @@ static void tech_reattach(verto_pvt_t *tech_pvt, jsock_t *jsock) switch_channel_set_flag(tech_pvt->channel, CF_REATTACHED); switch_channel_set_flag(tech_pvt->channel, CF_REINVITE); switch_channel_set_flag(tech_pvt->channel, CF_RECOVERING); - switch_core_media_gen_local_sdp(tech_pvt->session, SDP_TYPE_REQUEST, NULL, 0, NULL, 0); + switch_core_media_gen_local_sdp(tech_pvt->session, SDP_OFFER, NULL, 0, NULL, 0); switch_channel_clear_flag(tech_pvt->channel, CF_REINVITE); switch_channel_clear_flag(tech_pvt->channel, CF_RECOVERING); switch_core_session_request_video_refresh(tech_pvt->session); @@ -2405,7 +2405,7 @@ static switch_status_t verto_connect(switch_core_session_t *session, const char } } - switch_core_media_gen_local_sdp(session, SDP_TYPE_REQUEST, NULL, 0, NULL, 0); + switch_core_media_gen_local_sdp(session, SDP_OFFER, NULL, 0, NULL, 0); } msg = jrpc_new_req(method, tech_pvt->call_id, ¶ms); @@ -2641,7 +2641,7 @@ static switch_status_t verto_media(switch_core_session_t *session) switch_core_media_prepare_codecs(tech_pvt->session, SWITCH_TRUE); if (tech_pvt->r_sdp) { - if (verto_tech_media(tech_pvt, tech_pvt->r_sdp, SDP_TYPE_REQUEST) != SWITCH_STATUS_SUCCESS) { + if (verto_tech_media(tech_pvt, tech_pvt->r_sdp, SDP_OFFER) != SWITCH_STATUS_SUCCESS) { switch_channel_set_variable(tech_pvt->channel, SWITCH_ENDPOINT_DISPOSITION_VARIABLE, "CODEC NEGOTIATION ERROR"); return SWITCH_STATUS_FALSE; } @@ -2653,7 +2653,7 @@ static switch_status_t verto_media(switch_core_session_t *session) return status; } - switch_core_media_gen_local_sdp(session, SDP_TYPE_RESPONSE, NULL, 0, NULL, 0); + switch_core_media_gen_local_sdp(session, SDP_ANSWER, NULL, 0, NULL, 0); if (switch_core_media_activate_rtp(tech_pvt->session) != SWITCH_STATUS_SUCCESS) { switch_channel_hangup(tech_pvt->channel, SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER); @@ -2963,7 +2963,7 @@ static switch_bool_t verto__answer_func(const char *method, cJSON *params, jsock switch_channel_set_variable(tech_pvt->channel, SWITCH_R_SDP_VARIABLE, sdp); switch_channel_set_variable(tech_pvt->channel, "verto_client_address", jsock->name); switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Remote SDP %s:\n%s\n", switch_channel_get_name(tech_pvt->channel), sdp); - switch_core_media_set_sdp_codec_string(session, sdp, SDP_TYPE_RESPONSE); + switch_core_media_set_sdp_codec_string(session, sdp, SDP_ANSWER); if (!switch_channel_var_true(switch_core_session_get_channel(session),"verto_skip_set_user")) { switch_ivr_set_user(session, jsock->uid); @@ -2978,7 +2978,7 @@ static switch_bool_t verto__answer_func(const char *method, cJSON *params, jsock if (switch_channel_test_flag(tech_pvt->channel, CF_PROXY_MODE)) { pass_sdp(tech_pvt); } else { - if (verto_tech_media(tech_pvt, tech_pvt->r_sdp, SDP_TYPE_RESPONSE) != SWITCH_STATUS_SUCCESS) { + if (verto_tech_media(tech_pvt, tech_pvt->r_sdp, SDP_ANSWER) != SWITCH_STATUS_SUCCESS) { switch_channel_set_variable(tech_pvt->channel, SWITCH_ENDPOINT_DISPOSITION_VARIABLE, "CODEC NEGOTIATION ERROR"); cJSON_AddItemToObject(obj, "message", cJSON_CreateString("CODEC ERROR")); err = 1; @@ -3448,8 +3448,8 @@ static switch_bool_t verto__modify_func(const char *method, cJSON *params, jsock //switch_channel_set_flag(tech_pvt->channel, CF_VIDEO_BREAK); //switch_core_session_kill_channel(tech_pvt->session, SWITCH_SIG_BREAK); - if (switch_core_media_negotiate_sdp(tech_pvt->session, tech_pvt->r_sdp, &p, SDP_TYPE_REQUEST)) { - switch_core_media_gen_local_sdp(session, SDP_TYPE_RESPONSE, NULL, 0, NULL, 0); + if (switch_core_media_negotiate_sdp(tech_pvt->session, tech_pvt->r_sdp, &p, SDP_OFFER)) { + switch_core_media_gen_local_sdp(session, SDP_ANSWER, NULL, 0, NULL, 0); if (switch_core_media_activate_rtp(tech_pvt->session) != SWITCH_STATUS_SUCCESS) { switch_channel_set_variable(tech_pvt->channel, SWITCH_ENDPOINT_DISPOSITION_VARIABLE, "MEDIA ERROR"); @@ -3606,8 +3606,8 @@ static switch_bool_t verto__attach_func(const char *method, cJSON *params, jsock //switch_channel_set_flag(tech_pvt->channel, CF_VIDEO_BREAK); //switch_core_session_kill_channel(tech_pvt->session, SWITCH_SIG_BREAK); - if (switch_core_media_negotiate_sdp(tech_pvt->session, tech_pvt->r_sdp, &p, SDP_TYPE_RESPONSE)) { - //switch_core_media_gen_local_sdp(session, SDP_TYPE_RESPONSE, NULL, 0, NULL, 0); + if (switch_core_media_negotiate_sdp(tech_pvt->session, tech_pvt->r_sdp, &p, SDP_ANSWER)) { + //switch_core_media_gen_local_sdp(session, SDP_ANSWER, NULL, 0, NULL, 0); if (switch_core_media_activate_rtp(tech_pvt->session) != SWITCH_STATUS_SUCCESS) { switch_channel_set_variable(tech_pvt->channel, SWITCH_ENDPOINT_DISPOSITION_VARIABLE, "MEDIA ERROR"); @@ -4020,7 +4020,7 @@ static switch_bool_t verto__invite_func(const char *method, cJSON *params, jsock tech_pvt->channel = channel; tech_pvt->jsock_uuid = switch_core_session_strdup(session, jsock->uuid_str); tech_pvt->r_sdp = switch_core_session_strdup(session, sdp); - switch_core_media_set_sdp_codec_string(session, sdp, SDP_TYPE_REQUEST); + switch_core_media_set_sdp_codec_string(session, sdp, SDP_OFFER); switch_core_session_set_private_class(session, tech_pvt, SWITCH_PVT_SECONDARY); tech_pvt->call_id = switch_core_session_strdup(session, call_id); diff --git a/src/mod/languages/mod_managed/managed/swig.cs b/src/mod/languages/mod_managed/managed/swig.cs index fbab2f3f775..dc3926cbbb6 100644 --- a/src/mod/languages/mod_managed/managed/swig.cs +++ b/src/mod/languages/mod_managed/managed/swig.cs @@ -45055,8 +45055,8 @@ public switch_scheduler_task() : this(freeswitchPINVOKE.new_switch_scheduler_tas namespace FreeSWITCH.Native { public enum switch_sdp_type_t { - SDP_TYPE_REQUEST, - SDP_TYPE_RESPONSE + SDP_OFFER, + SDP_ANSWER } } diff --git a/src/switch_core_media.c b/src/switch_core_media.c index 4b6d8aff8b6..58ef94a53ed 100644 --- a/src/switch_core_media.c +++ b/src/switch_core_media.c @@ -713,7 +713,7 @@ SWITCH_DECLARE(payload_map_t *) switch_core_media_add_payload_map(switch_core_se for (pmap = engine->payload_map; pmap && pmap->allocated; pmap = pmap->next) { - if (sdp_type == SDP_TYPE_RESPONSE) { + if (sdp_type == SDP_ANSWER) { switch(type) { case SWITCH_MEDIA_TYPE_TEXT: exists = (type == pmap->type && !strcasecmp(name, pmap->iananame)); @@ -722,11 +722,11 @@ SWITCH_DECLARE(payload_map_t *) switch_core_media_add_payload_map(switch_core_se exists = (type == pmap->type && !strcasecmp(name, pmap->iananame) && pmap->pt == pt && (!pmap->rate || rate == pmap->rate) && (!pmap->ptime || pmap->ptime == ptime)); break; case SWITCH_MEDIA_TYPE_VIDEO: - exists = (pmap->sdp_type == SDP_TYPE_REQUEST && type == pmap->type && !strcasecmp(name, pmap->iananame)); + exists = (pmap->sdp_type == SDP_OFFER && type == pmap->type && !strcasecmp(name, pmap->iananame)); switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG1, "CHECK PMAP %s:%s %d %s:%s %d ... %d\n", name, "RES", pt, - pmap->iananame, pmap->sdp_type == SDP_TYPE_REQUEST ? "REQ" : "RES", pmap->pt, exists); + pmap->iananame, pmap->sdp_type == SDP_OFFER ? "REQ" : "RES", pmap->pt, exists); break; @@ -797,7 +797,7 @@ SWITCH_DECLARE(payload_map_t *) switch_core_media_add_payload_map(switch_core_se } if (!zstr(fmtp)) { - if (sdp_type == SDP_TYPE_REQUEST || !exists) { + if (sdp_type == SDP_OFFER || !exists) { pmap->rm_fmtp = switch_core_strdup(session->pool, fmtp); } } @@ -807,7 +807,7 @@ SWITCH_DECLARE(payload_map_t *) switch_core_media_add_payload_map(switch_core_se pmap->recv_pt = (switch_payload_t) pt; - if (sdp_type == SDP_TYPE_REQUEST || !exists) { + if (sdp_type == SDP_OFFER || !exists) { pmap->pt = (switch_payload_t) pt; } @@ -818,7 +818,7 @@ SWITCH_DECLARE(payload_map_t *) switch_core_media_add_payload_map(switch_core_se if (!exists) { pmap->sdp_type = sdp_type; - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG1, "ADD PMAP %s %s %d\n", sdp_type == SDP_TYPE_REQUEST ? "REQ" : "RES", name, pt); + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG1, "ADD PMAP %s %s %d\n", sdp_type == SDP_OFFER ? "REQ" : "RES", name, pt); if (pmap == engine->payload_map) { engine->pmap_tail = pmap; @@ -1724,7 +1724,7 @@ SWITCH_DECLARE(int) switch_core_session_check_incoming_crypto(switch_core_sessio const char *a = switch_stristr("AE", engine->ssec[engine->crypto_type].remote_crypto_key); const char *b = switch_stristr("AE", crypto); - if (sdp_type == SDP_TYPE_REQUEST) { + if (sdp_type == SDP_OFFER) { if (!vval) { switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Unsupported Crypto [%s]\n", crypto); goto end; @@ -4633,7 +4633,7 @@ static void check_stream_changes(switch_core_session_t *session, const char *r_s switch_channel_set_flag(other_session->channel, CF_PROCESSING_STREAM_CHANGE); switch_channel_set_flag(session->channel, CF_AWAITING_STREAM_CHANGE); - if (sdp_type == SDP_TYPE_REQUEST && r_sdp) { + if (sdp_type == SDP_OFFER && r_sdp) { const char *filter_codec_string = switch_channel_get_variable(session->channel, "filter_codec_string"); switch_channel_set_variable(session->channel, "codec_string", NULL); @@ -4654,7 +4654,7 @@ static void check_stream_changes(switch_core_session_t *session, const char *r_s } if (other_session) { - if (sdp_type == SDP_TYPE_RESPONSE && switch_channel_test_flag(session->channel, CF_PROCESSING_STREAM_CHANGE)) { + if (sdp_type == SDP_ANSWER && switch_channel_test_flag(session->channel, CF_PROCESSING_STREAM_CHANGE)) { switch_channel_clear_flag(session->channel, CF_PROCESSING_STREAM_CHANGE); if (switch_channel_test_flag(other_session->channel, CF_AWAITING_STREAM_CHANGE)) { @@ -4667,7 +4667,7 @@ static void check_stream_changes(switch_core_session_t *session, const char *r_s } sdp_in = switch_channel_get_variable(other_session->channel, SWITCH_R_SDP_VARIABLE); - res = switch_core_media_negotiate_sdp(other_session, sdp_in, &proceed, SDP_TYPE_REQUEST); + res = switch_core_media_negotiate_sdp(other_session, sdp_in, &proceed, SDP_OFFER); (void)res; switch_core_media_activate_rtp(other_session); msg = switch_core_session_alloc(other_session, sizeof(*msg)); @@ -4715,11 +4715,11 @@ SWITCH_DECLARE(void) switch_core_media_set_smode(switch_core_session_t *session, engine->pass_codecs = 0; if (switch_channel_var_true(session->channel, "rtp_pass_codecs_on_stream_change")) { - if (sdp_type == SDP_TYPE_REQUEST && switch_channel_test_flag(session->channel, CF_REINVITE) && + if (sdp_type == SDP_OFFER && switch_channel_test_flag(session->channel, CF_REINVITE) && switch_channel_media_up(session->channel) && (pass_codecs || old_smode != smode)) { if (switch_core_session_get_partner(session, &other_session) == SWITCH_STATUS_SUCCESS) { - switch_core_media_set_smode(other_session, type, opp_smode, SDP_TYPE_REQUEST); + switch_core_media_set_smode(other_session, type, opp_smode, SDP_OFFER); switch_channel_set_flag(session->channel, CF_STREAM_CHANGED); switch_core_session_rwunlock(other_session); } @@ -4752,7 +4752,7 @@ static void switch_core_media_set_rmode(switch_core_session_t *session, switch_m if (switch_core_session_get_partner(session, &other_session) == SWITCH_STATUS_SUCCESS) { - if (sdp_type == SDP_TYPE_RESPONSE && (switch_channel_test_flag(other_session->channel, CF_REINVITE) || switch_channel_direction(session->channel) == SWITCH_CALL_DIRECTION_OUTBOUND)) { + if (sdp_type == SDP_ANSWER && (switch_channel_test_flag(other_session->channel, CF_REINVITE) || switch_channel_direction(session->channel) == SWITCH_CALL_DIRECTION_OUTBOUND)) { switch_core_media_set_smode(other_session, type, rmode, sdp_type); } @@ -5099,7 +5099,7 @@ SWITCH_DECLARE(uint8_t) switch_core_media_negotiate_sdp(switch_core_session_t *s switch_channel_clear_app_flag_key("T38", session->channel, CF_APP_T38); switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "%s T38 REFUSE on %s\n", switch_channel_get_name(channel), - sdp_type == SDP_TYPE_RESPONSE ? "response" : "request"); + sdp_type == SDP_ANSWER ? "response" : "request"); restore_pmaps(a_engine); fmatch = 0; @@ -5112,7 +5112,7 @@ SWITCH_DECLARE(uint8_t) switch_core_media_negotiate_sdp(switch_core_session_t *s switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "%s T38 ACCEPT on %s\n", switch_channel_get_name(channel), - sdp_type == SDP_TYPE_RESPONSE ? "response" : "request"); + sdp_type == SDP_ANSWER ? "response" : "request"); if (switch_channel_test_app_flag_key("T38", session->channel, CF_APP_T38)) { if (proceed) *proceed = 0; @@ -5217,7 +5217,7 @@ SWITCH_DECLARE(uint8_t) switch_core_media_negotiate_sdp(switch_core_session_t *s switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "%s T38 %s POSSIBLE on %s\n", switch_channel_get_name(channel), fmatch ? "IS" : "IS NOT", - sdp_type == SDP_TYPE_RESPONSE ? "response" : "request"); + sdp_type == SDP_ANSWER ? "response" : "request"); goto done; @@ -5249,7 +5249,7 @@ SWITCH_DECLARE(uint8_t) switch_core_media_negotiate_sdp(switch_core_session_t *s switch_core_media_set_rmode(smh->session, SWITCH_MEDIA_TYPE_AUDIO, sdp_media_flow(m->m_mode), sdp_type); - if (sdp_type == SDP_TYPE_REQUEST) { + if (sdp_type == SDP_OFFER) { switch(a_engine->rmode) { case SWITCH_MEDIA_FLOW_RECVONLY: switch_core_media_set_smode(smh->session, SWITCH_MEDIA_TYPE_AUDIO, SWITCH_MEDIA_FLOW_SENDONLY, sdp_type); @@ -5315,7 +5315,7 @@ SWITCH_DECLARE(uint8_t) switch_core_media_negotiate_sdp(switch_core_session_t *s switch_channel_set_variable(session->channel, "media_audio_mode", NULL); } - if (sdp_type == SDP_TYPE_RESPONSE) { + if (sdp_type == SDP_ANSWER) { if (inactive) { // When freeswitch had previously sent inactive in sip request. it should remain inactive otherwise smode should be sendrecv if (a_engine->smode==SWITCH_MEDIA_FLOW_INACTIVE) { @@ -5834,7 +5834,7 @@ SWITCH_DECLARE(uint8_t) switch_core_media_negotiate_sdp(switch_core_session_t *s if (smh->mparams->dtmf_type == DTMF_AUTO || smh->mparams->dtmf_type == DTMF_2833 || switch_channel_test_flag(session->channel, CF_LIBERAL_DTMF)) { - if (sdp_type == SDP_TYPE_REQUEST) { + if (sdp_type == SDP_OFFER) { smh->mparams->te = smh->mparams->recv_te = (switch_payload_t) best_te; switch_channel_set_variable(session->channel, "dtmf_type", "rfc2833"); smh->mparams->dtmf_type = DTMF_2833; @@ -5902,7 +5902,7 @@ SWITCH_DECLARE(uint8_t) switch_core_media_negotiate_sdp(switch_core_session_t *s map->rm_encoding, NULL, NULL, - SDP_TYPE_REQUEST, + SDP_OFFER, map->rm_pt, 1000, 0, @@ -5980,7 +5980,7 @@ SWITCH_DECLARE(uint8_t) switch_core_media_negotiate_sdp(switch_core_session_t *s switch_core_media_set_rmode(smh->session, SWITCH_MEDIA_TYPE_VIDEO, sdp_media_flow(m->m_mode), sdp_type); - if (sdp_type == SDP_TYPE_REQUEST) { + if (sdp_type == SDP_OFFER) { sdp_bandwidth_t *bw; int tias = 0; @@ -6146,7 +6146,7 @@ SWITCH_DECLARE(uint8_t) switch_core_media_negotiate_sdp(switch_core_session_t *s vmatch = strcasecmp(rm_encoding, imp->iananame) ? 0 : 1; } - if (sdp_type == SDP_TYPE_RESPONSE && consider_video_fmtp && vmatch && !zstr(map->rm_fmtp) && !zstr(smh->fmtps[i])) { + if (sdp_type == SDP_ANSWER && consider_video_fmtp && vmatch && !zstr(map->rm_fmtp) && !zstr(smh->fmtps[i])) { almost_vmatch = 1; vmatch = !strcasecmp(smh->fmtps[i], map->rm_fmtp); } @@ -6321,7 +6321,7 @@ SWITCH_DECLARE(uint8_t) switch_core_media_negotiate_sdp(switch_core_session_t *s "L16", NULL, NULL, - SDP_TYPE_REQUEST, + SDP_OFFER, 97, 8000, 20, @@ -6378,7 +6378,7 @@ SWITCH_DECLARE(uint8_t) switch_core_media_negotiate_sdp(switch_core_session_t *s if (switch_channel_test_flag(channel, CF_VIDEO) && !saw_video) { //switch_core_media_set_rmode(smh->session, SWITCH_MEDIA_TYPE_VIDEO, SWITCH_MEDIA_FLOW_INACTIVE, sdp_type); - if (sdp_type == SDP_TYPE_REQUEST) { + if (sdp_type == SDP_OFFER) { switch_core_media_set_smode(smh->session, SWITCH_MEDIA_TYPE_VIDEO, SWITCH_MEDIA_FLOW_INACTIVE, sdp_type); } } @@ -9708,7 +9708,7 @@ static const char *get_media_profile_name(switch_core_session_t *session, int se static char *get_setup(switch_rtp_engine_t *engine, switch_core_session_t *session, switch_sdp_type_t sdp_type) { - if (sdp_type == SDP_TYPE_REQUEST) { + if (sdp_type == SDP_OFFER) { engine->dtls_controller = 0; engine->new_dtls = 1; engine->new_ice = 1; @@ -9809,7 +9809,7 @@ static void generate_m(switch_core_session_t *session, char *buf, size_t buflen, } if (smh->mparams->dtmf_type == DTMF_2833 && smh->mparams->te > 95) { - if (sdp_type == SDP_TYPE_RESPONSE) { + if (sdp_type == SDP_ANSWER) { switch_rtp_engine_t *a_engine = &smh->engines[SWITCH_MEDIA_TYPE_AUDIO]; if (a_engine) { payload_map_t *pmap; @@ -9915,7 +9915,7 @@ static void generate_m(switch_core_session_t *session, char *buf, size_t buflen, if ((smh->mparams->dtmf_type == DTMF_2833 || switch_channel_test_flag(session->channel, CF_LIBERAL_DTMF)) && smh->mparams->te > 95) { - if (smh->mparams->dtmf_type == DTMF_2833 && sdp_type == SDP_TYPE_RESPONSE) { + if (smh->mparams->dtmf_type == DTMF_2833 && sdp_type == SDP_ANSWER) { switch_rtp_engine_t *a_engine = &smh->engines[SWITCH_MEDIA_TYPE_AUDIO]; if (a_engine) { payload_map_t *pmap; @@ -10264,7 +10264,7 @@ SWITCH_DECLARE(void) switch_core_media_gen_local_sdp(switch_core_session_t *sess v_engine->rtcp_mux = -1; } - if ((a_engine->rtcp_mux != -1 && v_engine->rtcp_mux != -1) && (sdp_type == SDP_TYPE_REQUEST)) { + if ((a_engine->rtcp_mux != -1 && v_engine->rtcp_mux != -1) && (sdp_type == SDP_OFFER)) { a_engine->rtcp_mux = 1; v_engine->rtcp_mux = 1; } @@ -10347,7 +10347,7 @@ SWITCH_DECLARE(void) switch_core_media_gen_local_sdp(switch_core_session_t *sess continue; } - if (sdp_type == SDP_TYPE_REQUEST) { + if (sdp_type == SDP_OFFER) { for (j = 0; j < SWITCH_MAX_CODECS; j++) { if (smh->rates[j] == 0) { break; @@ -10365,7 +10365,7 @@ SWITCH_DECLARE(void) switch_core_media_gen_local_sdp(switch_core_session_t *sess continue; } - if (sdp_type == SDP_TYPE_REQUEST) { + if (sdp_type == SDP_OFFER) { switch_core_session_t *orig_session = NULL; switch_core_session_get_partner(session, &orig_session); @@ -11180,7 +11180,7 @@ SWITCH_DECLARE(void) switch_core_media_gen_local_sdp(switch_core_session_t *sess } } - if (sdp_type == SDP_TYPE_REQUEST) { + if (sdp_type == SDP_OFFER) { fir++; pli++; nack++; @@ -11441,7 +11441,7 @@ SWITCH_DECLARE(void) switch_core_media_gen_local_sdp(switch_core_session_t *sess // RTP TEXT - if (sdp_type == SDP_TYPE_RESPONSE && !switch_channel_test_flag(session->channel, CF_RTT)) { + if (sdp_type == SDP_ANSWER && !switch_channel_test_flag(session->channel, CF_RTT)) { if (switch_channel_test_flag(session->channel, CF_TEXT_SDP_RECVD)) { switch_channel_clear_flag(session->channel, CF_TEXT_SDP_RECVD); switch_snprintf(buf + strlen(buf), SDPBUFLEN - strlen(buf), "m=text 0 %s 19\r\n", @@ -11456,7 +11456,7 @@ SWITCH_DECLARE(void) switch_core_media_gen_local_sdp(switch_core_session_t *sess t_engine->t140_pt = 0; t_engine->red_pt = 0; - if (sdp_type == SDP_TYPE_REQUEST) { + if (sdp_type == SDP_OFFER) { t_engine->t140_pt = 96; t_engine->red_pt = 97; @@ -11465,7 +11465,7 @@ SWITCH_DECLARE(void) switch_core_media_gen_local_sdp(switch_core_session_t *sess "red", NULL, NULL, - SDP_TYPE_REQUEST, + SDP_OFFER, t_engine->red_pt, 1000, 0, @@ -11477,7 +11477,7 @@ SWITCH_DECLARE(void) switch_core_media_gen_local_sdp(switch_core_session_t *sess "t140", NULL, NULL, - SDP_TYPE_REQUEST, + SDP_OFFER, t_engine->t140_pt, 1000, 0, @@ -11978,7 +11978,7 @@ SWITCH_DECLARE(void) switch_core_media_patch_sdp(switch_core_session_t *session) "PROXY", NULL, NULL, - SDP_TYPE_RESPONSE, + SDP_ANSWER, 0, 8000, 20, @@ -12135,7 +12135,7 @@ SWITCH_DECLARE(void) switch_core_media_patch_sdp(switch_core_session_t *session) "PROXY-VID", NULL, NULL, - SDP_TYPE_RESPONSE, + SDP_ANSWER, 0, 90000, 90000, @@ -12198,7 +12198,7 @@ SWITCH_DECLARE(void) switch_core_media_patch_sdp(switch_core_session_t *session) "PROXY-TXT", NULL, NULL, - SDP_TYPE_RESPONSE, + SDP_ANSWER, 0, 90000, 90000, @@ -13099,7 +13099,7 @@ SWITCH_DECLARE(switch_status_t) switch_core_media_receive_message(switch_core_se switch_core_media_prepare_codecs(session, 1); clear_pmaps(a_engine); clear_pmaps(v_engine); - switch_core_media_gen_local_sdp(session, SDP_TYPE_REQUEST, ip, (switch_port_t)atoi(port), NULL, 1); + switch_core_media_gen_local_sdp(session, SDP_OFFER, ip, (switch_port_t)atoi(port), NULL, 1); } } @@ -13151,7 +13151,7 @@ SWITCH_DECLARE(switch_status_t) switch_core_media_receive_message(switch_core_se switch_core_media_prepare_codecs(session, SWITCH_TRUE); switch_core_media_check_video_codecs(session); - switch_core_media_gen_local_sdp(session, SDP_TYPE_REQUEST, NULL, 0, NULL, 1); + switch_core_media_gen_local_sdp(session, SDP_OFFER, NULL, 0, NULL, 1); } if (msg->numeric_arg && switch_core_session_get_partner(session, &nsession) == SWITCH_STATUS_SUCCESS) { @@ -13964,7 +13964,7 @@ SWITCH_DECLARE(void) switch_core_media_check_outgoing_proxy(switch_core_session_ "PROXY", NULL, NULL, - SDP_TYPE_RESPONSE, + SDP_ANSWER, 0, 8000, 20, @@ -13980,7 +13980,7 @@ SWITCH_DECLARE(void) switch_core_media_check_outgoing_proxy(switch_core_session_ "PROXY-VID", NULL, NULL, - SDP_TYPE_RESPONSE, + SDP_ANSWER, 0, 90000, 90000, @@ -14001,7 +14001,7 @@ SWITCH_DECLARE(void) switch_core_media_check_outgoing_proxy(switch_core_session_ "PROXY-TXT", NULL, NULL, - SDP_TYPE_RESPONSE, + SDP_ANSWER, 0, 1000, 1000, @@ -14155,7 +14155,7 @@ SWITCH_DECLARE (void) switch_core_media_recover_session(switch_core_session_t *s } } - switch_core_media_gen_local_sdp(session, SDP_TYPE_REQUEST, NULL, 0, NULL, 1); + switch_core_media_gen_local_sdp(session, SDP_OFFER, NULL, 0, NULL, 1); switch_core_media_set_video_codec(session, 1); if (switch_core_media_activate_rtp(session) != SWITCH_STATUS_SUCCESS) { diff --git a/src/switch_ivr.c b/src/switch_ivr.c index c36149c0a57..1443f989cfa 100644 --- a/src/switch_ivr.c +++ b/src/switch_ivr.c @@ -2151,7 +2151,7 @@ SWITCH_DECLARE(void) switch_ivr_check_hold(switch_core_session_t *session) msg.message_id = SWITCH_MESSAGE_INDICATE_MEDIA_RENEG; msg.from = __FILE__; - switch_core_media_set_smode(session, SWITCH_MEDIA_TYPE_AUDIO, SWITCH_MEDIA_FLOW_SENDRECV, SDP_TYPE_REQUEST); + switch_core_media_set_smode(session, SWITCH_MEDIA_TYPE_AUDIO, SWITCH_MEDIA_FLOW_SENDRECV, SDP_OFFER); switch_core_session_receive_message(session, &msg); } diff --git a/tests/unit/switch_rtp.c b/tests/unit/switch_rtp.c index 48c0f80d6bb..7d22524358a 100644 --- a/tests/unit/switch_rtp.c +++ b/tests/unit/switch_rtp.c @@ -187,7 +187,7 @@ FST_TEARDOWN_END() switch_core_media_prepare_codecs(session, SWITCH_FALSE); - match = switch_core_media_negotiate_sdp(session, r_sdp, &p, SDP_TYPE_REQUEST); + match = switch_core_media_negotiate_sdp(session, r_sdp, &p, SDP_OFFER); fst_requires(match == 1); status = switch_core_media_choose_ports(session, SWITCH_TRUE, SWITCH_FALSE); diff --git a/tests/unit/switch_rtp_pcap.c b/tests/unit/switch_rtp_pcap.c index 647e481c8e3..eb4993a616c 100644 --- a/tests/unit/switch_rtp_pcap.c +++ b/tests/unit/switch_rtp_pcap.c @@ -206,7 +206,7 @@ static switch_status_t rtp_test_start_call(switch_core_session_t **psession) return SWITCH_STATUS_FALSE; } - match = switch_core_media_negotiate_sdp(session, r_sdp, &p, SDP_TYPE_REQUEST); + match = switch_core_media_negotiate_sdp(session, r_sdp, &p, SDP_OFFER); if (match != 1) { switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "switch_core_media_negotiate_sdp() failed\n"); return SWITCH_STATUS_FALSE; From 9df3076f29a52a690ebd25b1972a8b97d55442e0 Mon Sep 17 00:00:00 2001 From: Anton Olofsson Date: Mon, 29 Jan 2024 17:05:45 +0100 Subject: [PATCH 08/56] [mod_event_socket] Check if listener is running before pushing more logs or events to its queue This fixes a possibility for MAX_MISSED to be exceeded if more logs are attempted to be pushed to the listener's queue after running kill_listener but before the listener thread gets CPU time and removes itself. On a heavily loaded system with a lot of logs in the event dispatch queue these excessive logs may prove fatal since socket_logger itself will produce logs about the full queue, resulting in a circular situation of never-ending logs. The same logic was applied to event_handler after finding the same behaviour mentioned in signalwire/freeswitch#2143. --- src/mod/event_handlers/mod_event_socket/mod_event_socket.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/mod/event_handlers/mod_event_socket/mod_event_socket.c b/src/mod/event_handlers/mod_event_socket/mod_event_socket.c index 520bd92ac7a..935f726ee15 100644 --- a/src/mod/event_handlers/mod_event_socket/mod_event_socket.c +++ b/src/mod/event_handlers/mod_event_socket/mod_event_socket.c @@ -173,7 +173,7 @@ static switch_status_t socket_logger(const switch_log_node_t *node, switch_log_l switch_status_t qstatus; switch_mutex_lock(globals.listener_mutex); for (l = listen_list.listeners; l; l = l->next) { - if (switch_test_flag(l, LFLAG_LOG) && l->level >= node->level) { + if (switch_test_flag(l, LFLAG_LOG) && l->level >= node->level && switch_test_flag(l, LFLAG_RUNNING)) { switch_log_node_t *dnode = switch_log_node_dup(node); qstatus = switch_queue_trypush(l->log_queue, dnode); if (qstatus == SWITCH_STATUS_SUCCESS) { @@ -302,7 +302,7 @@ static void event_handler(switch_event_t *event) } } - if (l->expire_time || !switch_test_flag(l, LFLAG_EVENTS)) { + if (l->expire_time || !switch_test_flag(l, LFLAG_EVENTS) || !switch_test_flag(l, LFLAG_RUNNING)) { last = l; continue; } From 647035c323369acb75fac18d13f2cf1a635ffff4 Mon Sep 17 00:00:00 2001 From: Andrey Volk Date: Mon, 5 Feb 2024 23:50:01 +0300 Subject: [PATCH 09/56] [mod_opus] Fix status returned by switch_opus_decode(). Should be SWITCH_STATUS_FALSE instead of SWITCH_STATUS_NOOP. Add a unit-test. --- Freeswitch.2017.sln | 15 ++ src/mod/codecs/mod_opus/mod_opus.c | 2 +- tests/unit/switch_core_codec.c | 26 +++ .../unit/test_switch_core_codec.2017.vcxproj | 205 ++++++++++++++++++ 4 files changed, 247 insertions(+), 1 deletion(-) create mode 100644 tests/unit/test_switch_core_codec.2017.vcxproj diff --git a/Freeswitch.2017.sln b/Freeswitch.2017.sln index 5f3259a6e0b..0326ffac12c 100644 --- a/Freeswitch.2017.sln +++ b/Freeswitch.2017.sln @@ -554,6 +554,8 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "test_switch_core_db", "test EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "test_switch_ivr_originate", "tests\unit\test_switch_ivr_originate.2017.vcxproj", "{69A7464A-9B0D-4804-A108-835229DACF58}" EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "test_switch_core_codec", "tests\unit\test_switch_core_codec.2017.vcxproj", "{589A07E7-5DE5-49FD-A62C-27795B806AFB}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution All|Win32 = All|Win32 @@ -2516,6 +2518,18 @@ Global {69A7464A-9B0D-4804-A108-835229DACF58}.Release|Win32.Build.0 = Release|Win32 {69A7464A-9B0D-4804-A108-835229DACF58}.Release|x64.ActiveCfg = Release|x64 {69A7464A-9B0D-4804-A108-835229DACF58}.Release|x64.Build.0 = Release|x64 + {589A07E7-5DE5-49FD-A62C-27795B806AFB}.All|Win32.ActiveCfg = Debug|Win32 + {589A07E7-5DE5-49FD-A62C-27795B806AFB}.All|Win32.Build.0 = Debug|Win32 + {589A07E7-5DE5-49FD-A62C-27795B806AFB}.All|x64.ActiveCfg = Debug|x64 + {589A07E7-5DE5-49FD-A62C-27795B806AFB}.All|x64.Build.0 = Debug|x64 + {589A07E7-5DE5-49FD-A62C-27795B806AFB}.Debug|Win32.ActiveCfg = Debug|Win32 + {589A07E7-5DE5-49FD-A62C-27795B806AFB}.Debug|Win32.Build.0 = Debug|Win32 + {589A07E7-5DE5-49FD-A62C-27795B806AFB}.Debug|x64.ActiveCfg = Debug|x64 + {589A07E7-5DE5-49FD-A62C-27795B806AFB}.Debug|x64.Build.0 = Debug|x64 + {589A07E7-5DE5-49FD-A62C-27795B806AFB}.Release|Win32.ActiveCfg = Release|Win32 + {589A07E7-5DE5-49FD-A62C-27795B806AFB}.Release|Win32.Build.0 = Release|Win32 + {589A07E7-5DE5-49FD-A62C-27795B806AFB}.Release|x64.ActiveCfg = Release|x64 + {589A07E7-5DE5-49FD-A62C-27795B806AFB}.Release|x64.Build.0 = Release|x64 EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -2714,6 +2728,7 @@ Global {0B612F84-7533-4DEC-AEDD-5C9CBCF15EAC} = {31C2761D-20E0-4BF8-98B9-E32F0D8DD6E1} {580675D7-C1C9-4197-AAC5-00F64FAFDE78} = {9388C266-C3FC-468A-92EF-0CBC35941412} {69A7464A-9B0D-4804-A108-835229DACF58} = {9388C266-C3FC-468A-92EF-0CBC35941412} + {589A07E7-5DE5-49FD-A62C-27795B806AFB} = {9388C266-C3FC-468A-92EF-0CBC35941412} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {09840DE7-9208-45AA-9667-1A71EE93BD1E} diff --git a/src/mod/codecs/mod_opus/mod_opus.c b/src/mod/codecs/mod_opus/mod_opus.c index a38389d031e..96933e6ea59 100644 --- a/src/mod/codecs/mod_opus/mod_opus.c +++ b/src/mod/codecs/mod_opus/mod_opus.c @@ -930,7 +930,7 @@ static switch_status_t switch_opus_decode(switch_codec_t *codec, if (samples < 0) { switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Decoder Error: %s fs:%u plc:%s!\n", opus_strerror(samples), frame_size, plc ? "true" : "false"); - return SWITCH_STATUS_NOOP; + return SWITCH_STATUS_FALSE; } *decoded_data_len = samples * 2 * (!context->codec_settings.sprop_stereo ? codec->implementation->number_of_channels : 2); diff --git a/tests/unit/switch_core_codec.c b/tests/unit/switch_core_codec.c index 61a70314a4d..2c499e13140 100644 --- a/tests/unit/switch_core_codec.c +++ b/tests/unit/switch_core_codec.c @@ -127,6 +127,32 @@ FST_CORE_BEGIN("./conf") } FST_TEST_END() + + FST_TEST_BEGIN(test_mod_opus_switch_status_false) + { + signed char outbuf[SWITCH_RECOMMENDED_BUFFER_SIZE] = { 0 }; + uint32_t decoded_len = 0; + uint32_t decoded_rate = 48000; + unsigned int flags = 0; + switch_codec_t orig_codec = { 0 }; + switch_status_t status; + switch_codec_settings_t codec_settings = { { 0 } }; + status = switch_core_codec_init(&orig_codec, + "OPUS", + "mod_opus", + NULL, + 48000, + 20, + 1, SWITCH_CODEC_FLAG_ENCODE | SWITCH_CODEC_FLAG_DECODE, + &codec_settings, fst_pool); + fst_check(status == SWITCH_STATUS_SUCCESS); + + status = switch_core_codec_decode(&orig_codec, NULL, "test", 5, 48000, outbuf, &decoded_len, &decoded_rate, &flags); + fst_check_int_equals(status, SWITCH_STATUS_FALSE); + switch_core_codec_destroy(&orig_codec); + } + FST_TEST_END() + } FST_SUITE_END() } diff --git a/tests/unit/test_switch_core_codec.2017.vcxproj b/tests/unit/test_switch_core_codec.2017.vcxproj new file mode 100644 index 00000000000..1434d80475d --- /dev/null +++ b/tests/unit/test_switch_core_codec.2017.vcxproj @@ -0,0 +1,205 @@ + + + + + Debug + Win32 + + + Debug + x64 + + + Release + Win32 + + + Release + x64 + + + + test_switch_core_codec + test_switch_core_codec + Win32Proj + 10.0.17134.0 + {589A07E7-5DE5-49FD-A62C-27795B806AFB} + + + + Application + MultiByte + $(DefaultPlatformToolset) + + + Application + MultiByte + $(DefaultPlatformToolset) + + + Application + MultiByte + $(DefaultPlatformToolset) + + + Application + MultiByte + $(DefaultPlatformToolset) + + + + + + + + + + + + + + + + + + + + + + + + <_ProjectFileVersion>10.0.30319.1 + $(SolutionDir)$(PlatformName)\$(Configuration)\ + $(PlatformName)\$(Configuration)\$(ProjectName)\ + false + $(SolutionDir)$(PlatformName)\$(Configuration)\ + $(Platform)\$(Configuration)\$(ProjectName)\ + false + $(SolutionDir)$(PlatformName)\$(Configuration)\ + $(PlatformName)\$(Configuration)\$(ProjectName)\ + false + $(SolutionDir)$(Platform)\$(Configuration)\ + $(Platform)\$(Configuration)\$(ProjectName)\ + false + + + + $(SolutionDir)src\include;%(AdditionalIncludeDirectories) + SWITCH_TEST_BASE_DIR_FOR_CONF="..\\..\\tests\\unit\\";%(PreprocessorDefinitions) + + + + + + Disabled + WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + EnableFastChecks + MultiThreadedDebugDLL + + + Level4 + ProgramDatabase + true + 6031;6340;6246;6011;6387;%(DisableSpecificWarnings) + + + $(OutDir);%(AdditionalLibraryDirectories) + true + Console + true + + + MachineX86 + + + + + + X64 + + + Disabled + WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + EnableFastChecks + MultiThreadedDebugDLL + + + Level4 + ProgramDatabase + true + 6031;6340;6246;6011;6387;%(DisableSpecificWarnings) + + + $(OutDir);%(AdditionalLibraryDirectories) + true + Console + true + + + MachineX64 + + + + + + WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + MultiThreadedDLL + + + Level4 + ProgramDatabase + 6031;6340;6246;6011;6387;%(DisableSpecificWarnings) + + + $(OutDir);%(AdditionalLibraryDirectories) + false + Console + true + true + true + + + MachineX86 + + + + + + X64 + + + WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + MultiThreadedDLL + + + Level4 + ProgramDatabase + 6031;6340;6246;6011;6387;%(DisableSpecificWarnings) + + + $(OutDir);%(AdditionalLibraryDirectories) + false + Console + true + true + true + + + MachineX64 + + + + + + + + {202d7a4e-760d-4d0e-afa1-d7459ced30ff} + false + + + + + + \ No newline at end of file From eb5476ff6659035f3bd180354f37968797a4a557 Mon Sep 17 00:00:00 2001 From: s3rj1k Date: Thu, 15 Feb 2024 18:51:46 +0100 Subject: [PATCH 10/56] [build] Split `create_dsc` and `create-orig` functions in `util.sh`. --- debian/util.sh | 140 ++++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 114 insertions(+), 26 deletions(-) diff --git a/debian/util.sh b/debian/util.sh index 110e6d87633..bc11f0bac1f 100755 --- a/debian/util.sh +++ b/debian/util.sh @@ -135,50 +135,94 @@ get_nightly_revision_human () { echo "git $(git rev-list -n1 --abbrev=7 --abbrev-commit HEAD) $(date -u '+%Y-%m-%d %H:%M:%SZ')" } -create_orig () { +prep_create_orig () { { set -e + local OPTIND OPTARG - local uver="" hrev="" bundle_deps=true modules_list="" zl=9e + local uver="" hrev="" bundle_deps=true + while getopts 'bm:nv:z:' o "$@"; do case "$o" in - m) modules_list="$OPTARG";; + b) ;; + m) ;; n) uver="nightly";; v) uver="$OPTARG";; - z) zl="$OPTARG";; + z) ;; esac done shift $(($OPTIND-1)) + if [ -z "$uver" ] || [ "$uver" = "nightly" ]; then uver="$(get_nightly_version)" hrev="$(get_nightly_revision_human)" fi - local treeish="$1" dver="$(mk_dver "$uver")" - local orig="../freeswitch_$dver~$(lsb_release -sc).orig.tar.xz" + + local treeish="$1" [ -n "$treeish" ] || treeish="HEAD" + check_repo_clean git reset --hard "$treeish" + + if $bundle_deps; then + (cd libs && getlibs) + fi + + ./build/set-fs-version.sh "$uver" "$hrev" # ToDo: Handle empty $hrev + + echo "$uver" > .version + } 1>&2 + echo "$uver" +} + +create_orig () { + { + set -e + + local OPTIND OPTARG + local bundle_deps=true modules_list="" zl=9e + + local uver="$(prep_create_orig "$@")" + + while getopts 'bm:nv:z:' o "$@"; do + case "$o" in + b) ;; + m) modules_list="$OPTARG";; + n) ;; + v) ;; + z) zl="$OPTARG";; + esac + done + shift $(($OPTIND-1)) + + local dver="$(mk_dver "$uver")" + local orig="../freeswitch_$dver~$(lsb_release -sc).orig.tar.xz" + mv .gitattributes .gitattributes.orig + local -a args=(-e '\bdebian-ignore\b') test "$modules_list" = "non-dfsg" || args+=(-e '\bdfsg-nonfree\b') grep .gitattributes.orig "${args[@]}" \ | while xread l; do echo "$l export-ignore" >> .gitattributes done + if $bundle_deps; then - (cd libs && getlibs) git add -f libs fi - ./build/set-fs-version.sh "$uver" "$hrev" && git add configure.ac - echo "$uver" > .version && git add -f .version + + git add -f configure.ac .version git commit --allow-empty -m "nightly v$uver" + git archive -v \ --worktree-attributes \ --format=tar \ --prefix=freeswitch-$uver/ \ HEAD \ | xz -c -${zl}v > $orig + mv .gitattributes.orig .gitattributes + git reset --hard HEAD^ && git clean -fdx } 1>&2 echo $orig @@ -190,11 +234,12 @@ applications/mod_commands EOF } -create_dsc () { +prep_create_dsc () { { set -e - local OPTIND OPTARG modules_conf="" modules_list="" speed="normal" suite_postfix="" suite_postfix_p=false zl=9 - local modules_add="" + + local OPTIND OPTARG modules_conf="" modules_add="" modules_list="" speed="normal" + while getopts 'a:f:m:p:s:u:z:' o "$@"; do case "$o" in a) avoid_mods_arch="$OPTARG";; @@ -202,46 +247,87 @@ create_dsc () { m) modules_list="$OPTARG";; p) modules_add="$modules_add $OPTARG";; s) speed="$OPTARG";; - u) suite_postfix="$OPTARG"; suite_postfix_p=true;; - z) zl="$OPTARG";; + u) ;; + z) ;; esac done shift $(($OPTIND-1)) - local distro="$(find_distro $1)" orig="$2" - local suite="$(find_suite $distro)" - local orig_ver="$(echo "$orig" | sed -e 's/^.*_//' -e 's/\.orig\.tar.*$//')" - local dver="${orig_ver}-1~${distro}+1" - $suite_postfix_p && { suite="${distro}${suite_postfix}"; } - [ -x "$(which dch)" ] \ - || err "package devscripts isn't installed" + + local distro="$(find_distro $1)" + if [ -n "$modules_conf" ]; then cp $modules_conf debian/modules.conf fi + local bootstrap_args="" + if [ -n "$modules_list" ]; then if [ "$modules_list" = "non-dfsg" ]; then bootstrap_args="-mnon-dfsg" - else set_modules_${modules_list}; fi + else + set_modules_${modules_list} + fi fi + if test -n "$modules_add"; then for x in $modules_add; do bootstrap_args="$bootstrap_args -p${x}" done fi + (cd debian && ./bootstrap.sh -a "$avoid_mods_arch" -c $distro $bootstrap_args) + case "$speed" in paranoid) sed -i ./debian/rules \ -e '/\.stamp-bootstrap:/{:l2 n; /\.\/bootstrap.sh -j/{s/ -j//; :l3 n; b l3}; b l2};' ;; reckless) sed -i ./debian/rules \ -e '/\.stamp-build:/{:l2 n; /make/{s/$/ -j/; :l3 n; b l3}; b l2};' ;; esac + } 1>&2 +} + +create_dsc () { + { + set -e + + prep_create_dsc "$@" + + local OPTIND OPTARG suite_postfix="" suite_postfix_p=false zl=9 + + while getopts 'a:f:m:p:s:u:z:' o "$@"; do + case "$o" in + a) ;; + f) ;; + m) ;; + p) ;; + s) ;; + u) suite_postfix="$OPTARG"; suite_postfix_p=true;; + z) zl="$OPTARG";; + esac + done + shift $(($OPTIND-1)) + + local distro="$(find_distro $1)" orig="$2" + local suite="$(find_suite $distro)" + local orig_ver="$(echo "$orig" | sed -e 's/^.*_//' -e 's/\.orig\.tar.*$//')" + local dver="${orig_ver}-1~${distro}+1" + + $suite_postfix_p && { suite="${distro}${suite_postfix}"; } + + [ -x "$(which dch)" ] \ + || err "package devscripts isn't installed" + [ "$zl" -ge "1" ] || zl=1 - git add debian/rules + dch -b -m -v "$dver" --force-distribution -D "$suite" "Nightly build." - git add debian/changelog && git commit -m "nightly v$orig_ver" + + git add debian/rules debian/changelog && git commit -m "nightly v$orig_ver" + dpkg-source -i.* -Zxz -z${zl} -b . dpkg-genchanges -S > ../$(dsc_base)_source.changes + local dsc="../$(dsc_base).dsc" + git reset --hard HEAD^ && git clean -fdx } 1>&2 echo $dsc @@ -588,7 +674,7 @@ commands: create-dbg-pkgs - create-dsc + create-dsc (same for 'prep-create-dsc') -f Build only modules listed in this file @@ -602,7 +688,7 @@ commands: Specify a custom suite postfix -z Set compression level - create-orig + create-orig (same for 'prep_create_orig') -m [ quicktest | non-dfsg ] Choose custom list of modules to build @@ -629,7 +715,9 @@ case "$cmd" in build-all) build_all "$@" ;; build-debs) build_debs "$@" ;; create-dbg-pkgs) create_dbg_pkgs ;; + prep-create-dsc) prep_create_dsc "$@" ;; create-dsc) create_dsc "$@" ;; + prep-create-orig) prep_create_orig "$@" ;; create-orig) create_orig "$@" ;; *) usage ;; esac From 70d76bcc0e9970f1d0f49d16413f3e061735d87f Mon Sep 17 00:00:00 2001 From: Andrey Volk Date: Wed, 21 Feb 2024 21:27:35 +0300 Subject: [PATCH 11/56] [Core] Remove mod_kazoo from tree --- build/modules.conf.in | 1 - build/modules.conf.most | 1 - conf/vanilla/autoload_configs/kazoo.conf.xml | 215 --- configure.ac | 1 - debian/bootstrap.sh | 2 - debian/control-modules | 6 - freeswitch.spec | 16 +- src/mod/event_handlers/mod_kazoo/Makefile.am | 37 - .../event_handlers/mod_kazoo/kazoo.conf.xml | 1275 ------------- src/mod/event_handlers/mod_kazoo/kazoo_api.c | 573 ------ src/mod/event_handlers/mod_kazoo/kazoo_cdr.c | 630 ------ .../event_handlers/mod_kazoo/kazoo_commands.c | 592 ------ .../event_handlers/mod_kazoo/kazoo_config.c | 553 ------ .../event_handlers/mod_kazoo/kazoo_config.h | 63 - .../mod_kazoo/kazoo_definitions.S | 8 - src/mod/event_handlers/mod_kazoo/kazoo_defs.h | 9 - .../event_handlers/mod_kazoo/kazoo_dptools.c | 980 ---------- src/mod/event_handlers/mod_kazoo/kazoo_ei.h | 295 --- .../mod_kazoo/kazoo_ei_config.c | 708 ------- .../event_handlers/mod_kazoo/kazoo_ei_utils.c | 1089 ----------- .../mod_kazoo/kazoo_endpoints.c | 500 ----- .../mod_kazoo/kazoo_event_stream.c | 750 -------- .../mod_kazoo/kazoo_fetch_agent.c | 803 -------- .../event_handlers/mod_kazoo/kazoo_fields.h | 203 -- .../event_handlers/mod_kazoo/kazoo_message.c | 488 ----- .../event_handlers/mod_kazoo/kazoo_message.h | 66 - src/mod/event_handlers/mod_kazoo/kazoo_node.c | 1694 ----------------- .../event_handlers/mod_kazoo/kazoo_tweaks.c | 666 ------- .../event_handlers/mod_kazoo/kazoo_tweaks.h | 32 - .../event_handlers/mod_kazoo/kazoo_utils.c | 700 ------- .../event_handlers/mod_kazoo/kazoo_utils.h | 51 - src/mod/event_handlers/mod_kazoo/kz_node.c | 91 - src/mod/event_handlers/mod_kazoo/mod_kazoo.c | 152 -- src/mod/event_handlers/mod_kazoo/mod_kazoo.h | 87 - 34 files changed, 1 insertion(+), 13336 deletions(-) delete mode 100644 conf/vanilla/autoload_configs/kazoo.conf.xml delete mode 100644 src/mod/event_handlers/mod_kazoo/Makefile.am delete mode 100644 src/mod/event_handlers/mod_kazoo/kazoo.conf.xml delete mode 100644 src/mod/event_handlers/mod_kazoo/kazoo_api.c delete mode 100644 src/mod/event_handlers/mod_kazoo/kazoo_cdr.c delete mode 100644 src/mod/event_handlers/mod_kazoo/kazoo_commands.c delete mode 100644 src/mod/event_handlers/mod_kazoo/kazoo_config.c delete mode 100644 src/mod/event_handlers/mod_kazoo/kazoo_config.h delete mode 100644 src/mod/event_handlers/mod_kazoo/kazoo_definitions.S delete mode 100644 src/mod/event_handlers/mod_kazoo/kazoo_defs.h delete mode 100644 src/mod/event_handlers/mod_kazoo/kazoo_dptools.c delete mode 100644 src/mod/event_handlers/mod_kazoo/kazoo_ei.h delete mode 100644 src/mod/event_handlers/mod_kazoo/kazoo_ei_config.c delete mode 100644 src/mod/event_handlers/mod_kazoo/kazoo_ei_utils.c delete mode 100644 src/mod/event_handlers/mod_kazoo/kazoo_endpoints.c delete mode 100644 src/mod/event_handlers/mod_kazoo/kazoo_event_stream.c delete mode 100644 src/mod/event_handlers/mod_kazoo/kazoo_fetch_agent.c delete mode 100644 src/mod/event_handlers/mod_kazoo/kazoo_fields.h delete mode 100644 src/mod/event_handlers/mod_kazoo/kazoo_message.c delete mode 100644 src/mod/event_handlers/mod_kazoo/kazoo_message.h delete mode 100644 src/mod/event_handlers/mod_kazoo/kazoo_node.c delete mode 100644 src/mod/event_handlers/mod_kazoo/kazoo_tweaks.c delete mode 100644 src/mod/event_handlers/mod_kazoo/kazoo_tweaks.h delete mode 100644 src/mod/event_handlers/mod_kazoo/kazoo_utils.c delete mode 100644 src/mod/event_handlers/mod_kazoo/kazoo_utils.h delete mode 100644 src/mod/event_handlers/mod_kazoo/kz_node.c delete mode 100644 src/mod/event_handlers/mod_kazoo/mod_kazoo.c delete mode 100644 src/mod/event_handlers/mod_kazoo/mod_kazoo.h diff --git a/build/modules.conf.in b/build/modules.conf.in index 7bf59e2accf..8453e290b70 100644 --- a/build/modules.conf.in +++ b/build/modules.conf.in @@ -110,7 +110,6 @@ event_handlers/mod_event_socket #event_handlers/mod_json_cdr #event_handlers/mod_radius_cdr #event_handlers/mod_odbc_cdr -#event_handlers/mod_kazoo #event_handlers/mod_rayo #event_handlers/mod_smpp #event_handlers/mod_snmp diff --git a/build/modules.conf.most b/build/modules.conf.most index fbf8100a90a..62595a4891d 100644 --- a/build/modules.conf.most +++ b/build/modules.conf.most @@ -104,7 +104,6 @@ event_handlers/mod_event_multicast event_handlers/mod_event_socket event_handlers/mod_format_cdr event_handlers/mod_json_cdr -event_handlers/mod_kazoo #event_handlers/mod_radius_cdr event_handlers/mod_odbc_cdr event_handlers/mod_rayo diff --git a/conf/vanilla/autoload_configs/kazoo.conf.xml b/conf/vanilla/autoload_configs/kazoo.conf.xml deleted file mode 100644 index b730523d4c2..00000000000 --- a/conf/vanilla/autoload_configs/kazoo.conf.xml +++ /dev/null @@ -1,215 +0,0 @@ - - - - - - - - - - - - - - - - - - -
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- - -
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- - -
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- - -
-
-
-
-
-
-
-
-
-
- - - diff --git a/configure.ac b/configure.ac index e4ab33ae5cc..348103f8db6 100644 --- a/configure.ac +++ b/configure.ac @@ -2208,7 +2208,6 @@ AC_CONFIG_FILES([Makefile src/mod/event_handlers/mod_fail2ban/Makefile src/mod/event_handlers/mod_format_cdr/Makefile src/mod/event_handlers/mod_json_cdr/Makefile - src/mod/event_handlers/mod_kazoo/Makefile src/mod/event_handlers/mod_radius_cdr/Makefile src/mod/event_handlers/mod_odbc_cdr/Makefile src/mod/event_handlers/mod_rayo/Makefile diff --git a/debian/bootstrap.sh b/debian/bootstrap.sh index 75a89575096..aba9e38bf70 100755 --- a/debian/bootstrap.sh +++ b/debian/bootstrap.sh @@ -673,7 +673,6 @@ Depends: \${misc:Depends}, freeswitch (= \${binary:Version}), freeswitch-mod-event-multicast (= \${binary:Version}), freeswitch-mod-event-socket (= \${binary:Version}), freeswitch-mod-json-cdr (= \${binary:Version}), - freeswitch-mod-kazoo (= \${binary:Version}), freeswitch-mod-snmp (= \${binary:Version}), freeswitch-mod-local-stream (= \${binary:Version}), freeswitch-mod-native-file (= \${binary:Version}), @@ -910,7 +909,6 @@ Depends: \${misc:Depends}, freeswitch (= \${binary:Version}), freeswitch-mod-event-multicast-dbg (= \${binary:Version}), freeswitch-mod-event-socket-dbg (= \${binary:Version}), freeswitch-mod-json-cdr-dbg (= \${binary:Version}), - freeswitch-mod-kazoo-dbg (= \${binary:Version}), freeswitch-mod-snmp-dbg (= \${binary:Version}), freeswitch-mod-local-stream-dbg (= \${binary:Version}), freeswitch-mod-native-file-dbg (= \${binary:Version}), diff --git a/debian/control-modules b/debian/control-modules index 3179f8eeefc..0f0784d3f58 100644 --- a/debian/control-modules +++ b/debian/control-modules @@ -542,12 +542,6 @@ Module: event_handlers/mod_json_cdr Description: mod_json_cdr Adds mod_json_cdr. -Module: event_handlers/mod_kazoo -Description: mod_kazoo - Adds mod_kazoo. -Build-Depends: erlang-dev -Depends: erlang - Module: event_handlers/mod_odbc_cdr Description: mod_odbc_cdr Adds mod_odbc_cdr. diff --git a/freeswitch.spec b/freeswitch.spec index 9e3d505e801..98ce36cb903 100644 --- a/freeswitch.spec +++ b/freeswitch.spec @@ -952,16 +952,6 @@ Requires: %{name} = %{version}-%{release} %description event-format-cdr JSON and XML Logger for the FreeSWITCH open source telephony platform -%package kazoo -Summary: Kazoo Module for the FreeSWITCH open source telephony platform -Group: System/Libraries -Requires: %{name} = %{version}-%{release} -Requires: erlang -BuildRequires: erlang - -%description kazoo -Kazoo Module for FreeSWITCH. - %package event-multicast Summary: Multicast Event System for the FreeSWITCH open source telephony platform Group: System/Libraries @@ -1480,7 +1470,7 @@ ENDPOINTS_MODULES=" \ ###################################################################################################################### EVENT_HANDLERS_MODULES="event_handlers/mod_cdr_csv event_handlers/mod_cdr_pg_csv event_handlers/mod_cdr_sqlite \ event_handlers/mod_cdr_mongodb event_handlers/mod_format_cdr event_handlers/mod_erlang_event event_handlers/mod_event_multicast \ - event_handlers/mod_event_socket event_handlers/mod_json_cdr event_handlers/mod_kazoo event_handlers/mod_radius_cdr \ + event_handlers/mod_event_socket event_handlers/mod_json_cdr event_handlers/mod_radius_cdr \ event_handlers/mod_snmp" %if %{build_mod_rayo} EVENT_HANDLERS_MODULES+=" event_handlers/mod_rayo" @@ -1916,7 +1906,6 @@ fi %config(noreplace) %attr(0640, freeswitch, daemon) %{sysconfdir}/autoload_configs/http_cache.conf.xml %config(noreplace) %attr(0640, freeswitch, daemon) %{sysconfdir}/autoload_configs/ivr.conf.xml %config(noreplace) %attr(0640, freeswitch, daemon) %{sysconfdir}/autoload_configs/java.conf.xml -%config(noreplace) %attr(0640, freeswitch, daemon) %{sysconfdir}/autoload_configs/kazoo.conf.xml %config(noreplace) %attr(0640, freeswitch, daemon) %{sysconfdir}/autoload_configs/lcr.conf.xml %config(noreplace) %attr(0640, freeswitch, daemon) %{sysconfdir}/autoload_configs/local_stream.conf.xml %config(noreplace) %attr(0640, freeswitch, daemon) %{sysconfdir}/autoload_configs/logfile.conf.xml @@ -2286,9 +2275,6 @@ fi %files event-json-cdr %{MODINSTDIR}/mod_json_cdr.so* -%files kazoo -%{MODINSTDIR}/mod_kazoo.so* - %files event-radius-cdr %{MODINSTDIR}/mod_radius_cdr.so* diff --git a/src/mod/event_handlers/mod_kazoo/Makefile.am b/src/mod/event_handlers/mod_kazoo/Makefile.am deleted file mode 100644 index 36e7a9ea4a4..00000000000 --- a/src/mod/event_handlers/mod_kazoo/Makefile.am +++ /dev/null @@ -1,37 +0,0 @@ -include $(top_srcdir)/build/modmake.rulesam -MODNAME=mod_kazoo - -if HAVE_ERLANG - -KAZOO_DEFS=kazoo_definitions.o - -mod_LTLIBRARIES = mod_kazoo.la -mod_kazoo_la_SOURCES = mod_kazoo.c kazoo_utils.c kazoo_dptools.c kazoo_tweaks.c -mod_kazoo_la_SOURCES += kazoo_api.c kazoo_commands.c kazoo_config.c -mod_kazoo_la_SOURCES += kazoo_message.c -mod_kazoo_la_SOURCES += kazoo_ei_config.c kazoo_ei_utils.c kazoo_event_stream.c -mod_kazoo_la_SOURCES += kazoo_fetch_agent.c kazoo_node.c -mod_kazoo_la_SOURCES += kazoo_endpoints.c -mod_kazoo_la_SOURCES += kazoo_cdr.c -mod_kazoo_la_SOURCES += kz_node.c - -mod_kazoo_la_CFLAGS = $(AM_CFLAGS) @ERLANG_CFLAGS@ -D_REENTRANT -DERLANG_VERSION=@ERLANG_VERSION@ -DERLANG_MAJOR=@ERLANG_MAJOR@ -DERLANG_MINOR=@ERLANG_MINOR@ -mod_kazoo_la_LIBADD = $(KAZOO_DEFS) $(switch_builddir)/libfreeswitch.la -mod_kazoo_la_LDFLAGS = -avoid-version -module -no-undefined -shared @ERLANG_LDFLAGS@ - -BUILT_SOURCES = $(KAZOO_DEFS) - -$(KAZOO_DEFS): kazoo.conf.xml - -.S.o: $< - @$(CC) $(CFLAGS) -o $@ -c $< - -install-exec-am: - @install `which epmd` $(DESTDIR)$(bindir)/fs_epmd - -else -install: error -all: error -error: - $(error You must install erlang to build this module) -endif diff --git a/src/mod/event_handlers/mod_kazoo/kazoo.conf.xml b/src/mod/event_handlers/mod_kazoo/kazoo.conf.xml deleted file mode 100644 index 4422af121ba..00000000000 --- a/src/mod/event_handlers/mod_kazoo/kazoo.conf.xml +++ /dev/null @@ -1,1275 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/mod/event_handlers/mod_kazoo/kazoo_api.c b/src/mod/event_handlers/mod_kazoo/kazoo_api.c deleted file mode 100644 index 96f9ff7bb43..00000000000 --- a/src/mod/event_handlers/mod_kazoo/kazoo_api.c +++ /dev/null @@ -1,573 +0,0 @@ -/* - * FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application - * Copyright (C) 2005-2012, Anthony Minessale II - * - * 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 - * Portions created by the Initial Developer are Copyright (C) - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * - * Karl Anderson - * Darren Schreiber - * - * - * mod_kazoo.c -- Socket Controlled Event Handler - * - */ -#include "mod_kazoo.h" - -#define KAZOO_DESC "kazoo information" -#define KAZOO_SYNTAX " []" - -#define API_COMMAND_DISCONNECT 0 -#define API_COMMAND_REMOTE_IP 1 -#define API_COMMAND_STREAMS 2 -#define API_COMMAND_BINDINGS 3 -#define API_COMMAND_OPTION 4 - -#define API_NODE_OPTION_FRAMING 0 -#define API_NODE_OPTION_KEEPALIVE 1 -#define API_NODE_OPTION_LEGACY 2 -#define API_NODE_OPTION_MAX 99 - -static const char *node_runtime_options[] = { - "event-stream-framing", - "event-stream-keepalive", - "enable-legacy", - NULL -}; - -static int api_find_node_option(char *option) { - int i; - for(i = 0; node_runtime_options[i] != NULL; i++) { - if(!strcasecmp(option, node_runtime_options[i])) { - return i; - } - } - return API_NODE_OPTION_MAX; -} - -static switch_status_t api_get_node_option(ei_node_t *ei_node, switch_stream_handle_t *stream, char *arg) { - int option = api_find_node_option(arg); - switch_status_t ret = SWITCH_STATUS_SUCCESS; - switch (option) { - case API_NODE_OPTION_FRAMING: - stream->write_function(stream, "+OK %i", ei_node->event_stream_framing); - break; - - case API_NODE_OPTION_KEEPALIVE: - stream->write_function(stream, "+OK %i", ei_node->event_stream_keepalive); - break; - - case API_NODE_OPTION_LEGACY: - stream->write_function(stream, "+OK %s", ei_node->legacy ? "true" : "false"); - break; - - default: - stream->write_function(stream, "-ERR invalid option %s", arg); - ret = SWITCH_STATUS_NOTFOUND; - break; - } - - return ret; -} - -static switch_status_t api_set_node_option(ei_node_t *ei_node, switch_stream_handle_t *stream, char *name, char *value) { - int option = api_find_node_option(name); - short val; - switch_status_t ret = SWITCH_STATUS_SUCCESS; - switch (option) { - case API_NODE_OPTION_FRAMING: - val = atoi(value); - if (val != 1 && val != 2 && val != 4) { - stream->write_function(stream, "-ERR Invalid event stream framing value (%i)", val); - ret = SWITCH_STATUS_GENERR; - } else { - stream->write_function(stream, "+OK %i", val); - ei_node->event_stream_framing = val; - } - break; - - case API_NODE_OPTION_KEEPALIVE: - val = switch_true(value); - stream->write_function(stream, "+OK %i", val); - ei_node->event_stream_keepalive = val; - break; - - case API_NODE_OPTION_LEGACY: - ei_node->legacy = switch_true(value); - stream->write_function(stream, "+OK %s", ei_node->legacy ? "true" : "false"); - break; - - default: - stream->write_function(stream, "-ERR invalid option %s", name); - ret = SWITCH_STATUS_NOTFOUND; - break; - } - - return ret; -} - -static switch_status_t api_erlang_status(switch_stream_handle_t *stream) { - switch_sockaddr_t *sa; - uint16_t port; - char ipbuf[48]; - const char *ip_addr; - ei_node_t *ei_node; - - switch_socket_addr_get(&sa, SWITCH_FALSE, kazoo_globals.acceptor); - - port = switch_sockaddr_get_port(sa); - ip_addr = switch_get_addr(ipbuf, sizeof (ipbuf), sa); - - stream->write_function(stream, "Running %s\n", VERSION); - stream->write_function(stream, "Listening for new Erlang connections on %s:%u with cookie %s\n", ip_addr, port, kazoo_globals.ei_cookie); - stream->write_function(stream, "Registered as Erlang node %s, visible as %s\n", kazoo_globals.ei_cnode.thisnodename, kazoo_globals.ei_cnode.thisalivename); - - if (kazoo_globals.ei_compat_rel) { - stream->write_function(stream, "Using Erlang compatibility mode: %d\n", kazoo_globals.ei_compat_rel); - } - - switch_thread_rwlock_rdlock(kazoo_globals.ei_nodes_lock); - ei_node = kazoo_globals.ei_nodes; - if (!ei_node) { - stream->write_function(stream, "No erlang nodes connected\n"); - } else { - stream->write_function(stream, "Connected to:\n"); - while(ei_node != NULL) { - unsigned int year, day, hour, min, sec, delta; - - delta = (switch_micro_time_now() - ei_node->created_time) / 1000000; - sec = delta % 60; - min = delta / 60 % 60; - hour = delta / 3600 % 24; - day = delta / 86400 % 7; - year = delta / 31556926 % 12; - stream->write_function(stream, " %s (%s:%d) up %d years, %d days, %d hours, %d minutes, %d seconds\n" - ,ei_node->peer_nodename, ei_node->remote_ip, ei_node->remote_port, year, day, hour, min, sec); - ei_node = ei_node->next; - } - } - switch_thread_rwlock_unlock(kazoo_globals.ei_nodes_lock); - - return SWITCH_STATUS_SUCCESS; -} - -static switch_status_t api_erlang_event_filter(switch_stream_handle_t *stream) { - switch_hash_index_t *hi = NULL; - int column = 0; - int idx = 0; - - for (hi = (switch_hash_index_t *)switch_core_hash_first_iter(kazoo_globals.event_filter, hi); hi; hi = switch_core_hash_next(&hi)) { - const void *key; - void *val; - switch_core_hash_this(hi, &key, NULL, &val); - stream->write_function(stream, "%-50s", (char *)key); - if (++column > 2) { - stream->write_function(stream, "\n"); - column = 0; - } - } - - if (++column > 2) { - stream->write_function(stream, "\n"); - } - - while(kazoo_globals.kazoo_var_prefixes[idx] != NULL) { - char var[100]; - char *prefix = kazoo_globals.kazoo_var_prefixes[idx]; - sprintf(var, "%s*", prefix); - stream->write_function(stream, "%-50s", var); - idx++; - } - - - return SWITCH_STATUS_SUCCESS; -} - -static switch_status_t api_erlang_nodes_list(switch_stream_handle_t *stream) { - ei_node_t *ei_node; - - switch_thread_rwlock_rdlock(kazoo_globals.ei_nodes_lock); - ei_node = kazoo_globals.ei_nodes; - while(ei_node != NULL) { - stream->write_function(stream, "%s (%s)\n", ei_node->peer_nodename, ei_node->remote_ip); - ei_node = ei_node->next; - } - switch_thread_rwlock_unlock(kazoo_globals.ei_nodes_lock); - - return SWITCH_STATUS_SUCCESS; -} - -static switch_status_t api_erlang_nodes_count(switch_stream_handle_t *stream) { - ei_node_t *ei_node; - int count = 0; - - switch_thread_rwlock_rdlock(kazoo_globals.ei_nodes_lock); - ei_node = kazoo_globals.ei_nodes; - while(ei_node != NULL) { - count++; - ei_node = ei_node->next; - } - switch_thread_rwlock_unlock(kazoo_globals.ei_nodes_lock); - - stream->write_function(stream, "%d\n", count); - - return SWITCH_STATUS_SUCCESS; -} - -static switch_status_t api_complete_erlang_node(const char *line, const char *cursor, switch_console_callback_match_t **matches) { - switch_console_callback_match_t *my_matches = NULL; - switch_status_t status = SWITCH_STATUS_FALSE; - ei_node_t *ei_node; - - switch_thread_rwlock_rdlock(kazoo_globals.ei_nodes_lock); - ei_node = kazoo_globals.ei_nodes; - while(ei_node != NULL) { - switch_console_push_match(&my_matches, ei_node->peer_nodename); - ei_node = ei_node->next; - } - switch_thread_rwlock_unlock(kazoo_globals.ei_nodes_lock); - - if (my_matches) { - *matches = my_matches; - status = SWITCH_STATUS_SUCCESS; - } - - return status; -} - -static switch_status_t handle_node_api_event_stream(ei_event_stream_t *event_stream, switch_stream_handle_t *stream) { - ei_event_binding_t *binding; - int column = 0; - - switch_mutex_lock(event_stream->socket_mutex); - if (event_stream->connected == SWITCH_FALSE) { - switch_sockaddr_t *sa; - uint16_t port; - char ipbuf[48] = {0}; - const char *ip_addr; - - switch_socket_addr_get(&sa, SWITCH_TRUE, event_stream->acceptor); - port = switch_sockaddr_get_port(sa); - ip_addr = switch_get_addr(ipbuf, sizeof (ipbuf), sa); - - if (zstr(ip_addr)) { - ip_addr = kazoo_globals.ip; - } - - stream->write_function(stream, "%s:%d -> disconnected\n" - ,ip_addr, port); - } else { - unsigned int year, day, hour, min, sec, delta; - - delta = (switch_micro_time_now() - event_stream->connected_time) / 1000000; - sec = delta % 60; - min = delta / 60 % 60; - hour = delta / 3600 % 24; - day = delta / 86400 % 7; - year = delta / 31556926 % 12; - - stream->write_function(stream, "%s:%d -> %s:%d for %d years, %d days, %d hours, %d minutes, %d seconds\n" - ,event_stream->local_ip, event_stream->local_port - ,event_stream->remote_ip, event_stream->remote_port - ,year, day, hour, min, sec); - } - - binding = event_stream->bindings; - while(binding != NULL) { - if (binding->type == SWITCH_EVENT_CUSTOM) { - stream->write_function(stream, "CUSTOM %-43s", binding->subclass_name); - } else { - stream->write_function(stream, "%-50s", switch_event_name(binding->type)); - } - - if (++column > 2) { - stream->write_function(stream, "\n"); - column = 0; - } - - binding = binding->next; - } - switch_mutex_unlock(event_stream->socket_mutex); - - if (!column) { - stream->write_function(stream, "\n"); - } else { - stream->write_function(stream, "\n\n"); - } - - return SWITCH_STATUS_SUCCESS; -} - -static switch_status_t handle_node_api_event_streams(ei_node_t *ei_node, switch_stream_handle_t *stream) { - ei_event_stream_t *event_stream; - - switch_mutex_lock(ei_node->event_streams_mutex); - event_stream = ei_node->event_streams; - while(event_stream != NULL) { - handle_node_api_event_stream(event_stream, stream); - event_stream = event_stream->next; - } - switch_mutex_unlock(ei_node->event_streams_mutex); - - return SWITCH_STATUS_SUCCESS; -} - -static switch_status_t handle_node_api_command(ei_node_t *ei_node, switch_stream_handle_t *stream, uint32_t command) { - unsigned int year, day, hour, min, sec, delta; - - switch (command) { - case API_COMMAND_DISCONNECT: - stream->write_function(stream, "Disconnecting erlang node %s at managers request\n", ei_node->peer_nodename); - switch_clear_flag(ei_node, LFLAG_RUNNING); - break; - case API_COMMAND_REMOTE_IP: - delta = (switch_micro_time_now() - ei_node->created_time) / 1000000; - sec = delta % 60; - min = delta / 60 % 60; - hour = delta / 3600 % 24; - day = delta / 86400 % 7; - year = delta / 31556926 % 12; - - stream->write_function(stream, "Uptime %d years, %d days, %d hours, %d minutes, %d seconds\n", year, day, hour, min, sec); - stream->write_function(stream, "Local Address %s:%d\n", ei_node->local_ip, ei_node->local_port); - stream->write_function(stream, "Remote Address %s:%d\n", ei_node->remote_ip, ei_node->remote_port); - break; - case API_COMMAND_STREAMS: - handle_node_api_event_streams(ei_node, stream); - break; - case API_COMMAND_BINDINGS: - handle_api_command_streams(ei_node, stream); - break; - default: - break; - } - - return SWITCH_STATUS_SUCCESS; -} - -static switch_status_t api_erlang_node_command(switch_stream_handle_t *stream, const char *nodename, uint32_t command) { - ei_node_t *ei_node; - - switch_thread_rwlock_rdlock(kazoo_globals.ei_nodes_lock); - ei_node = kazoo_globals.ei_nodes; - while(ei_node != NULL) { - int length = strlen(ei_node->peer_nodename); - - if (!strncmp(ei_node->peer_nodename, nodename, length)) { - handle_node_api_command(ei_node, stream, command); - switch_thread_rwlock_unlock(kazoo_globals.ei_nodes_lock); - return SWITCH_STATUS_SUCCESS; - } - - ei_node = ei_node->next; - } - switch_thread_rwlock_unlock(kazoo_globals.ei_nodes_lock); - - return SWITCH_STATUS_NOTFOUND; -} - -static switch_status_t handle_node_api_command_arg(ei_node_t *ei_node, switch_stream_handle_t *stream, uint32_t command, char *arg) { - - switch (command) { - case API_COMMAND_OPTION: - return api_get_node_option(ei_node, stream, arg); - break; - default: - break; - } - - return SWITCH_STATUS_NOTFOUND; -} - -static switch_status_t handle_node_api_command_args(ei_node_t *ei_node, switch_stream_handle_t *stream, uint32_t command, int argc, char *argv[]) { - - switch (command) { - case API_COMMAND_OPTION: - return api_set_node_option(ei_node, stream, argv[0], argv[1]); - break; - default: - break; - } - - return SWITCH_STATUS_NOTFOUND; -} - -static switch_status_t api_erlang_node_command_arg(switch_stream_handle_t *stream, const char *nodename, uint32_t command, char *arg) { - ei_node_t *ei_node; - switch_status_t ret = SWITCH_STATUS_NOTFOUND; - - switch_thread_rwlock_rdlock(kazoo_globals.ei_nodes_lock); - ei_node = kazoo_globals.ei_nodes; - while(ei_node != NULL) { - int length = strlen(ei_node->peer_nodename); - - if (!strncmp(ei_node->peer_nodename, nodename, length)) { - ret = handle_node_api_command_arg(ei_node, stream, command, arg); - switch_thread_rwlock_unlock(kazoo_globals.ei_nodes_lock); - return ret ; - } - - ei_node = ei_node->next; - } - switch_thread_rwlock_unlock(kazoo_globals.ei_nodes_lock); - - return ret; -} - -static switch_status_t api_erlang_node_command_args(switch_stream_handle_t *stream, const char *nodename, uint32_t command, int argc, char *argv[]) { - ei_node_t *ei_node; - switch_status_t ret = SWITCH_STATUS_NOTFOUND; - - switch_thread_rwlock_rdlock(kazoo_globals.ei_nodes_lock); - ei_node = kazoo_globals.ei_nodes; - while(ei_node != NULL) { - int length = strlen(ei_node->peer_nodename); - - if (!strncmp(ei_node->peer_nodename, nodename, length)) { - ret = handle_node_api_command_args(ei_node, stream, command, argc, argv); - switch_thread_rwlock_unlock(kazoo_globals.ei_nodes_lock); - return ret; - } - - ei_node = ei_node->next; - } - switch_thread_rwlock_unlock(kazoo_globals.ei_nodes_lock); - - return ret; -} - -SWITCH_STANDARD_API(exec_api_cmd) -{ - char *argv[1024] = { 0 }; - int unknown_command = 1, argc = 0; - char *mycmd = NULL; - - const char *usage_string = "USAGE:\n" - "--------------------------------------------------------------------------------------------------------------------\n" - "erlang status - provides an overview of the current status\n" - "erlang event_filter - lists the event headers that will be sent to Erlang nodes\n" - "erlang nodes list - lists connected Erlang nodes (usefull for monitoring tools)\n" - "erlang nodes count - provides a count of connected Erlang nodes (usefull for monitoring tools)\n" - "erlang node disconnect - disconnects an Erlang node\n" - "erlang node connection - Shows the connection info\n" - "erlang node event_streams - lists the event streams for an Erlang node\n" - "erlang node fetch_bindings - lists the XML fetch bindings for an Erlang node\n" - "---------------------------------------------------------------------------------------------------------------------\n"; - - if (zstr(cmd)) { - stream->write_function(stream, "%s", usage_string); - return SWITCH_STATUS_SUCCESS; - } - - if (!(mycmd = strdup(cmd))) { - return SWITCH_STATUS_MEMERR; - } - - if (!(argc = switch_separate_string(mycmd, ' ', argv, (sizeof(argv) / sizeof(argv[0]))))) { - stream->write_function(stream, "%s", usage_string); - switch_safe_free(mycmd); - return SWITCH_STATUS_SUCCESS; - } - - if (zstr(argv[0])) { - stream->write_function(stream, "%s", usage_string); - switch_safe_free(mycmd); - return SWITCH_STATUS_SUCCESS; - } - - if (!strncmp(argv[0], "status", 7)) { - unknown_command = 0; - api_erlang_status(stream); - } else if (!strncmp(argv[0], "event_filter", 13)) { - unknown_command = 0; - api_erlang_event_filter(stream); - } else if (!strncmp(argv[0], "nodes", 6) && !zstr(argv[1])) { - if (!strncmp(argv[1], "list", 6)) { - unknown_command = 0; - api_erlang_nodes_list(stream); - } else if (!strncmp(argv[1], "count", 6)) { - unknown_command = 0; - api_erlang_nodes_count(stream); - } - } else if (!strncmp(argv[0], "node", 6) && !zstr(argv[1]) && !zstr(argv[2])) { - if (!strncmp(argv[2], "disconnect", 11)) { - unknown_command = 0; - api_erlang_node_command(stream, argv[1], API_COMMAND_DISCONNECT); - } else if (!strncmp(argv[2], "connection", 11)) { - unknown_command = 0; - api_erlang_node_command(stream, argv[1], API_COMMAND_REMOTE_IP); - } else if (!strncmp(argv[2], "event_streams", 14)) { - unknown_command = 0; - api_erlang_node_command(stream, argv[1], API_COMMAND_STREAMS); - } else if (!strncmp(argv[2], "fetch_bindings", 15)) { - unknown_command = 0; - api_erlang_node_command(stream, argv[1], API_COMMAND_BINDINGS); - } else if (!strncmp(argv[2], "option", 7) && !zstr(argv[3])) { - unknown_command = 0; - if(argc > 4 && !zstr(argv[4])) - api_erlang_node_command_args(stream, argv[1], API_COMMAND_OPTION, argc - 3, &argv[3]); - else - api_erlang_node_command_arg(stream, argv[1], API_COMMAND_OPTION, argv[3]); - } - } - - if (unknown_command) { - stream->write_function(stream, "%s", usage_string); - } - - switch_safe_free(mycmd); - return SWITCH_STATUS_SUCCESS; -} - -void add_cli_api(switch_loadable_module_interface_t **module_interface) -{ - switch_api_interface_t *api_interface = NULL; - SWITCH_ADD_API(api_interface, "erlang", KAZOO_DESC, exec_api_cmd, KAZOO_SYNTAX); - switch_console_set_complete("add erlang status"); - switch_console_set_complete("add erlang event_filter"); - switch_console_set_complete("add erlang nodes list"); - switch_console_set_complete("add erlang nodes count"); - switch_console_set_complete("add erlang node ::erlang::node disconnect"); - switch_console_set_complete("add erlang node ::erlang::node connection"); - switch_console_set_complete("add erlang node ::erlang::node event_streams"); - switch_console_set_complete("add erlang node ::erlang::node fetch_bindings"); - switch_console_add_complete_func("::erlang::node", api_complete_erlang_node); - -} - -void remove_cli_api() -{ - switch_console_set_complete("del erlang"); - switch_console_del_complete_func("::erlang::node"); - -} - - -/* For Emacs: - * Local Variables: - * mode:c - * indent-tabs-mode:t - * tab-width:4 - * c-basic-offset:4 - * End: - * For VIM: - * vim:set softtabstop=4 shiftwidth=4 tabstop=4: - */ diff --git a/src/mod/event_handlers/mod_kazoo/kazoo_cdr.c b/src/mod/event_handlers/mod_kazoo/kazoo_cdr.c deleted file mode 100644 index fef66f8be34..00000000000 --- a/src/mod/event_handlers/mod_kazoo/kazoo_cdr.c +++ /dev/null @@ -1,630 +0,0 @@ -/* - * FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application - * Copyright (C) 2005-2012, Anthony Minessale II - * - * 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 - * Portions created by the Initial Developer are Copyright (C) - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * - * Luis Azedo - * - * mod_hacks.c -- hacks with state handlers - * - */ -#include "mod_kazoo.h" - -#define MY_EVENT_JSON_CDR "KZ_CDR" - -#define maybe_add_json_string(_json, _name, _string) \ - if (!zstr(_string)) cJSON_AddItemToObject(_json, _name, cJSON_CreateString((char *)_string)) - -static void kz_switch_ivr_set_json_profile_data(cJSON *json, switch_caller_profile_t *caller_profile) -{ - cJSON *soft = NULL; - profile_node_t *pn = NULL; - - maybe_add_json_string(json, "Username", caller_profile->username); - maybe_add_json_string(json, "Dialplan", caller_profile->dialplan); - maybe_add_json_string(json, "ANI", caller_profile->ani); - maybe_add_json_string(json, "ANIII", caller_profile->aniii); - maybe_add_json_string(json, "Caller-ID-Name", caller_profile->caller_id_name); - maybe_add_json_string(json, "Caller-ID-Number", caller_profile->caller_id_number); - maybe_add_json_string(json, "Caller-ID-Original-Name", caller_profile->orig_caller_id_name); - maybe_add_json_string(json, "Caller-ID-Original-Number", caller_profile->orig_caller_id_number); - maybe_add_json_string(json, "Network-Address", caller_profile->network_addr); - maybe_add_json_string(json, "RDNIS", caller_profile->rdnis); - maybe_add_json_string(json, "Destination-Number", caller_profile->destination_number); - maybe_add_json_string(json, "Callee-ID-Name", caller_profile->callee_id_name); - maybe_add_json_string(json, "Callee-ID-Number", caller_profile->callee_id_number); - maybe_add_json_string(json, "UUID", caller_profile->uuid); - maybe_add_json_string(json, "Source", caller_profile->source); - maybe_add_json_string(json, "Context", caller_profile->context); - maybe_add_json_string(json, "Channel-Name", caller_profile->chan_name); - maybe_add_json_string(json, "Profile-UUID", caller_profile->uuid_str); - maybe_add_json_string(json, "Profile-Clone-Of", caller_profile->clone_of); - maybe_add_json_string(json, "Transfer-Source", caller_profile->transfer_source); - cJSON_AddItemToObject(json, "Direction", cJSON_CreateString(caller_profile->direction == SWITCH_CALL_DIRECTION_OUTBOUND ? "outbound" : "inbound")); - cJSON_AddItemToObject(json, "Logical-Direction", cJSON_CreateString(caller_profile->logical_direction == SWITCH_CALL_DIRECTION_OUTBOUND ? "outbound" : "inbound")); - - soft = cJSON_CreateObject(); - for (pn = caller_profile->soft; pn; pn = pn->next) { - maybe_add_json_string(soft, pn->var, pn->val); - } - - cJSON_AddItemToObject(json, "Directory", soft); -} - -SWITCH_DECLARE(void) kz_switch_ivr_set_json_call_flaws(cJSON *json, switch_core_session_t *session, switch_media_type_t type) -{ - const char *name = (type == SWITCH_MEDIA_TYPE_VIDEO) ? "Video" : "Audio"; - cJSON *j_stat; - switch_rtp_stats_t *stats = switch_core_media_get_stats(session, type, NULL); - - if (!stats) return; - - if (!stats->inbound.error_log && !stats->outbound.error_log) return; - - j_stat = cJSON_CreateObject(); - cJSON_AddItemToObject(json, name, j_stat); - - if (stats->inbound.error_log) { - cJSON *j_err_log, *j_err, *j_in; - switch_error_period_t *ep; - - j_in = cJSON_CreateObject(); - cJSON_AddItemToObject(j_stat, "Inbound", j_in); - - j_err_log = cJSON_CreateArray(); - cJSON_AddItemToObject(j_in, "Error-Log", j_err_log); - - for(ep = stats->inbound.error_log; ep; ep = ep->next) { - - if (!(ep->start && ep->stop)) continue; - - j_err = cJSON_CreateObject(); - - cJSON_AddItemToObject(j_err, "Start", cJSON_CreateNumber(ep->start)); - cJSON_AddItemToObject(j_err, "Stop", cJSON_CreateNumber(ep->stop)); - cJSON_AddItemToObject(j_err, "Flaws", cJSON_CreateNumber(ep->flaws)); - cJSON_AddItemToObject(j_err, "Consecutive-Flaws", cJSON_CreateNumber(ep->consecutive_flaws)); - cJSON_AddItemToObject(j_err, "Duration-MS", cJSON_CreateNumber((ep->stop - ep->start) / 1000)); - cJSON_AddItemToArray(j_err_log, j_err); - } - } - - if (stats->outbound.error_log) { - cJSON *j_err_log, *j_err, *j_out; - switch_error_period_t *ep; - - j_out = cJSON_CreateObject(); - cJSON_AddItemToObject(j_stat, "Outbound", j_out); - - j_err_log = cJSON_CreateArray(); - cJSON_AddItemToObject(j_out, "Error-Log", j_err_log); - - for(ep = stats->outbound.error_log; ep; ep = ep->next) { - - if (!(ep->start && ep->stop)) continue; - - j_err = cJSON_CreateObject(); - - cJSON_AddItemToObject(j_err, "Start", cJSON_CreateNumber(ep->start)); - cJSON_AddItemToObject(j_err, "Stop", cJSON_CreateNumber(ep->stop)); - cJSON_AddItemToObject(j_err, "Flaws", cJSON_CreateNumber(ep->flaws)); - cJSON_AddItemToObject(j_err, "Consecutive-Flaws", cJSON_CreateNumber(ep->consecutive_flaws)); - cJSON_AddItemToObject(j_err, "Duration-MS", cJSON_CreateNumber((ep->stop - ep->start) / 1000)); - cJSON_AddItemToArray(j_err_log, j_err); - } - } -} - -#define add_jstat(_j, _i, _s) \ - switch_snprintf(var_val, sizeof(var_val), "%" SWITCH_SIZE_T_FMT, _i); \ - cJSON_AddItemToObject(_j, _s, cJSON_CreateNumber(_i)) - -SWITCH_DECLARE(void) kz_switch_ivr_set_json_call_stats(cJSON *json, switch_core_session_t *session, switch_media_type_t type) -{ - const char *name = (type == SWITCH_MEDIA_TYPE_VIDEO) ? "Video" : "Audio"; - cJSON *j_stat, *j_in, *j_out; - switch_rtp_stats_t *stats = switch_core_media_get_stats(session, type, NULL); - char var_val[35] = ""; - - if (!stats) return; - - j_stat = cJSON_CreateObject(); - j_in = cJSON_CreateObject(); - j_out = cJSON_CreateObject(); - - cJSON_AddItemToObject(json, name, j_stat); - cJSON_AddItemToObject(j_stat, "Inbound", j_in); - cJSON_AddItemToObject(j_stat, "Outbound", j_out); - - stats->inbound.std_deviation = sqrt(stats->inbound.variance); - - add_jstat(j_in, stats->inbound.raw_bytes, "Raw-Bytes"); - add_jstat(j_in, stats->inbound.media_bytes, "Media-Bytes"); - add_jstat(j_in, stats->inbound.packet_count, "Packet-Count"); - add_jstat(j_in, stats->inbound.media_packet_count, "Media-Packet-Count"); - add_jstat(j_in, stats->inbound.skip_packet_count, "Skip-Packet-Count"); - add_jstat(j_in, stats->inbound.jb_packet_count, "Jitter-Packet-Count"); - add_jstat(j_in, stats->inbound.dtmf_packet_count, "DTMF-Packet-Count"); - add_jstat(j_in, stats->inbound.cng_packet_count, "CNG-Packet-Count"); - add_jstat(j_in, stats->inbound.flush_packet_count, "Flush-Packet-Count"); - add_jstat(j_in, stats->inbound.largest_jb_size, "Largest-JB-Size"); - add_jstat(j_in, stats->inbound.min_variance, "Jitter-Min-Variance"); - add_jstat(j_in, stats->inbound.max_variance, "Jitter-Max-Variance"); - add_jstat(j_in, stats->inbound.lossrate, "Jitter-Loss-Rate"); - add_jstat(j_in, stats->inbound.burstrate, "Jitter-Burst-Rate"); - add_jstat(j_in, stats->inbound.mean_interval, "Mean-Interval"); - add_jstat(j_in, stats->inbound.flaws, "Flaw-Total"); - add_jstat(j_in, stats->inbound.R, "Quality-Percentage"); - add_jstat(j_in, stats->inbound.mos, "MOS"); - - - add_jstat(j_out, stats->outbound.raw_bytes, "Raw-Bytes"); - add_jstat(j_out, stats->outbound.media_bytes, "Media-Bytes"); - add_jstat(j_out, stats->outbound.packet_count, "Packet-Count"); - add_jstat(j_out, stats->outbound.media_packet_count, "Media-Packet-Count"); - add_jstat(j_out, stats->outbound.skip_packet_count, "Skip-Packet-Count"); - add_jstat(j_out, stats->outbound.dtmf_packet_count, "DTMF-Packet-Count"); - add_jstat(j_out, stats->outbound.cng_packet_count, "CNG-Packet-Count"); - add_jstat(j_out, stats->rtcp.packet_count, "RTCP-Packet-Count"); - add_jstat(j_out, stats->rtcp.octet_count, "RTCP-Octet-Count"); -} - -static switch_status_t kz_report_channel_flaws(switch_core_session_t *session, switch_event_t *cdr_event) -{ - cJSON *callStats = cJSON_CreateObject(); - - kz_switch_ivr_set_json_call_flaws(callStats, session, SWITCH_MEDIA_TYPE_AUDIO); - kz_switch_ivr_set_json_call_flaws(callStats, session, SWITCH_MEDIA_TYPE_VIDEO); - - switch_event_add_header_string_nodup(cdr_event, SWITCH_STACK_BOTTOM, "_json_channel_media_errors", cJSON_PrintUnformatted(callStats)); - - cJSON_Delete(callStats); - - return SWITCH_STATUS_SUCCESS; -} - -static switch_status_t kz_report_channel_stats(switch_core_session_t *session, switch_event_t *cdr_event) -{ - cJSON *callStats = cJSON_CreateObject(); - - kz_switch_ivr_set_json_call_stats(callStats, session, SWITCH_MEDIA_TYPE_AUDIO); - kz_switch_ivr_set_json_call_stats(callStats, session, SWITCH_MEDIA_TYPE_VIDEO); - - switch_event_add_header_string_nodup(cdr_event, SWITCH_STACK_BOTTOM, "_json_channel_stats", cJSON_PrintUnformatted(callStats)); - - cJSON_Delete(callStats); - - return SWITCH_STATUS_SUCCESS; - -} - -static switch_status_t kz_report_app_log(switch_core_session_t *session, switch_event_t *cdr_event) -{ - switch_app_log_t *ap, *app_log = switch_core_session_get_app_log(session); - cJSON *j_apps = NULL; - - if (!app_log) { - return SWITCH_STATUS_FALSE; - } - - j_apps = cJSON_CreateArray(); - - for (ap = app_log; ap; ap = ap->next) { - cJSON *j_application = cJSON_CreateObject(); - cJSON_AddItemToObject(j_application, "app_name", cJSON_CreateString(ap->app)); - cJSON_AddItemToObject(j_application, "app_data", cJSON_CreateString(ap->arg)); - cJSON_AddItemToObject(j_application, "app_stamp", cJSON_CreateNumber(ap->stamp)); - cJSON_AddItemToArray(j_apps, j_application); - } - - switch_event_add_header_string_nodup(cdr_event, SWITCH_STACK_BOTTOM, "_json_application_log", cJSON_PrintUnformatted(j_apps)); - - cJSON_Delete(j_apps); - - return SWITCH_STATUS_SUCCESS; - -} - -static switch_status_t kz_report_callflow_extension(switch_caller_profile_t *caller_profile, cJSON *j_profile) -{ - cJSON *j_caller_extension, *j_caller_extension_apps, *j_application, *j_inner_extension; - if (caller_profile->caller_extension) { - switch_caller_application_t *ap; - - j_caller_extension = cJSON_CreateObject(); - j_caller_extension_apps = cJSON_CreateArray(); - - cJSON_AddItemToObject(j_profile, "extension", j_caller_extension); - - cJSON_AddItemToObject(j_caller_extension, "name", cJSON_CreateString(caller_profile->caller_extension->extension_name)); - cJSON_AddItemToObject(j_caller_extension, "number", cJSON_CreateString(caller_profile->caller_extension->extension_number)); - cJSON_AddItemToObject(j_caller_extension, "applications", j_caller_extension_apps); - - if (caller_profile->caller_extension->current_application) { - cJSON_AddItemToObject(j_caller_extension, "current_app", cJSON_CreateString(caller_profile->caller_extension->current_application->application_name)); - } - - for (ap = caller_profile->caller_extension->applications; ap; ap = ap->next) { - j_application = cJSON_CreateObject(); - - cJSON_AddItemToArray(j_caller_extension_apps, j_application); - - if (ap == caller_profile->caller_extension->current_application) { - cJSON_AddItemToObject(j_application, "last_executed", cJSON_CreateString("true")); - } - cJSON_AddItemToObject(j_application, "app_name", cJSON_CreateString(ap->application_name)); - cJSON_AddItemToObject(j_application, "app_data", cJSON_CreateString(switch_str_nil(ap->application_data))); - } - - if (caller_profile->caller_extension->children) { - switch_caller_profile_t *cp = NULL; - j_inner_extension = cJSON_CreateArray(); - cJSON_AddItemToObject(j_caller_extension, "sub_extensions", j_inner_extension); - for (cp = caller_profile->caller_extension->children; cp; cp = cp->next) { - - if (!cp->caller_extension) { - continue; - } - - j_caller_extension = cJSON_CreateObject(); - cJSON_AddItemToArray(j_inner_extension, j_caller_extension); - - cJSON_AddItemToObject(j_caller_extension, "name", cJSON_CreateString(cp->caller_extension->extension_name)); - cJSON_AddItemToObject(j_caller_extension, "number", cJSON_CreateString(cp->caller_extension->extension_number)); - - cJSON_AddItemToObject(j_caller_extension, "dialplan", cJSON_CreateString((char *)cp->dialplan)); - - if (cp->caller_extension->current_application) { - cJSON_AddItemToObject(j_caller_extension, "current_app", cJSON_CreateString(cp->caller_extension->current_application->application_name)); - } - - j_caller_extension_apps = cJSON_CreateArray(); - cJSON_AddItemToObject(j_caller_extension, "applications", j_caller_extension_apps); - for (ap = cp->caller_extension->applications; ap; ap = ap->next) { - j_application = cJSON_CreateObject(); - cJSON_AddItemToArray(j_caller_extension_apps, j_application); - - if (ap == cp->caller_extension->current_application) { - cJSON_AddItemToObject(j_application, "last_executed", cJSON_CreateString("true")); - } - cJSON_AddItemToObject(j_application, "app_name", cJSON_CreateString(ap->application_name)); - cJSON_AddItemToObject(j_application, "app_data", cJSON_CreateString(switch_str_nil(ap->application_data))); - } - } - } - } - - return SWITCH_STATUS_SUCCESS; - -} - -static switch_status_t kz_report_callflow(switch_core_session_t *session, switch_event_t *cdr_event) -{ - switch_channel_t *channel = switch_core_session_get_channel(session); - switch_caller_profile_t *caller_profile; - cJSON *j_main_cp, *j_times, *j_callflow, *j_profile, *j_o; - - - caller_profile = switch_channel_get_caller_profile(channel); - - j_callflow = cJSON_CreateArray(); - - while (caller_profile) { - - j_profile = cJSON_CreateObject(); - - if (!zstr(caller_profile->dialplan)) { - cJSON_AddItemToObject(j_profile, "dialplan", cJSON_CreateString((char *)caller_profile->dialplan)); - } - - if (!zstr(caller_profile->profile_index)) { - cJSON_AddItemToObject(j_profile, "profile_index", cJSON_CreateString((char *)caller_profile->profile_index)); - } - - kz_report_callflow_extension(caller_profile, j_profile); - - j_main_cp = cJSON_CreateObject(); - cJSON_AddItemToObject(j_profile, "Caller-Profile", j_main_cp); - - kz_switch_ivr_set_json_profile_data(j_main_cp, caller_profile); - - if (caller_profile->originator_caller_profile) { - j_o = cJSON_CreateObject(); - cJSON_AddItemToObject(j_main_cp, "originator", j_o); - kz_switch_ivr_set_json_profile_data(j_o, caller_profile->originator_caller_profile); - kz_report_callflow_extension(caller_profile->originator_caller_profile, j_o); - } - - if (caller_profile->originatee_caller_profile) { - j_o = cJSON_CreateObject(); - cJSON_AddItemToObject(j_main_cp, "originatee", j_o); - kz_switch_ivr_set_json_profile_data(j_o, caller_profile->originatee_caller_profile); - kz_report_callflow_extension(caller_profile->originatee_caller_profile, j_o); - } - - if (caller_profile->times) { - j_times = cJSON_CreateObject(); - cJSON_AddItemToObject(j_profile, "Time", j_times); - cJSON_AddItemToObject(j_times, "Created", cJSON_CreateNumber(caller_profile->times->created)); - cJSON_AddItemToObject(j_times, "Profile-Created", cJSON_CreateNumber(caller_profile->times->profile_created)); - cJSON_AddItemToObject(j_times, "Progress", cJSON_CreateNumber(caller_profile->times->progress)); - cJSON_AddItemToObject(j_times, "Progress-Media", cJSON_CreateNumber(caller_profile->times->progress_media)); - cJSON_AddItemToObject(j_times, "Answered", cJSON_CreateNumber(caller_profile->times->answered)); - cJSON_AddItemToObject(j_times, "Bridged", cJSON_CreateNumber(caller_profile->times->bridged)); - cJSON_AddItemToObject(j_times, "Last-Hold", cJSON_CreateNumber(caller_profile->times->last_hold)); - cJSON_AddItemToObject(j_times, "Hold-Accumulated", cJSON_CreateNumber(caller_profile->times->hold_accum)); - cJSON_AddItemToObject(j_times, "Hangup", cJSON_CreateNumber(caller_profile->times->hungup)); - cJSON_AddItemToObject(j_times, "Resurrect", cJSON_CreateNumber(caller_profile->times->resurrected)); - cJSON_AddItemToObject(j_times, "Transfer", cJSON_CreateNumber(caller_profile->times->transferred)); - } - cJSON_AddItemToArray(j_callflow, j_profile); - caller_profile = caller_profile->next; - } - - switch_event_add_header_string_nodup(cdr_event, SWITCH_STACK_BOTTOM, "_json_callflow", cJSON_PrintUnformatted(j_callflow)); - - cJSON_Delete(j_callflow); - - - return SWITCH_STATUS_SUCCESS; - -} - - -#define ORIGINATED_LEGS_VARIABLE "originated_legs" -#define ORIGINATED_LEGS_ITEM_DELIM ';' - -#define ORIGINATE_CAUSES_VARIABLE "originate_causes" -#define ORIGINATE_CAUSES_ITEM_DELIM ';' - -static switch_status_t kz_report_originated_legs(switch_core_session_t *session, switch_event_t *cdr_event) -{ - switch_channel_t *channel = switch_core_session_get_channel(session); - cJSON *j_originated = cJSON_CreateArray(); - const char *originated_legs_var = NULL, *originate_causes_var = NULL; - int idx = 0; - - while(1) { - char *argv_leg[10] = { 0 }, *argv_cause[10] = { 0 }; - char *originated_legs, *originate_causes; - cJSON *j_originated_leg; - originated_legs_var = switch_channel_get_variable_dup(channel, ORIGINATED_LEGS_VARIABLE, SWITCH_FALSE, idx); - originate_causes_var = switch_channel_get_variable_dup(channel, ORIGINATE_CAUSES_VARIABLE, SWITCH_FALSE, idx); - - if (zstr(originated_legs_var) || zstr(originate_causes_var)) { - break; - } - - originated_legs = strdup(originated_legs_var); - originate_causes = strdup(originate_causes_var); - - switch_separate_string(originated_legs, ORIGINATED_LEGS_ITEM_DELIM, argv_leg, (sizeof(argv_leg) / sizeof(argv_leg[0]))); - switch_separate_string(originate_causes, ORIGINATE_CAUSES_ITEM_DELIM, argv_cause, (sizeof(argv_cause) / sizeof(argv_cause[0]))); - - j_originated_leg = cJSON_CreateObject(); - cJSON_AddItemToObject(j_originated_leg, "Call-ID", cJSON_CreateString(argv_leg[0])); - cJSON_AddItemToObject(j_originated_leg, "Caller-ID-Name", cJSON_CreateString(argv_leg[1])); - cJSON_AddItemToObject(j_originated_leg, "Caller-ID-Number", cJSON_CreateString(argv_leg[2])); - cJSON_AddItemToObject(j_originated_leg, "Result", cJSON_CreateString(argv_cause[1])); - - cJSON_AddItemToArray(j_originated, j_originated_leg); - - switch_safe_free(originated_legs); - switch_safe_free(originate_causes); - - idx++; - } - - switch_event_add_header_string_nodup(cdr_event, SWITCH_STACK_BOTTOM, "_json_originated_legs", cJSON_PrintUnformatted(j_originated)); - - cJSON_Delete(j_originated); - - return SWITCH_STATUS_SUCCESS; -} - -#define MAX_HISTORY 50 -#define HST_ARRAY_DELIM "|:" -#define HST_ITEM_DELIM ':' - -static void kz_report_transfer_history_item(char* value, cJSON *json) -{ - char *argv[4] = { 0 }; - char *item = strdup(value); - int argc = switch_separate_string(item, HST_ITEM_DELIM, argv, (sizeof(argv) / sizeof(argv[0]))); - cJSON *jitem = cJSON_CreateObject(); - char *epoch = NULL, *callid = NULL, *type = NULL; - int add = 0; - if(argc == 4) { - add = 1; - epoch = argv[0]; - callid = argv[1]; - type = argv[2]; - - if(!strncmp(type, "bl_xfer", 7)) { - //char *split = strchr(argv[3], '/'); - //if(split) *(split++) = '\0'; - cJSON_AddItemToObject(jitem, "Caller-Profile-ID", cJSON_CreateString(callid)); - cJSON_AddItemToObject(jitem, "Type", cJSON_CreateString("blind")); - cJSON_AddItemToObject(jitem, "Extension", cJSON_CreateString(argv[3])); - cJSON_AddItemToObject(jitem, "Timestamp", cJSON_CreateNumber(strtod(epoch, NULL))); - } else if(!strncmp(type, "att_xfer", 8)) { - char *split = strchr(argv[3], '/'); - if(split) { - *(split++) = '\0'; - cJSON_AddItemToObject(jitem, "Caller-Profile-ID", cJSON_CreateString(callid)); - cJSON_AddItemToObject(jitem, "Type", cJSON_CreateString("attended")); - cJSON_AddItemToObject(jitem, "Transferee", cJSON_CreateString(argv[3])); - cJSON_AddItemToObject(jitem, "Transferer", cJSON_CreateString(split)); - cJSON_AddItemToObject(jitem, "Timestamp", cJSON_CreateNumber(strtod(epoch, NULL))); - } else { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "TRANSFER TYPE '%s' NOT HANDLED => %s\n", type, item); - add = 0; - } - } else if(!strncmp(type, "uuid_br", 7)) { - cJSON_AddItemToObject(jitem, "Caller-Profile-ID", cJSON_CreateString(callid)); - cJSON_AddItemToObject(jitem, "Type", cJSON_CreateString("bridge")); - cJSON_AddItemToObject(jitem, "Other-Leg", cJSON_CreateString(argv[3])); - cJSON_AddItemToObject(jitem, "Timestamp", cJSON_CreateNumber(strtod(epoch, NULL))); - } else { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "TRANSFER TYPE '%s' NOT HANDLED => %s\n", type, item); - add = 0; - } - } else { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "TRANSFER TYPE SPLIT ERROR %i => %s\n", argc, item); - } - if(add) { - cJSON_AddItemToArray(json, jitem); - } else { - cJSON_Delete(jitem); - } - switch_safe_free(item); -} - -static switch_status_t kz_report_transfer_history(switch_core_session_t *session, switch_event_t *cdr_event, const char* var_name) -{ - switch_channel_t *channel = switch_core_session_get_channel(session); - cJSON *j_transfer = NULL; - char *tmp_history = NULL, *history = NULL, *argv[MAX_HISTORY] = { 0 }; - char event_header[50]; - int n, argc = 0; - const char *transfer_var = switch_channel_get_variable_dup(channel, var_name, SWITCH_FALSE, -1); - if (zstr(transfer_var)) { - return SWITCH_STATUS_SUCCESS; - } - - if (!(tmp_history = strdup(transfer_var))) { - return SWITCH_STATUS_SUCCESS; - } - - sprintf(event_header, "_json_%s", var_name); - history = tmp_history; - j_transfer = cJSON_CreateArray(); - - if (!strncmp(history, "ARRAY::", 7)) { - history += 7; - argc = switch_separate_string_string(history, HST_ARRAY_DELIM, argv, (sizeof(argv) / sizeof(argv[0]))); - for(n=0; n < argc; n++) { - kz_report_transfer_history_item(argv[n], j_transfer); - } - switch_event_add_header_string_nodup(cdr_event, SWITCH_STACK_BOTTOM, event_header, cJSON_PrintUnformatted(j_transfer)); - } else if (strchr(history, HST_ITEM_DELIM)) { - kz_report_transfer_history_item(history, j_transfer); - switch_event_add_header_string_nodup(cdr_event, SWITCH_STACK_BOTTOM, event_header, cJSON_PrintUnformatted(j_transfer)); - } - cJSON_Delete(j_transfer); - switch_safe_free(tmp_history); - - return SWITCH_STATUS_SUCCESS; -} - -static switch_status_t kz_report(switch_core_session_t *session, switch_event_t *cdr_event) -{ - kz_report_app_log(session, cdr_event); - kz_report_callflow(session, cdr_event); - kz_report_channel_stats(session, cdr_event); - kz_report_channel_flaws(session, cdr_event); - kz_report_originated_legs(session, cdr_event); - kz_report_transfer_history(session, cdr_event, SWITCH_TRANSFER_HISTORY_VARIABLE); - kz_report_transfer_history(session, cdr_event, SWITCH_TRANSFER_SOURCE_VARIABLE); - return SWITCH_STATUS_SUCCESS; -} - - -static switch_status_t kz_cdr_on_reporting(switch_core_session_t *session) -{ - switch_event_t *cdr_event = NULL; - switch_channel_t *channel = switch_core_session_get_channel(session); - - if (switch_event_create_subclass(&cdr_event, SWITCH_EVENT_CUSTOM, MY_EVENT_JSON_CDR) != SWITCH_STATUS_SUCCESS) { - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "error creating event for report data!\n"); - return SWITCH_STATUS_FALSE; - } - - kz_report(session, cdr_event); - switch_channel_event_set_data(channel, cdr_event); - switch_event_fire(&cdr_event); - - return SWITCH_STATUS_SUCCESS; -} - - -static switch_state_handler_table_t kz_cdr_state_handlers = { - /*.on_init */ NULL, - /*.on_routing */ NULL, - /*.on_execute */ NULL, - /*.on_hangup */ NULL, - /*.on_exchange_media */ NULL, - /*.on_soft_execute */ NULL, - /*.on_consume_media */ NULL, - /*.on_hibernate */ NULL, - /*.on_reset */ NULL, - /*.on_park */ NULL, - /*.on_reporting */ kz_cdr_on_reporting -}; - - -static void kz_cdr_register_state_handlers() -{ - switch_core_add_state_handler(&kz_cdr_state_handlers); -} - -static void kz_cdr_unregister_state_handlers() -{ - switch_core_remove_state_handler(&kz_cdr_state_handlers); -} - -static void kz_cdr_register_events() -{ - if (switch_event_reserve_subclass(MY_EVENT_JSON_CDR) != SWITCH_STATUS_SUCCESS) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Couldn't register subclass %s!\n", MY_EVENT_JSON_CDR); - } -} - -static void kz_cdr_unregister_events() -{ - switch_event_free_subclass(MY_EVENT_JSON_CDR); -} - - -void kz_cdr_start() -{ - kz_cdr_register_events(); - kz_cdr_register_state_handlers(); -} - -void kz_cdr_stop() -{ - kz_cdr_unregister_state_handlers(); - kz_cdr_unregister_events(); -} - -/* For Emacs: - * Local Variables: - * mode:c - * indent-tabs-mode:t - * tab-width:4 - * c-basic-offset:4 - * End: - * For VIM: - * vim:set softtabstop=4 shiftwidth=4 tabstop=4: - */ diff --git a/src/mod/event_handlers/mod_kazoo/kazoo_commands.c b/src/mod/event_handlers/mod_kazoo/kazoo_commands.c deleted file mode 100644 index 16f00ad1a03..00000000000 --- a/src/mod/event_handlers/mod_kazoo/kazoo_commands.c +++ /dev/null @@ -1,592 +0,0 @@ -/* - * FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application - * Copyright (C) 2005-2012, Anthony Minessale II - * - * 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 - * Portions created by the Initial Developer are Copyright (C) - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * - * Karl Anderson - * Darren Schreiber - * - * - * kazoo_commands.c -- clones of mod_commands commands slightly modified for kazoo - * - */ -#include "mod_kazoo.h" -#include -#include - -#define UUID_SET_DESC "Set a variable" -#define UUID_SET_SYNTAX " [value]" - -#define UUID_MULTISET_DESC "Set multiple variables" -#define UUID_MULTISET_SYNTAX " =;=..." - -#define KZ_HTTP_PUT_DESC "upload a local freeswitch file to a url" -#define KZ_HTTP_PUT_SYNTAX "localfile url" - -#define KZ_FIRST_OF_DESC "returns first-of existing event header in params" -#define KZ_FIRST_OF_SYNTAX "list of headers to check" - -#define MAX_FIRST_OF 25 - -SWITCH_STANDARD_API(kz_first_of) -{ - char delim = '|'; - 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) == '^') { - mycmd += 2; - delim = *mycmd++; - } - argc = switch_separate_string(mycmd, delim, argv, (sizeof(argv) / sizeof(argv[0]))); - for(n=0; n < argc; n++) { - char* item = argv[n]; - if(*item == '#' || *item == '!' || *item == '?') { - if(*(++item) != '\0') { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG1, "RETURNING default %s\n", item); - stream->write_function(stream, item); - break; - } - } 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); - stream->write_function(stream, header->value); - break; - } - } - } - - switch_safe_free(mycmd_dup); - return SWITCH_STATUS_SUCCESS; -} - -switch_status_t kz_uuid_setvar(int urldecode, const char *cmd, switch_core_session_t *session, switch_stream_handle_t *stream) -{ - switch_core_session_t *psession = NULL; - char *mycmd = NULL, *argv[3] = { 0 }; - int argc = 0; - - if (!zstr(cmd) && (mycmd = strdup(cmd))) { - argc = switch_separate_string(mycmd, ' ', argv, (sizeof(argv) / sizeof(argv[0]))); - if ((argc == 2 || argc == 3) && !zstr(argv[0])) { - char *uuid = argv[0]; - char *var_name = argv[1]; - char *var_value = NULL; - - if (argc == 3) { - var_value = argv[2]; - } - - if ((psession = switch_core_session_locate(uuid))) { - switch_channel_t *channel; - switch_event_t *event; - channel = switch_core_session_get_channel(psession); - - if (zstr(var_name)) { - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "No variable name specified.\n"); - stream->write_function(stream, "-ERR No variable specified\n"); - } else { - if(urldecode) { - switch_url_decode(var_value); - } - switch_channel_set_variable(channel, var_name, var_value); - kz_check_set_profile_var(channel, var_name, var_value); - stream->write_function(stream, "+OK\n"); - } - - if (switch_event_create(&event, SWITCH_EVENT_CHANNEL_DATA) == SWITCH_STATUS_SUCCESS) { - switch_channel_event_set_data(channel, event); - switch_event_fire(&event); - } - - switch_core_session_rwunlock(psession); - - } else { - stream->write_function(stream, "-ERR No such channel!\n"); - } - goto done; - } - } - - stream->write_function(stream, "-USAGE: %s\n", UUID_SET_SYNTAX); - - done: - switch_safe_free(mycmd); - return SWITCH_STATUS_SUCCESS; -} - -SWITCH_STANDARD_API(uuid_setvar_function) -{ - return kz_uuid_setvar(0, cmd, session, stream); -} - -SWITCH_STANDARD_API(uuid_setvar_encoded_function) -{ - return kz_uuid_setvar(1, cmd, session, stream); -} - -switch_status_t kz_uuid_setvar_multi(int urldecode, const char *cmd, switch_core_session_t *session, switch_stream_handle_t *stream) -{ - switch_core_session_t *psession = NULL; - char delim = ';'; - char *mycmd = NULL, *vars, *argv[64] = { 0 }; - int argc = 0; - char *var_name, *var_value = NULL; - - if (!zstr(cmd) && (mycmd = strdup(cmd))) { - char *uuid = mycmd; - if (!(vars = strchr(uuid, ' '))) { - goto done; - } - *vars++ = '\0'; - if (*vars == '^' && *(vars+1) == '^') { - vars += 2; - delim = *vars++; - } - if ((psession = switch_core_session_locate(uuid))) { - switch_channel_t *channel = switch_core_session_get_channel(psession); - switch_event_t *event; - int x, y = 0; - argc = switch_separate_string(vars, delim, argv, (sizeof(argv) / sizeof(argv[0]))); - - for (x = 0; x < argc; x++) { - var_name = argv[x]; - if (var_name && (var_value = strchr(var_name, '='))) { - *var_value++ = '\0'; - } - if (zstr(var_name)) { - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "No variable name specified.\n"); - stream->write_function(stream, "-ERR No variable specified\n"); - } else { - if(urldecode) { - switch_url_decode(var_value); - } - switch_channel_set_variable(channel, var_name, var_value); - kz_check_set_profile_var(channel, var_name, var_value); - - y++; - } - } - - /* keep kazoo nodes in sync */ - if (switch_event_create(&event, SWITCH_EVENT_CHANNEL_DATA) == SWITCH_STATUS_SUCCESS) { - switch_channel_event_set_data(channel, event); - switch_event_fire(&event); - } - - switch_core_session_rwunlock(psession); - if (y) { - stream->write_function(stream, "+OK\n"); - goto done; - } - } else { - stream->write_function(stream, "-ERR No such channel!\n"); - } - } - - stream->write_function(stream, "-USAGE: %s\n", UUID_MULTISET_SYNTAX); - - done: - switch_safe_free(mycmd); - return SWITCH_STATUS_SUCCESS; -} - -SWITCH_STANDARD_API(uuid_setvar_multi_function) -{ - return kz_uuid_setvar_multi(0, cmd, session, stream); -} - -SWITCH_STANDARD_API(uuid_setvar_multi_encoded_function) -{ - return kz_uuid_setvar_multi(1, cmd, session, stream); -} - -static size_t body_callback(char *buffer, size_t size, size_t nitems, void *userdata) -{ - return size * nitems; -} - -static size_t header_callback(char *buffer, size_t size, size_t nitems, void *userdata) -{ - switch_event_t* event = (switch_event_t*)userdata; - int len = strlen(buffer); - char buf[1024]; - if(len > 2 && len < 1024) { - snprintf(buf, sizeof(buf), "%s", buffer); - switch_event_add_header_string(event, SWITCH_STACK_PUSH | SWITCH_STACK_BOTTOM, "Reply-Headers", buf); - } - return nitems * size; -} - -SWITCH_STANDARD_API(kz_http_put) -{ - switch_status_t status = SWITCH_STATUS_SUCCESS; - switch_memory_pool_t *lpool = NULL; - switch_memory_pool_t *pool = NULL; - char *args = NULL; - char *argv[10] = { 0 }; - int argc = 0; - switch_event_t *params = NULL; - char *url = NULL; - char *filename = NULL; - int delete_file = 0; - - switch_curl_slist_t *headers = NULL; /* optional linked-list of HTTP headers */ - char *ext; /* file extension, used for MIME type identification */ - const char *mime_type = "application/octet-stream"; - char *buf = NULL; - char *error = NULL; - - CURL *curl_handle = NULL; - long httpRes = 0; - struct stat file_info = {0}; - FILE *file_to_put = NULL; - - if (session) { - pool = switch_core_session_get_pool(session); - } else { - switch_core_new_memory_pool(&lpool); - pool = lpool; - } - - if (zstr(cmd)) { - stream->write_function(stream, "USAGE: %s\n", KZ_HTTP_PUT_SYNTAX); - status = SWITCH_STATUS_SUCCESS; - goto done; - } - - args = strdup(cmd); - argc = switch_separate_string(args, ' ', argv, (sizeof(argv) / sizeof(argv[0]))); - if (argc != 2) { - stream->write_function(stream, "USAGE: %s\n", KZ_HTTP_PUT_SYNTAX); - status = SWITCH_STATUS_SUCCESS; - goto done; - } - - /* parse params and get profile */ - url = switch_core_strdup(pool, argv[0]); - if (*url == '{') { - if (switch_event_create_brackets(url, '{', '}', ',', ¶ms, &url, SWITCH_FALSE) != SWITCH_STATUS_SUCCESS) { - status = SWITCH_STATUS_FALSE; - stream->write_function(stream, "-ERR error parsing parameters\n"); - goto done; - } - } - - filename = switch_core_strdup(pool, argv[1]); - - /* guess what type of mime content this is going to be */ - if ((ext = strrchr(filename, '.'))) { - ext++; - if (!(mime_type = switch_core_mime_ext2type(ext))) { - mime_type = "application/octet-stream"; - } - } - - buf = switch_mprintf("Content-Type: %s", mime_type); - headers = switch_curl_slist_append(headers, buf); - - /* open file and get the file size */ - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "opening %s for upload to %s\n", filename, url); - - /* libcurl requires FILE* */ - file_to_put = fopen(filename, "rb"); - if (!file_to_put) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "fopen() error: %s\n", strerror(errno)); - stream->write_function(stream, "-ERR error opening file\n"); - status = SWITCH_STATUS_FALSE; - goto done; - } - - if (fstat(fileno(file_to_put), &file_info) == -1) { - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "fstat() error: %s\n", strerror(errno)); - stream->write_function(stream, "-ERR fstat error\n"); - goto done; - } - - curl_handle = switch_curl_easy_init(); - if (!curl_handle) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "switch_curl_easy_init() failure\n"); - status = SWITCH_STATUS_FALSE; - stream->write_function(stream, "-ERR switch_curl_easy init failure\n"); - goto done; - } - switch_curl_easy_setopt(curl_handle, CURLOPT_UPLOAD, 1); -#if !defined(LIBCURL_VERSION_NUM) || (LIBCURL_VERSION_NUM < 0x070c01) - switch_curl_easy_setopt(curl_handle, CURLOPT_PUT, 1); -#endif - switch_curl_easy_setopt(curl_handle, CURLOPT_NOSIGNAL, 1); - switch_curl_easy_setopt(curl_handle, CURLOPT_HTTPHEADER, headers); - switch_curl_easy_setopt(curl_handle, CURLOPT_URL, url); - switch_curl_easy_setopt(curl_handle, CURLOPT_READDATA, file_to_put); - switch_curl_easy_setopt(curl_handle, CURLOPT_INFILESIZE_LARGE, (curl_off_t)file_info.st_size); - switch_curl_easy_setopt(curl_handle, CURLOPT_FOLLOWLOCATION, 1); - switch_curl_easy_setopt(curl_handle, CURLOPT_MAXREDIRS, 10); - switch_curl_easy_setopt(curl_handle, CURLOPT_FAILONERROR, 1); - switch_curl_easy_setopt(curl_handle, CURLOPT_USERAGENT, "freeswitch-kazoo/1.0"); - switch_curl_easy_setopt(curl_handle, CURLOPT_HEADERDATA, stream->param_event); - switch_curl_easy_setopt(curl_handle, CURLOPT_HEADERFUNCTION, header_callback); - switch_curl_easy_setopt(curl_handle, CURLOPT_WRITEFUNCTION, body_callback); - - switch_curl_easy_setopt(curl_handle, CURLOPT_SSL_VERIFYPEER, 0L); - switch_curl_easy_perform(curl_handle); - switch_curl_easy_getinfo(curl_handle, CURLINFO_RESPONSE_CODE, &httpRes); - switch_curl_easy_cleanup(curl_handle); - - if (httpRes == 200 || httpRes == 201 || httpRes == 202 || httpRes == 204) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "%s saved to %s\n", filename, url); - switch_event_add_header(stream->param_event, SWITCH_STACK_BOTTOM, "API-Output", "%s saved to %s", filename, url); - stream->write_function(stream, "+OK %s saved to %s", filename, url); - delete_file = 1; - } else { - error = switch_mprintf("Received HTTP error %ld trying to save %s to %s", httpRes, filename, url); - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "%s\n", error); - switch_event_add_header(stream->param_event, SWITCH_STACK_BOTTOM, "API-Error", "%s", error); - switch_event_add_header(stream->param_event, SWITCH_STACK_BOTTOM, "API-HTTP-Error", "%ld", httpRes); - stream->write_function(stream, "-ERR %s", error); - status = SWITCH_STATUS_GENERR; - } - -done: - if (file_to_put) { - fclose(file_to_put); - if(delete_file) { - remove(filename); - } - } - - if (headers) { - switch_curl_slist_free_all(headers); - } - - switch_safe_free(buf); - switch_safe_free(error); - - switch_safe_free(args); - - if (lpool) { - switch_core_destroy_memory_pool(&lpool); - } - - if (params) { - switch_event_destroy(¶ms); - } - - return status; -} - -SWITCH_STANDARD_API(kz_expand_api) -{ - char *p = NULL, *input = NULL; - char *uuid = NULL, *mycmd; - - 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'; - } else { - stream->write_function(stream, "-ERR invalid argument"); - switch_safe_free(mycmd); - return SWITCH_STATUS_GENERR; - } - } else { - input = mycmd; - } - - p = kz_expand(input, uuid); - stream->write_function(stream, "+OK %s", p); - if (p != input) { - switch_safe_free(p); - } - switch_safe_free(mycmd); - 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; -} - -#define KZ_CONTACT_DESC "returns kazoo contact" -#define KZ_CONTACT_SYNTAX "endpoint@account" - -SWITCH_STANDARD_API(kz_contact_fun) -{ - switch_event_t *params = NULL; - const char *var = NULL; - switch_xml_t xml_node = NULL; - switch_xml_t xml_root = NULL; - - const char *reply = "error/subscriber_absent"; - - if (!cmd) { - stream->write_function(stream, "%s", reply); - return SWITCH_STATUS_SUCCESS; - } - - switch_event_create(¶ms, SWITCH_EVENT_REQUEST_PARAMS); - switch_assert(params); - switch_event_add_header_string(params, SWITCH_STACK_BOTTOM, "action", "call"); - switch_event_add_header_string(params, SWITCH_STACK_BOTTOM, "Fetch-Exclude-Cache", "true"); - - /* - if (stream->param_event) { - switch_event_merge(params, stream->param_event); - } - */ - - /* - if (session) { - switch_event_add_header_string(params, SWITCH_STACK_BOTTOM, "Fetch-Call-UUID", switch_core_session_get_uuid(session)); - } else if (stream->param_event && (var = switch_event_get_header(stream->param_event, "ent_originate_aleg_uuid")) != NULL) { - switch_event_add_header_string(params, SWITCH_STACK_BOTTOM, "Fetch-Call-UUID", var); - } - */ - - if (switch_xml_locate("directory", "location", "id", cmd, &xml_root, &xml_node, params, SWITCH_FALSE) != SWITCH_STATUS_SUCCESS) { - stream->write_function(stream, "%s", reply); - return SWITCH_STATUS_SUCCESS; - } - - var = switch_xml_attr(xml_node, "value"); - if (!zstr(var)) { - reply = var; - } - - stream->write_function(stream, "%s", reply); - - switch_xml_free(xml_root); - 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); - SWITCH_ADD_API(api_interface, "kz_uuid_setvar_multi_encoded", UUID_SET_DESC, uuid_setvar_multi_encoded_function, UUID_MULTISET_SYNTAX); - switch_console_set_complete("add kz_uuid_setvar_multi ::console::list_uuid"); - switch_console_set_complete("add kz_uuid_setvar_multi_encoded ::console::list_uuid"); - SWITCH_ADD_API(api_interface, "kz_uuid_setvar", UUID_MULTISET_DESC, uuid_setvar_function, UUID_SET_SYNTAX); - SWITCH_ADD_API(api_interface, "kz_uuid_setvar_encoded", UUID_MULTISET_DESC, uuid_setvar_encoded_function, UUID_SET_SYNTAX); - switch_console_set_complete("add kz_uuid_setvar ::console::list_uuid"); - switch_console_set_complete("add kz_uuid_setvar_encoded ::console::list_uuid"); - 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); - SWITCH_ADD_API(api_interface, "kz_contact", KZ_CONTACT_DESC, kz_contact_fun, KZ_CONTACT_SYNTAX); -} - diff --git a/src/mod/event_handlers/mod_kazoo/kazoo_config.c b/src/mod/event_handlers/mod_kazoo/kazoo_config.c deleted file mode 100644 index a64677074b2..00000000000 --- a/src/mod/event_handlers/mod_kazoo/kazoo_config.c +++ /dev/null @@ -1,553 +0,0 @@ -/* -* FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application -* Copyright (C) 2005-2012, Anthony Minessale II -* -* 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 -* Portions created by the Initial Developer are Copyright (C) -* the Initial Developer. All Rights Reserved. -* -* Based on mod_skel by -* Anthony Minessale II -* -* Contributor(s): -* -* Daniel Bryars -* Tim Brown -* Anthony Minessale II -* William King -* Mike Jerris -* -* kazoo.c -- Sends FreeSWITCH events to an AMQP broker -* -*/ - -#include "mod_kazoo.h" - -static const char *LOG_LEVEL_NAMES[] = { - "SWITCH_LOG_DEBUG10", - "SWITCH_LOG_DEBUG9", - "SWITCH_LOG_DEBUG8", - "SWITCH_LOG_DEBUG7", - "SWITCH_LOG_DEBUG6", - "SWITCH_LOG_DEBUG5", - "SWITCH_LOG_DEBUG4", - "SWITCH_LOG_DEBUG3", - "SWITCH_LOG_DEBUG2", - "SWITCH_LOG_DEBUG1", - "SWITCH_LOG_DEBUG", - "SWITCH_LOG_INFO", - "SWITCH_LOG_NOTICE", - "SWITCH_LOG_WARNING", - "SWITCH_LOG_ERROR", - "SWITCH_LOG_CRIT", - "SWITCH_LOG_ALERT", - "SWITCH_LOG_CONSOLE", - "SWITCH_LOG_INVALID", - "SWITCH_LOG_UNINIT", - NULL -}; - -static const switch_log_level_t LOG_LEVEL_VALUES[] = { - SWITCH_LOG_DEBUG10, - SWITCH_LOG_DEBUG9, - SWITCH_LOG_DEBUG8, - SWITCH_LOG_DEBUG7, - SWITCH_LOG_DEBUG6, - SWITCH_LOG_DEBUG5, - SWITCH_LOG_DEBUG4, - SWITCH_LOG_DEBUG3, - SWITCH_LOG_DEBUG2, - SWITCH_LOG_DEBUG1, - SWITCH_LOG_DEBUG, - SWITCH_LOG_INFO, - SWITCH_LOG_NOTICE, - SWITCH_LOG_WARNING, - SWITCH_LOG_ERROR, - SWITCH_LOG_CRIT, - SWITCH_LOG_ALERT, - SWITCH_LOG_CONSOLE, - SWITCH_LOG_INVALID, - SWITCH_LOG_UNINIT -}; - -switch_log_level_t log_str2level(const char *str) -{ - int x = 0; - switch_log_level_t level = SWITCH_LOG_INVALID; - - if (switch_is_number(str)) { - x = atoi(str); - - if (x > SWITCH_LOG_INVALID) { - return SWITCH_LOG_INVALID - 1; - } else if (x < 0) { - return 0; - } else { - return x; - } - } - - - for (x = 0;; x++) { - if (!LOG_LEVEL_NAMES[x]) { - break; - } - - if (!strcasecmp(LOG_LEVEL_NAMES[x], str)) { - level = LOG_LEVEL_VALUES[x]; //(switch_log_level_t) x; - break; - } - } - - return level; -} - -switch_status_t kazoo_config_loglevels(switch_memory_pool_t *pool, switch_xml_t cfg, kazoo_loglevels_ptr *ptr) -{ - switch_xml_t xml_level, xml_logging; - kazoo_loglevels_ptr loglevels = (kazoo_loglevels_ptr) switch_core_alloc(pool, sizeof(kazoo_loglevels_t)); - - loglevels->failed_log_level = SWITCH_LOG_ALERT; - loglevels->filtered_event_log_level = SWITCH_LOG_DEBUG1; - loglevels->filtered_field_log_level = SWITCH_LOG_DEBUG1; - loglevels->info_log_level = SWITCH_LOG_INFO; - loglevels->warn_log_level = SWITCH_LOG_WARNING; - loglevels->success_log_level = SWITCH_LOG_DEBUG; - loglevels->time_log_level = SWITCH_LOG_DEBUG1; - loglevels->trace_log_level = SWITCH_LOG_DEBUG1; - loglevels->debug_log_level = SWITCH_LOG_DEBUG; - loglevels->error_log_level = SWITCH_LOG_ERROR; - loglevels->hashing_log_level = SWITCH_LOG_DEBUG1; - - if ((xml_logging = switch_xml_child(cfg, "logging")) != NULL) { - for (xml_level = switch_xml_child(xml_logging, "log"); xml_level; xml_level = xml_level->next) { - char *var = (char *) switch_xml_attr_soft(xml_level, "name"); - char *val = (char *) switch_xml_attr_soft(xml_level, "value"); - - if (!var) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "logging param missing 'name' attribute\n"); - continue; - } - - if (!val) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "logging param[%s] missing 'value' attribute\n", var); - continue; - } - - if (!strncmp(var, "success", 7)) { - loglevels->success_log_level = log_str2level(val); - } else if (!strncmp(var, "failed", 6)) { - loglevels->failed_log_level = log_str2level(val); - } else if (!strncmp(var, "info", 4)) { - loglevels->info_log_level = log_str2level(val); - } else if (!strncmp(var, "warn", 4)) { - loglevels->warn_log_level = log_str2level(val); - } else if (!strncmp(var, "time", 4)) { - loglevels->time_log_level = log_str2level(val); - } else if (!strncmp(var, "filtered-event", 14)) { - loglevels->filtered_event_log_level = log_str2level(val); - } else if (!strncmp(var, "filtered-field", 14)) { - loglevels->filtered_field_log_level = log_str2level(val); - } else if (!strncmp(var, "trace", 5)) { - loglevels->trace_log_level = log_str2level(val); - } else if (!strncmp(var, "debug", 5)) { - loglevels->debug_log_level = log_str2level(val); - } else if (!strncmp(var, "error", 5)) { - loglevels->error_log_level = log_str2level(val); - } else if (!strncmp(var, "hashing", 7)) { - loglevels->hashing_log_level = log_str2level(val); - } - } /* xml_level for loop */ - } - - *ptr = loglevels; - return SWITCH_STATUS_SUCCESS; - -} - -switch_status_t kazoo_config_filters(switch_memory_pool_t *pool, switch_xml_t cfg, kazoo_filter_ptr *ptr) -{ - switch_xml_t filters, filter; -// char *routing_key = NULL; - kazoo_filter_ptr root = NULL, prv = NULL, cur = NULL; - - - if ((filters = switch_xml_child(cfg, "filters")) != NULL) { - for (filter = switch_xml_child(filters, "filter"); filter; filter = filter->next) { - const char *var = switch_xml_attr(filter, "name"); - const char *val = switch_xml_attr(filter, "value"); - const char *type = switch_xml_attr(filter, "type"); - const char *compare = switch_xml_attr(filter, "compare"); - cur = (kazoo_filter_ptr) switch_core_alloc(pool, sizeof(kazoo_filter)); - memset(cur, 0, sizeof(kazoo_filter)); - if(prv == NULL) { - root = prv = cur; - } else { - prv->next = cur; - prv = cur; - } - cur->type = FILTER_EXCLUDE; - cur->compare = FILTER_COMPARE_VALUE; - - if(var) - cur->name = switch_core_strdup(pool, var); - - if(val) - cur->value = switch_core_strdup(pool, val); - - if(type) { - if (!strncmp(type, "exclude", 7)) { - cur->type = FILTER_EXCLUDE; - } else if (!strncmp(type, "include", 7)) { - cur->type = FILTER_INCLUDE; - } - } - - if(compare) { - if (!strncmp(compare, "value", 7)) { - cur->compare = FILTER_COMPARE_VALUE; - } else if (!strncmp(compare, "prefix", 6)) { - cur->compare = FILTER_COMPARE_PREFIX; - } else if (!strncmp(compare, "list", 4)) { - cur->compare = FILTER_COMPARE_LIST; - } else if (!strncmp(compare, "exists", 6)) { - cur->compare = FILTER_COMPARE_EXISTS; - } else if (!strncmp(compare, "regex", 5)) { - cur->compare = FILTER_COMPARE_REGEX; - } else if (!strncmp(compare, "field", 5)) { - cur->compare = FILTER_COMPARE_FIELD; - } - } - - if(cur->value == NULL) - cur->compare = FILTER_COMPARE_EXISTS; - - if(cur->compare == FILTER_COMPARE_LIST) { - cur->list.size = switch_separate_string(cur->value, '|', cur->list.value, MAX_LIST_FIELDS); - } - - } - - } - - *ptr = root; - - return SWITCH_STATUS_SUCCESS; - -} - -switch_status_t kazoo_config_field(kazoo_config_ptr definitions, switch_memory_pool_t *pool, switch_xml_t cfg, kazoo_field_ptr *ptr) -{ - const char *var = switch_xml_attr(cfg, "name"); - const char *val = switch_xml_attr(cfg, "value"); - const char *as = switch_xml_attr(cfg, "as"); - const char *type = switch_xml_attr(cfg, "type"); - const char *exclude_prefix = switch_xml_attr(cfg, "exclude-prefix"); - const char *serialize_as = switch_xml_attr(cfg, "serialize-as"); - const char *as_array = switch_xml_attr(cfg, "as-array"); - kazoo_field_ptr cur = (kazoo_field_ptr) switch_core_alloc(pool, sizeof(kazoo_field)); - cur->in_type = FIELD_NONE; - cur->out_type = JSON_NONE; - - if(var) - cur->name = switch_core_strdup(pool, var); - - if(val) - cur->value = switch_core_strdup(pool, val); - - if(as) - cur->as = switch_core_strdup(pool, as); - - if(type) { - if (!strncmp(type, "copy", 4)) { - cur->in_type = FIELD_COPY; - } else if (!strncmp(type, "static", 6)) { - cur->in_type = FIELD_STATIC; - } else if (!strncmp(type, "first-of", 8)) { - cur->in_type = FIELD_FIRST_OF; - } else if (!strncmp(type, "expand", 6)) { - cur->in_type = FIELD_EXPAND; - } else if (!strncmp(type, "prefix", 10)) { - cur->in_type = FIELD_PREFIX; - } else if (!strncmp(type, "group", 5)) { - cur->in_type = FIELD_GROUP; - } else if (!strncmp(type, "reference", 9)) { - cur->in_type = FIELD_REFERENCE; - } - } - - if(serialize_as) { - if (!strncmp(serialize_as, "string", 5)) { - cur->out_type = JSON_STRING; - } else if (!strncmp(serialize_as, "number", 6)) { - cur->out_type = JSON_NUMBER; - } else if (!strncmp(serialize_as, "boolean", 7)) { - cur->out_type = JSON_BOOLEAN; - } else if (!strncmp(serialize_as, "object", 6)) { - cur->out_type = JSON_OBJECT; - } else if (!strncmp(serialize_as, "raw", 6)) { - cur->out_type = JSON_RAW; - } - } - - if(as_array) { - cur->out_type_as_array = switch_true(as_array); - } - - if(exclude_prefix) - cur->exclude_prefix = switch_true(exclude_prefix); - - kazoo_config_filters(pool, cfg, &cur->filter); - kazoo_config_fields(definitions, pool, cfg, &cur->children); - - if(cur->children != NULL - && (cur->in_type == FIELD_STATIC) - && (cur->out_type == JSON_NONE) - ) { - cur->out_type = JSON_OBJECT; - } - if(cur->in_type == FIELD_NONE) { - cur->in_type = FIELD_COPY; - } - - if(cur->out_type == JSON_NONE) { - cur->out_type = JSON_STRING; - } - - if(cur->in_type == FIELD_FIRST_OF) { - cur->list.size = switch_separate_string(cur->value, '|', cur->list.value, MAX_LIST_FIELDS); - } - - if(cur->in_type == FIELD_REFERENCE) { - cur->ref = (kazoo_definition_ptr)switch_core_hash_find(definitions->hash, cur->name); - if(cur->ref == NULL) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "referenced field %s not found\n", cur->name); - } - } - - *ptr = cur; - - return SWITCH_STATUS_SUCCESS; - -} - -switch_status_t kazoo_config_fields_loop(kazoo_config_ptr definitions, switch_memory_pool_t *pool, switch_xml_t cfg, kazoo_field_ptr *ptr) -{ - switch_xml_t field; - kazoo_field_ptr root = NULL, prv = NULL; - - - for (field = switch_xml_child(cfg, "field"); field; field = field->next) { - kazoo_field_ptr cur = NULL; - kazoo_config_field(definitions, pool, field, &cur); - if(root == NULL) { - root = prv = cur; - } else { - prv->next = cur; - prv = cur; - } - } - - *ptr = root; - - return SWITCH_STATUS_SUCCESS; - -} - -switch_status_t kazoo_config_fields(kazoo_config_ptr definitions, switch_memory_pool_t *pool, switch_xml_t cfg, kazoo_fields_ptr *ptr) -{ - switch_xml_t fields; - kazoo_fields_ptr root = NULL; - - - if ((fields = switch_xml_child(cfg, "fields")) != NULL) { - const char *verbose = switch_xml_attr(fields, "verbose"); - root = (kazoo_fields_ptr) switch_core_alloc(pool, sizeof(kazoo_fields)); - root->verbose = SWITCH_TRUE; - if(verbose) { - root->verbose = switch_true(verbose); - } - - kazoo_config_fields_loop(definitions, pool, fields, &root->head); - - } - - *ptr = root; - - return SWITCH_STATUS_SUCCESS; - -} - -kazoo_config_ptr kazoo_config_event_handlers(kazoo_config_ptr definitions, switch_xml_t cfg) -{ - switch_xml_t xml_profiles = NULL, xml_profile = NULL; - kazoo_config_ptr profiles = NULL; - switch_memory_pool_t *pool = NULL; - - if (switch_core_new_memory_pool(&pool) != SWITCH_STATUS_SUCCESS) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "error creating memory pool for producers\n"); - return NULL; - } - - profiles = switch_core_alloc(pool, sizeof(kazoo_config)); - profiles->pool = pool; - switch_core_hash_init(&profiles->hash); - - if ((xml_profiles = switch_xml_child(cfg, "event-handlers"))) { - if ((xml_profile = switch_xml_child(xml_profiles, "profile"))) { - for (; xml_profile; xml_profile = xml_profile->next) { - const char *name = switch_xml_attr(xml_profile, "name"); - if(name == NULL) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "missing attr name\n" ); - continue; - } - kazoo_config_event_handler(definitions, profiles, xml_profile, NULL); - } - } else { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "unable to locate a event-handler profile for kazoo\n" ); - } - } else { - destroy_config(&profiles); - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "unable to locate event-handlers section for kazoo, using default\n" ); - } - - return profiles; - -} - -kazoo_config_ptr kazoo_config_fetch_handlers(kazoo_config_ptr definitions, switch_xml_t cfg) -{ - switch_xml_t xml_profiles = NULL, xml_profile = NULL; - kazoo_config_ptr profiles = NULL; - switch_memory_pool_t *pool = NULL; - - if (switch_core_new_memory_pool(&pool) != SWITCH_STATUS_SUCCESS) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "error creating memory pool for producers\n"); - return NULL; - } - - profiles = switch_core_alloc(pool, sizeof(kazoo_config)); - profiles->pool = pool; - switch_core_hash_init(&profiles->hash); - - if ((xml_profiles = switch_xml_child(cfg, "fetch-handlers"))) { - if ((xml_profile = switch_xml_child(xml_profiles, "profile"))) { - for (; xml_profile; xml_profile = xml_profile->next) { - const char *name = switch_xml_attr(xml_profile, "name"); - if(name == NULL) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "missing attr name\n" ); - continue; - } - kazoo_config_fetch_handler(definitions, profiles, xml_profile, NULL); - } - } else { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "unable to locate a fetch-handler profile for kazoo\n" ); - } - } else { - destroy_config(&profiles); - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "unable to locate fetch-handlers section for kazoo, using default\n" ); - } - - return profiles; - -} - - -switch_status_t kazoo_config_definition(kazoo_config_ptr root, switch_xml_t cfg) -{ - kazoo_definition_ptr definition = NULL; - char *name = (char *) switch_xml_attr_soft(cfg, "name"); - - if (zstr(name)) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "failed to load kazoo profile, check definition missing name attr\n"); - return SWITCH_STATUS_GENERR; - } - - definition = switch_core_alloc(root->pool, sizeof(kazoo_definition)); - definition->name = switch_core_strdup(root->pool, name); - - kazoo_config_filters(root->pool, cfg, &definition->filter); - kazoo_config_fields_loop(root, root->pool, cfg, &definition->head); - - if ( switch_core_hash_insert(root->hash, name, (void *) definition) != SWITCH_STATUS_SUCCESS) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "failed to insert new definition [%s] into kazoo definitions hash\n", name); - return SWITCH_STATUS_GENERR; - } - - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "definition[%s] successfully configured\n", definition->name); - return SWITCH_STATUS_SUCCESS; -} - -kazoo_config_ptr kazoo_config_definitions(switch_xml_t cfg) -{ - switch_xml_t xml_definitions = NULL, xml_definition = NULL; - kazoo_config_ptr definitions = NULL; - switch_memory_pool_t *pool = NULL; - - if (switch_core_new_memory_pool(&pool) != SWITCH_STATUS_SUCCESS) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "error creating memory pool for definitions\n"); - return NULL; - } - - definitions = switch_core_alloc(pool, sizeof(kazoo_config)); - definitions->pool = pool; - switch_core_hash_init(&definitions->hash); - - if ((xml_definitions = switch_xml_child(cfg, "definitions"))) { - if ((xml_definition = switch_xml_child(xml_definitions, "definition"))) { - for (; xml_definition; xml_definition = xml_definition->next) { - kazoo_config_definition(definitions, xml_definition); - } - } else { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "no definitions for kazoo\n" ); - } - } else { - destroy_config(&definitions); - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "unable to locate definitions section for kazoo, using default\n" ); - } - - return definitions; -} - -void destroy_config(kazoo_config_ptr *ptr) -{ - kazoo_config_ptr config = NULL; - switch_memory_pool_t *pool; - - if (!ptr || !*ptr) { - return; - } - config = *ptr; - pool = config->pool; - - switch_core_hash_destroy(&(config->hash)); - switch_core_destroy_memory_pool(&pool); - - *ptr = NULL; -} - -/* For Emacs: - * Local Variables: - * mode:c - * indent-tabs-mode:t - * tab-width:4 - * c-basic-offset:4 - * End: - * For VIM: - * vim:set softtabstop=4 shiftwidth=4 tabstop=4 - */ diff --git a/src/mod/event_handlers/mod_kazoo/kazoo_config.h b/src/mod/event_handlers/mod_kazoo/kazoo_config.h deleted file mode 100644 index d0117fda5f6..00000000000 --- a/src/mod/event_handlers/mod_kazoo/kazoo_config.h +++ /dev/null @@ -1,63 +0,0 @@ -/* -* FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application -* Copyright (C) 2005-2012, Anthony Minessale II -* -* 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 -* Portions created by the Initial Developer are Copyright (C) -* the Initial Developer. All Rights Reserved. -* -* Based on mod_skel by -* Anthony Minessale II -* -* Contributor(s): -* -* Daniel Bryars -* Tim Brown -* Anthony Minessale II -* William King -* Mike Jerris -* -* kazoo.c -- Sends FreeSWITCH events to an AMQP broker -* -*/ - -#ifndef KAZOO_CONFIG_H -#define KAZOO_CONFIG_H - -#include - - -struct kazoo_config_t { - switch_hash_t *hash; - switch_memory_pool_t *pool; -}; - -switch_status_t kazoo_config_loglevels(switch_memory_pool_t *pool, switch_xml_t cfg, kazoo_loglevels_ptr *ptr); -switch_status_t kazoo_config_filters(switch_memory_pool_t *pool, switch_xml_t cfg, kazoo_filter_ptr *ptr); -switch_status_t kazoo_config_fields(kazoo_config_ptr definitions, switch_memory_pool_t *pool, switch_xml_t cfg, kazoo_fields_ptr *ptr); - -switch_status_t kazoo_config_event_handler(kazoo_config_ptr definitions, kazoo_config_ptr root, switch_xml_t cfg, kazoo_event_profile_ptr *ptr); -switch_status_t kazoo_config_fetch_handler(kazoo_config_ptr definitions, kazoo_config_ptr root, switch_xml_t cfg, kazoo_fetch_profile_ptr *ptr); -kazoo_config_ptr kazoo_config_event_handlers(kazoo_config_ptr definitions, switch_xml_t cfg); -kazoo_config_ptr kazoo_config_fetch_handlers(kazoo_config_ptr definitions, switch_xml_t cfg); -kazoo_config_ptr kazoo_config_definitions(switch_xml_t cfg); -switch_status_t kazoo_config_field(kazoo_config_ptr definitions, switch_memory_pool_t *pool, switch_xml_t cfg, kazoo_field_ptr *ptr); -void destroy_config(kazoo_config_ptr *ptr); - -#endif /* KAZOO_CONFIG_H */ - diff --git a/src/mod/event_handlers/mod_kazoo/kazoo_definitions.S b/src/mod/event_handlers/mod_kazoo/kazoo_definitions.S deleted file mode 100644 index 0bbe0137cbb..00000000000 --- a/src/mod/event_handlers/mod_kazoo/kazoo_definitions.S +++ /dev/null @@ -1,8 +0,0 @@ - .global kz_default_config - .global kz_default_config_size - .section .rodata -kz_default_config: - .incbin "kazoo.conf.xml" -1: -kz_default_config_size: - .int 1b - kz_default_config diff --git a/src/mod/event_handlers/mod_kazoo/kazoo_defs.h b/src/mod/event_handlers/mod_kazoo/kazoo_defs.h deleted file mode 100644 index 7fe86dd3549..00000000000 --- a/src/mod/event_handlers/mod_kazoo/kazoo_defs.h +++ /dev/null @@ -1,9 +0,0 @@ -#ifndef KAZOO_DEFS_H_ -#define KAZOO_DEFS_H_ - -#define INTERACTION_VARIABLE "Call-Interaction-ID" - -#define UNIX_EPOCH_IN_GREGORIAN 62167219200 -#define UNIX_EPOCH_IN_GREGORIAN_STR "62167219200" - -#endif /* KAZOO_DEFS_H_ */ diff --git a/src/mod/event_handlers/mod_kazoo/kazoo_dptools.c b/src/mod/event_handlers/mod_kazoo/kazoo_dptools.c deleted file mode 100644 index 5a016509694..00000000000 --- a/src/mod/event_handlers/mod_kazoo/kazoo_dptools.c +++ /dev/null @@ -1,980 +0,0 @@ -/* - * FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application - * Copyright (C) 2005-2012, Anthony Minessale II - * - * 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 - * Portions created by the Initial Developer are Copyright (C) - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * - * Karl Anderson - * Darren Schreiber - * - * - * kazoo_dptools.c -- clones of mod_dptools commands slightly modified for kazoo - * - */ -#include "mod_kazoo.h" - -#define SET_SHORT_DESC "Set a channel variable" -#define SET_LONG_DESC "Set a channel variable for the channel calling the application." -#define SET_SYNTAX "=" - -#define MULTISET_SHORT_DESC "Set many channel variables" -#define MULTISET_LONG_DESC "Set many channel variables for the channel calling the application" -#define MULTISET_SYNTAX "[^^]= =" - -#define UNSET_SHORT_DESC "Unset a channel variable" -#define UNSET_LONG_DESC "Unset a channel variable for the channel calling the application." -#define UNSET_SYNTAX "" - -#define MULTIUNSET_SHORT_DESC "Unset many channel variables" -#define MULTIUNSET_LONG_DESC "Unset many channel variables for the channel calling the application." -#define MULTIUNSET_SYNTAX "[^^] " - -#define EXPORT_SHORT_DESC "Export many channel variables" -#define EXPORT_LONG_DESC "Export many channel variables for the channel calling the application" -#define EXPORT_SYNTAX "[^^]= =" - -#define PREFIX_UNSET_SHORT_DESC "clear variables by prefix" -#define PREFIX_UNSET_LONG_DESC "clears the channel variables that start with prefix supplied" -#define PREFIX_UNSET_SYNTAX "" - -#define UUID_MULTISET_SHORT_DESC "Set many channel variables" -#define UUID_MULTISET_LONG_DESC "Set many channel variables for a specific channel" -#define UUID_MULTISET_SYNTAX " [^^]= =" - -#define KZ_ENDLESS_PLAYBACK_SHORT_DESC "Playback File Endlessly until break" -#define KZ_ENDLESS_PLAYBACK_LONG_DESC "Endlessly Playback a file to the channel until a break occurs" -#define KZ_ENDLESS_PLAYBACK_SYNTAX "" - -#define NOOP_SHORT_DESC "no operation" -#define NOOP_LONG_DESC "no operation. serves as a control point" -#define NOOP_SYNTAX "[]" - -static void base_set (switch_core_session_t *session, const char *data, int urldecode, switch_stack_t stack) -{ - char *var, *val = NULL; - - if (zstr(data)) { - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "No variable name specified.\n"); - } else { - switch_channel_t *channel = switch_core_session_get_channel(session); - char *expanded = NULL; - - var = switch_core_session_strdup(session, data); - - if (!(val = strchr(var, '='))) { - val = strchr(var, ','); - } - - if (val) { - *val++ = '\0'; - if (zstr(val)) { - val = NULL; - } - } - - if (val) { - if(urldecode) { - switch_url_decode(val); - } - expanded = switch_channel_expand_variables(channel, val); - } - - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "%s SET [%s]=[%s] => [%s]\n", switch_channel_get_name(channel), var, val, - expanded ? expanded : "UNDEF"); - switch_channel_add_variable_var_check(channel, var, expanded, SWITCH_FALSE, stack); - kz_check_set_profile_var(channel, var, expanded); - if (expanded && expanded != val) { - switch_safe_free(expanded); - } - } -} - -static int kz_is_exported(switch_core_session_t *session, char *varname) -{ - char *array[256] = {0}; - int i, argc; - switch_channel_t *channel = switch_core_session_get_channel(session); - const char *exports = switch_channel_get_variable(channel, SWITCH_EXPORT_VARS_VARIABLE); - char *arg = switch_core_session_strdup(session, exports); - argc = switch_split(arg, ',', array); - for(i=0; i < argc; i++) { - if(!strcasecmp(array[i], varname)) - return 1; - } - - return 0; -} - -static void base_export (switch_core_session_t *session, const char *data, int urldecode, switch_stack_t stack) -{ - char *var, *val = NULL; - - if (zstr(data)) { - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "No variable name specified.\n"); - } else { - switch_channel_t *channel = switch_core_session_get_channel(session); - char *expanded = NULL; - - var = switch_core_session_strdup(session, data); - - if (!(val = strchr(var, '='))) { - val = strchr(var, ','); - } - - if (val) { - *val++ = '\0'; - if (zstr(val)) { - val = NULL; - } - } - - if (val) { - if(urldecode) { - switch_url_decode(val); - } - expanded = switch_channel_expand_variables(channel, val); - - if(!kz_is_exported(session, var)) { - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "%s EXPORT [%s]=[%s]\n", switch_channel_get_name(channel), var, expanded ? expanded : "UNDEF"); - switch_channel_export_variable_var_check(channel, var, expanded, SWITCH_EXPORT_VARS_VARIABLE, SWITCH_FALSE); - } else { - if(strcmp(switch_str_nil(switch_channel_get_variable_dup(channel, var, SWITCH_FALSE, -1)), expanded)) { - switch_channel_set_variable(channel, var, expanded); - } - } - if (expanded && expanded != val) { - switch_safe_free(expanded); - } - } - } -} - -SWITCH_STANDARD_APP(prefix_unset_function) -{ - switch_channel_t *channel = switch_core_session_get_channel(session); - switch_event_header_t *ei = NULL; - switch_event_t *clear; - char *arg = (char *) data; - - if(switch_event_create(&clear, SWITCH_EVENT_CLONE) != SWITCH_STATUS_SUCCESS) { - return; - } - - for (ei = switch_channel_variable_first(channel); ei; ei = ei->next) { - const char *name = ei->name; - char *value = ei->value; - if (!strncasecmp(name, arg, strlen(arg))) { - switch_event_add_header_string(clear, SWITCH_STACK_BOTTOM, name, value); - } - } - - switch_channel_variable_last(channel); - for (ei = clear->headers; ei; ei = ei->next) { - char *varname = ei->name; - switch_channel_set_variable(channel, varname, NULL); - } - - switch_event_destroy(&clear); -} - -void kz_multiset(switch_core_session_t *session, const char* data, int urldecode) -{ - char delim = ' '; - char *arg = (char *) data; - switch_event_t *event; - - if (!zstr(arg) && *arg == '^' && *(arg+1) == '^') { - arg += 2; - delim = *arg++; - } - - if(delim != '\0') { - switch_channel_t *channel = switch_core_session_get_channel(session); - if (arg) { - char *array[256] = {0}; - int i, argc; - - arg = switch_core_session_strdup(session, arg); - argc = switch_split(arg, delim, array); - - for(i = 0; i < argc; i++) { - base_set(session, array[i], urldecode, SWITCH_STACK_BOTTOM); - } - } - if (switch_event_create(&event, SWITCH_EVENT_CHANNEL_DATA) == SWITCH_STATUS_SUCCESS) { - switch_channel_event_set_data(channel, event); - switch_event_fire(&event); - } - } else { - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "multiset with empty args\n"); - } -} - -SWITCH_STANDARD_APP(multiset_function) -{ - kz_multiset(session, data, 0); -} - -SWITCH_STANDARD_APP(multiset_encoded_function) -{ - kz_multiset(session, data, 1); -} - -void kz_uuid_multiset(switch_core_session_t *session, const char* data, int urldecode) -{ - char delim = ' '; - char *arg0 = (char *) data; - char *arg = strchr(arg0, ' '); - switch_event_t *event; - - - if(arg == NULL) { - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "uuid_multiset with invalid args\n"); - return; - } - *arg = '\0'; - arg++; - - if(zstr(arg0)) { - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "uuid_multiset with invalid uuid\n"); - return; - } - - - if (!zstr(arg) && *arg == '^' && *(arg+1) == '^') { - arg += 2; - delim = *arg++; - } - - if(delim != '\0') { - switch_core_session_t *uuid_session = NULL; - if ((uuid_session = switch_core_session_locate(arg0)) != NULL) { - switch_channel_t *uuid_channel = switch_core_session_get_channel(uuid_session); - if (arg) { - char *array[256] = {0}; - int i, argc; - - arg = switch_core_session_strdup(session, arg); - argc = switch_split(arg, delim, array); - - for(i = 0; i < argc; i++) { - base_set(uuid_session, array[i], urldecode, SWITCH_STACK_BOTTOM); - } - } - if (switch_event_create(&event, SWITCH_EVENT_CHANNEL_DATA) == SWITCH_STATUS_SUCCESS) { - switch_channel_event_set_data(uuid_channel, event); - switch_event_fire(&event); - } - switch_core_session_rwunlock(uuid_session); - } else { - base_set(session, data, urldecode, SWITCH_STACK_BOTTOM); - } - } else { - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "multiset with empty args\n"); - } -} - -SWITCH_STANDARD_APP(uuid_multiset_function) -{ - kz_uuid_multiset(session, data, 0); -} - -SWITCH_STANDARD_APP(uuid_multiset_encoded_function) -{ - kz_uuid_multiset(session, data, 1); -} - -void kz_set(switch_core_session_t *session, const char* data, int urldecode) { - switch_channel_t *channel = switch_core_session_get_channel(session); - switch_event_t *event; - - base_set(session, data, urldecode, SWITCH_STACK_BOTTOM); - - if (switch_event_create(&event, SWITCH_EVENT_CHANNEL_DATA) == SWITCH_STATUS_SUCCESS) { - switch_channel_event_set_data(channel, event); - switch_event_fire(&event); - } -} - -SWITCH_STANDARD_APP(set_function) -{ - kz_set(session, data, 0); -} - -SWITCH_STANDARD_APP(set_encoded_function) -{ - kz_set(session, data, 1); -} - -SWITCH_STANDARD_APP(unset_function) { - switch_channel_t *channel = switch_core_session_get_channel(session); - switch_event_t *event; - - if (zstr(data)) { - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "No variable name specified.\n"); - } else { - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "UNSET [%s]\n", (char *) data); - switch_channel_set_variable(switch_core_session_get_channel(session), data, NULL); - } - - if (switch_event_create(&event, SWITCH_EVENT_CHANNEL_DATA) == SWITCH_STATUS_SUCCESS) { - switch_channel_event_set_data(channel, event); - switch_event_fire(&event); - } -} - -SWITCH_STANDARD_APP(multiunset_function) { - char delim = ' '; - char *arg = (char *) data; - - if (!zstr(arg) && *arg == '^' && *(arg+1) == '^') { - arg += 2; - delim = *arg++; - } - - if(delim != '\0') { - if (arg) { - char *array[256] = {0}; - int i, argc; - - arg = switch_core_session_strdup(session, arg); - argc = switch_split(arg, delim, array); - - for(i = 0; i < argc; i++) { - switch_channel_set_variable(switch_core_session_get_channel(session), array[i], NULL); - } - - } else { - switch_channel_set_variable(switch_core_session_get_channel(session), arg, NULL); - } - } else { - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "multiunset with empty args\n"); - } -} - - -void kz_export(switch_core_session_t *session, const char* data, int urldecode) -{ - char delim = ' '; - char *arg = (char *) data; - - if (!zstr(arg) && *arg == '^' && *(arg+1) == '^') { - arg += 2; - delim = *arg++; - } - - if(delim != '\0') { - if (arg) { - char *array[256] = {0}; - int i, argc; - - arg = switch_core_session_strdup(session, arg); - argc = switch_split(arg, delim, array); - - for(i = 0; i < argc; i++) { - base_export(session, array[i], urldecode, SWITCH_STACK_BOTTOM); - } - } else { - base_export(session, data, urldecode, SWITCH_STACK_BOTTOM); - } - } else { - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "export with empty args\n"); - } -} - -SWITCH_STANDARD_APP(export_function) -{ - kz_export(session, data, 0); -} - -SWITCH_STANDARD_APP(export_encoded_function) -{ - kz_export(session, data, 1); -} - -// copied from mod_dptools with allow SWITCH_STATUS_BREAK -SWITCH_STANDARD_APP(kz_endless_playback_function) -{ - switch_channel_t *channel = switch_core_session_get_channel(session); - switch_status_t status = SWITCH_STATUS_SUCCESS; - const char *file = data; - - while (switch_channel_ready(channel)) { - status = switch_ivr_play_file(session, NULL, file, NULL); - - if (status != SWITCH_STATUS_SUCCESS) { - break; - } - } - - switch (status) { - case SWITCH_STATUS_SUCCESS: - switch_channel_set_variable(channel, SWITCH_CURRENT_APPLICATION_RESPONSE_VARIABLE, "FILE PLAYED"); - break; - case SWITCH_STATUS_BREAK: - switch_channel_set_variable(channel, SWITCH_CURRENT_APPLICATION_RESPONSE_VARIABLE, "PLAYBACK_INTERRUPTED"); - break; - case SWITCH_STATUS_NOTFOUND: - switch_channel_set_variable(channel, SWITCH_CURRENT_APPLICATION_RESPONSE_VARIABLE, "FILE NOT FOUND"); - break; - default: - switch_channel_set_variable(channel, SWITCH_CURRENT_APPLICATION_RESPONSE_VARIABLE, "PLAYBACK ERROR"); - break; - } - -} - -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; - char * my_data = NULL; - - 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, ""); - - /* - * hack for proper position - */ - if (!strncmp(data, "http_cache://", 13) && session) { - switch_channel_t *channel = switch_core_session_get_channel(session); - char * resolve = switch_mprintf("${http_get({prefetch=true}%s)}", data+13); - my_data = switch_channel_expand_variables_check(channel, resolve, NULL, NULL, 0); - } else { - my_data = strdup(data); - } - - status = switch_ivr_play_file(session, &fh, my_data, NULL); -// 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 %" SWITCH_INT64_T_FMT "\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 %" SWITCH_INT64_T_FMT "\n", fh.pos); - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG1, "MOH sample_count %" SWITCH_SIZE_T_FMT "\n", fh.sample_count); - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG1, "MOH samples %d\n", fh.samples); - - switch_safe_free(my_data); -} - -SWITCH_STANDARD_APP(noop_function) -{ - switch_channel_t *channel = switch_core_session_get_channel(session); - char uuid_str[SWITCH_UUID_FORMATTED_LENGTH + 1]; - const char *response = uuid_str; - - if (zstr(data)) { - switch_uuid_str(uuid_str, sizeof(uuid_str)); - } else { - response = data; - } - - switch_channel_set_variable(channel, SWITCH_CURRENT_APPLICATION_RESPONSE_VARIABLE, response); -} - -SWITCH_STANDARD_APP(kz_restore_caller_id_function) -{ - switch_channel_t *channel = switch_core_session_get_channel(session); - switch_caller_profile_t *cp = switch_channel_get_caller_profile(channel); - cp->caller_id_name = cp->orig_caller_id_name; - cp->caller_id_number = cp->orig_caller_id_number; -} - -SWITCH_STANDARD_APP(kz_audio_bridge_function) -{ - switch_channel_t *caller_channel = switch_core_session_get_channel(session); - switch_core_session_t *peer_session = NULL; - switch_call_cause_t cause = SWITCH_CAUSE_NORMAL_CLEARING; - switch_status_t status = SWITCH_STATUS_FALSE; - - if (zstr(data)) { - return; - } - - status = switch_ivr_originate(session, &peer_session, &cause, data, 0, NULL, NULL, NULL, NULL, NULL, SOF_NONE, NULL, NULL); - - if (status != SWITCH_STATUS_SUCCESS) { - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_INFO, "Originate Failed. Cause: %s\n", switch_channel_cause2str(cause)); - - switch_channel_set_variable(caller_channel, "originate_failed_cause", switch_channel_cause2str(cause)); - switch_channel_set_variable(caller_channel, SWITCH_CURRENT_APPLICATION_RESPONSE_VARIABLE, switch_channel_cause2str(cause)); - switch_channel_handle_cause(caller_channel, cause); - - return; - } else { - const char* uuid = switch_core_session_get_uuid(session); - const char* peer_uuid = switch_core_session_get_uuid(peer_session); - - - switch_channel_t *peer_channel = switch_core_session_get_channel(peer_session); - if (switch_true(switch_channel_get_variable(caller_channel, SWITCH_BYPASS_MEDIA_AFTER_BRIDGE_VARIABLE)) || - switch_true(switch_channel_get_variable(peer_channel, SWITCH_BYPASS_MEDIA_AFTER_BRIDGE_VARIABLE))) { - switch_channel_set_flag(caller_channel, CF_BYPASS_MEDIA_AFTER_BRIDGE); - } - - while(1) { - const char *xfer_uuid; - switch_channel_state_t a_state , a_running_state; - switch_channel_state_t b_state , b_running_state; - status = switch_ivr_multi_threaded_bridge(session, peer_session, NULL, NULL, NULL); - - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "BRIDGE RESULT %i\n", status); - if(status != 0) { - break; - } - - a_state = switch_channel_get_state(caller_channel); - a_running_state = switch_channel_get_running_state(caller_channel); - - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "A STATE %s %s => %s , %s\n", switch_channel_state_name(a_running_state), switch_channel_state_name(a_state), uuid, peer_uuid); - - if(a_state >= CS_HANGUP) { - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "A HANGUP = %s , %s\n", uuid, peer_uuid); - break; - } - - b_state = switch_channel_get_state(peer_channel); - b_running_state = switch_channel_get_running_state(peer_channel); - - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "B STATE %s %s => %s , %s\n", switch_channel_state_name(b_running_state), switch_channel_state_name(b_state), uuid, peer_uuid); - - if(b_state >= CS_HANGUP) { - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "B HANGUP = %s , %s\n", uuid, peer_uuid); - switch_channel_set_variable(caller_channel, SWITCH_CURRENT_APPLICATION_RESPONSE_VARIABLE, switch_channel_cause2str(switch_channel_get_cause(peer_channel))); - break; - } - - if(!(xfer_uuid=switch_channel_get_variable(caller_channel, "att_xfer_peer_uuid"))) { - if(!(xfer_uuid=switch_channel_get_variable(peer_channel, "att_xfer_peer_uuid"))) { - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "XFER UUID NULL\n"); - break; - } - } - - switch_channel_set_variable(caller_channel, "att_xfer_peer_uuid", NULL); - switch_channel_set_variable(peer_channel, "att_xfer_peer_uuid", NULL); - - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "WAIT 1\n"); - - switch_channel_clear_flag(peer_channel, CF_UUID_BRIDGE_ORIGINATOR); - switch_channel_set_state(peer_channel, CS_RESET); - switch_channel_wait_for_state(peer_channel, NULL, CS_RESET); - switch_channel_clear_state_handler(peer_channel, NULL); - - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "WAIT 3\n"); - - switch_channel_set_flag(caller_channel, CF_UUID_BRIDGE_ORIGINATOR); - switch_channel_clear_flag(caller_channel, CF_TRANSFER); - switch_channel_clear_flag(caller_channel, CF_REDIRECT); - switch_channel_set_flag(peer_channel, CF_UUID_BRIDGE_ORIGINATOR); - switch_channel_clear_flag(peer_channel, CF_TRANSFER); - switch_channel_clear_flag(peer_channel, CF_REDIRECT); - - if(!switch_channel_media_up(caller_channel)) { - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "A MEDIA DOWN HANGUP = %s, %s , %s\n", xfer_uuid, uuid, peer_uuid); - } - if(!switch_channel_media_up(peer_channel)) { - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "B MEDIA DOWN HANGUP = %s, %s , %s\n", xfer_uuid, uuid, peer_uuid); - } - switch_channel_set_state(caller_channel, CS_EXECUTE); - switch_channel_set_state(peer_channel, CS_EXECUTE); - - - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "XFER LOOP %s %s , %s\n", xfer_uuid, uuid, peer_uuid); - - } - - if (peer_session) { - switch_core_session_rwunlock(peer_session); - } - } -} - -SWITCH_STANDARD_APP(kz_audio_bridge_uuid_function) -{ - switch_core_session_t *peer_session = NULL; - const char * peer_uuid = NULL; - - if (zstr(data)) { - return; - } - - peer_uuid = switch_core_session_strdup(session, data); - if (peer_uuid && (peer_session = switch_core_session_locate(peer_uuid))) { - switch_ivr_multi_threaded_bridge(session, peer_session, NULL, NULL, NULL); - } - - if (peer_session) { - switch_core_session_rwunlock(peer_session); - } -} - - -struct kz_att_keys { - const char *attxfer_cancel_key; - const char *attxfer_hangup_key; - const char *attxfer_conf_key; -}; - -static switch_status_t kz_att_xfer_on_dtmf(switch_core_session_t *session, void *input, switch_input_type_t itype, void *buf, unsigned int buflen) -{ - switch_core_session_t *peer_session = (switch_core_session_t *) buf; - if (!buf || !peer_session) { - return SWITCH_STATUS_SUCCESS; - } - - switch (itype) { - case SWITCH_INPUT_TYPE_DTMF: - { - switch_dtmf_t *dtmf = (switch_dtmf_t *) input; - switch_channel_t *channel = switch_core_session_get_channel(session); - switch_channel_t *peer_channel = switch_core_session_get_channel(peer_session); - struct kz_att_keys *keys = switch_channel_get_private(channel, "__kz_keys"); - - if (dtmf->digit == *keys->attxfer_hangup_key) { - switch_channel_hangup(channel, SWITCH_CAUSE_ATTENDED_TRANSFER); - return SWITCH_STATUS_FALSE; - } - - if (dtmf->digit == *keys->attxfer_cancel_key) { - switch_channel_hangup(peer_channel, SWITCH_CAUSE_NORMAL_CLEARING); - return SWITCH_STATUS_FALSE; - } - - if (dtmf->digit == *keys->attxfer_conf_key) { - switch_caller_extension_t *extension = NULL; - const char *app = "three_way"; - const char *app_arg = switch_core_session_get_uuid(session); - const char *holding = switch_channel_get_variable(channel, SWITCH_SOFT_HOLDING_UUID_VARIABLE); - switch_core_session_t *b_session; - - if (holding && (b_session = switch_core_session_locate(holding))) { - switch_channel_t *b_channel = switch_core_session_get_channel(b_session); - if (!switch_channel_ready(b_channel)) { - app = "intercept"; - } - switch_core_session_rwunlock(b_session); - } - - if ((extension = switch_caller_extension_new(peer_session, app, app_arg)) == 0) { - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_CRIT, "Memory Error!\n"); - abort(); - } - - switch_caller_extension_add_application(peer_session, extension, app, app_arg); - switch_channel_set_caller_extension(peer_channel, extension); - switch_channel_set_state(peer_channel, CS_RESET); - switch_channel_wait_for_state(peer_channel, channel, CS_RESET); - switch_channel_set_state(peer_channel, CS_EXECUTE); - switch_channel_set_variable(channel, SWITCH_HANGUP_AFTER_BRIDGE_VARIABLE, NULL); - return SWITCH_STATUS_FALSE; - } - - } - break; - default: - break; - } - - return SWITCH_STATUS_SUCCESS; -} - -static switch_status_t kz_att_xfer_tmp_hanguphook(switch_core_session_t *session) -{ - switch_channel_t *channel = switch_core_session_get_channel(session); - switch_channel_state_t state = switch_channel_get_state(channel); - - if (state == CS_HANGUP || state == CS_ROUTING) { - const char *bond = switch_channel_get_variable(channel, SWITCH_SOFT_HOLDING_UUID_VARIABLE); - - if (!zstr(bond)) { - switch_core_session_t *b_session; - - if ((b_session = switch_core_session_locate(bond))) { - switch_channel_t *b_channel = switch_core_session_get_channel(b_session); - if (switch_channel_up(b_channel)) { - switch_channel_set_flag(b_channel, CF_REDIRECT); - } - switch_core_session_rwunlock(b_session); - } - } - - switch_core_event_hook_remove_state_change(session, kz_att_xfer_tmp_hanguphook); - } - - return SWITCH_STATUS_SUCCESS; -} - -static switch_status_t kz_att_xfer_hanguphook(switch_core_session_t *session) -{ - switch_channel_t *channel = switch_core_session_get_channel(session); - switch_channel_state_t state = switch_channel_get_state(channel); - const char *id = NULL; - const char *peer_uuid = NULL; - - if (state == CS_HANGUP || state == CS_ROUTING) { - if ((id = switch_channel_get_variable(channel, "xfer_uuids"))) { - switch_stream_handle_t stream = { 0 }; - SWITCH_STANDARD_STREAM(stream); - if ((peer_uuid = switch_channel_get_variable(channel, "xfer_peer_uuid"))) { - switch_core_session_t *peer_session = NULL; - if ((peer_session = switch_core_session_locate(peer_uuid)) != NULL ) { - switch_ivr_transfer_recordings(session, peer_session); - switch_core_session_rwunlock(peer_session); - } - } - switch_api_execute("uuid_bridge", id, NULL, &stream); - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "\nHangup Command uuid_bridge(%s):\n%s\n", id, - switch_str_nil((char *) stream.data)); - switch_safe_free(stream.data); - } - - switch_core_event_hook_remove_state_change(session, kz_att_xfer_hanguphook); - } - return SWITCH_STATUS_SUCCESS; -} - - -static void kz_att_xfer_set_result(switch_channel_t *channel, switch_status_t status) -{ - switch_channel_set_variable(channel, SWITCH_ATT_XFER_RESULT_VARIABLE, status == SWITCH_STATUS_SUCCESS ? "success" : "failure"); -} - -struct kz_att_obj { - switch_core_session_t *session; - const char *data; - int running; -}; - -void *SWITCH_THREAD_FUNC kz_att_thread_run(switch_thread_t *thread, void *obj) -{ - struct kz_att_obj *att = (struct kz_att_obj *) obj; - struct kz_att_keys *keys = NULL; - switch_core_session_t *session = att->session; - switch_core_session_t *peer_session = NULL; - const char *data = att->data; - switch_call_cause_t cause = SWITCH_CAUSE_NORMAL_CLEARING; - switch_channel_t *channel = switch_core_session_get_channel(session), *peer_channel = NULL; - const char *bond = NULL; - switch_bool_t follow_recording = switch_true(switch_channel_get_variable(channel, "recording_follow_attxfer")); - const char *attxfer_cancel_key = NULL, *attxfer_hangup_key = NULL, *attxfer_conf_key = NULL; - int br = 0; - switch_event_t *event = NULL; - switch_core_session_t *b_session = NULL; - switch_channel_t *b_channel = NULL; - - att->running = 1; - - if (switch_core_session_read_lock(session) != SWITCH_STATUS_SUCCESS) { - return NULL; - } - - bond = switch_channel_get_partner_uuid(channel); - if ((b_session = switch_core_session_locate(bond)) == NULL) { - switch_core_session_rwunlock(session); - return NULL; - } - switch_channel_set_variable(channel, SWITCH_SOFT_HOLDING_UUID_VARIABLE, bond); - switch_core_event_hook_add_state_change(session, kz_att_xfer_tmp_hanguphook); - - if (switch_ivr_originate(session, &peer_session, &cause, data, 0, NULL, NULL, NULL, NULL, NULL, SOF_NONE, NULL, NULL) - != SWITCH_STATUS_SUCCESS || !peer_session) { - switch_channel_set_variable(channel, SWITCH_SIGNAL_BOND_VARIABLE, bond); - goto end; - } - - peer_channel = switch_core_session_get_channel(peer_session); - switch_channel_set_flag(peer_channel, CF_INNER_BRIDGE); - switch_channel_set_flag(channel, CF_INNER_BRIDGE); - - if (!(attxfer_cancel_key = switch_channel_get_variable(channel, "attxfer_cancel_key"))) { - if (!(attxfer_cancel_key = switch_channel_get_variable(peer_channel, "attxfer_cancel_key"))) { - attxfer_cancel_key = "#"; - } - } - - if (!(attxfer_hangup_key = switch_channel_get_variable(channel, "attxfer_hangup_key"))) { - if (!(attxfer_hangup_key = switch_channel_get_variable(peer_channel, "attxfer_hangup_key"))) { - attxfer_hangup_key = "*"; - } - } - - if (!(attxfer_conf_key = switch_channel_get_variable(channel, "attxfer_conf_key"))) { - if (!(attxfer_conf_key = switch_channel_get_variable(peer_channel, "attxfer_conf_key"))) { - attxfer_conf_key = "0"; - } - } - - keys = switch_core_session_alloc(session, sizeof(*keys)); - keys->attxfer_cancel_key = switch_core_session_strdup(session, attxfer_cancel_key); - keys->attxfer_hangup_key = switch_core_session_strdup(session, attxfer_hangup_key); - keys->attxfer_conf_key = switch_core_session_strdup(session, attxfer_conf_key); - switch_channel_set_private(channel, "__kz_keys", keys); - - switch_channel_set_variable(channel, "att_xfer_peer_uuid", switch_core_session_get_uuid(peer_session)); - - switch_ivr_multi_threaded_bridge(session, peer_session, kz_att_xfer_on_dtmf, peer_session, NULL); - - switch_channel_clear_flag(peer_channel, CF_INNER_BRIDGE); - switch_channel_clear_flag(channel, CF_INNER_BRIDGE); - - if (switch_channel_down(peer_channel)) { - switch_core_session_rwunlock(peer_session); - switch_channel_set_variable(channel, SWITCH_SIGNAL_BOND_VARIABLE, bond); - goto end; - } - - /* - * we're emiting the transferee event so that callctl can update - */ - b_channel = switch_core_session_get_channel(b_session); - if (switch_event_create_subclass(&event, SWITCH_EVENT_CUSTOM, "sofia::transferee") == SWITCH_STATUS_SUCCESS) { - switch_channel_event_set_data(b_channel, event); - switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "att_xfer_replaced_call_id", switch_core_session_get_uuid(peer_session)); - switch_event_fire(&event); - } - - if (!switch_channel_ready(channel)) { - switch_status_t status; - - if (follow_recording) { - switch_ivr_transfer_recordings(session, peer_session); - } - status = switch_ivr_uuid_bridge(switch_core_session_get_uuid(peer_session), bond); - kz_att_xfer_set_result(peer_channel, status); - br++; - } else { - // switch_channel_set_variable_printf(b_channel, "xfer_uuids", "%s %s", switch_core_session_get_uuid(peer_session), switch_core_session_get_uuid(session)); - switch_channel_set_variable_printf(channel, "xfer_uuids", "%s %s", switch_core_session_get_uuid(peer_session), bond); - switch_channel_set_variable(channel, "xfer_peer_uuid", switch_core_session_get_uuid(peer_session)); - - switch_core_event_hook_add_state_change(session, kz_att_xfer_hanguphook); - // switch_core_event_hook_add_state_change(b_session, kz_att_xfer_hanguphook); - } - -/* - * this was commented so that the existing bridge - * doesn't end - * - if (!br) { - switch_status_t status = switch_ivr_uuid_bridge(switch_core_session_get_uuid(session), bond); - att_xfer_set_result(channel, status); - } -*/ - - switch_core_session_rwunlock(peer_session); - - end: - - switch_core_event_hook_remove_state_change(session, kz_att_xfer_tmp_hanguphook); - - switch_channel_set_variable(channel, SWITCH_SOFT_HOLDING_UUID_VARIABLE, NULL); - switch_channel_clear_flag(channel, CF_XFER_ZOMBIE); - - switch_core_session_rwunlock(b_session); - switch_core_session_rwunlock(session); - att->running = 0; - - return NULL; -} - -SWITCH_STANDARD_APP(kz_att_xfer_function) -{ - switch_thread_t *thread; - switch_threadattr_t *thd_attr = NULL; - switch_memory_pool_t *pool = switch_core_session_get_pool(session); - struct kz_att_obj *att; - switch_channel_t *channel = switch_core_session_get_channel(session); - - switch_threadattr_create(&thd_attr, pool); - switch_threadattr_detach_set(thd_attr, 1); - switch_threadattr_stacksize_set(thd_attr, SWITCH_THREAD_STACKSIZE); - switch_threadattr_detach_set(thd_attr, 1); - - att = switch_core_session_alloc(session, sizeof(*att)); - att->running = -1; - att->session = session; - att->data = switch_core_session_strdup(session, data); - switch_thread_create(&thread, thd_attr, kz_att_thread_run, att, pool); - - while(att->running && switch_channel_up(channel)) { - switch_yield(100000); - } -} - -void add_kz_dptools(switch_loadable_module_interface_t **module_interface) { - switch_application_interface_t *app_interface = NULL; - SWITCH_ADD_APP(app_interface, "kz_set", SET_SHORT_DESC, SET_LONG_DESC, set_function, SET_SYNTAX, SAF_SUPPORT_NOMEDIA | SAF_ROUTING_EXEC | SAF_ZOMBIE_EXEC); - SWITCH_ADD_APP(app_interface, "kz_set_encoded", SET_SHORT_DESC, SET_LONG_DESC, set_encoded_function, SET_SYNTAX, SAF_SUPPORT_NOMEDIA | SAF_ROUTING_EXEC | SAF_ZOMBIE_EXEC); - SWITCH_ADD_APP(app_interface, "kz_multiset", MULTISET_SHORT_DESC, MULTISET_LONG_DESC, multiset_function, MULTISET_SYNTAX, SAF_SUPPORT_NOMEDIA | SAF_ROUTING_EXEC | SAF_ZOMBIE_EXEC); - SWITCH_ADD_APP(app_interface, "kz_multiset_encoded", MULTISET_SHORT_DESC, MULTISET_LONG_DESC, multiset_encoded_function, MULTISET_SYNTAX, SAF_SUPPORT_NOMEDIA | SAF_ROUTING_EXEC | SAF_ZOMBIE_EXEC); - SWITCH_ADD_APP(app_interface, "kz_unset", UNSET_SHORT_DESC, UNSET_LONG_DESC, unset_function, UNSET_SYNTAX, SAF_SUPPORT_NOMEDIA | SAF_ROUTING_EXEC | SAF_ZOMBIE_EXEC); - SWITCH_ADD_APP(app_interface, "kz_multiunset", MULTISET_SHORT_DESC, MULTISET_LONG_DESC, multiunset_function, MULTIUNSET_SYNTAX, SAF_SUPPORT_NOMEDIA | SAF_ROUTING_EXEC | SAF_ZOMBIE_EXEC); - SWITCH_ADD_APP(app_interface, "kz_export", EXPORT_SHORT_DESC, EXPORT_LONG_DESC, export_function, EXPORT_SYNTAX, SAF_SUPPORT_NOMEDIA | SAF_ROUTING_EXEC | SAF_ZOMBIE_EXEC); - SWITCH_ADD_APP(app_interface, "kz_export_encoded", EXPORT_SHORT_DESC, EXPORT_LONG_DESC, export_encoded_function, EXPORT_SYNTAX, SAF_SUPPORT_NOMEDIA | SAF_ROUTING_EXEC | SAF_ZOMBIE_EXEC); - SWITCH_ADD_APP(app_interface, "kz_prefix_unset", PREFIX_UNSET_SHORT_DESC, PREFIX_UNSET_LONG_DESC, prefix_unset_function, PREFIX_UNSET_SYNTAX, SAF_SUPPORT_NOMEDIA | SAF_ROUTING_EXEC | SAF_ZOMBIE_EXEC); - SWITCH_ADD_APP(app_interface, "kz_uuid_multiset", UUID_MULTISET_SHORT_DESC, UUID_MULTISET_LONG_DESC, uuid_multiset_function, UUID_MULTISET_SYNTAX, SAF_SUPPORT_NOMEDIA | SAF_ROUTING_EXEC | SAF_ZOMBIE_EXEC); - SWITCH_ADD_APP(app_interface, "kz_uuid_multiset_encoded", UUID_MULTISET_SHORT_DESC, UUID_MULTISET_LONG_DESC, uuid_multiset_encoded_function, UUID_MULTISET_SYNTAX, SAF_SUPPORT_NOMEDIA | SAF_ROUTING_EXEC | SAF_ZOMBIE_EXEC); - SWITCH_ADD_APP(app_interface, "kz_endless_playback", KZ_ENDLESS_PLAYBACK_SHORT_DESC, KZ_ENDLESS_PLAYBACK_LONG_DESC, kz_endless_playback_function, KZ_ENDLESS_PLAYBACK_SYNTAX, SAF_NONE); - SWITCH_ADD_APP(app_interface, "kz_restore_caller_id", NOOP_SHORT_DESC, NOOP_LONG_DESC, kz_restore_caller_id_function, NOOP_SYNTAX, SAF_NONE); - SWITCH_ADD_APP(app_interface, "noop", NOOP_SHORT_DESC, NOOP_LONG_DESC, noop_function, NOOP_SYNTAX, SAF_NONE); - SWITCH_ADD_APP(app_interface, "kz_bridge", "Bridge Audio", "Bridge the audio between two sessions", kz_audio_bridge_function, "", 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, "", SAF_SUPPORT_NOMEDIA|SAF_SUPPORT_TEXT_ONLY); - SWITCH_ADD_APP(app_interface, "kz_att_xfer", "Attended Transfer", "Attended Transfer", kz_att_xfer_function, "", SAF_NONE); - SWITCH_ADD_APP(app_interface, "kz_moh", "Kazoo MOH Playback", "Kazoo MOH Playback", kz_moh_function, "", SAF_NONE); -} diff --git a/src/mod/event_handlers/mod_kazoo/kazoo_ei.h b/src/mod/event_handlers/mod_kazoo/kazoo_ei.h deleted file mode 100644 index 5f617b5f1da..00000000000 --- a/src/mod/event_handlers/mod_kazoo/kazoo_ei.h +++ /dev/null @@ -1,295 +0,0 @@ -#ifndef KAZOO_EI_H -#define KAZOO_EI_H - -#include -#include - -#define MODNAME "mod_kazoo" -#define BUNDLE "community" -#define RELEASE "v1.5.0-1" -#define VERSION "mod_kazoo v1.5.0-1 community" - -#define KZ_MAX_SEPARATE_STRINGS 10 -#define HOSTNAME_MAX 1024 -#define NODENAME_MAX 1024 - -typedef enum {KAZOO_FETCH_PROFILE, KAZOO_EVENT_PROFILE} kazoo_profile_type; - -typedef enum {ERLANG_TUPLE, ERLANG_MAP} kazoo_json_term; - -typedef struct ei_xml_agent_s ei_xml_agent_t; -typedef ei_xml_agent_t *ei_xml_agent_ptr; - -typedef struct kazoo_event kazoo_event_t; -typedef kazoo_event_t *kazoo_event_ptr; - -typedef struct kazoo_event_profile kazoo_event_profile_t; -typedef kazoo_event_profile_t *kazoo_event_profile_ptr; - -typedef struct kazoo_fetch_profile kazoo_fetch_profile_t; -typedef kazoo_fetch_profile_t *kazoo_fetch_profile_ptr; - -typedef struct kazoo_config_t kazoo_config; -typedef kazoo_config *kazoo_config_ptr; - -#include "kazoo_fields.h" -#include "kazoo_config.h" - -struct ei_send_msg_s { - ei_x_buff buf; - erlang_pid pid; -}; -typedef struct ei_send_msg_s ei_send_msg_t; - -struct ei_received_msg_s { - ei_x_buff buf; - erlang_msg msg; -}; -typedef struct ei_received_msg_s ei_received_msg_t; - - -typedef struct ei_event_stream_s ei_event_stream_t; -typedef struct ei_node_s ei_node_t; - -struct ei_event_binding_s { - char id[SWITCH_UUID_FORMATTED_LENGTH + 1]; - switch_event_node_t *node; - switch_event_types_t type; - const char *subclass_name; - ei_event_stream_t* stream; - kazoo_event_ptr event; - - struct ei_event_binding_s *next; -}; -typedef struct ei_event_binding_s ei_event_binding_t; - -struct ei_event_stream_s { - switch_memory_pool_t *pool; - ei_event_binding_t *bindings; - switch_queue_t *queue; - switch_socket_t *acceptor; - switch_pollset_t *pollset; - switch_pollfd_t *pollfd; - switch_socket_t *socket; - switch_mutex_t *socket_mutex; - switch_bool_t connected; - switch_time_t connected_time; - char remote_ip[48]; - uint16_t remote_port; - char local_ip[48]; - uint16_t local_port; - erlang_pid pid; - uint32_t flags; - ei_node_t *node; - short event_stream_framing; - short event_stream_keepalive; - switch_interval_time_t queue_timeout; - struct ei_event_stream_s *next; -}; - -struct ei_node_s { - int nodefd; - switch_atomic_t pending_bgapi; - switch_atomic_t receive_handlers; - switch_memory_pool_t *pool; - ei_event_stream_t *event_streams; - switch_mutex_t *event_streams_mutex; - switch_queue_t *send_msgs; - switch_queue_t *received_msgs; - char *peer_nodename; - switch_time_t created_time; - switch_socket_t *socket; - char remote_ip[48]; - uint16_t remote_port; - char local_ip[48]; - uint16_t local_port; - uint32_t flags; - int legacy; - short event_stream_framing; - short event_stream_keepalive; - switch_interval_time_t event_stream_queue_timeout; - switch_interval_time_t receiver_queue_timeout; - switch_interval_time_t sender_queue_timeout; - struct ei_node_s *next; -}; - - -struct xml_fetch_reply_s { - char uuid_str[SWITCH_UUID_FORMATTED_LENGTH + 1]; - char *xml_str; - struct xml_fetch_reply_s *next; -}; -typedef struct xml_fetch_reply_s xml_fetch_reply_t; - -struct fetch_handler_s { - erlang_pid pid; - struct fetch_handler_s *next; -}; -typedef struct fetch_handler_s fetch_handler_t; - -struct ei_xml_client_s { - ei_node_t *ei_node; - fetch_handler_t *fetch_handlers; - struct ei_xml_client_s *next; -}; -typedef struct ei_xml_client_s ei_xml_client_t; - -struct ei_xml_agent_s { - switch_memory_pool_t *pool; - switch_xml_section_t section; - switch_thread_rwlock_t *lock; - ei_xml_client_t *clients; - switch_mutex_t *current_client_mutex; - ei_xml_client_t *current_client; - switch_mutex_t *replies_mutex; - switch_thread_cond_t *new_reply; - xml_fetch_reply_t *replies; - kazoo_fetch_profile_ptr profile; - -}; - -struct kz_globals_s { - switch_memory_pool_t *pool; - switch_atomic_t threads; - switch_socket_t *acceptor; - struct ei_cnode_s ei_cnode; - switch_thread_rwlock_t *ei_nodes_lock; - ei_node_t *ei_nodes; - - switch_xml_binding_t *config_fetch_binding; - switch_xml_binding_t *directory_fetch_binding; - switch_xml_binding_t *dialplan_fetch_binding; - switch_xml_binding_t *channels_fetch_binding; - switch_xml_binding_t *languages_fetch_binding; - switch_xml_binding_t *chatplan_fetch_binding; - - switch_hash_t *event_filter; - int epmdfd; - int node_worker_threads; - switch_bool_t nat_map; - switch_bool_t ei_shortname; - int ei_compat_rel; - char *ip; - char *hostname; - struct hostent* hostname_ent; - char *ei_cookie; - char *ei_nodename; - uint32_t flags; - int send_all_headers; - int send_all_private_headers; - int connection_timeout; - int ei_receive_timeout; - switch_interval_time_t node_sender_queue_timeout; - switch_interval_time_t node_receiver_queue_timeout; - int receive_msg_preallocate; - int event_stream_preallocate; - int send_msg_batch; - short event_stream_framing; - short event_stream_keepalive; - switch_interval_time_t event_stream_queue_timeout; - switch_port_t port; - int config_fetched; - int io_fault_tolerance; - switch_interval_time_t io_fault_tolerance_sleep; - kazoo_event_profile_ptr events; - kazoo_config_ptr definitions; - kazoo_config_ptr event_handlers; - kazoo_config_ptr fetch_handlers; - kazoo_json_term json_encoding; - - char **profile_vars_prefixes; - char **kazoo_var_prefixes; - - int legacy_events; - uint8_t tweaks[KZ_TWEAK_MAX]; - switch_bool_t expand_headers_on_fetch; - - switch_interval_time_t delay_before_initial_fetch; - - -}; -typedef struct kz_globals_s kz_globals_t; -extern kz_globals_t kazoo_globals; - -/* kazoo_event_stream.c */ -ei_event_stream_t *find_event_stream(ei_event_stream_t *event_streams, const erlang_pid *from); - -//ei_event_stream_t *new_event_stream(ei_event_stream_t **event_streams, const erlang_pid *from); -ei_event_stream_t *new_event_stream(ei_node_t *ei_node, const erlang_pid *from); - - -switch_status_t remove_event_stream(ei_event_stream_t **event_streams, const erlang_pid *from); -switch_status_t remove_event_streams(ei_event_stream_t **event_streams); -unsigned long get_stream_port(const ei_event_stream_t *event_stream); -switch_status_t add_event_binding(ei_event_stream_t *event_stream, const char *event_name); -//switch_status_t add_event_binding(ei_event_stream_t *event_stream, const switch_event_types_t event_type, const char *subclass_name); -switch_status_t remove_event_binding(ei_event_stream_t *event_stream, const switch_event_types_t event_type, const char *subclass_name); -switch_status_t remove_event_bindings(ei_event_stream_t *event_stream); - -/* kazoo_node.c */ -switch_status_t new_kazoo_node(int nodefd, ErlConnect *conn); - -/* kazoo_ei_utils.c */ -void close_socket(switch_socket_t **sock); -void close_socketfd(int *sockfd); -switch_socket_t *create_socket_with_port(switch_memory_pool_t *pool, switch_port_t port); -switch_socket_t *create_socket(switch_memory_pool_t *pool); -switch_status_t create_ei_cnode(const char *ip_addr, const char *name, struct ei_cnode_s *ei_cnode); -switch_status_t ei_compare_pids(const erlang_pid *pid1, const erlang_pid *pid2); -void ei_encode_switch_event_headers(ei_x_buff *ebuf, switch_event_t *event); -void ei_encode_switch_event_headers_2(ei_x_buff *ebuf, switch_event_t *event, int decode); -void ei_encode_json(ei_x_buff *ebuf, cJSON *JObj); -void ei_link(ei_node_t *ei_node, erlang_pid * from, erlang_pid * to); -void ei_encode_switch_event(ei_x_buff * ebuf, switch_event_t *event); -int ei_helper_send(ei_node_t *ei_node, erlang_pid* to, ei_x_buff *buf); -int ei_decode_atom_safe(char *buf, int *index, char *dst); -int ei_decode_string_or_binary_limited(char *buf, int *index, int maxsize, char *dst); -int ei_decode_string_or_binary(char *buf, int *index, char **dst); -switch_status_t create_acceptor(); -switch_hash_t *create_default_filter(); -void kz_erl_init(); -void kz_erl_shutdown(); -SWITCH_DECLARE(switch_status_t) ei_queue_pop(switch_queue_t *queue, void **data, switch_interval_time_t timeout); - -void fetch_config(); - -switch_status_t kazoo_load_config(); -void kazoo_destroy_config(); -void kz_set_hostname(); - -#define _ei_x_encode_string(buf, string) { ei_x_encode_binary(buf, string, strlen(string)); } - -/* kazoo_fetch_agent.c */ -switch_status_t bind_fetch_agents(); -switch_status_t unbind_fetch_agents(); -switch_status_t remove_xml_clients(ei_node_t *ei_node); -switch_status_t add_fetch_handler(ei_node_t *ei_node, erlang_pid *from, switch_xml_binding_t *binding); -switch_status_t remove_fetch_handlers(ei_node_t *ei_node, erlang_pid *from); -switch_status_t fetch_reply(char *uuid_str, char *xml_str, switch_xml_binding_t *binding); -switch_status_t handle_api_command_streams(ei_node_t *ei_node, switch_stream_handle_t *stream); - -void bind_event_profiles(kazoo_event_ptr event); -void rebind_fetch_profiles(kazoo_config_ptr fetch_handlers); -switch_status_t kazoo_config_handlers(switch_xml_t cfg); - -/* runtime */ -SWITCH_MODULE_RUNTIME_FUNCTION(mod_kazoo_runtime); - - - -#define kz_test_tweak(flag) (kazoo_globals.tweaks[flag] ? 1 : 0) -#define kz_set_tweak(flag) kazoo_globals.tweaks[flag] = 1 -#define kz_clear_tweak(flag) kazoo_globals.tweaks[flag] = 0 - -#endif /* KAZOO_EI_H */ - -/* For Emacs: - * Local Variables: - * mode:c - * indent-tabs-mode:t - * tab-width:4 - * c-basic-offset:4 - * End: - * For VIM: - * vim:set softtabstop=4 shiftwidth=4 tabstop=4: - */ diff --git a/src/mod/event_handlers/mod_kazoo/kazoo_ei_config.c b/src/mod/event_handlers/mod_kazoo/kazoo_ei_config.c deleted file mode 100644 index 3c626c15da0..00000000000 --- a/src/mod/event_handlers/mod_kazoo/kazoo_ei_config.c +++ /dev/null @@ -1,708 +0,0 @@ -/* -* FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application -* Copyright (C) 2005-2012, Anthony Minessale II -* -* 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 -* Portions created by the Initial Developer are Copyright (C) -* the Initial Developer. All Rights Reserved. -* -* Based on mod_skel by -* Anthony Minessale II -* -* Contributor(s): -* -* Daniel Bryars -* Tim Brown -* Anthony Minessale II -* William King -* Mike Jerris -* -* kazoo.c -- Sends FreeSWITCH events to an AMQP broker -* -*/ - -#include "mod_kazoo.h" - -#define KZ_DEFAULT_STREAM_PRE_ALLOCATE 8192 - -#define KAZOO_DECLARE_GLOBAL_STRING_FUNC(fname, vname) static void __attribute__((__unused__)) fname(const char *string) { if (!string) return;\ - if (vname) {free(vname); vname = NULL;}vname = strdup(string);} static void fname(const char *string) - -KAZOO_DECLARE_GLOBAL_STRING_FUNC(set_pref_ip, kazoo_globals.ip); -KAZOO_DECLARE_GLOBAL_STRING_FUNC(set_pref_ei_cookie, kazoo_globals.ei_cookie); -KAZOO_DECLARE_GLOBAL_STRING_FUNC(set_pref_ei_nodename, kazoo_globals.ei_nodename); -//KAZOO_DECLARE_GLOBAL_STRING_FUNC(set_pref_kazoo_var_prefix, kazoo_globals.kazoo_var_prefix); - -static int read_cookie_from_file(char *filename) { - int fd; - char cookie[MAXATOMLEN + 1]; - char *end; - struct stat buf; - - if (!stat(filename, &buf)) { - if ((buf.st_mode & S_IRWXG) || (buf.st_mode & S_IRWXO)) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "%s must only be accessible by owner only.\n", filename); - return 2; - } - if (buf.st_size > MAXATOMLEN) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "%s contains a cookie larger than the maximum atom size of %d.\n", filename, MAXATOMLEN); - return 2; - } - fd = open(filename, O_RDONLY); - if (fd < 1) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Unable to open cookie file %s : %d.\n", filename, errno); - return 2; - } - - if (read(fd, cookie, MAXATOMLEN) < 1) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Unable to read cookie file %s : %d.\n", filename, errno); - } - - cookie[MAXATOMLEN] = '\0'; - - /* replace any end of line characters with a null */ - if ((end = strchr(cookie, '\n'))) { - *end = '\0'; - } - - if ((end = strchr(cookie, '\r'))) { - *end = '\0'; - } - - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Set cookie from file %s: %s\n", filename, cookie); - - set_pref_ei_cookie(cookie); - return 0; - } else { - /* don't error here, because we might be blindly trying to read $HOME/.erlang.cookie, and that can fail silently */ - return 1; - } -} - -void kz_set_hostname() -{ - if (kazoo_globals.hostname == NULL) { - char hostname[NODENAME_MAX]; - memcpy(hostname, switch_core_get_hostname(), NODENAME_MAX); - kazoo_globals.hostname_ent = gethostbyname(hostname); - if(kazoo_globals.hostname_ent != NULL) { - kazoo_globals.hostname = switch_core_strdup(kazoo_globals.pool, kazoo_globals.hostname_ent->h_name); - } else { - kazoo_globals.hostname = switch_core_strdup(kazoo_globals.pool, hostname); - } - } -} - -switch_status_t kazoo_ei_config(switch_xml_t cfg) { - switch_xml_t child, param; - char* kazoo_var_prefix = NULL; - char* profile_vars_prefix = NULL; - char* sep_array[KZ_MAX_SEPARATE_STRINGS]; - int array_len, i; - kazoo_globals.send_all_headers = 0; - kazoo_globals.send_all_private_headers = 1; - kazoo_globals.connection_timeout = 500; - kazoo_globals.ei_receive_timeout = 200; - kazoo_globals.receive_msg_preallocate = 2000; - kazoo_globals.event_stream_preallocate = KZ_DEFAULT_STREAM_PRE_ALLOCATE; - kazoo_globals.send_msg_batch = 10; - kazoo_globals.event_stream_framing = 2; - kazoo_globals.event_stream_keepalive = 1; - kazoo_globals.event_stream_queue_timeout = 200000; - kazoo_globals.node_receiver_queue_timeout = 100000; - kazoo_globals.node_sender_queue_timeout = 0; - kazoo_globals.port = 0; - kazoo_globals.io_fault_tolerance = 3; - kazoo_globals.io_fault_tolerance_sleep = 100000; // 100 ms - kazoo_globals.json_encoding = ERLANG_TUPLE; - kazoo_globals.delay_before_initial_fetch = 10000000; - - kazoo_globals.legacy_events = SWITCH_FALSE; - kazoo_globals.expand_headers_on_fetch = SWITCH_TRUE; - - kz_set_tweak(KZ_TWEAK_INTERACTION_ID); - kz_set_tweak(KZ_TWEAK_EXPORT_VARS); - kz_set_tweak(KZ_TWEAK_SWITCH_URI); - kz_set_tweak(KZ_TWEAK_REPLACES_CALL_ID); - kz_set_tweak(KZ_TWEAK_LOOPBACK_VARS); - kz_set_tweak(KZ_TWEAK_CALLER_ID); - kz_set_tweak(KZ_TWEAK_TRANSFERS); - kz_set_tweak(KZ_TWEAK_BRIDGE); - kz_set_tweak(KZ_TWEAK_BRIDGE_REPLACES_ALEG); - kz_set_tweak(KZ_TWEAK_BRIDGE_REPLACES_CALL_ID); - kz_set_tweak(KZ_TWEAK_BRIDGE_VARIABLES); - kz_set_tweak(KZ_TWEAK_RESTORE_CALLER_ID_ON_BLIND_XFER); - - - - if ((child = switch_xml_child(cfg, "settings"))) { - for (param = switch_xml_child(child, "param"); param; param = param->next) { - char *var = (char *) switch_xml_attr_soft(param, "name"); - char *val = (char *) switch_xml_attr_soft(param, "value"); - - if (!strcmp(var, "listen-ip")) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Set bind ip address: %s\n", val); - set_pref_ip(val); - } else if (!strcmp(var, "listen-port")) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Set bind port: %s\n", val); - kazoo_globals.port = atoi(val); - } else if (!strcmp(var, "cookie")) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Set cookie: %s\n", val); - set_pref_ei_cookie(val); - } else if (!strcmp(var, "cookie-file")) { - if (read_cookie_from_file(val) == 1) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Unable to read cookie from %s\n", val); - } - } else if (!strcmp(var, "nodename")) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Set node name: %s\n", val); - set_pref_ei_nodename(val); - } else if (!strcmp(var, "shortname")) { - kazoo_globals.ei_shortname = switch_true(val); - } else if (!strcmp(var, "kazoo-var-prefix")) { - kazoo_var_prefix = switch_core_strdup(kazoo_globals.pool, val); - } else if (!strcmp(var, "set-profile-vars-prefix")) { - profile_vars_prefix = switch_core_strdup(kazoo_globals.pool, val); - } else if (!strcmp(var, "compat-rel")) { - if (atoi(val) >= 7) - kazoo_globals.ei_compat_rel = atoi(val); - else - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Invalid compatibility release '%s' specified\n", val); - } else if (!strcmp(var, "nat-map")) { - kazoo_globals.nat_map = switch_true(val); - } else if (!strcmp(var, "send-all-headers")) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Set send-all-headers: %s\n", val); - kazoo_globals.send_all_headers = switch_true(val); - } else if (!strcmp(var, "send-all-private-headers")) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Set send-all-private-headers: %s\n", val); - kazoo_globals.send_all_private_headers = switch_true(val); - } else if (!strcmp(var, "connection-timeout")) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Set connection-timeout: %s\n", val); - kazoo_globals.connection_timeout = atoi(val); - } else if (!strcmp(var, "receive-timeout")) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Set receive-timeout: %s\n", val); - kazoo_globals.ei_receive_timeout = atoi(val); - } else if (!strcmp(var, "receive-msg-preallocate")) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Set receive-msg-preallocate: %s\n", val); - kazoo_globals.receive_msg_preallocate = atoi(val); - } else if (!strcmp(var, "event-stream-preallocate")) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Set event-stream-preallocate: %s\n", val); - kazoo_globals.event_stream_preallocate = atoi(val); - } else if (!strcmp(var, "send-msg-batch-size")) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Set send-msg-batch-size: %s\n", val); - kazoo_globals.send_msg_batch = atoi(val); - } else if (!strcmp(var, "event-stream-framing")) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Set event-stream-framing: %s\n", val); - kazoo_globals.event_stream_framing = atoi(val); - - } else if (!strcmp(var, "event-stream-keep-alive")) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Set event-stream-keep-alive: %s\n", val); - kazoo_globals.event_stream_keepalive = switch_true(val); - - } else if (!strcmp(var, "io-fault-tolerance")) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Set io-fault-tolerance: %s\n", val); - kazoo_globals.io_fault_tolerance = atoi(val); - } else if (!strcmp(var, "io-fault-tolerance-sleep-micro")) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Set %s : %s\n", var, val); - kazoo_globals.io_fault_tolerance_sleep = atoi(val); - } else if (!strcmp(var, "io-fault-tolerance-sleep-ms")) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Set %s : %s\n", var, val); - kazoo_globals.io_fault_tolerance_sleep = atoi(val) * 1000; - } else if (!strcmp(var, "io-fault-tolerance-sleep-sec")) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Set %s : %s\n", var, val); - kazoo_globals.io_fault_tolerance_sleep = atoi(val) * 1000000; - - - } else if (!strcmp(var, "node-worker-threads")) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Set node-worker-threads: %s\n", val); - kazoo_globals.node_worker_threads = atoi(val); - } else if (!strcmp(var, "json-term-encoding")) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Set json-term-encoding: %s\n", val); - if(!strcmp(val, "map")) { - kazoo_globals.json_encoding = ERLANG_MAP; - } - } else if (!strcmp(var, "legacy-events")) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Set legacy-events: %s\n", val); - kazoo_globals.legacy_events = switch_true(val); - } else if (!strcmp(var, "expand-headers-on-fetch")) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Set expand-headers-on-fetch: %s\n", val); - kazoo_globals.expand_headers_on_fetch = switch_true(val); - } else if (!strcmp(var, "node-receiver-queue-timeout")) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Set %s : %s\n", var, val); - kazoo_globals.node_receiver_queue_timeout = atoi(val); - } else if (!strcmp(var, "node-sender-queue-timeout")) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Set %s : %s\n", var, val); - kazoo_globals.node_sender_queue_timeout = atoi(val); - } else if (!strcmp(var, "event-stream-queue-timeout")) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Set %s : %s\n", var, val); - kazoo_globals.event_stream_queue_timeout = atoi(val); - } else if (!strcmp(var, "delay-before-initial-fetch-micro")) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Set %s : %s\n", var, val); - kazoo_globals.delay_before_initial_fetch = atoi(val); - } else if (!strcmp(var, "delay-before-initial-fetch-ms")) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Set %s : %s\n", var, val); - kazoo_globals.delay_before_initial_fetch = atoi(val) * 1000; - } else if (!strcmp(var, "delay-before-initial-fetch-sec")) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Set %s : %s\n", var, val); - kazoo_globals.delay_before_initial_fetch = atoi(val) * 1000000; - } else { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "unknown config option %s : %s\n", var, val); - } - } - } - - if ((child = switch_xml_child(cfg, "tweaks"))) { - char *default_tweaks = (char *) switch_xml_attr_soft(child, "default"); - if (default_tweaks && !zstr(default_tweaks)) { - int i, v = switch_true(default_tweaks) ? 1 : 0; - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Set tweak default : %s\n", default_tweaks); - for (i = 0; i < KZ_TWEAK_MAX; i++) kazoo_globals.tweaks[i] = v; - } - for (param = switch_xml_child(child, "tweak"); param; param = param->next) { - kz_tweak_t tweak = KZ_TWEAK_MAX; - char *var = (char *) switch_xml_attr_soft(param, "name"); - char *val = (char *) switch_xml_attr_soft(param, "value"); - if(var && val && kz_name_tweak(var, &tweak) == SWITCH_STATUS_SUCCESS) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Set tweak %s : %s\n", var, val); - if(switch_true(val)) { - kz_set_tweak(tweak); - } else { - kz_clear_tweak(tweak); - } - } - } - } - - if ((child = switch_xml_child(cfg, "variables"))) { - for (param = switch_xml_child(child, "variable"); param; param = param->next) { - char *var = (char *) switch_xml_attr_soft(param, "name"); - char *val = (char *) switch_xml_attr_soft(param, "value"); - if(var && val) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Set core variable %s : %s\n", var, val); - switch_core_set_variable(var, val); - } - } - } - - if ((child = switch_xml_child(cfg, "event-filter"))) { - switch_hash_t *filter; - - switch_core_hash_init(&filter); - for (param = switch_xml_child(child, "header"); param; param = param->next) { - char *var = (char *) switch_xml_attr_soft(param, "name"); - switch_core_hash_insert(filter, var, "1"); - } - kazoo_globals.event_filter = filter; - } - - if (kazoo_globals.receive_msg_preallocate < 0) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Invalid receive message preallocate value, disabled\n"); - kazoo_globals.receive_msg_preallocate = 0; - } - - if (kazoo_globals.event_stream_preallocate < 0) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Invalid event stream preallocate value, disabled\n"); - kazoo_globals.event_stream_preallocate = 0; - } - - if (kazoo_globals.send_msg_batch < 1) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Invalid send message batch size, reverting to default\n"); - kazoo_globals.send_msg_batch = 10; - } - - if (kazoo_globals.io_fault_tolerance < 1) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Invalid I/O fault tolerance, reverting to default\n"); - kazoo_globals.io_fault_tolerance = 10; - } - - if (!kazoo_globals.event_filter) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Event filter not found in configuration, using default\n"); - kazoo_globals.event_filter = create_default_filter(); - } - - if (kazoo_globals.event_stream_framing < 1 || kazoo_globals.event_stream_framing > 4) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Invalid event stream framing value, using default\n"); - kazoo_globals.event_stream_framing = 2; - } - - if (zstr(kazoo_var_prefix)) { - kazoo_var_prefix = switch_core_strdup(kazoo_globals.pool, "ecallmgr_;cav_"); - } - - if (zstr(profile_vars_prefix)) { - profile_vars_prefix = switch_core_strdup(kazoo_globals.pool, "effective_;origination_"); - } - - kazoo_globals.kazoo_var_prefixes = switch_core_alloc(kazoo_globals.pool, sizeof(char*) * KZ_MAX_SEPARATE_STRINGS); - array_len = switch_separate_string(kazoo_var_prefix, ';', sep_array, KZ_MAX_SEPARATE_STRINGS - 1); - for(i=0; i < array_len; i++) { - char var[100]; - sprintf(var, "variable_%s", sep_array[i]); - kazoo_globals.kazoo_var_prefixes[i] = switch_core_strdup(kazoo_globals.pool, var); - } - - kazoo_globals.profile_vars_prefixes = switch_core_alloc(kazoo_globals.pool, sizeof(char*) * KZ_MAX_SEPARATE_STRINGS); - array_len = switch_separate_string(profile_vars_prefix, ';', sep_array, KZ_MAX_SEPARATE_STRINGS - 1); - for(i=0; i < array_len; i++) { - kazoo_globals.profile_vars_prefixes[i] = switch_core_strdup(kazoo_globals.pool, sep_array[i]); - } - - if (!kazoo_globals.node_worker_threads) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Number of node worker threads not found in configuration, using default\n"); - kazoo_globals.node_worker_threads = 10; - } - - if (zstr(kazoo_globals.ip)) { - set_pref_ip("0.0.0.0"); - } - - if (zstr(kazoo_globals.ei_cookie)) { - int res; - char *home_dir = getenv("HOME"); - char path_buf[1024]; - - if (!zstr(home_dir)) { - /* $HOME/.erlang.cookie */ - switch_snprintf(path_buf, sizeof (path_buf), "%s%s%s", home_dir, SWITCH_PATH_SEPARATOR, ".erlang.cookie"); - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Checking for cookie at path: %s\n", path_buf); - - res = read_cookie_from_file(path_buf); - if (res) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "No cookie or valid cookie file specified, using default cookie\n"); - set_pref_ei_cookie("ClueCon"); - } - } - } - - if (!kazoo_globals.ei_nodename) { - set_pref_ei_nodename("freeswitch"); - } - - if (!kazoo_globals.nat_map) { - kazoo_globals.nat_map = 0; - } - - return SWITCH_STATUS_SUCCESS; -} - -switch_status_t kazoo_config_handlers(switch_xml_t cfg) -{ - switch_xml_t def = NULL; - switch_xml_t child, param; - char* xml = NULL; - kazoo_config_ptr definitions = NULL, fetch_handlers = NULL, event_handlers = NULL; - kazoo_event_profile_ptr events = NULL; - - xml = strndup(kz_default_config, kz_default_config_size); - def = switch_xml_parse_str_dup(xml); - - kz_xml_process(def); - kz_xml_process(cfg); - - if ((child = switch_xml_child(cfg, "variables"))) { - for (param = switch_xml_child(child, "variable"); param; param = param->next) { - char *var = (char *) switch_xml_attr_soft(param, "name"); - char *val = (char *) switch_xml_attr_soft(param, "value"); - if(var && val) { - switch_core_set_variable(var, val); - } - } - } else if ((child = switch_xml_child(def, "variables"))) { - for (param = switch_xml_child(child, "variable"); param; param = param->next) { - char *var = (char *) switch_xml_attr_soft(param, "name"); - char *val = (char *) switch_xml_attr_soft(param, "value"); - if(var && val) { - switch_core_set_variable(var, val); - } - } - } - - definitions = kazoo_config_definitions(cfg); - if(definitions == NULL) { - if(kazoo_globals.definitions == NULL) { - definitions = kazoo_config_definitions(def); - } else { - definitions = kazoo_globals.definitions; - } - } - - fetch_handlers = kazoo_config_fetch_handlers(definitions, cfg); - if(fetch_handlers == NULL) { - if(kazoo_globals.fetch_handlers == NULL) { - fetch_handlers = kazoo_config_fetch_handlers(definitions, def); - } else { - fetch_handlers = kazoo_globals.fetch_handlers; - } - } - - event_handlers = kazoo_config_event_handlers(definitions, cfg); - if(event_handlers == NULL) { - if(kazoo_globals.event_handlers == NULL) { - event_handlers = kazoo_config_event_handlers(definitions, def); - } else { - event_handlers = kazoo_globals.event_handlers; - } - } - - if(event_handlers != NULL) { - events = (kazoo_event_profile_ptr) switch_core_hash_find(event_handlers->hash, "default"); - } - - if(events == NULL) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Failed to get default handler for events\n"); - destroy_config(&event_handlers); - event_handlers = kazoo_config_event_handlers(definitions, def); - events = (kazoo_event_profile_ptr) switch_core_hash_find(event_handlers->hash, "default"); - } - - if(kazoo_globals.events != events) { - bind_event_profiles(events->events); - kazoo_globals.events = events; - } - - if(kazoo_globals.event_handlers != event_handlers) { - kazoo_config_ptr tmp = kazoo_globals.event_handlers; - kazoo_globals.event_handlers = event_handlers; - destroy_config(&tmp); - } - - if(kazoo_globals.fetch_handlers != fetch_handlers) { - kazoo_config_ptr tmp = kazoo_globals.fetch_handlers; - kazoo_globals.fetch_handlers = fetch_handlers; - rebind_fetch_profiles(fetch_handlers); - destroy_config(&tmp); - } - - if(kazoo_globals.definitions != definitions) { - kazoo_config_ptr tmp = kazoo_globals.definitions; - kazoo_globals.definitions = definitions; - destroy_config(&tmp); - } - - - switch_xml_free(def); - switch_safe_free(xml); - - return SWITCH_STATUS_SUCCESS; -} - -switch_status_t kazoo_load_config() -{ - char *cf = "kazoo.conf"; - switch_xml_t cfg, xml; - if (!(xml = switch_xml_open_cfg(cf, &cfg, NULL))) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Failed to open configuration file %s\n", cf); - return SWITCH_STATUS_FALSE; - } else { - kazoo_ei_config(cfg); - kazoo_config_handlers(cfg); - switch_xml_free(xml); - } - - return SWITCH_STATUS_SUCCESS; -} - -void kazoo_destroy_config() -{ - destroy_config(&kazoo_globals.event_handlers); - destroy_config(&kazoo_globals.fetch_handlers); - destroy_config(&kazoo_globals.definitions); -} - -switch_status_t kazoo_config_events(kazoo_config_ptr definitions, switch_memory_pool_t *pool, switch_xml_t cfg, kazoo_event_profile_ptr profile) -{ - switch_xml_t events, event; - kazoo_event_ptr prv = NULL, cur = NULL; - - - if ((events = switch_xml_child(cfg, "events")) != NULL) { - for (event = switch_xml_child(events, "event"); event; event = event->next) { - const char *var = switch_xml_attr(event, "name"); - cur = (kazoo_event_ptr) switch_core_alloc(pool, sizeof(kazoo_event_t)); - memset(cur, 0, sizeof(kazoo_event_t)); - if(prv == NULL) { - profile->events = prv = cur; - } else { - prv->next = cur; - prv = cur; - } - cur->profile = profile; - cur->name = switch_core_strdup(pool, var); - kazoo_config_filters(pool, event, &cur->filter); - kazoo_config_fields(definitions, pool, event, &cur->fields); - if (switch_xml_child(event, "logging") != NULL) { - kazoo_config_loglevels(pool, event, &cur->logging); - } - } - } - - return SWITCH_STATUS_SUCCESS; - -} - - -switch_status_t kazoo_config_fetch_handler(kazoo_config_ptr definitions, kazoo_config_ptr root, switch_xml_t cfg, kazoo_fetch_profile_ptr *ptr) -{ - kazoo_fetch_profile_ptr profile = NULL; - switch_xml_t params, param; - switch_xml_section_t fetch_section; - int fetch_timeout = 2000000; - switch_memory_pool_t *pool = NULL; - - char *name = (char *) switch_xml_attr_soft(cfg, "name"); - - if (zstr(name)) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "missing name in profile\n"); - - return SWITCH_STATUS_GENERR; - } - - if (switch_core_new_memory_pool(&pool) != SWITCH_STATUS_SUCCESS) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "error allocation pool for new profile : %s\n", name); - - return SWITCH_STATUS_GENERR; - } - - profile = switch_core_alloc(pool, sizeof(kazoo_fetch_profile_t)); - profile->pool = pool; - profile->root = root; - profile->name = switch_core_strdup(profile->pool, name); - - fetch_section = switch_xml_parse_section_string(name); - - if ((params = switch_xml_child(cfg, "params")) != NULL) { - - for (param = switch_xml_child(params, "param"); param; param = param->next) { - char *var = (char *) switch_xml_attr_soft(param, "name"); - char *val = (char *) switch_xml_attr_soft(param, "value"); - - if (!var) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Profile[%s] param missing 'name' attribute\n", name); - continue; - } - - if (!val) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Profile[%s] param[%s] missing 'value' attribute\n", name, var); - continue; - } - - if (!strncmp(var, "fetch-timeout", 13)) { - fetch_timeout = atoi(val); - } else if (!strncmp(var, "fetch-section", 13)) { - fetch_section = switch_xml_parse_section_string(val); - } - } - } - - if (fetch_section == SWITCH_XML_SECTION_RESULT) { - char *tmp = switch_xml_toxml(cfg, SWITCH_FALSE); - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Fetch Profile[%s] invalid fetch-section: %s\n", name, tmp); - free(tmp); - goto err; - } - - - profile->fetch_timeout = fetch_timeout; - profile->section = fetch_section; - kazoo_config_fields(definitions, pool, cfg, &profile->fields); - kazoo_config_loglevels(pool, cfg, &profile->logging); - - if(root) { - if ( switch_core_hash_insert(root->hash, name, (void *) profile) != SWITCH_STATUS_SUCCESS) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "failed to insert new fetch profile [%s] into kazoo profile hash\n", name); - goto err; - } - } - - if (ptr) { - *ptr = profile; - } - - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "fetch handler profile %s successfully configured\n", name); - - return SWITCH_STATUS_SUCCESS; - - err: - /* Cleanup */ - if(pool) { - switch_core_destroy_memory_pool(&pool); - } - - return SWITCH_STATUS_GENERR; - -} - -switch_status_t kazoo_config_event_handler(kazoo_config_ptr definitions, kazoo_config_ptr root, switch_xml_t cfg, kazoo_event_profile_ptr *ptr) -{ - kazoo_event_profile_ptr profile = NULL; - switch_memory_pool_t *pool = NULL; - - char *name = (char *) switch_xml_attr_soft(cfg, "name"); - if (zstr(name)) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "missing name in profile\n"); - return SWITCH_STATUS_GENERR; - } - - if (switch_core_new_memory_pool(&pool) != SWITCH_STATUS_SUCCESS) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "error allocation pool for new profile : %s\n", name); - return SWITCH_STATUS_GENERR; - } - - profile = switch_core_alloc(pool, sizeof(kazoo_event_profile_t)); - profile->pool = pool; - profile->root = root; - profile->name = switch_core_strdup(profile->pool, name); - - kazoo_config_filters(pool, cfg, &profile->filter); - kazoo_config_fields(definitions, pool, cfg, &profile->fields); - kazoo_config_events(definitions, pool, cfg, profile); - kazoo_config_loglevels(pool, cfg, &profile->logging); - - if(root) { - if ( switch_core_hash_insert(root->hash, name, (void *) profile) != SWITCH_STATUS_SUCCESS) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Failed to insert new profile [%s] into kazoo profile hash\n", name); - goto err; - } - } - - if(ptr) - *ptr = profile; - - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "event handler profile %s successfully configured\n", name); - return SWITCH_STATUS_SUCCESS; - - err: - /* Cleanup */ - if(pool) { - switch_core_destroy_memory_pool(&pool); - } - return SWITCH_STATUS_GENERR; - -} - - - -/* For Emacs: - * Local Variables: - * mode:c - * indent-tabs-mode:t - * tab-width:4 - * c-basic-offset:4 - * End: - * For VIM: - * vim:set softtabstop=4 shiftwidth=4 tabstop=4 - */ diff --git a/src/mod/event_handlers/mod_kazoo/kazoo_ei_utils.c b/src/mod/event_handlers/mod_kazoo/kazoo_ei_utils.c deleted file mode 100644 index ef45af0ea36..00000000000 --- a/src/mod/event_handlers/mod_kazoo/kazoo_ei_utils.c +++ /dev/null @@ -1,1089 +0,0 @@ -/* - * FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application - * Copyright (C) 2005-2012, Anthony Minessale II - * - * 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 - * Portions created by the Initial Developer are Copyright (C) - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * - * Anthony Minessale II - * Andrew Thompson - * Rob Charlton - * Karl Anderson - * - * Original from mod_erlang_event. - * ei_helpers.c -- helper functions for ei - * - */ -#include "mod_kazoo.h" - -/* Stolen from code added to ei in R12B-5. - * Since not everyone has this version yet; - * provide our own version. - * */ - -#define put8(s,n) do { \ - (s)[0] = (char)((n) & 0xff); \ - (s) += 1; \ - } while (0) - -#define put32be(s,n) do { \ - (s)[0] = ((n) >> 24) & 0xff; \ - (s)[1] = ((n) >> 16) & 0xff; \ - (s)[2] = ((n) >> 8) & 0xff; \ - (s)[3] = (n) & 0xff; \ - (s) += 4; \ - } while (0) - -#ifdef EI_DEBUG -static void ei_x_print_reg_msg(ei_x_buff *buf, char *dest, int send) { - char *mbuf = NULL; - int i = 1; - - ei_s_print_term(&mbuf, buf->buff, &i); - - if (send) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Encoded term %s to '%s'\n", mbuf, dest); - } else { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Decoded term %s for '%s'\n", mbuf, dest); - } - - free(mbuf); -} - -static void ei_x_print_msg(ei_x_buff *buf, erlang_pid *pid, int send) { - char *pbuf = NULL; - int i = 0; - ei_x_buff pidbuf; - - ei_x_new(&pidbuf); - ei_x_encode_pid(&pidbuf, pid); - - ei_s_print_term(&pbuf, pidbuf.buff, &i); - - ei_x_print_reg_msg(buf, pbuf, send); - free(pbuf); -} -#endif - -void ei_encode_switch_event_headers(ei_x_buff *ebuf, switch_event_t *event) -{ - ei_encode_switch_event_headers_2(ebuf, event, 1); -} - -void ei_encode_switch_event_headers_2(ei_x_buff *ebuf, switch_event_t *event, int encode) -{ - switch_event_header_t *hp; - char *uuid = switch_event_get_header(event, "unique-id"); - int i; - - for (i = 0, hp = event->headers; hp; hp = hp->next, i++) - ; - - if (event->body) - i++; - - ei_x_encode_list_header(ebuf, i + 1); - - if (uuid) { - char *unique_id = switch_event_get_header(event, "unique-id"); - ei_x_encode_binary(ebuf, unique_id, strlen(unique_id)); - } else { - ei_x_encode_atom(ebuf, "undefined"); - } - - for (hp = event->headers; hp; hp = hp->next) { - ei_x_encode_tuple_header(ebuf, 2); - ei_x_encode_binary(ebuf, hp->name, strlen(hp->name)); - if (encode) { - switch_url_decode(hp->value); - } - ei_x_encode_binary(ebuf, hp->value, strlen(hp->value)); - } - - if (event->body) { - ei_x_encode_tuple_header(ebuf, 2); - ei_x_encode_binary(ebuf, "body", strlen("body")); - ei_x_encode_binary(ebuf, event->body, strlen(event->body)); - } - - ei_x_encode_empty_list(ebuf); -} - -int ei_json_child_count(cJSON *JObj) -{ - int mask = cJSON_False | cJSON_True | cJSON_NULL | cJSON_Number | cJSON_String | cJSON_Array | cJSON_Object | cJSON_Raw; - - cJSON *item = JObj->child; - int i = 0; - while (item) { - if (item->type & mask) - i++; - item = item->next; - } - return i; - -} - -void ei_encode_json_array(ei_x_buff *ebuf, cJSON *JObj) -{ - cJSON *item; - int count = ei_json_child_count(JObj); - - ei_x_encode_list_header(ebuf, count); - if (count == 0) - return; - - item = JObj->child; - while (item) { - switch (item->type){ - case cJSON_String: - ei_x_encode_binary(ebuf, item->valuestring, strlen(item->valuestring)); - break; - - case cJSON_Number: - if ((fabs(((double) item->valueint) - item->valuedouble) <= DBL_EPSILON) && (item->valuedouble <= INT_MAX) && (item->valuedouble >= INT_MIN)) { - ei_x_encode_longlong(ebuf, item->valueint); - } else { - if (fmod(item->valuedouble, 1) == 0) { - ei_x_encode_ulonglong(ebuf, item->valuedouble); - } else { - ei_x_encode_double(ebuf, item->valuedouble); - } - } - break; - - case cJSON_True: - ei_x_encode_boolean(ebuf, 1); - break; - - case cJSON_False: - ei_x_encode_boolean(ebuf, 0); - break; - - case cJSON_Object: - ei_encode_json(ebuf, item); - break; - - case cJSON_Array: - ei_encode_json_array(ebuf, item); - break; - - case cJSON_Raw: { - cJSON *Decoded = cJSON_Parse(item->valuestring); - if (!Decoded) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "ERROR DECODING RAW JSON %s\n", item->valuestring); - ei_x_encode_tuple_header(ebuf, 0); - } else { - ei_encode_json(ebuf, Decoded); - cJSON_Delete(Decoded); - } - break; - } - - case cJSON_NULL: - ei_x_encode_atom(ebuf, "null"); - break; - - default: - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "NOT ENCODED %i\n", item->type); - break; - - } - item = item->next; - } - - ei_x_encode_empty_list(ebuf); - -} - -void ei_encode_json(ei_x_buff *ebuf, cJSON *JObj) -{ - cJSON *item; - int count = ei_json_child_count(JObj); - - if (kazoo_globals.json_encoding == ERLANG_TUPLE) { - ei_x_encode_tuple_header(ebuf, 1); - ei_x_encode_list_header(ebuf, count); - } else { - ei_x_encode_map_header(ebuf, count); - } - - if (count == 0) - return; - - item = JObj->child; - while (item) { - if (kazoo_globals.json_encoding == ERLANG_TUPLE) { - ei_x_encode_tuple_header(ebuf, 2); - } - ei_x_encode_binary(ebuf, item->string, strlen(item->string)); - - switch (item->type){ - case cJSON_String: - ei_x_encode_binary(ebuf, item->valuestring, strlen(item->valuestring)); - break; - - case cJSON_Number: - if ((fabs(((double) item->valueint) - item->valuedouble) <= DBL_EPSILON) && (item->valuedouble <= INT_MAX) && (item->valuedouble >= INT_MIN)) { - ei_x_encode_longlong(ebuf, item->valueint); - } else { - if (fmod(item->valuedouble, 1) == 0) { - ei_x_encode_ulonglong(ebuf, item->valuedouble); - } else { - ei_x_encode_double(ebuf, item->valuedouble); - } - } - break; - - case cJSON_True: - ei_x_encode_boolean(ebuf, 1); - break; - - case cJSON_False: - ei_x_encode_boolean(ebuf, 0); - break; - - case cJSON_Object: - ei_encode_json(ebuf, item); - break; - - case cJSON_Array: - ei_encode_json_array(ebuf, item); - break; - - case cJSON_Raw: { - cJSON *Decoded = cJSON_Parse(item->valuestring); - if (!Decoded) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "ERROR DECODING RAW JSON %s\n", item->valuestring); - ei_x_encode_tuple_header(ebuf, 0); - } else { - ei_encode_json(ebuf, Decoded); - cJSON_Delete(Decoded); - } - break; - } - - case cJSON_NULL: - ei_x_encode_atom(ebuf, "null"); - break; - - default: - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "NOT ENCODED %i\n", item->type); - break; - - } - item = item->next; - } - - if (kazoo_globals.json_encoding == ERLANG_TUPLE) { - ei_x_encode_empty_list(ebuf); - } - -} - -void close_socket(switch_socket_t ** sock) -{ - if (*sock) { - switch_socket_shutdown(*sock, SWITCH_SHUTDOWN_READWRITE); - switch_socket_close(*sock); - *sock = NULL; - } -} - -void close_socketfd(int *sockfd) -{ - if (*sockfd) { - shutdown(*sockfd, SHUT_RDWR); - close(*sockfd); - } -} - -switch_socket_t *create_socket_with_port(switch_memory_pool_t *pool, switch_port_t port) -{ - switch_sockaddr_t *sa; - switch_socket_t *socket; - - if (switch_sockaddr_info_get(&sa, kazoo_globals.ip, SWITCH_UNSPEC, port, 0, pool)) { - return NULL; - } - - if (switch_socket_create(&socket, switch_sockaddr_get_family(sa), SOCK_STREAM, SWITCH_PROTO_TCP, pool)) { - return NULL; - } - - if (switch_socket_opt_set(socket, SWITCH_SO_REUSEADDR, 1)) { - return NULL; - } - - if (switch_socket_bind(socket, sa)) { - return NULL; - } - - if (switch_socket_listen(socket, 5)) { - return NULL; - } - - if (kazoo_globals.nat_map && switch_nat_get_type()) { - switch_nat_add_mapping(port, SWITCH_NAT_TCP, NULL, SWITCH_FALSE); - } - - return socket; -} - -switch_socket_t *create_socket(switch_memory_pool_t *pool) -{ - return create_socket_with_port(pool, 0); - -} - -switch_status_t create_ei_cnode(const char *ip_addr, const char *name, struct ei_cnode_s *ei_cnode) -{ - char hostname[EI_MAXHOSTNAMELEN + 1]; - char nodename[MAXNODELEN + 1]; - char cnodename[EI_MAXALIVELEN + 1]; - char *atsign; - - /* copy the erlang interface nodename into something we can modify */ - strncpy(cnodename, name, EI_MAXALIVELEN); - - if ((atsign = strchr(cnodename, '@'))) { - /* we got a qualified node name, don't guess the host/domain */ - snprintf(nodename, MAXNODELEN + 1, "%s", name); - /* truncate the alivename at the @ */ - *atsign++ = '\0'; - strncpy(hostname, atsign, EI_MAXHOSTNAMELEN); - } else { - strncpy(hostname, kazoo_globals.hostname, EI_MAXHOSTNAMELEN); - snprintf(nodename, MAXNODELEN + 1, "%s@%s", name, hostname); - } - - if (kazoo_globals.ei_shortname) { - char *off; - if ((off = strchr(nodename, '.'))) { - *off = '\0'; - } - } - - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "creating nodename: %s\n", nodename); - - /* init the ec stuff */ - if (ei_connect_xinit(ei_cnode, hostname, cnodename, nodename, (Erl_IpAddr) ip_addr, kazoo_globals.ei_cookie, 0) < 0) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Failed to initialize the erlang interface connection structure\n"); - return SWITCH_STATUS_FALSE; - } - - return SWITCH_STATUS_SUCCESS; -} - -switch_status_t ei_compare_pids(const erlang_pid *pid1, const erlang_pid *pid2) -{ - if ((!strcmp(pid1->node, pid2->node)) && pid1->creation == pid2->creation && pid1->num == pid2->num && pid1->serial == pid2->serial) { - return SWITCH_STATUS_SUCCESS; - } else { - return SWITCH_STATUS_FALSE; - } -} - -void ei_link(ei_node_t *ei_node, erlang_pid * from, erlang_pid * to) -{ - char msgbuf[2048]; - char *s; - int index = 0; - - index = 5; /* max sizes: */ - ei_encode_version(msgbuf, &index); /* 1 */ - ei_encode_tuple_header(msgbuf, &index, 3); - ei_encode_long(msgbuf, &index, ERL_LINK); - ei_encode_pid(msgbuf, &index, from); /* 268 */ - ei_encode_pid(msgbuf, &index, to); /* 268 */ - - /* 5 byte header missing */ - s = msgbuf; - put32be(s, index - 4); /* 4 */ - put8(s, ERL_PASS_THROUGH); /* 1 */ - /* sum: 542 */ - - if (write(ei_node->nodefd, msgbuf, index) == -1) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Failed to link to process on %s\n", ei_node->peer_nodename); - } -} - -void ei_encode_switch_event(ei_x_buff *ebuf, switch_event_t *event) -{ - ei_x_encode_tuple_header(ebuf, 2); - ei_x_encode_atom(ebuf, "event"); - ei_encode_switch_event_headers(ebuf, event); -} - -int ei_helper_send(ei_node_t *ei_node, erlang_pid *to, ei_x_buff *buf) -{ - int ret = 0; - - if (ei_node->nodefd) { -#ifdef EI_DEBUG - ei_x_print_msg(buf, to, 1); -#endif - ret = ei_send(ei_node->nodefd, to, buf->buff, buf->index); - } - - return ret; -} - -int ei_decode_atom_safe(char *buf, int *index, char *dst) -{ - int type, size; - - ei_get_type(buf, index, &type, &size); - - if (type != ERL_ATOM_EXT) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Unexpected erlang term type %d (size %d), needed atom\n", type, size); - return -1; - } else if (size > MAXATOMLEN) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Requested decoding of atom with size %d into a buffer of size %d\n", size, MAXATOMLEN); - return -1; - } else { - return ei_decode_atom(buf, index, dst); - } -} - -int ei_decode_string_or_binary(char *buf, int *index, char **dst) -{ - int type, size, res; - long len; - - ei_get_type(buf, index, &type, &size); - - if (type != ERL_STRING_EXT && type != ERL_BINARY_EXT && type != ERL_LIST_EXT && type != ERL_NIL_EXT) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Unexpected erlang term type %d (size %d), needed binary or string\n", type, size); - return -1; - } - - *dst = malloc(size + 1); - - if (type == ERL_NIL_EXT) { - res = 0; - **dst = '\0'; - } else if (type == ERL_BINARY_EXT) { - res = ei_decode_binary(buf, index, *dst, &len); - (*dst)[len] = '\0'; - } else { - res = ei_decode_string(buf, index, *dst); - } - - return res; -} - -int ei_decode_string_or_binary_limited(char *buf, int *index, int maxsize, char *dst) -{ - int type, size, res; - long len; - - ei_get_type(buf, index, &type, &size); - - if (type != ERL_STRING_EXT && type != ERL_BINARY_EXT && type != ERL_LIST_EXT && type != ERL_NIL_EXT) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Unexpected erlang term type %d (size %d), needed binary or string\n", type, size); - return -1; - } - - if (size > maxsize) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Requested decoding of %s with size %d into a buffer of size %d\n", - type == ERL_BINARY_EXT ? "binary" : "string", size, maxsize); - return -1; - } - - if (type == ERL_NIL_EXT) { - res = 0; - *dst = '\0'; - } else if (type == ERL_BINARY_EXT) { - res = ei_decode_binary(buf, index, dst, &len); - dst[len] = '\0'; /* binaries aren't null terminated */ - } else { - res = ei_decode_string(buf, index, dst); - } - - return res; -} - -switch_status_t create_acceptor() -{ - switch_sockaddr_t *sa; - uint16_t port; - char ipbuf[48]; - const char *ip_addr; - - /* if the config has specified an erlang release compatibility then pass that along to the erlang interface */ - if (kazoo_globals.ei_compat_rel) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Compatability with OTP R%d requested\n", kazoo_globals.ei_compat_rel); - ei_set_compat_rel(kazoo_globals.ei_compat_rel); - } - - if (!(kazoo_globals.acceptor = create_socket_with_port(kazoo_globals.pool, kazoo_globals.port))) { - return SWITCH_STATUS_SOCKERR; - } - - switch_socket_addr_get(&sa, SWITCH_FALSE, kazoo_globals.acceptor); - - port = switch_sockaddr_get_port(sa); - ip_addr = switch_get_addr(ipbuf, sizeof(ipbuf), sa); - - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Erlang connection acceptor listening on %s:%u\n", ip_addr, port); - - /* try to initialize the erlang interface */ - if (create_ei_cnode(ip_addr, kazoo_globals.ei_nodename, &kazoo_globals.ei_cnode) != SWITCH_STATUS_SUCCESS) { - return SWITCH_STATUS_SOCKERR; - } - - /* tell the erlang port manager where we can be reached. this returns a file descriptor pointing to epmd or -1 */ - if ((kazoo_globals.epmdfd = ei_publish(&kazoo_globals.ei_cnode, port)) == -1) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Failed to publish port to epmd, trying to start epmd via system()\n"); - if (system("fs_epmd -daemon")) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, - "Failed to start epmd manually! Is epmd in $PATH? If not, start it yourself or run an erl shell with -sname or -name\n"); - return SWITCH_STATUS_SOCKERR; - } - switch_yield(100000); - if ((kazoo_globals.epmdfd = ei_publish(&kazoo_globals.ei_cnode, port)) == -1) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Failed to publish port to epmd AGAIN\n"); - return SWITCH_STATUS_SOCKERR; - } - } - - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Connected to epmd and published erlang cnode name %s at port %d\n", kazoo_globals.ei_cnode.thisnodename, - port); - - return SWITCH_STATUS_SUCCESS; -} - -switch_hash_t *create_default_filter() -{ - switch_hash_t *filter; - - switch_core_hash_init(&filter); - - switch_core_hash_insert(filter, "Acquired-UUID", "1"); - switch_core_hash_insert(filter, "action", "1"); - switch_core_hash_insert(filter, "Action", "1"); - switch_core_hash_insert(filter, "alt_event_type", "1"); - switch_core_hash_insert(filter, "Answer-State", "1"); - switch_core_hash_insert(filter, "Application", "1"); - switch_core_hash_insert(filter, "Application-Data", "1"); - switch_core_hash_insert(filter, "Application-Name", "1"); - switch_core_hash_insert(filter, "Application-Response", "1"); - switch_core_hash_insert(filter, "att_xfer_replaced_by", "1"); - switch_core_hash_insert(filter, "Auth-Method", "1"); - switch_core_hash_insert(filter, "Auth-Realm", "1"); - switch_core_hash_insert(filter, "Auth-User", "1"); - switch_core_hash_insert(filter, "Bridge-A-Unique-ID", "1"); - switch_core_hash_insert(filter, "Bridge-B-Unique-ID", "1"); - switch_core_hash_insert(filter, "Call-Direction", "1"); - switch_core_hash_insert(filter, "Caller-Callee-ID-Name", "1"); - switch_core_hash_insert(filter, "Caller-Callee-ID-Number", "1"); - switch_core_hash_insert(filter, "Caller-Caller-ID-Name", "1"); - switch_core_hash_insert(filter, "Caller-Caller-ID-Number", "1"); - switch_core_hash_insert(filter, "Caller-Screen-Bit", "1"); - switch_core_hash_insert(filter, "Caller-Privacy-Hide-Name", "1"); - switch_core_hash_insert(filter, "Caller-Privacy-Hide-Number", "1"); - switch_core_hash_insert(filter, "Caller-Context", "1"); - switch_core_hash_insert(filter, "Caller-Controls", "1"); - switch_core_hash_insert(filter, "Caller-Destination-Number", "1"); - switch_core_hash_insert(filter, "Caller-Dialplan", "1"); - switch_core_hash_insert(filter, "Caller-Network-Addr", "1"); - switch_core_hash_insert(filter, "Caller-Unique-ID", "1"); - switch_core_hash_insert(filter, "Call-ID", "1"); - switch_core_hash_insert(filter, "Channel-Call-State", "1"); - switch_core_hash_insert(filter, "Channel-Call-UUID", "1"); - switch_core_hash_insert(filter, "Channel-Presence-ID", "1"); - switch_core_hash_insert(filter, "Channel-State", "1"); - switch_core_hash_insert(filter, "Chat-Permissions", "1"); - switch_core_hash_insert(filter, "Conference-Name", "1"); - switch_core_hash_insert(filter, "Conference-Profile-Name", "1"); - switch_core_hash_insert(filter, "Conference-Unique-ID", "1"); - switch_core_hash_insert(filter, "contact", "1"); - switch_core_hash_insert(filter, "Detected-Tone", "1"); - switch_core_hash_insert(filter, "dialog_state", "1"); - switch_core_hash_insert(filter, "direction", "1"); - switch_core_hash_insert(filter, "Distributed-From", "1"); - switch_core_hash_insert(filter, "DTMF-Digit", "1"); - switch_core_hash_insert(filter, "DTMF-Duration", "1"); - switch_core_hash_insert(filter, "Event-Date-Timestamp", "1"); - switch_core_hash_insert(filter, "Event-Name", "1"); - switch_core_hash_insert(filter, "Event-Subclass", "1"); - switch_core_hash_insert(filter, "expires", "1"); - switch_core_hash_insert(filter, "Expires", "1"); - switch_core_hash_insert(filter, "Ext-SIP-IP", "1"); - switch_core_hash_insert(filter, "File", "1"); - switch_core_hash_insert(filter, "FreeSWITCH-Hostname", "1"); - switch_core_hash_insert(filter, "from", "1"); - switch_core_hash_insert(filter, "Hunt-Destination-Number", "1"); - switch_core_hash_insert(filter, "ip", "1"); - switch_core_hash_insert(filter, "Message-Account", "1"); - switch_core_hash_insert(filter, "metadata", "1"); - switch_core_hash_insert(filter, "old_node_channel_uuid", "1"); - switch_core_hash_insert(filter, "Other-Leg-Callee-ID-Name", "1"); - switch_core_hash_insert(filter, "Other-Leg-Callee-ID-Number", "1"); - switch_core_hash_insert(filter, "Other-Leg-Caller-ID-Name", "1"); - switch_core_hash_insert(filter, "Other-Leg-Caller-ID-Number", "1"); - switch_core_hash_insert(filter, "Other-Leg-Destination-Number", "1"); - switch_core_hash_insert(filter, "Other-Leg-Direction", "1"); - switch_core_hash_insert(filter, "Other-Leg-Unique-ID", "1"); - switch_core_hash_insert(filter, "Other-Leg-Channel-Name", "1"); - switch_core_hash_insert(filter, "Participant-Type", "1"); - switch_core_hash_insert(filter, "Path", "1"); - switch_core_hash_insert(filter, "profile_name", "1"); - switch_core_hash_insert(filter, "Profiles", "1"); - switch_core_hash_insert(filter, "proto-specific-event-name", "1"); - switch_core_hash_insert(filter, "Raw-Application-Data", "1"); - switch_core_hash_insert(filter, "realm", "1"); - switch_core_hash_insert(filter, "Resigning-UUID", "1"); - switch_core_hash_insert(filter, "set", "1"); - switch_core_hash_insert(filter, "sip_auto_answer", "1"); - switch_core_hash_insert(filter, "sip_auth_method", "1"); - switch_core_hash_insert(filter, "sip_from_host", "1"); - switch_core_hash_insert(filter, "sip_from_user", "1"); - switch_core_hash_insert(filter, "sip_to_host", "1"); - switch_core_hash_insert(filter, "sip_to_user", "1"); - switch_core_hash_insert(filter, "sub-call-id", "1"); - switch_core_hash_insert(filter, "technology", "1"); - switch_core_hash_insert(filter, "to", "1"); - switch_core_hash_insert(filter, "Unique-ID", "1"); - switch_core_hash_insert(filter, "URL", "1"); - switch_core_hash_insert(filter, "username", "1"); - switch_core_hash_insert(filter, "variable_channel_is_moving", "1"); - switch_core_hash_insert(filter, "variable_collected_digits", "1"); - switch_core_hash_insert(filter, "variable_current_application", "1"); - switch_core_hash_insert(filter, "variable_current_application_data", "1"); - switch_core_hash_insert(filter, "variable_domain_name", "1"); - switch_core_hash_insert(filter, "variable_effective_caller_id_name", "1"); - switch_core_hash_insert(filter, "variable_effective_caller_id_number", "1"); - switch_core_hash_insert(filter, "variable_holding_uuid", "1"); - switch_core_hash_insert(filter, "variable_hold_music", "1"); - switch_core_hash_insert(filter, "variable_media_group_id", "1"); - switch_core_hash_insert(filter, "variable_originate_disposition", "1"); - switch_core_hash_insert(filter, "variable_origination_uuid", "1"); - switch_core_hash_insert(filter, "variable_playback_terminator_used", "1"); - switch_core_hash_insert(filter, "variable_presence_id", "1"); - switch_core_hash_insert(filter, "variable_record_ms", "1"); - switch_core_hash_insert(filter, "variable_recovered", "1"); - switch_core_hash_insert(filter, "variable_silence_hits_exhausted", "1"); - switch_core_hash_insert(filter, "variable_sip_auth_realm", "1"); - switch_core_hash_insert(filter, "variable_sip_from_host", "1"); - switch_core_hash_insert(filter, "variable_sip_from_user", "1"); - switch_core_hash_insert(filter, "variable_sip_from_tag", "1"); - switch_core_hash_insert(filter, "variable_sip_h_X-AUTH-IP", "1"); - switch_core_hash_insert(filter, "variable_sip_received_ip", "1"); - switch_core_hash_insert(filter, "variable_sip_to_host", "1"); - switch_core_hash_insert(filter, "variable_sip_to_user", "1"); - switch_core_hash_insert(filter, "variable_sip_to_tag", "1"); - switch_core_hash_insert(filter, "variable_sofia_profile_name", "1"); - switch_core_hash_insert(filter, "variable_transfer_history", "1"); - switch_core_hash_insert(filter, "variable_user_name", "1"); - switch_core_hash_insert(filter, "variable_endpoint_disposition", "1"); - switch_core_hash_insert(filter, "variable_originate_disposition", "1"); - switch_core_hash_insert(filter, "variable_bridge_hangup_cause", "1"); - switch_core_hash_insert(filter, "variable_hangup_cause", "1"); - switch_core_hash_insert(filter, "variable_last_bridge_proto_specific_hangup_cause", "1"); - switch_core_hash_insert(filter, "variable_proto_specific_hangup_cause", "1"); - switch_core_hash_insert(filter, "VM-Call-ID", "1"); - switch_core_hash_insert(filter, "VM-sub-call-id", "1"); - switch_core_hash_insert(filter, "whistle_application_name", "1"); - switch_core_hash_insert(filter, "whistle_application_response", "1"); - switch_core_hash_insert(filter, "whistle_event_name", "1"); - switch_core_hash_insert(filter, "kazoo_application_name", "1"); - switch_core_hash_insert(filter, "kazoo_application_response", "1"); - switch_core_hash_insert(filter, "kazoo_event_name", "1"); - switch_core_hash_insert(filter, "sip_auto_answer_notify", "1"); - switch_core_hash_insert(filter, "eavesdrop_group", "1"); - switch_core_hash_insert(filter, "origination_caller_id_name", "1"); - switch_core_hash_insert(filter, "origination_caller_id_number", "1"); - switch_core_hash_insert(filter, "origination_callee_id_name", "1"); - switch_core_hash_insert(filter, "origination_callee_id_number", "1"); - switch_core_hash_insert(filter, "sip_auth_username", "1"); - switch_core_hash_insert(filter, "sip_auth_password", "1"); - switch_core_hash_insert(filter, "effective_caller_id_name", "1"); - switch_core_hash_insert(filter, "effective_caller_id_number", "1"); - switch_core_hash_insert(filter, "effective_callee_id_name", "1"); - switch_core_hash_insert(filter, "effective_callee_id_number", "1"); - switch_core_hash_insert(filter, "variable_destination_number", "1"); - switch_core_hash_insert(filter, "variable_effective_callee_id_name", "1"); - switch_core_hash_insert(filter, "variable_effective_callee_id_number", "1"); - switch_core_hash_insert(filter, "variable_record_silence_hits", "1"); - switch_core_hash_insert(filter, "variable_refer_uuid", "1"); - switch_core_hash_insert(filter, "variable_sip_call_id", "1"); - switch_core_hash_insert(filter, "variable_sip_h_Referred-By", "1"); - switch_core_hash_insert(filter, "variable_sip_h_X-AUTH-PORT", "1"); - switch_core_hash_insert(filter, "variable_sip_loopback_req_uri", "1"); - switch_core_hash_insert(filter, "variable_sip_received_port", "1"); - switch_core_hash_insert(filter, "variable_sip_refer_to", "1"); - switch_core_hash_insert(filter, "variable_sip_req_host", "1"); - switch_core_hash_insert(filter, "variable_sip_req_uri", "1"); - switch_core_hash_insert(filter, "variable_transfer_source", "1"); - switch_core_hash_insert(filter, "variable_uuid", "1"); - - /* Registration headers */ - switch_core_hash_insert(filter, "call-id", "1"); - switch_core_hash_insert(filter, "profile-name", "1"); - switch_core_hash_insert(filter, "from-user", "1"); - switch_core_hash_insert(filter, "from-host", "1"); - switch_core_hash_insert(filter, "presence-hosts", "1"); - switch_core_hash_insert(filter, "contact", "1"); - switch_core_hash_insert(filter, "rpid", "1"); - switch_core_hash_insert(filter, "status", "1"); - switch_core_hash_insert(filter, "expires", "1"); - switch_core_hash_insert(filter, "to-user", "1"); - switch_core_hash_insert(filter, "to-host", "1"); - switch_core_hash_insert(filter, "network-ip", "1"); - switch_core_hash_insert(filter, "network-port", "1"); - switch_core_hash_insert(filter, "username", "1"); - switch_core_hash_insert(filter, "realm", "1"); - switch_core_hash_insert(filter, "user-agent", "1"); - - switch_core_hash_insert(filter, "Hangup-Cause", "1"); - switch_core_hash_insert(filter, "Unique-ID", "1"); - switch_core_hash_insert(filter, "variable_switch_r_sdp", "1"); - switch_core_hash_insert(filter, "variable_rtp_local_sdp_str", "1"); - switch_core_hash_insert(filter, "variable_sip_to_uri", "1"); - switch_core_hash_insert(filter, "variable_sip_from_uri", "1"); - switch_core_hash_insert(filter, "variable_sip_user_agent", "1"); - switch_core_hash_insert(filter, "variable_duration", "1"); - switch_core_hash_insert(filter, "variable_billsec", "1"); - switch_core_hash_insert(filter, "variable_billmsec", "1"); - switch_core_hash_insert(filter, "variable_progresssec", "1"); - switch_core_hash_insert(filter, "variable_progress_uepoch", "1"); - switch_core_hash_insert(filter, "variable_progress_media_uepoch", "1"); - switch_core_hash_insert(filter, "variable_start_uepoch", "1"); - switch_core_hash_insert(filter, "variable_digits_dialed", "1"); - switch_core_hash_insert(filter, "Member-ID", "1"); - switch_core_hash_insert(filter, "Floor", "1"); - switch_core_hash_insert(filter, "Video", "1"); - switch_core_hash_insert(filter, "Hear", "1"); - switch_core_hash_insert(filter, "Speak", "1"); - switch_core_hash_insert(filter, "Talking", "1"); - switch_core_hash_insert(filter, "Current-Energy", "1"); - switch_core_hash_insert(filter, "Energy-Level", "1"); - switch_core_hash_insert(filter, "Mute-Detect", "1"); - - /* RTMP headers */ - switch_core_hash_insert(filter, "RTMP-Session-ID", "1"); - switch_core_hash_insert(filter, "RTMP-Profile", "1"); - switch_core_hash_insert(filter, "RTMP-Flash-Version", "1"); - switch_core_hash_insert(filter, "RTMP-SWF-URL", "1"); - switch_core_hash_insert(filter, "RTMP-TC-URL", "1"); - switch_core_hash_insert(filter, "RTMP-Page-URL", "1"); - switch_core_hash_insert(filter, "User", "1"); - switch_core_hash_insert(filter, "Domain", "1"); - - /* Fax headers */ - switch_core_hash_insert(filter, "variable_fax_bad_rows", "1"); - switch_core_hash_insert(filter, "variable_fax_document_total_pages", "1"); - switch_core_hash_insert(filter, "variable_fax_document_transferred_pages", "1"); - switch_core_hash_insert(filter, "variable_fax_ecm_used", "1"); - switch_core_hash_insert(filter, "variable_fax_result_code", "1"); - switch_core_hash_insert(filter, "variable_fax_result_text", "1"); - switch_core_hash_insert(filter, "variable_fax_success", "1"); - switch_core_hash_insert(filter, "variable_fax_transfer_rate", "1"); - switch_core_hash_insert(filter, "variable_fax_local_station_id", "1"); - switch_core_hash_insert(filter, "variable_fax_remote_station_id", "1"); - switch_core_hash_insert(filter, "variable_fax_remote_country", "1"); - switch_core_hash_insert(filter, "variable_fax_remote_vendor", "1"); - switch_core_hash_insert(filter, "variable_fax_remote_model", "1"); - switch_core_hash_insert(filter, "variable_fax_image_resolution", "1"); - switch_core_hash_insert(filter, "variable_fax_file_image_resolution", "1"); - switch_core_hash_insert(filter, "variable_fax_image_size", "1"); - switch_core_hash_insert(filter, "variable_fax_image_pixel_size", "1"); - switch_core_hash_insert(filter, "variable_fax_file_image_pixel_size", "1"); - switch_core_hash_insert(filter, "variable_fax_longest_bad_row_run", "1"); - switch_core_hash_insert(filter, "variable_fax_encoding", "1"); - switch_core_hash_insert(filter, "variable_fax_encoding_name", "1"); - switch_core_hash_insert(filter, "variable_fax_header", "1"); - switch_core_hash_insert(filter, "variable_fax_ident", "1"); - switch_core_hash_insert(filter, "variable_fax_timezone", "1"); - switch_core_hash_insert(filter, "variable_fax_doc_id", "1"); - switch_core_hash_insert(filter, "variable_fax_doc_database", "1"); - switch_core_hash_insert(filter, "variable_has_t38", "1"); - - /* Secure headers */ - switch_core_hash_insert(filter, "variable_sdp_secure_savp_only", "1"); - switch_core_hash_insert(filter, "variable_rtp_has_crypto", "1"); - switch_core_hash_insert(filter, "variable_rtp_secure_media", "1"); - switch_core_hash_insert(filter, "variable_rtp_secure_media_confirmed", "1"); - switch_core_hash_insert(filter, "variable_rtp_secure_media_confirmed_audio", "1"); - switch_core_hash_insert(filter, "variable_rtp_secure_media_confirmed_video", "1"); - switch_core_hash_insert(filter, "sdp_secure_savp_only", "1"); - switch_core_hash_insert(filter, "rtp_has_crypto", "1"); - switch_core_hash_insert(filter, "rtp_secure_media", "1"); - switch_core_hash_insert(filter, "rtp_secure_media_confirmed", "1"); - switch_core_hash_insert(filter, "rtp_secure_media_confirmed_audio", "1"); - switch_core_hash_insert(filter, "rtp_secure_media_confirmed_video", "1"); - - /* Device Redirect headers */ - switch_core_hash_insert(filter, "variable_last_bridge_hangup_cause", "1"); - switch_core_hash_insert(filter, "variable_sip_redirected_by", "1"); - switch_core_hash_insert(filter, "intercepted_by", "1"); - switch_core_hash_insert(filter, "variable_bridge_uuid", "1"); - switch_core_hash_insert(filter, "Record-File-Path", "1"); - - /* Loopback headers */ - switch_core_hash_insert(filter, "variable_loopback_bowout_on_execute", "1"); - switch_core_hash_insert(filter, "variable_loopback_bowout", "1"); - switch_core_hash_insert(filter, "variable_other_loopback_leg_uuid", "1"); - switch_core_hash_insert(filter, "variable_loopback_leg", "1"); - switch_core_hash_insert(filter, "variable_is_loopback", "1"); - - // SMS - switch_core_hash_insert(filter, "Message-ID", "1"); - switch_core_hash_insert(filter, "Delivery-Failure", "1"); - switch_core_hash_insert(filter, "Delivery-Result-Code", "1"); - - return filter; -} - -static void fetch_config_filters(switch_memory_pool_t *pool) -{ - char *cf = "kazoo.conf"; - switch_xml_t cfg, xml, child, param; - switch_event_t *params; - - switch_event_create(¶ms, SWITCH_EVENT_REQUEST_PARAMS); - switch_event_add_header_string(params, SWITCH_STACK_BOTTOM, "Action", "request-filter"); - - if (!(xml = switch_xml_open_cfg(cf, &cfg, params))) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Failed to open configuration file %s\n", cf); - } else { - if ((child = switch_xml_child(cfg, "event-filter"))) { - switch_hash_t *filter; - switch_hash_t *old_filter; - - switch_core_hash_init(&filter); - for (param = switch_xml_child(child, "header"); param; param = param->next) { - char *var = (char *) switch_xml_attr_soft(param, "name"); - switch_core_hash_insert(filter, var, "1"); - } - - old_filter = kazoo_globals.event_filter; - kazoo_globals.event_filter = filter; - if (old_filter) { - switch_core_hash_destroy(&old_filter); - } - } - - kazoo_globals.config_fetched = 1; - switch_xml_free(xml); - } - switch_event_destroy(¶ms); - -} - -static void fetch_config_handlers(switch_memory_pool_t *pool) -{ - char *cf = "kazoo.conf"; - switch_xml_t cfg, xml; - switch_event_t *params; - - switch_event_create(¶ms, SWITCH_EVENT_REQUEST_PARAMS); - switch_event_add_header_string(params, SWITCH_STACK_BOTTOM, "Action", "request-handlers"); - - if (!(xml = switch_xml_open_cfg(cf, &cfg, params))) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Failed to open configuration file %s\n", cf); - } else { - kazoo_config_handlers(cfg); - kazoo_globals.config_fetched = 1; - switch_xml_free(xml); - } - switch_event_destroy(¶ms); - -} - -static void *SWITCH_THREAD_FUNC fetch_config_exec(switch_thread_t *thread, void *obj) -{ - switch_memory_pool_t *pool = (switch_memory_pool_t *) obj; - ei_node_t *node; - int fetch_filters = 0, fetch_handlers = 0; - - // give some time for node initialization - switch_sleep(kazoo_globals.delay_before_initial_fetch); - - for (node = kazoo_globals.ei_nodes; node != NULL; node = node->next) { - if (node->legacy ) { - fetch_filters++; - } else { - fetch_handlers++; - } - } - - if (fetch_filters) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "fetching filters for kazoo\n"); - fetch_config_filters(pool); - } - - if (fetch_handlers) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "fetching kazoo handlers\n"); - fetch_config_handlers(pool); - } - - kazoo_globals.config_fetched = 1; - - return NULL; -} - -void fetch_config() -{ - switch_memory_pool_t *pool; - switch_thread_t *thread; - switch_threadattr_t *thd_attr = NULL; - switch_uuid_t uuid; - - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "scheduling fetch for kazoo config\n"); - - switch_core_new_memory_pool(&pool); - - switch_threadattr_create(&thd_attr, pool); - switch_threadattr_detach_set(thd_attr, 1); - switch_threadattr_stacksize_set(thd_attr, SWITCH_THREAD_STACKSIZE); - - switch_uuid_get(&uuid); - switch_thread_create(&thread, thd_attr, fetch_config_exec, pool, pool); - -} - -#ifdef WITH_KAZOO_ERL_SHUTDOWN -#if (ERLANG_MAJOR == 10 && ERLANG_MINOR >= 3) || ERLANG_MAJOR >= 11 -typedef struct ei_mutex_s { -#ifdef __WIN32__ - HANDLE lock; -#elif VXWORKS - SEM_ID lock; -#else /* unix */ -#if defined(HAVE_MIT_PTHREAD_H) || defined(HAVE_PTHREAD_H) - pthread_mutex_t *lock; -#else /* ! (HAVE_MIT_PTHREAD_H || HAVE_PTHREAD_H) */ - void *dummy; /* Actually never used */ -#endif /* ! (HAVE_MIT_PTHREAD_H || HAVE_PTHREAD_H) */ -#endif /* unix */ -}ei_mutex_t; - -typedef struct ei_socket_info_s { - int socket; - ei_socket_callbacks *cbs; - void *ctx; - int dist_version; - ei_cnode cnode; /* A copy, not a pointer. We don't know when freed */ - char cookie[EI_MAX_COOKIE_SIZE+1]; -}ei_socket_info; - -extern ei_socket_info *ei_sockets; -extern ei_mutex_t* ei_sockets_lock; -extern int ei_n_sockets; -extern int ei_sz_sockets; - -int ei_mutex_free(ei_mutex_t *l, int nblock); - -#endif -#endif - -void kz_erl_init() -{ -#if (ERLANG_MAJOR == 10 && ERLANG_MINOR >= 3) || ERLANG_MAJOR >= 11 - ei_init(); -#endif -} - -void kz_erl_shutdown() -{ -#ifdef WITH_KAZOO_ERL_SHUTDOWN -#if (ERLANG_MAJOR == 10 && ERLANG_MINOR >= 3) || ERLANG_MAJOR >= 11 - ei_mutex_free(ei_sockets_lock, 1); - ei_sockets_lock = NULL; - free(ei_sockets); - ei_sockets = NULL; - ei_n_sockets = ei_sz_sockets = 0; -#endif -#endif -} - -SWITCH_MODULE_RUNTIME_FUNCTION(mod_kazoo_runtime) -{ - switch_os_socket_t os_socket; - - if (create_acceptor() != SWITCH_STATUS_SUCCESS) { - // TODO: what would we need to clean up here - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Unable to create erlang connection acceptor!\n"); - close_socket(&kazoo_globals.acceptor); - return SWITCH_STATUS_TERM; - } - - switch_atomic_inc(&kazoo_globals.threads); - switch_os_sock_get(&os_socket, kazoo_globals.acceptor); - - while (switch_test_flag(&kazoo_globals, LFLAG_RUNNING)) { - int nodefd; - ErlConnect conn; - - /* zero out errno because ei_accept doesn't differentiate between a */ - /* failed authentication or a socket failure, or a client version */ - /* mismatch or a godzilla attack (and a godzilla attack is highly likely) */ - errno = 0; - - /* wait here for an erlang node to connect, timming out to check if our module is still running every now-and-again */ - if ((nodefd = ei_accept_tmo(&kazoo_globals.ei_cnode, (int) os_socket, &conn, kazoo_globals.connection_timeout)) == ERL_ERROR) { - if (erl_errno == ETIMEDOUT) { - continue; - } else if (errno) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Erlang connection acceptor socket error %d %d\n", erl_errno, errno); - } else { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, - "Erlang node connection failed - ensure your cookie matches '%s' and you are using a good nodename\n", kazoo_globals.ei_cookie); - } - continue; - } - - if (!switch_test_flag(&kazoo_globals, LFLAG_RUNNING)) { - break; - } - - /* NEW ERLANG NODE CONNECTION! Hello friend! */ - new_kazoo_node(nodefd, &conn); - } - - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Erlang connection acceptor shut down\n"); - - switch_atomic_dec(&kazoo_globals.threads); - - return SWITCH_STATUS_TERM; -} - -SWITCH_DECLARE(switch_status_t) ei_queue_pop(switch_queue_t *queue, void **data, switch_interval_time_t timeout) -{ - if (timeout == 0) { - return switch_queue_trypop(queue, data); - } else { - return switch_queue_pop_timeout(queue, data, timeout); - } -} -/* For Emacs: - * Local Variables: - * mode:c - * indent-tabs-mode:t - * tab-width:4 - * c-basic-offset:4 - * End: - * For VIM: - * vim:set softtabstop=4 shiftwidth=4 tabstop=4: - */ diff --git a/src/mod/event_handlers/mod_kazoo/kazoo_endpoints.c b/src/mod/event_handlers/mod_kazoo/kazoo_endpoints.c deleted file mode 100644 index 4ddfeddae4b..00000000000 --- a/src/mod/event_handlers/mod_kazoo/kazoo_endpoints.c +++ /dev/null @@ -1,500 +0,0 @@ -/* - * FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application - * Copyright (C) 2005-2012, Anthony Minessale II - * - * 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 - * Portions created by the Initial Developer are Copyright (C) - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * - * Karl Anderson - * Darren Schreiber - * - * - * kazoo_dptools.c -- clones of mod_dptools commands slightly modified for kazoo - * - */ -#include "mod_kazoo.h" - -#define INTERACTION_VARIABLE "Call-Interaction-ID" - -static const char *x_bridge_variables[] = { - "Call-Control-Queue", - "Call-Control-PID", - "Call-Control-Node", - INTERACTION_VARIABLE, - "ecallmgr_Ecallmgr-Node", - "sip_h_k-cid", - "Switch-URI", - "Switch-URL", - NULL -}; - -static void kz_tweaks_variables_to_event(switch_core_session_t *session, switch_event_t *event) -{ - int i; - switch_channel_t *channel = switch_core_session_get_channel(session); - for(i = 0; x_bridge_variables[i] != NULL; i++) { - const char *val = switch_channel_get_variable_dup(channel, x_bridge_variables[i], SWITCH_FALSE, -1); - switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, x_bridge_variables[i], val); - } -} - -static switch_call_cause_t kz_endpoint_outgoing_channel(switch_core_session_t *session, - switch_event_t *var_event, - switch_caller_profile_t *outbound_profile_in, - switch_core_session_t **new_session, switch_memory_pool_t **pool, switch_originate_flag_t flags, - switch_call_cause_t *cancel_cause) -{ - switch_xml_t x_user = NULL, x_param, x_params, x_callfwd; - char *user = NULL, *domain = NULL, *dup_domain = NULL, *dialed_user = NULL; - char *dest = NULL; - switch_call_cause_t cause = SWITCH_CAUSE_NONE; - unsigned int timelimit = SWITCH_DEFAULT_TIMEOUT; - switch_channel_t *new_channel = NULL; - switch_event_t *params = NULL, *var_event_orig = var_event; - char stupid[128] = ""; - const char *skip = NULL, *var = NULL; - switch_core_session_t *a_session = NULL, *e_session = NULL; - cJSON * ctx = NULL; - const char *endpoint_dial = NULL; - const char *callforward_dial = NULL; - const char *failover_dial = NULL; - char *b_failover_dial = NULL; - const char *endpoint_separator = NULL; - const char *varval = NULL; - char *d_dest = NULL; - switch_channel_t *channel = NULL; - switch_originate_flag_t myflags = SOF_NONE; - char *cid_name_override = NULL; - char *cid_num_override = NULL; - switch_event_t *event = NULL; - switch_status_t status = SWITCH_STATUS_SUCCESS; - switch_caller_profile_t *outbound_profile = NULL; - - - if (zstr(outbound_profile_in->destination_number)) { - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_WARNING, "NO DESTINATION NUMBER\n"); - goto done; - } - - user = strdup(outbound_profile_in->destination_number); - - if (!user) - goto done; - - if ((domain = strchr(user, '@'))) { - *domain++ = '\0'; - } else { - domain = switch_core_get_domain(SWITCH_TRUE); - dup_domain = domain; - } - - if (!domain) { - goto done; - } - - - switch_event_create(¶ms, SWITCH_EVENT_REQUEST_PARAMS); - switch_assert(params); - switch_event_add_header_string(params, SWITCH_STACK_BOTTOM, "as_channel", "true"); - switch_event_add_header_string(params, SWITCH_STACK_BOTTOM, "action", "user_call"); - if (session) { - switch_event_add_header_string(params, SWITCH_STACK_BOTTOM, "Unique-ID", switch_core_session_get_uuid(session)); - } - - if (var_event) { - switch_event_merge(params, var_event); - } - - if (var_event && (skip = switch_event_get_header(var_event, "user_recurse_variables")) && switch_false(skip)) { - if ((var = switch_event_get_header(var_event, SWITCH_CALL_TIMEOUT_VARIABLE)) || (var = switch_event_get_header(var_event, "leg_timeout"))) { - timelimit = atoi(var); - } - var_event = NULL; - } - - if (switch_xml_locate_user_merged("id", user, domain, NULL, &x_user, params) != SWITCH_STATUS_SUCCESS) { - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_WARNING, "Can't find user [%s@%s]\n", user, domain); - cause = SWITCH_CAUSE_SUBSCRIBER_ABSENT; - goto done; - } - - if (var_event) { - const char * str_ctx = switch_event_get_header(var_event, "kz-endpoint-runtime-context"); - if ( str_ctx ) { - ctx = cJSON_Parse(str_ctx); - if (ctx) { - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "call context parsed => %s\n", str_ctx); - } - } - } - - if ((x_params = switch_xml_child(x_user, "variables"))) { - for (x_param = switch_xml_child(x_params, "variable"); x_param; x_param = x_param->next) { - const char *pvar = switch_xml_attr_soft(x_param, "name"); - const char *val = switch_xml_attr(x_param, "value"); - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "adding variable to var_event => %s = %s\n", pvar, val); - if (!var_event) { - switch_event_create(&var_event, SWITCH_EVENT_GENERAL); - } else { - switch_event_del_header(var_event, pvar); - } - switch_event_add_header_string(var_event, SWITCH_STACK_BOTTOM, pvar, val); - } - } - - if ((x_params = switch_xml_child(x_user, "params"))) { - for (x_param = switch_xml_child(x_params, "param"); x_param; x_param = x_param->next) { - const char *pvar = switch_xml_attr_soft(x_param, "name"); - const char *val = switch_xml_attr(x_param, "value"); - - if (!strcasecmp(pvar, "endpoint-dial-string")) { - endpoint_dial = val; - } else if (!strcasecmp(pvar, "callforward-dial-string")) { - callforward_dial = val; - } else if (!strcasecmp(pvar, "endpoint-separator")) { - endpoint_separator = val; - } else if (!strncasecmp(pvar, "dial-var-", 9)) { - if (!var_event) { - switch_event_create(&var_event, SWITCH_EVENT_GENERAL); - } else { - switch_event_del_header(var_event, pvar + 9); - } - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "adding dialog var to var_event => %s = %s\n", pvar + 9, val); - switch_event_add_header_string(var_event, SWITCH_STACK_BOTTOM, pvar + 9, val); - } - } - } - - x_callfwd = switch_xml_child(x_user, "call-forward"); - if (x_callfwd) { - switch_bool_t call_fwd_is_substitute = SWITCH_FALSE, - call_fwd_is_failover = SWITCH_FALSE, - call_fwd_direct_calls_only = SWITCH_FALSE, - call_fwd_is_valid = SWITCH_TRUE; - for (x_param = switch_xml_child(x_callfwd, "variable"); x_param; x_param = x_param->next) { - const char *var = switch_xml_attr_soft(x_param, "name"); - const char *val = switch_xml_attr(x_param, "value"); - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "cfw %s => %s\n", var, val); - if (!strcasecmp(var, "Is-Substitute")) { - call_fwd_is_substitute = switch_true(val); - } else if (!strcasecmp(var, "Is-Failover")) { - call_fwd_is_failover = switch_true(val); - } else if (!strcasecmp(var, "Direct-Calls-Only")) { - call_fwd_direct_calls_only = switch_true(val); - } - } - - if (call_fwd_direct_calls_only) { - call_fwd_is_valid = SWITCH_FALSE; - if (ctx ) { - cJSON *json_flags = cJSON_GetObjectItem(ctx, "Flags"); - if (json_flags && json_flags->type == cJSON_Array) { - cJSON *item; - cJSON_ArrayForEach(item, json_flags) { - if (!strcmp(item->valuestring, "direct_call")) { - call_fwd_is_valid = SWITCH_TRUE; - break; - } - } - if (!call_fwd_is_valid) { - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "call fwd requires direct_call and it was not found\n"); - } - } - } - } - - if (!call_fwd_is_valid) { - dest = endpoint_dial ? strdup(endpoint_dial) : strdup(""); - } else if (call_fwd_is_failover) { - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "setting failover => %s\n", callforward_dial); - dest = endpoint_dial ? strdup(endpoint_dial) : strdup(""); - failover_dial = callforward_dial; - } else if (call_fwd_is_substitute) { - dest = callforward_dial ? strdup(callforward_dial) : strdup(""); - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "setting call fwd substitute => %s\n", dest); - } else { - dest = switch_mprintf("%s%s%s", endpoint_dial ? endpoint_dial : "", (endpoint_dial ? endpoint_separator ? endpoint_separator : "," : ""), callforward_dial); - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "setting call fwd append => %s => %s\n", callforward_dial, dest); - } - } else { - dest = endpoint_dial ? strdup(endpoint_dial) : strdup(""); - } - - dialed_user = (char *)switch_xml_attr(x_user, "id"); - - if (var_event) { - switch_event_add_header_string(var_event, SWITCH_STACK_BOTTOM, "dialed_user", dialed_user); - switch_event_add_header_string(var_event, SWITCH_STACK_BOTTOM, "dialed_domain", domain); - } - - if (!dest) { - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "No dial-string available, please check your user directory.\n"); - cause = SWITCH_CAUSE_MANDATORY_IE_MISSING; - goto done; - } - - if (var_event) { - cid_name_override = switch_event_get_header(var_event, "origination_caller_id_name"); - cid_num_override = switch_event_get_header(var_event, "origination_caller_id_number"); - } - - if(session) { - a_session = session; - } else if(var_event) { - const char* uuid_e_session = switch_event_get_header(var_event, "ent_originate_aleg_uuid"); - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "CHECKING ORIGINATE-UUID : %s\n", uuid_e_session); - if (uuid_e_session && (e_session = switch_core_session_locate(uuid_e_session)) != NULL) { - a_session = e_session; - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "FOUND ORIGINATE-UUID : %s\n", uuid_e_session); - } - } - - if (a_session) { - switch_event_create(&event, SWITCH_EVENT_GENERAL); - channel = switch_core_session_get_channel(a_session); - if ((varval = switch_channel_get_variable(channel, SWITCH_CALL_TIMEOUT_VARIABLE)) - || (var_event && (varval = switch_event_get_header(var_event, "leg_timeout")))) { - timelimit = atoi(varval); - } - switch_channel_event_set_data(channel, event); - - switch_channel_set_variable(channel, "dialed_user", dialed_user); - switch_channel_set_variable(channel, "dialed_domain", domain); - - } else { - if (var_event) { - switch_event_dup(&event, var_event); - switch_event_del_header(event, "dialed_user"); - switch_event_del_header(event, "dialed_domain"); - if ((varval = switch_event_get_header(var_event, SWITCH_CALL_TIMEOUT_VARIABLE)) || - (varval = switch_event_get_header(var_event, "leg_timeout"))) { - timelimit = atoi(varval); - } - } else { - switch_event_create(&event, SWITCH_EVENT_REQUEST_PARAMS); - switch_assert(event); - } - - switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "dialed_user", dialed_user); - switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "dialed_domain", domain); - } - - if ((x_params = switch_xml_child(x_user, "profile-variables"))) { - for (x_param = switch_xml_child(x_params, "variable"); x_param; x_param = x_param->next) { - const char *pvar = switch_xml_attr_soft(x_param, "name"); - const char *val = switch_xml_attr(x_param, "value"); - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "adding profile variable to event => %s = %s\n", pvar, val); - switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, pvar, val); - } - } - - if ((x_params = switch_xml_child(x_user, "variables"))) { - for (x_param = switch_xml_child(x_params, "variable"); x_param; x_param = x_param->next) { - const char *pvar = switch_xml_attr_soft(x_param, "name"); - const char *val = switch_xml_attr(x_param, "value"); - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "adding variable to event => %s = %s\n", pvar, val); - switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, pvar, val); - } - } - - if ((x_params = switch_xml_child(x_user, "params"))) { - for (x_param = switch_xml_child(x_params, "param"); x_param; x_param = x_param->next) { - const char *pvar = switch_xml_attr_soft(x_param, "name"); - const char *val = switch_xml_attr(x_param, "value"); - - if (!strncasecmp(pvar, "dial-var-", 9)) { - switch_event_del_header(event, pvar + 9); - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "adding dialog var to event => %s = %s\n", pvar + 9, val); - switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, pvar + 9, val); - } - } - } - - // add runtime vars to event for expand - if (ctx) { - kz_expand_json_to_event(ctx, event, "kz_ctx"); - } - - d_dest = kz_event_expand_headers(event, dest); - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "dialing %s => %s\n", dest, d_dest); - - if(failover_dial) { - b_failover_dial = kz_event_expand_headers(event, failover_dial); - } - - if (var_event) { - kz_expand_headers(event, var_event); - } - - switch_event_destroy(&event); - - - if ((flags & SOF_NO_LIMITS)) { - myflags |= SOF_NO_LIMITS; - } - - if ((flags & SOF_FORKED_DIAL)) { - myflags |= SOF_NOBLOCK; - } - - if ( a_session ) { - if(var_event) { - kz_tweaks_variables_to_event(a_session, var_event); - } - } - - if(e_session) { - switch_core_session_rwunlock(e_session); - } - - switch_snprintf(stupid, sizeof(stupid), "kz/%s", dialed_user); - if (switch_stristr(stupid, d_dest)) { - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_WARNING, "Waddya Daft? You almost called '%s' in an infinate loop!\n", stupid); - cause = SWITCH_CAUSE_INVALID_IE_CONTENTS; - goto done; - } - - // - outbound_profile = outbound_profile_in; - /* - outbound_profile = switch_caller_profile_dup(outbound_profile_in->pool, outbound_profile_in); - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(*new_session), SWITCH_LOG_DEBUG1, "CHECKING CALLER-ID\n"); - if ((x_params = switch_xml_child(x_user, "profile-variables"))) { - const char* val = NULL; - outbound_profile->soft = NULL; - for (x_param = switch_xml_child(x_params, "variable"); x_param; x_param = x_param->next) { - const char *pvar = switch_xml_attr(x_param, "name"); - const char *val = switch_xml_attr(x_param, "value"); - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(*new_session), SWITCH_LOG_DEBUG1, "setting profile var %s = %s\n", pvar, val); - switch_caller_profile_set_var(outbound_profile, pvar, val); - } - // * TODO * verify onnet/offnet - if((val=switch_caller_get_field_by_name(outbound_profile, "Endpoint-Caller-ID-Name"))) { - outbound_profile->callee_id_name = val; - outbound_profile->orig_caller_id_name = val; - } - if((val=switch_caller_get_field_by_name(outbound_profile, "Endpoint-Caller-ID-Number"))) { - outbound_profile->callee_id_number = val; - outbound_profile->orig_caller_id_number = val; - } - } - */ - - status = switch_ivr_originate(session, new_session, &cause, d_dest, timelimit, NULL, - cid_name_override, cid_num_override, outbound_profile, var_event, myflags, - cancel_cause, NULL); - - if (status != SWITCH_STATUS_SUCCESS && b_failover_dial) { - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_INFO, "trying failover => %s\n", failover_dial); - status = switch_ivr_originate(session, new_session, &cause, b_failover_dial, timelimit, NULL, - cid_name_override, cid_num_override, outbound_profile, var_event, myflags, - cancel_cause, NULL); - } - - if (status == SWITCH_STATUS_SUCCESS) { - const char *context; - switch_caller_profile_t *cp; - - if (var_event) { - switch_event_del_header(var_event, "origination_uuid"); - } - - new_channel = switch_core_session_get_channel(*new_session); - - if ((context = switch_channel_get_variable(new_channel, "user_context"))) { - if ((cp = switch_channel_get_caller_profile(new_channel))) { - cp->context = switch_core_strdup(cp->pool, context); - } - } - - - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(*new_session), SWITCH_LOG_DEBUG1, "CHECKING CALLER-ID\n"); - if ((x_params = switch_xml_child(x_user, "profile-variables"))) { - switch_caller_profile_t *cp = switch_channel_get_caller_profile(new_channel); - const char* val = NULL; - cp->soft = NULL; - for (x_param = switch_xml_child(x_params, "variable"); x_param; x_param = x_param->next) { - const char *pvar = switch_xml_attr(x_param, "name"); - const char *val = switch_xml_attr(x_param, "value"); - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(*new_session), SWITCH_LOG_DEBUG1, "setting profile var %s = %s\n", pvar, val); - switch_channel_set_profile_var(new_channel, pvar, val); - //switch_caller_profile_set_var(cp, pvar, val); - } - // * TODO * verify onnet/offnet - if((val=switch_caller_get_field_by_name(cp, "Endpoint-Caller-ID-Name"))) { - cp->callee_id_name = val; - cp->orig_caller_id_name = val; - } - if((val=switch_caller_get_field_by_name(cp, "Endpoint-Caller-ID-Number"))) { - cp->callee_id_number = val; - cp->orig_caller_id_number = val; - } - } - switch_core_session_rwunlock(*new_session); - } - - done: - - if (d_dest && d_dest != dest) { - switch_safe_free(d_dest); - } - - if(b_failover_dial && b_failover_dial != failover_dial) { - switch_safe_free(b_failover_dial); - } - - switch_safe_free(dest); - - if (ctx) { - cJSON_Delete(ctx); - } - - if (x_user) { - switch_xml_free(x_user); - } - - if (params) { - switch_event_destroy(¶ms); - } - - if (var_event && var_event_orig != var_event) { - switch_event_destroy(&var_event); - } - - switch_safe_free(user); - switch_safe_free(dup_domain); - return cause; -} - - -/* kazoo endpoint */ - - -switch_io_routines_t kz_endpoint_io_routines = { - /*.outgoing_channel */ kz_endpoint_outgoing_channel -}; - -void add_kz_endpoints(switch_loadable_module_interface_t **module_interface) { - switch_endpoint_interface_t *kz_endpoint_interface; - kz_endpoint_interface = (switch_endpoint_interface_t *) switch_loadable_module_create_interface(*module_interface, SWITCH_ENDPOINT_INTERFACE); - kz_endpoint_interface->interface_name = "kz"; - kz_endpoint_interface->io_routines = &kz_endpoint_io_routines; -} diff --git a/src/mod/event_handlers/mod_kazoo/kazoo_event_stream.c b/src/mod/event_handlers/mod_kazoo/kazoo_event_stream.c deleted file mode 100644 index 3d1f18326b2..00000000000 --- a/src/mod/event_handlers/mod_kazoo/kazoo_event_stream.c +++ /dev/null @@ -1,750 +0,0 @@ -/* - * FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application - * Copyright (C) 2005-2012, Anthony Minessale II - * - * 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 - * Portions created by the Initial Developer are Copyright (C) - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * - * Karl Anderson - * Darren Schreiber - * - * - * kazoo_event_streams.c -- Event Publisher - * - */ -#include "mod_kazoo.h" - -#define MAX_FRAMING 4 - -/* Blatantly repurposed from switch_eventc */ -static char *my_dup(const char *s) { - size_t len = strlen(s) + 1; - void *new = malloc(len); - switch_assert(new); - - return (char *) memcpy(new, s, len); -} - -#ifndef DUP -#define DUP(str) my_dup(str) -#endif - -static const char* private_headers[] = {"variable_sip_h_", "sip_h_", "P-", "X-"}; - -static int is_private_header(const char *name) { - int i; - for(i=0; i < 4; i++) { - if(!strncmp(name, private_headers[i], strlen(private_headers[i]))) { - return 1; - } - } - return 0; -} - -static int is_kazoo_var(char* header) -{ - int idx = 0; - while(kazoo_globals.kazoo_var_prefixes[idx] != NULL) { - char *prefix = kazoo_globals.kazoo_var_prefixes[idx]; - if(!strncasecmp(header, prefix, strlen(prefix))) { - return 1; - } - idx++; - } - - return 0; -} - -static switch_status_t kazoo_event_dup(switch_event_t **clone, switch_event_t *event, switch_hash_t *filter) { - switch_event_header_t *header; - - if (switch_event_create_subclass(clone, SWITCH_EVENT_CLONE, event->subclass_name) != SWITCH_STATUS_SUCCESS) { - return SWITCH_STATUS_GENERR; - } - - (*clone)->event_id = event->event_id; - (*clone)->event_user_data = event->event_user_data; - (*clone)->bind_user_data = event->bind_user_data; - (*clone)->flags = event->flags; - - for (header = event->headers; header; header = header->next) { - if (event->subclass_name && !strcmp(header->name, "Event-Subclass")) { - continue; - } - - if (!is_kazoo_var(header->name) - && filter - && !switch_core_hash_find(filter, header->name) - && (!kazoo_globals.send_all_headers) - && (!(kazoo_globals.send_all_private_headers && is_private_header(header->name))) - ) - { - continue; - } - - if (header->idx) { - int i; - for (i = 0; i < header->idx; i++) { - switch_event_add_header_string(*clone, SWITCH_STACK_PUSH, header->name, header->array[i]); - } - } else { - switch_event_add_header_string(*clone, SWITCH_STACK_BOTTOM, header->name, header->value); - } - } - - if (event->body) { - (*clone)->body = DUP(event->body); - } - - (*clone)->key = event->key; - - return SWITCH_STATUS_SUCCESS; -} - -static int encode_event_old(switch_event_t *event, ei_x_buff *ebuf) { - switch_event_t *clone = NULL; - - if (kazoo_event_dup(&clone, event, kazoo_globals.event_filter) != SWITCH_STATUS_SUCCESS) { - return 0; - } - - ei_encode_switch_event(ebuf, clone); - - switch_event_destroy(&clone); - - return 1; -} - -static int encode_event_new(switch_event_t *event, ei_x_buff *ebuf) { - kazoo_message_ptr msg = NULL; - ei_event_binding_t *event_binding = (ei_event_binding_t *) event->bind_user_data; - - msg = kazoo_message_create_event(event, event_binding->event, kazoo_globals.events); - - if(msg == NULL) { - return 0; - } - - ei_x_encode_tuple_header(ebuf, 3); - ei_x_encode_atom(ebuf, "event"); - if(kazoo_globals.json_encoding == ERLANG_TUPLE) { - ei_x_encode_atom(ebuf, "json"); - } else { - ei_x_encode_atom(ebuf, "map"); - } - ei_encode_json(ebuf, msg->JObj); - - kazoo_message_destroy(&msg); - - return 1; -} - -/* - * event_handler is duplicated when there are 2+ nodes connected - * with the same bindings - * we should maintain a list of event_streams in event_binding struct - * and build a ref count in the message - * - */ -static void event_handler(switch_event_t *event) { - ei_event_binding_t *event_binding = (ei_event_binding_t *) event->bind_user_data; - ei_event_stream_t *event_stream = event_binding->stream; - ei_x_buff *ebuf = NULL; - int res = 0; - - /* if mod_kazoo or the event stream isn't running dont push a new event */ - if (!switch_test_flag(event_stream, LFLAG_RUNNING) || !switch_test_flag(&kazoo_globals, LFLAG_RUNNING)) { - return; - } - - kz_event_decode(event); - - switch_malloc(ebuf, sizeof(*ebuf)); - if(ebuf == NULL) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Could not allocate erlang buffer for mod_kazoo message\n"); - return; - } - memset(ebuf, 0, sizeof(*ebuf)); - - if(kazoo_globals.event_stream_preallocate > 0) { - ebuf->buff = malloc(kazoo_globals.event_stream_preallocate); - ebuf->buffsz = kazoo_globals.event_stream_preallocate; - ebuf->index = 0; - if(ebuf->buff == NULL) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Could not pre-allocate memory for mod_kazoo message\n"); - switch_safe_free(ebuf); - return; - } - } else { - ei_x_new(ebuf); - } - - ebuf->index = MAX_FRAMING; - - ei_x_encode_version(ebuf); - - switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Target-Node", event_binding->stream->node->peer_nodename); - switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Switch-Nodename", kazoo_globals.ei_cnode.thisnodename); - - if(event_stream->node->legacy) { - res = encode_event_old(event, ebuf); - } else { - res = encode_event_new(event, ebuf); - } - - switch_event_del_header(event, "Switch-Nodename"); - switch_event_del_header(event, "Target-Node"); - - if(!res) { - ei_x_free(ebuf); - switch_safe_free(ebuf); - return; - } - - if (kazoo_globals.event_stream_preallocate > 0 && ebuf->buffsz > kazoo_globals.event_stream_preallocate) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "increased event stream buffer size to %d\n", ebuf->buffsz); - } - - if (switch_queue_trypush(event_stream->queue, ebuf) != SWITCH_STATUS_SUCCESS) { - /* if we couldn't place the cloned event into the listeners */ - /* event queue make sure we destroy it, real good like */ - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "error placing the event in the listeners queue\n"); - ei_x_free(ebuf); - switch_safe_free(ebuf); - } - -} - -static void *SWITCH_THREAD_FUNC event_stream_loop(switch_thread_t *thread, void *obj) { - ei_event_stream_t *event_stream = (ei_event_stream_t *) obj; - ei_event_binding_t *event_binding; - switch_sockaddr_t *sa; - uint16_t port; - char ipbuf[48]; - const char *ip_addr; - void *pop; - short event_stream_framing; - short event_stream_keepalive; - short ok = 1; - - switch_atomic_inc(&kazoo_globals.threads); - - switch_assert(event_stream != NULL); - - event_stream_framing = event_stream->event_stream_framing; - event_stream_keepalive = event_stream->event_stream_keepalive; - - /* figure out what socket we just opened */ - switch_socket_addr_get(&sa, SWITCH_FALSE, event_stream->acceptor); - port = switch_sockaddr_get_port(sa); - ip_addr = switch_get_addr(ipbuf, sizeof(ipbuf), sa); - - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Starting erlang event stream %p on %s:%u for %s <%d.%d.%d>\n" - ,(void *)event_stream, ip_addr, port, event_stream->pid.node, event_stream->pid.creation - ,event_stream->pid.num, event_stream->pid.serial); - - while (switch_test_flag(event_stream, LFLAG_RUNNING) && switch_test_flag(&kazoo_globals, LFLAG_RUNNING) && ok) { - const switch_pollfd_t *fds; - int32_t numfds; - - /* check if a new connection is pending */ - if (switch_pollset_poll(event_stream->pollset, 0, &numfds, &fds) == SWITCH_STATUS_SUCCESS) { - int32_t i; - for (i = 0; i < numfds; i++) { - switch_socket_t *newsocket; - - /* accept the new client connection */ - if (switch_socket_accept(&newsocket, event_stream->acceptor, event_stream->pool) == SWITCH_STATUS_SUCCESS) { - switch_sockaddr_t *sa; - - if (switch_socket_opt_set(newsocket, SWITCH_SO_NONBLOCK, TRUE)) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Couldn't set socket as non-blocking\n"); - } - - if (event_stream_keepalive) { - if (switch_socket_opt_set(newsocket, SWITCH_SO_KEEPALIVE, TRUE)) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Couldn't set socket keep-alive\n"); - } - } - - if (switch_socket_opt_set(newsocket, SWITCH_SO_TCP_NODELAY, 1)) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Couldn't disable Nagle.\n"); - } - - /* close the current client, if there is one */ - close_socket(&event_stream->socket); - - switch_mutex_lock(event_stream->socket_mutex); - /* start sending to the new client */ - event_stream->socket = newsocket; - - switch_socket_addr_get(&sa, SWITCH_TRUE, newsocket); - event_stream->remote_port = switch_sockaddr_get_port(sa); - switch_get_addr(event_stream->remote_ip, sizeof (event_stream->remote_ip), sa); - - switch_socket_addr_get(&sa, SWITCH_FALSE, newsocket); - event_stream->local_port = switch_sockaddr_get_port(sa); - switch_get_addr(event_stream->local_ip, sizeof (event_stream->local_ip), sa); - - event_stream->connected = SWITCH_TRUE; - event_stream->connected_time = switch_micro_time_now(); - - switch_mutex_unlock(event_stream->socket_mutex); - - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Erlang event stream %p client %s:%u\n", (void *)event_stream, event_stream->remote_ip, event_stream->remote_port); - } - } - } - - /* if there was an event waiting in our queue send it to the client */ - if (ei_queue_pop(event_stream->queue, &pop, event_stream->queue_timeout) == SWITCH_STATUS_SUCCESS) { - ei_x_buff *ebuf = (ei_x_buff *) pop; - - if (event_stream->socket) { - switch_size_t size = 1, expected = 0; - switch_status_t status = SWITCH_STATUS_SUCCESS; - - if(ebuf->index >= pow(2, 8 * event_stream_framing)) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "sending frame size %d with insufficient frame capacity, change event_stream_framing here and tcp_packet_type in ecallmgr\n", ebuf->index); - } else { - if(event_stream_framing) { - int index = ebuf->index - MAX_FRAMING; - char byte; - short i = event_stream_framing; - while (i) { - byte = index >> (8 * --i); - ebuf->buff[MAX_FRAMING - i - 1] = byte; - } - } - expected = size = (switch_size_t)ebuf->index - MAX_FRAMING + event_stream_framing; - if((status = switch_socket_send(event_stream->socket, ebuf->buff + (MAX_FRAMING - event_stream_framing), &size)) != SWITCH_STATUS_SUCCESS) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "error %d sending event stream\n", status); - ok = 0; - } else if(expected != size) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "error sending event stream, sent bytes is different of expected\n"); - ok = 0; - } - } - } - - ei_x_free(ebuf); - switch_safe_free(ebuf); - } - } - - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Shutting down erlang event stream %p\n", (void *)event_stream); - - /* unbind from the system events */ - event_binding = event_stream->bindings; - while(event_binding != NULL) { - switch_event_unbind(&event_binding->node); - event_binding = event_binding->next; - } - event_stream->bindings = NULL; - - /* clear and destroy any remaining queued events */ - while (switch_queue_trypop(event_stream->queue, &pop) == SWITCH_STATUS_SUCCESS) { - ei_x_buff *ebuf = (ei_x_buff *) pop; - ei_x_free(ebuf); - switch_safe_free(ebuf); - } - - /* remove the acceptor pollset */ - switch_pollset_remove(event_stream->pollset, event_stream->pollfd); - - /* close any open sockets */ - close_socket(&event_stream->acceptor); - - switch_mutex_lock(event_stream->socket_mutex); - event_stream->connected = SWITCH_FALSE; - close_socket(&event_stream->socket); - switch_mutex_unlock(event_stream->socket_mutex); - - switch_mutex_destroy(event_stream->socket_mutex); - - /* clean up the memory */ - switch_core_destroy_memory_pool(&event_stream->pool); - - switch_atomic_dec(&kazoo_globals.threads); - - return NULL; -} - -ei_event_stream_t *new_event_stream(ei_node_t *ei_node, const erlang_pid *from) { - switch_thread_t *thread; - switch_threadattr_t *thd_attr = NULL; - switch_memory_pool_t *pool = NULL; - ei_event_stream_t *event_stream; - ei_event_stream_t **event_streams = &ei_node->event_streams; - - /* create memory pool for this event stream */ - if (switch_core_new_memory_pool(&pool) != SWITCH_STATUS_SUCCESS) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Out of memory: How many Alzheimer's patients does it take to screw in a light bulb? To get to the other side.\n"); - return NULL; - } - - /* from the memory pool, allocate the event stream structure */ - if (!(event_stream = switch_core_alloc(pool, sizeof (*event_stream)))) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Out of memory: I may have Alzheimers but at least I dont have Alzheimers.\n"); - goto cleanup; - } - - /* prepare the event stream */ - memset(event_stream, 0, sizeof(*event_stream)); - event_stream->bindings = NULL; - event_stream->pool = pool; - event_stream->connected = SWITCH_FALSE; - event_stream->node = ei_node; - event_stream->event_stream_framing = ei_node->event_stream_framing; - event_stream->event_stream_keepalive = ei_node->event_stream_keepalive; - event_stream->queue_timeout = ei_node->event_stream_queue_timeout; - memcpy(&event_stream->pid, from, sizeof(erlang_pid)); - switch_queue_create(&event_stream->queue, MAX_QUEUE_LEN, pool); - - /* create a socket for accepting the event stream client */ - if (!(event_stream->acceptor = create_socket(pool))) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Like car accidents, most hardware problems are due to driver error.\n"); - goto cleanup; - } - - if (switch_socket_opt_set(event_stream->acceptor, SWITCH_SO_NONBLOCK, TRUE)) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Hey, it compiles!\n"); - goto cleanup; - } - - /* create a pollset so we can efficiently check for new client connections */ - if (switch_pollset_create(&event_stream->pollset, 1000, pool, 0) != SWITCH_STATUS_SUCCESS) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "My software never has bugs. It just develops random features.\n"); - goto cleanup; - } - - switch_socket_create_pollfd(&event_stream->pollfd, event_stream->acceptor, SWITCH_POLLIN | SWITCH_POLLERR, NULL, pool); - if (switch_pollset_add(event_stream->pollset, event_stream->pollfd) != SWITCH_STATUS_SUCCESS) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "If you saw a heat wave, would you wave back?\n"); - goto cleanup; - } - - switch_mutex_init(&event_stream->socket_mutex, SWITCH_MUTEX_DEFAULT, pool); - - /* add the new event stream to the link list - * since the event streams link list is only - * accessed from the same thread no locks - * are required */ - if (!*event_streams) { - *event_streams = event_stream; - } else { - event_stream->next = *event_streams; - *event_streams = event_stream; - } - - /* when we start we are running */ - switch_set_flag(event_stream, LFLAG_RUNNING); - - switch_threadattr_create(&thd_attr, event_stream->pool); - switch_threadattr_detach_set(thd_attr, 1); - switch_threadattr_stacksize_set(thd_attr, SWITCH_THREAD_STACKSIZE); - switch_thread_create(&thread, thd_attr, event_stream_loop, event_stream, event_stream->pool); - - return event_stream; - -cleanup: - - if (event_stream) { - /* remove the acceptor pollset */ - if (event_stream->pollset) { - switch_pollset_remove(event_stream->pollset, event_stream->pollfd); - } - - /* close any open sockets */ - if (event_stream->acceptor) { - close_socket(&event_stream->acceptor); - } - } - - /* clean up the memory */ - switch_core_destroy_memory_pool(&pool); - - return NULL; - -} - -unsigned long get_stream_port(const ei_event_stream_t *event_stream) { - switch_sockaddr_t *sa; - switch_socket_addr_get(&sa, SWITCH_FALSE, event_stream->acceptor); - return (unsigned long) switch_sockaddr_get_port(sa); -} - -ei_event_stream_t *find_event_stream(ei_event_stream_t *event_stream, const erlang_pid *from) { - while (event_stream != NULL) { - if (ei_compare_pids(&event_stream->pid, from) == SWITCH_STATUS_SUCCESS) { - return event_stream; - } - event_stream = event_stream->next; - } - - return NULL; -} - -switch_status_t remove_event_stream(ei_event_stream_t **event_streams, const erlang_pid *from) { - ei_event_stream_t *event_stream, *prev = NULL; - int found = 0; - - /* if there are no event bindings there is nothing to do */ - if (!*event_streams) { - return SWITCH_STATUS_SUCCESS; - } - - /* try to find the event stream for the client process */ - event_stream = *event_streams; - while(event_stream != NULL) { - if (ei_compare_pids(&event_stream->pid, from) == SWITCH_STATUS_SUCCESS) { - found = 1; - break; - } - - prev = event_stream; - event_stream = event_stream->next; - } - - if (found) { - /* if we found an event stream remove it from - * from the link list */ - if (!prev) { - *event_streams = event_stream->next; - } else { - prev->next = event_stream->next; - } - - /* stop the event stream thread */ - switch_clear_flag(event_stream, LFLAG_RUNNING); - } - - return SWITCH_STATUS_SUCCESS; -} - -switch_status_t remove_event_streams(ei_event_stream_t **event_streams) { - ei_event_stream_t *event_stream = *event_streams; - - while(event_stream != NULL) { - /* stop the event bindings publisher thread */ - switch_clear_flag(event_stream, LFLAG_RUNNING); - - event_stream = event_stream->next; - } - - *event_streams = NULL; - - return SWITCH_STATUS_SUCCESS; -} - -void bind_event_profile(ei_event_binding_t *event_binding, kazoo_event_ptr event) -{ - switch_event_types_t event_type; - while(event != NULL) { - if (switch_name_event(event->name, &event_type) != SWITCH_STATUS_SUCCESS) { - event_type = SWITCH_EVENT_CUSTOM; - } - if(event_binding->type != SWITCH_EVENT_CUSTOM - && event_binding->type == event_type) { - break; - } - if (event_binding->type == SWITCH_EVENT_CUSTOM - && event_binding->type == event_type - && !strcasecmp(event_binding->subclass_name, event->name)) { - break; - } - event = event->next; - } - event_binding->event = event; - if(event == NULL && (!event_binding->stream->node->legacy)) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "event binding to an event without profile in non legacy mode => %s - %s\n",switch_event_name(event_binding->type), event_binding->subclass_name); - } -} - -void bind_event_profiles(kazoo_event_ptr event) -{ - ei_node_t *ei_node = kazoo_globals.ei_nodes; - while(ei_node) { - ei_event_stream_t *event_streams = ei_node->event_streams; - while(event_streams) { - ei_event_binding_t *bindings = event_streams->bindings; - while(bindings) { - bind_event_profile(bindings, event); - bindings = bindings->next; - } - event_streams = event_streams->next; - } - ei_node = ei_node->next; - } -} - -switch_status_t add_event_binding(ei_event_stream_t *event_stream, const char *event_name) { - ei_event_binding_t *event_binding = event_stream->bindings; - switch_event_types_t event_type; - - if(!strcasecmp(event_name, "CUSTOM")) { - return SWITCH_STATUS_SUCCESS; - } - - if (switch_name_event(event_name, &event_type) != SWITCH_STATUS_SUCCESS) { - event_type = SWITCH_EVENT_CUSTOM; - } - - /* check if the event binding already exists, ignore if so */ - while(event_binding != NULL) { - if (event_binding->type == SWITCH_EVENT_CUSTOM) { - if(event_type == SWITCH_EVENT_CUSTOM - && event_name - && event_binding->subclass_name - && !strcasecmp(event_name, event_binding->subclass_name)) { - return SWITCH_STATUS_SUCCESS; - } - } else if (event_binding->type == event_type) { - return SWITCH_STATUS_SUCCESS; - } - event_binding = event_binding->next; - } - - /* from the event stream memory pool, allocate the event binding structure */ - if (!(event_binding = switch_core_alloc(event_stream->pool, sizeof (*event_binding)))) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Out of random-access memory, attempting write-only memory\n"); - return SWITCH_STATUS_FALSE; - } - - /* prepare the event binding struct */ - event_binding->stream = event_stream; - event_binding->type = event_type; - if(event_binding->type == SWITCH_EVENT_CUSTOM) { - event_binding->subclass_name = switch_core_strdup(event_stream->pool, event_name); - } else { - event_binding->subclass_name = SWITCH_EVENT_SUBCLASS_ANY; - } - event_binding->next = NULL; - - bind_event_profile(event_binding, kazoo_globals.events->events); - - - /* bind to the event with a unique ID and capture the event_node pointer */ - switch_uuid_str(event_binding->id, sizeof(event_binding->id)); - if (switch_event_bind_removable(event_binding->id, event_type, event_binding->subclass_name, event_handler, event_binding, &event_binding->node) != SWITCH_STATUS_SUCCESS) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Unable to bind to event %s %s!\n" - ,switch_event_name(event_binding->type), event_binding->subclass_name ? event_binding->subclass_name : ""); - return SWITCH_STATUS_GENERR; - } - - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Adding event binding %s to stream %p for %s <%d.%d.%d>: %s %s\n" - ,event_binding->id, (void *)event_stream, event_stream->pid.node, event_stream->pid.creation - ,event_stream->pid.num, event_stream->pid.serial, switch_event_name(event_binding->type) - ,event_binding->subclass_name ? event_binding->subclass_name : ""); - - /* add the new binding to the list */ - if (!event_stream->bindings) { - event_stream->bindings = event_binding; - } else { - event_binding->next = event_stream->bindings; - event_stream->bindings = event_binding; - } - - return SWITCH_STATUS_SUCCESS; -} - -switch_status_t remove_event_binding(ei_event_stream_t *event_stream, const switch_event_types_t event_type, const char *subclass_name) { - ei_event_binding_t *event_binding = event_stream->bindings, *prev = NULL; - int found = 0; - - /* if there are no bindings then there is nothing to do */ - if (!event_binding) { - return SWITCH_STATUS_SUCCESS; - } - - /* try to find the event binding specified */ - while(event_binding != NULL) { - if (event_binding->type == SWITCH_EVENT_CUSTOM - && subclass_name - && event_binding->subclass_name - && !strcmp(subclass_name, event_binding->subclass_name)) { - found = 1; - break; - } else if (event_binding->type == event_type) { - found = 1; - break; - } - - prev = event_binding; - event_binding = event_binding->next; - } - - if (found) { - /* if the event binding exists, unbind from the system */ - switch_event_unbind(&event_binding->node); - - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Removing event binding %s from %p for %s <%d.%d.%d>: %s %s\n" - ,event_binding->id, (void *)event_stream, event_stream->pid.node, event_stream->pid.creation - ,event_stream->pid.num, event_stream->pid.serial, switch_event_name(event_binding->type) - ,event_binding->subclass_name ? event_binding->subclass_name : ""); - - /* remove the event binding from the list */ - if (!prev) { - event_stream->bindings = event_binding->next; - } else { - prev->next = event_binding->next; - } - } - - return SWITCH_STATUS_SUCCESS; -} - -switch_status_t remove_event_bindings(ei_event_stream_t *event_stream) { - ei_event_binding_t *event_binding = event_stream->bindings; - - /* if there are no bindings then there is nothing to do */ - if (!event_binding) { - return SWITCH_STATUS_SUCCESS; - } - - /* try to find the event binding specified */ - while(event_binding != NULL) { - /* if the event binding exists, unbind from the system */ - switch_event_unbind(&event_binding->node); - - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Removing event binding %s from %p for %s <%d.%d.%d>: %s %s\n" - ,event_binding->id, (void *)event_stream, event_stream->pid.node, event_stream->pid.creation - ,event_stream->pid.num, event_stream->pid.serial, switch_event_name(event_binding->type) - ,event_binding->subclass_name ? event_binding->subclass_name : ""); - - event_binding = event_binding->next; - } - - event_stream->bindings = NULL; - - return SWITCH_STATUS_SUCCESS; -} - -/* For Emacs: - * Local Variables: - * mode:c - * indent-tabs-mode:t - * tab-width:4 - * c-basic-offset:4 - * End: - * For VIM: - * vim:set softtabstop=4 shiftwidth=4 tabstop=4: - */ diff --git a/src/mod/event_handlers/mod_kazoo/kazoo_fetch_agent.c b/src/mod/event_handlers/mod_kazoo/kazoo_fetch_agent.c deleted file mode 100644 index 5023e393440..00000000000 --- a/src/mod/event_handlers/mod_kazoo/kazoo_fetch_agent.c +++ /dev/null @@ -1,803 +0,0 @@ -/* - * FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application - * Copyright (C) 2005-2012, Anthony Minessale II - * - * 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 - * Portions created by the Initial Developer are Copyright (C) - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * - * Karl Anderson - * Darren Schreiber - * - * - * kazoo_fetch.c -- XML fetch request handler - * - */ -#include "mod_kazoo.h" - -static const char *fetch_uuid_sources[] = { - "Fetch-Call-UUID", - "refer-from-channel-id", - "sip_call_id", - NULL -}; - -static char *xml_section_to_string(switch_xml_section_t section) { - switch(section) { - case SWITCH_XML_SECTION_CONFIG: - return "configuration"; - case SWITCH_XML_SECTION_DIRECTORY: - return "directory"; - case SWITCH_XML_SECTION_DIALPLAN: - return "dialplan"; - case SWITCH_XML_SECTION_CHATPLAN: - return "chatplan"; - case SWITCH_XML_SECTION_CHANNELS: - return "channels"; - case SWITCH_XML_SECTION_LANGUAGES: - return "languages"; - default: - return "unknown"; - } -} - -static char *expand_vars(char *xml_str) { - char *var, *val; - char *rp = xml_str; /* read pointer */ - char *ep, *wp, *buff; /* end pointer, write pointer, write buffer */ - - if (!(strstr(xml_str, "$${"))) { - return xml_str; - } - - switch_zmalloc(buff, strlen(xml_str) * 2); - wp = buff; - ep = buff + (strlen(xml_str) * 2) - 1; - - while (*rp && wp < ep) { - if (*rp == '$' && *(rp + 1) == '$' && *(rp + 2) == '{') { - char *e = switch_find_end_paren(rp + 2, '{', '}'); - - if (e) { - rp += 3; - var = rp; - *e++ = '\0'; - rp = e; - - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "trying to expand %s \n", var); - if ((val = switch_core_get_variable_dup(var))) { - char *p; - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "expanded %s to %s\n", var, val); - for (p = val; p && *p && wp <= ep; p++) { - *wp++ = *p; - } - switch_safe_free(val); - } - continue; - } - } - - *wp++ = *rp++; - } - - *wp++ = '\0'; - - switch_safe_free(xml_str); - return buff; -} - -static switch_xml_t fetch_handler(const char *section, const char *tag_name, const char *key_name, const char *key_value, switch_event_t *params, void *user_data) { - switch_xml_t xml = NULL; - switch_uuid_t uuid; - switch_time_t now = 0; - ei_xml_agent_t *agent = (ei_xml_agent_t *) user_data; - ei_xml_client_t *client; - fetch_handler_t *fetch_handler; - xml_fetch_reply_t reply, *pending, *prev = NULL; - switch_event_t *event = params; - kazoo_fetch_profile_ptr profile = agent->profile; - const char *fetch_call_id; - ei_send_msg_t *send_msg = NULL; - int sent = 0; - - now = switch_micro_time_now(); - - if (!switch_test_flag(&kazoo_globals, LFLAG_RUNNING)) { - return xml; - } - - /* read-lock the agent */ - switch_thread_rwlock_rdlock(agent->lock); - - /* serialize access to current, used to round-robin requests */ - /* TODO: check kazoo_globals for round-robin boolean or loop all clients */ - switch_mutex_lock(agent->current_client_mutex); - if (!agent->current_client) { - client = agent->clients; - } else { - client = agent->current_client; - } - if (client) { - agent->current_client = client->next; - } - switch_mutex_unlock(agent->current_client_mutex); - - /* no client, no work required */ - if (!client || !client->fetch_handlers) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "No %s XML erlang handler currently available\n" - ,section); - switch_thread_rwlock_unlock(agent->lock); - return xml; - } - - /* no profile, no work required */ - if (!profile) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "weird case where client is available but there's no profile for %s. try reloading mod_kazoo.\n" - ,section); - switch_thread_rwlock_unlock(agent->lock); - return xml; - } - - if(event == NULL) { - if (switch_event_create(&event, SWITCH_EVENT_GENERAL) != SWITCH_STATUS_SUCCESS) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "error creating event for fetch handler\n"); - return xml; - } - } - - switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Switch-Nodename", kazoo_globals.ei_cnode.thisnodename); - - /* prepare the reply collector */ - switch_uuid_get(&uuid); - switch_uuid_format(reply.uuid_str, &uuid); - reply.next = NULL; - reply.xml_str = NULL; - - if(switch_event_get_header(event, "Unique-ID") == NULL) { - int i; - for(i = 0; fetch_uuid_sources[i] != NULL; i++) { - if((fetch_call_id = switch_event_get_header(event, fetch_uuid_sources[i])) != NULL) { - switch_core_session_t *session = NULL; - if((session = switch_core_session_locate(fetch_call_id)) != NULL) { - switch_channel_t *channel = switch_core_session_get_channel(session); - uint32_t verbose = switch_channel_test_flag(channel, CF_VERBOSE_EVENTS); - switch_channel_set_flag(channel, CF_VERBOSE_EVENTS); - switch_channel_event_set_data(channel, event); - switch_channel_set_flag_value(channel, CF_VERBOSE_EVENTS, verbose); - switch_core_session_rwunlock(session); - break; - } - } - } - } - - switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Fetch-UUID", reply.uuid_str); - switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Fetch-Section", section); - switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Fetch-Tag", tag_name); - switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Fetch-Key-Name", key_name); - switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Fetch-Key-Value", key_value); - switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Fetch-Timeout", "%u", profile->fetch_timeout); - switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Fetch-Timestamp-Micro", "%" SWITCH_UINT64_T_FMT, (uint64_t)now); - switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Kazoo-Version", VERSION); - switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Kazoo-Bundle", BUNDLE); - switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Kazoo-Release", RELEASE); - - kz_event_decode(event); - - switch_malloc(send_msg, sizeof(*send_msg)); - - if(client->ei_node->legacy) { - ei_x_new_with_version(&send_msg->buf); - ei_x_encode_tuple_header(&send_msg->buf, 7); - ei_x_encode_atom(&send_msg->buf, "fetch"); - ei_x_encode_atom(&send_msg->buf, section); - _ei_x_encode_string(&send_msg->buf, tag_name ? tag_name : "undefined"); - _ei_x_encode_string(&send_msg->buf, key_name ? key_name : "undefined"); - _ei_x_encode_string(&send_msg->buf, key_value ? key_value : "undefined"); - _ei_x_encode_string(&send_msg->buf, reply.uuid_str); - ei_encode_switch_event_headers(&send_msg->buf, event); - } else { - kazoo_message_ptr msg = kazoo_message_create_fetch(event, profile); - ei_x_new_with_version(&send_msg->buf); - ei_x_encode_tuple_header(&send_msg->buf, 2); - ei_x_encode_atom(&send_msg->buf, "fetch"); - ei_encode_json(&send_msg->buf, msg->JObj); - kazoo_message_destroy(&msg); - } - - /* add our reply placeholder to the replies list */ - switch_mutex_lock(agent->replies_mutex); - if (!agent->replies) { - agent->replies = &reply; - } else { - reply.next = agent->replies; - agent->replies = &reply; - } - switch_mutex_unlock(agent->replies_mutex); - - fetch_handler = client->fetch_handlers; - while (fetch_handler != NULL && sent == 0) { - memcpy(&send_msg->pid, &fetch_handler->pid, sizeof(erlang_pid)); - if (switch_queue_trypush(client->ei_node->send_msgs, send_msg) != SWITCH_STATUS_SUCCESS) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Failed to send %s XML request to %s <%d.%d.%d>\n" - ,section - ,fetch_handler->pid.node - ,fetch_handler->pid.creation - ,fetch_handler->pid.num - ,fetch_handler->pid.serial); - } else { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Sending %s XML request (%s) to %s <%d.%d.%d>\n" - ,section - ,reply.uuid_str - ,fetch_handler->pid.node - ,fetch_handler->pid.creation - ,fetch_handler->pid.num - ,fetch_handler->pid.serial); - sent = 1; - } - fetch_handler = fetch_handler->next; - } - - if(!sent) { - ei_x_free(&send_msg->buf); - switch_safe_free(send_msg); - } - - if(params == NULL) - switch_event_destroy(&event); - - /* wait for a reply (if there isnt already one...amazingly improbable but lets not take shortcuts */ - switch_mutex_lock(agent->replies_mutex); - - switch_thread_rwlock_unlock(agent->lock); - - if (!reply.xml_str) { - switch_time_t timeout; - - timeout = switch_micro_time_now() + 3000000; - while (switch_micro_time_now() < timeout) { - /* unlock the replies list and go to sleep, calculate a three second timeout before we started the loop - * plus 100ms to add a little hysteresis between the timeout and the while loop */ - switch_thread_cond_timedwait(agent->new_reply, agent->replies_mutex, (timeout - switch_micro_time_now() + 100000)); - - /* if we woke up (and therefore have locked replies again) check if we got our reply - * otherwise we either timed-out (the while condition will fail) or one of - * our sibling processes got a reply and we should go back to sleep */ - if (reply.xml_str) { - break; - } - } - } - - /* find our reply placeholder in the linked list and remove it */ - pending = agent->replies; - while (pending != NULL) { - if (pending->uuid_str == reply.uuid_str) { - break; - } - - prev = pending; - pending = pending->next; - } - - if (pending) { - if (!prev) { - agent->replies = reply.next; - } else { - prev->next = reply.next; - } - } - - /* we are done with the replies link-list */ - switch_mutex_unlock(agent->replies_mutex); - - /* after all that did we get what we were after?! */ - if (reply.xml_str) { - /* HELL YA WE DID */ - if (kazoo_globals.expand_headers_on_fetch) { - reply.xml_str = expand_vars(reply.xml_str); - } - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Received %s XML (%s) after %dms: %s\n" - ,section - ,reply.uuid_str - ,(unsigned int) (switch_micro_time_now() - now) / 1000 - ,reply.xml_str); - if ((xml = switch_xml_parse_str_dynamic(reply.xml_str, SWITCH_FALSE)) == NULL) { - switch_safe_free(reply.xml_str); - } - } else { - /* facepalm */ - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "Request for %s XML (%s) timed-out after %dms\n" - ,section - ,reply.uuid_str - ,(unsigned int) (switch_micro_time_now() - now) / 1000); - } - - return xml; -} - -void bind_fetch_profile(ei_xml_agent_t *agent, kazoo_config_ptr fetch_handlers) -{ - switch_hash_index_t *hi; - kazoo_fetch_profile_ptr val = NULL, ptr = NULL; - - if (!fetch_handlers) return; - - for (hi = switch_core_hash_first(fetch_handlers->hash); hi; hi = switch_core_hash_next(&hi)) { - switch_core_hash_this(hi, NULL, NULL, (void**) &val); - if (val && val->section == agent->section) { - ptr = val; - break; - } - } - agent->profile = ptr; - switch_safe_free(hi); -} - -void rebind_fetch_profiles(kazoo_config_ptr fetch_handlers) -{ - if(kazoo_globals.config_fetch_binding != NULL) - bind_fetch_profile((ei_xml_agent_t *) switch_xml_get_binding_user_data(kazoo_globals.config_fetch_binding), fetch_handlers); - - if(kazoo_globals.directory_fetch_binding != NULL) - bind_fetch_profile((ei_xml_agent_t *) switch_xml_get_binding_user_data(kazoo_globals.directory_fetch_binding), fetch_handlers); - - if(kazoo_globals.dialplan_fetch_binding != NULL) - bind_fetch_profile((ei_xml_agent_t *) switch_xml_get_binding_user_data(kazoo_globals.dialplan_fetch_binding), fetch_handlers); - - if(kazoo_globals.channels_fetch_binding != NULL) - bind_fetch_profile((ei_xml_agent_t *) switch_xml_get_binding_user_data(kazoo_globals.channels_fetch_binding), fetch_handlers); - - if(kazoo_globals.languages_fetch_binding != NULL) - bind_fetch_profile((ei_xml_agent_t *) switch_xml_get_binding_user_data(kazoo_globals.languages_fetch_binding), fetch_handlers); - - if(kazoo_globals.chatplan_fetch_binding != NULL) - bind_fetch_profile((ei_xml_agent_t *) switch_xml_get_binding_user_data(kazoo_globals.chatplan_fetch_binding), fetch_handlers); -} - -static switch_status_t bind_fetch_agent(switch_xml_section_t section, switch_xml_binding_t **binding) { - switch_memory_pool_t *pool = NULL; - ei_xml_agent_t *agent; - - /* create memory pool for this xml search binging (lives for duration of mod_kazoo runtime) */ - if (switch_core_new_memory_pool(&pool) != SWITCH_STATUS_SUCCESS) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Out of memory: They're not people; they're hippies!\n"); - return SWITCH_STATUS_MEMERR; - } - - /* allocate some memory to store the fetch bindings for this section */ - if (!(agent = switch_core_alloc(pool, sizeof (*agent)))) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Out of memory: Oh, Jesus tap-dancing Christ!\n"); - return SWITCH_STATUS_MEMERR; - } - - /* try to bind to the switch */ - if (switch_xml_bind_search_function_ret(fetch_handler, section, agent, binding) != SWITCH_STATUS_SUCCESS) { - switch_core_destroy_memory_pool(&pool); - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Could not bind to FreeSWITCH %s XML requests\n" - ,xml_section_to_string(section)); - return SWITCH_STATUS_GENERR; - } - - agent->pool = pool; - agent->section = section; - switch_thread_rwlock_create(&agent->lock, pool); - agent->clients = NULL; - switch_mutex_init(&agent->current_client_mutex, SWITCH_MUTEX_DEFAULT, pool); - agent->current_client = NULL; - switch_mutex_init(&agent->replies_mutex, SWITCH_MUTEX_DEFAULT, pool); - switch_thread_cond_create(&agent->new_reply, pool); - agent->replies = NULL; - - bind_fetch_profile(agent, kazoo_globals.fetch_handlers); - - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Bound to %s XML requests\n" - ,xml_section_to_string(section)); - - return SWITCH_STATUS_SUCCESS; -} - -static switch_status_t unbind_fetch_agent(switch_xml_binding_t **binding) { - ei_xml_agent_t *agent; - ei_xml_client_t *client; - - if(*binding == NULL) - return SWITCH_STATUS_GENERR; - - /* get a pointer to our user_data */ - agent = (ei_xml_agent_t *)switch_xml_get_binding_user_data(*binding); - - /* unbind from the switch */ - switch_xml_unbind_search_function(binding); - - /* LOCK ALL THE THINGS */ - switch_thread_rwlock_wrlock(agent->lock); - switch_mutex_lock(agent->current_client_mutex); - switch_mutex_lock(agent->replies_mutex); - - /* cleanly destroy each client */ - client = agent->clients; - while(client != NULL) { - ei_xml_client_t *tmp_client = client; - fetch_handler_t *fetch_handler; - - fetch_handler = client->fetch_handlers; - while(fetch_handler != NULL) { - fetch_handler_t *tmp_fetch_handler = fetch_handler; - - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Removed %s XML handler %s <%d.%d.%d>\n" - ,xml_section_to_string(agent->section) - ,fetch_handler->pid.node - ,fetch_handler->pid.creation - ,fetch_handler->pid.num - ,fetch_handler->pid.serial); - - fetch_handler = fetch_handler->next; - switch_safe_free(tmp_fetch_handler); - } - - client = client->next; - switch_safe_free(tmp_client); - } - - /* keep the pointers clean, even if its just for a moment */ - agent->clients = NULL; - agent->current_client = NULL; - - /* release the locks! */ - switch_thread_rwlock_unlock(agent->lock); - switch_mutex_unlock(agent->current_client_mutex); - switch_mutex_unlock(agent->replies_mutex); - - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Unbound from %s XML requests\n" - ,xml_section_to_string(agent->section)); - - /* cleanly destroy the bindings */ - switch_thread_rwlock_destroy(agent->lock); - switch_mutex_destroy(agent->current_client_mutex); - switch_mutex_destroy(agent->replies_mutex); - switch_thread_cond_destroy(agent->new_reply); - switch_core_destroy_memory_pool(&agent->pool); - - return SWITCH_STATUS_SUCCESS; -} - -static switch_status_t remove_xml_client(ei_node_t *ei_node, switch_xml_binding_t *binding) { - ei_xml_agent_t *agent; - ei_xml_client_t *client, *prev = NULL; - int found = 0; - - if(binding == NULL) - return SWITCH_STATUS_GENERR; - - agent = (ei_xml_agent_t *)switch_xml_get_binding_user_data(binding); - - /* write-lock the agent */ - switch_thread_rwlock_wrlock(agent->lock); - - client = agent->clients; - while (client != NULL) { - if (client->ei_node == ei_node) { - found = 1; - break; - } - - prev = client; - client = client->next; - } - - if (found) { - fetch_handler_t *fetch_handler; - - if (!prev) { - agent->clients = client->next; - } else { - prev->next = client->next; - } - - /* the mutex lock is not required since we have the write lock - * but hey its fun and safe so do it anyway */ - switch_mutex_lock(agent->current_client_mutex); - if (agent->current_client == client) { - agent->current_client = agent->clients; - } - switch_mutex_unlock(agent->current_client_mutex); - - fetch_handler = client->fetch_handlers; - while(fetch_handler != NULL) { - fetch_handler_t *tmp_fetch_handler = fetch_handler; - - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Removed %s XML handler %s <%d.%d.%d>\n" - ,xml_section_to_string(agent->section) - ,fetch_handler->pid.node - ,fetch_handler->pid.creation - ,fetch_handler->pid.num - ,fetch_handler->pid.serial); - - fetch_handler = fetch_handler->next; - switch_safe_free(tmp_fetch_handler); - } - - switch_safe_free(client); - } - - switch_thread_rwlock_unlock(agent->lock); - - return SWITCH_STATUS_SUCCESS; -} - -static ei_xml_client_t *add_xml_client(ei_node_t *ei_node, ei_xml_agent_t *agent) { - ei_xml_client_t *client; - - switch_malloc(client, sizeof(*client)); - - client->ei_node = ei_node; - client->fetch_handlers = NULL; - client->next = NULL; - - if (agent->clients) { - client->next = agent->clients; - } - - agent->clients = client; - - return client; -} - -static ei_xml_client_t *find_xml_client(ei_node_t *ei_node, ei_xml_agent_t *agent) { - ei_xml_client_t *client; - - client = agent->clients; - while (client != NULL) { - if (client->ei_node == ei_node) { - return client; - } - - client = client->next; - } - - return NULL; -} - -static switch_status_t remove_fetch_handler(ei_node_t *ei_node, erlang_pid *from, switch_xml_binding_t *binding) { - ei_xml_agent_t *agent; - ei_xml_client_t *client; - fetch_handler_t *fetch_handler, *prev = NULL; - int found = 0; - - agent = (ei_xml_agent_t *)switch_xml_get_binding_user_data(binding); - - /* write-lock the agent */ - switch_thread_rwlock_wrlock(agent->lock); - - if (!(client = find_xml_client(ei_node, agent))) { - switch_thread_rwlock_unlock(agent->lock); - return SWITCH_STATUS_SUCCESS; - } - - fetch_handler = client->fetch_handlers; - while (fetch_handler != NULL) { - if (ei_compare_pids(&fetch_handler->pid, from) == SWITCH_STATUS_SUCCESS) { - found = 1; - break; - } - - prev = fetch_handler; - fetch_handler = fetch_handler->next; - } - - if (found) { - if (!prev) { - client->fetch_handlers = fetch_handler->next; - } else { - prev->next = fetch_handler->next; - } - - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Removed %s XML handler %s <%d.%d.%d>\n" - ,xml_section_to_string(agent->section) - ,fetch_handler->pid.node - ,fetch_handler->pid.creation - ,fetch_handler->pid.num - ,fetch_handler->pid.serial); - - switch_safe_free(fetch_handler); - } - - switch_thread_rwlock_unlock(agent->lock); - return SWITCH_STATUS_SUCCESS; -} - -static switch_status_t handle_api_command_stream(ei_node_t *ei_node, switch_stream_handle_t *stream, switch_xml_binding_t *binding) { - ei_xml_agent_t *agent; - ei_xml_client_t *client; - - if (!binding) { - return SWITCH_STATUS_GENERR; - } - - agent = (ei_xml_agent_t *)switch_xml_get_binding_user_data(binding); - - /* read-lock the agent */ - switch_thread_rwlock_rdlock(agent->lock); - client = agent->clients; - while (client != NULL) { - if (client->ei_node == ei_node) { - fetch_handler_t *fetch_handler; - fetch_handler = client->fetch_handlers; - while (fetch_handler != NULL) { - stream->write_function(stream, "XML %s handler <%d.%d.%d>\n" - ,xml_section_to_string(agent->section) - ,fetch_handler->pid.creation - ,fetch_handler->pid.num - ,fetch_handler->pid.serial); - fetch_handler = fetch_handler->next; - } - break; - } - - client = client->next; - } - switch_thread_rwlock_unlock(agent->lock); - - return SWITCH_STATUS_SUCCESS; -} - -switch_status_t bind_fetch_agents() { - bind_fetch_agent(SWITCH_XML_SECTION_CONFIG, &kazoo_globals.config_fetch_binding); - bind_fetch_agent(SWITCH_XML_SECTION_DIRECTORY, &kazoo_globals.directory_fetch_binding); - bind_fetch_agent(SWITCH_XML_SECTION_DIALPLAN, &kazoo_globals.dialplan_fetch_binding); - bind_fetch_agent(SWITCH_XML_SECTION_CHANNELS, &kazoo_globals.channels_fetch_binding); - bind_fetch_agent(SWITCH_XML_SECTION_LANGUAGES, &kazoo_globals.languages_fetch_binding); - bind_fetch_agent(SWITCH_XML_SECTION_CHATPLAN, &kazoo_globals.chatplan_fetch_binding); - - return SWITCH_STATUS_SUCCESS; -} - -switch_status_t unbind_fetch_agents() { - unbind_fetch_agent(&kazoo_globals.config_fetch_binding); - unbind_fetch_agent(&kazoo_globals.directory_fetch_binding); - unbind_fetch_agent(&kazoo_globals.dialplan_fetch_binding); - unbind_fetch_agent(&kazoo_globals.channels_fetch_binding); - unbind_fetch_agent(&kazoo_globals.languages_fetch_binding); - unbind_fetch_agent(&kazoo_globals.chatplan_fetch_binding); - - return SWITCH_STATUS_SUCCESS; -} - -switch_status_t remove_xml_clients(ei_node_t *ei_node) { - remove_xml_client(ei_node, kazoo_globals.config_fetch_binding); - remove_xml_client(ei_node, kazoo_globals.directory_fetch_binding); - remove_xml_client(ei_node, kazoo_globals.dialplan_fetch_binding); - remove_xml_client(ei_node, kazoo_globals.channels_fetch_binding); - remove_xml_client(ei_node, kazoo_globals.languages_fetch_binding); - remove_xml_client(ei_node, kazoo_globals.chatplan_fetch_binding); - - return SWITCH_STATUS_SUCCESS; -} - -switch_status_t add_fetch_handler(ei_node_t *ei_node, erlang_pid *from, switch_xml_binding_t *binding) { - ei_xml_agent_t *agent; - ei_xml_client_t *client; - fetch_handler_t *fetch_handler; - - if(binding == NULL) - return SWITCH_STATUS_GENERR; - - agent = (ei_xml_agent_t *)switch_xml_get_binding_user_data(binding); - - /* write-lock the agent */ - switch_thread_rwlock_wrlock(agent->lock); - - if (!(client = find_xml_client(ei_node, agent))) { - client = add_xml_client(ei_node, agent); - } - - fetch_handler = client->fetch_handlers; - while (fetch_handler != NULL) { - if (ei_compare_pids(&fetch_handler->pid, from) == SWITCH_STATUS_SUCCESS) { - switch_thread_rwlock_unlock(agent->lock); - return SWITCH_STATUS_SUCCESS; - } - fetch_handler = fetch_handler->next; - } - - switch_malloc(fetch_handler, sizeof(*fetch_handler)); - - memcpy(&fetch_handler->pid, from, sizeof(erlang_pid));; - - fetch_handler->next = NULL; - if (client->fetch_handlers) { - fetch_handler->next = client->fetch_handlers; - } - - client->fetch_handlers = fetch_handler; - - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Added %s XML handler %s <%d.%d.%d>\n" - ,xml_section_to_string(agent->section) - ,fetch_handler->pid.node - ,fetch_handler->pid.creation - ,fetch_handler->pid.num - ,fetch_handler->pid.serial); - - switch_thread_rwlock_unlock(agent->lock); - - ei_link(ei_node, ei_self(&kazoo_globals.ei_cnode), from); - - return SWITCH_STATUS_SUCCESS; -} - -switch_status_t remove_fetch_handlers(ei_node_t *ei_node, erlang_pid *from) { - remove_fetch_handler(ei_node, from, kazoo_globals.config_fetch_binding); - remove_fetch_handler(ei_node, from, kazoo_globals.directory_fetch_binding); - remove_fetch_handler(ei_node, from, kazoo_globals.dialplan_fetch_binding); - remove_fetch_handler(ei_node, from, kazoo_globals.channels_fetch_binding); - remove_fetch_handler(ei_node, from, kazoo_globals.languages_fetch_binding); - remove_fetch_handler(ei_node, from, kazoo_globals.chatplan_fetch_binding); - - return SWITCH_STATUS_SUCCESS; -} - -switch_status_t fetch_reply(char *uuid_str, char *xml_str, switch_xml_binding_t *binding) { - ei_xml_agent_t *agent; - xml_fetch_reply_t *reply; - switch_status_t status = SWITCH_STATUS_NOTFOUND; - - agent = (ei_xml_agent_t *)switch_xml_get_binding_user_data(binding); - - switch_mutex_lock(agent->replies_mutex); - reply = agent->replies; - while (reply != NULL) { - if (!strncmp(reply->uuid_str, uuid_str, SWITCH_UUID_FORMATTED_LENGTH)) { - if (!reply->xml_str) { - reply->xml_str = xml_str; - switch_thread_cond_broadcast(agent->new_reply); - status = SWITCH_STATUS_SUCCESS; - } - break; - } - - reply = reply->next; - } - switch_mutex_unlock(agent->replies_mutex); - - return status; -} - -switch_status_t handle_api_command_streams(ei_node_t *ei_node, switch_stream_handle_t *stream) { - handle_api_command_stream(ei_node, stream, kazoo_globals.config_fetch_binding); - handle_api_command_stream(ei_node, stream, kazoo_globals.directory_fetch_binding); - handle_api_command_stream(ei_node, stream, kazoo_globals.dialplan_fetch_binding); - handle_api_command_stream(ei_node, stream, kazoo_globals.channels_fetch_binding); - handle_api_command_stream(ei_node, stream, kazoo_globals.languages_fetch_binding); - handle_api_command_stream(ei_node, stream, kazoo_globals.chatplan_fetch_binding); - - return SWITCH_STATUS_SUCCESS; -} - -/* For Emacs: - * Local Variables: - * mode:c - * indent-tabs-mode:t - * tab-width:4 - * c-basic-offset:4 - * End: - * For VIM: - * vim:set softtabstop=4 shiftwidth=4 tabstop=4: - */ diff --git a/src/mod/event_handlers/mod_kazoo/kazoo_fields.h b/src/mod/event_handlers/mod_kazoo/kazoo_fields.h deleted file mode 100644 index 8d17378768e..00000000000 --- a/src/mod/event_handlers/mod_kazoo/kazoo_fields.h +++ /dev/null @@ -1,203 +0,0 @@ -/* -* FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application -* Copyright (C) 2005-2012, Anthony Minessale II -* -* 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 -* Portions created by the Initial Developer are Copyright (C) -* the Initial Developer. All Rights Reserved. -* -* Based on mod_skel by -* Anthony Minessale II -* -* Contributor(s): -* -* Daniel Bryars -* Tim Brown -* Anthony Minessale II -* William King -* Mike Jerris -* -* kazoo.c -- Sends FreeSWITCH events to an AMQP broker -* -*/ - -#ifndef KAZOO_FIELDS_H -#define KAZOO_FIELDS_H - -#include - -#define MAX_LIST_FIELDS 25 - -typedef struct kazoo_log_levels kazoo_loglevels_t; -typedef kazoo_loglevels_t *kazoo_loglevels_ptr; - -struct kazoo_log_levels -{ - switch_log_level_t success_log_level; - switch_log_level_t failed_log_level; - switch_log_level_t warn_log_level; - switch_log_level_t info_log_level; - switch_log_level_t time_log_level; - switch_log_level_t filtered_event_log_level; - switch_log_level_t filtered_field_log_level; - switch_log_level_t trace_log_level; - switch_log_level_t debug_log_level; - switch_log_level_t error_log_level; - switch_log_level_t hashing_log_level; - -}; - -typedef struct kazoo_logging kazoo_logging_t; -typedef kazoo_logging_t *kazoo_logging_ptr; - -struct kazoo_logging -{ - kazoo_loglevels_ptr levels; - const char *profile_name; - const char *event_name; -}; - -typedef struct kazoo_list_s { - char *value[MAX_LIST_FIELDS]; - int size; -} kazoo_list_t; - -typedef enum { - FILTER_COMPARE_REGEX, - FILTER_COMPARE_LIST, - FILTER_COMPARE_VALUE, - FILTER_COMPARE_PREFIX, - FILTER_COMPARE_EXISTS, - FILTER_COMPARE_FIELD - -} kazoo_filter_compare_type; - -typedef enum { - FILTER_EXCLUDE, - FILTER_INCLUDE, - FILTER_ENSURE -} kazoo_filter_type; - -typedef struct kazoo_filter_t { - kazoo_filter_type type; - kazoo_filter_compare_type compare; - char* name; - char* value; - kazoo_list_t list; - struct kazoo_filter_t* next; -} kazoo_filter, *kazoo_filter_ptr; - - -typedef enum { - JSON_NONE, - JSON_STRING, - JSON_NUMBER, - JSON_BOOLEAN, - JSON_OBJECT, - JSON_RAW -} kazoo_json_field_type; - -typedef enum { - FIELD_NONE, - FIELD_COPY, - FIELD_STATIC, - FIELD_FIRST_OF, - FIELD_EXPAND, - FIELD_PREFIX, - FIELD_OBJECT, - FIELD_GROUP, - FIELD_REFERENCE - -} kazoo_field_type; - -typedef struct kazoo_field_t kazoo_field; -typedef kazoo_field *kazoo_field_ptr; - -typedef struct kazoo_fields_t kazoo_fields; -typedef kazoo_fields *kazoo_fields_ptr; - -typedef struct kazoo_definition_t kazoo_definition; -typedef kazoo_definition *kazoo_definition_ptr; - -struct kazoo_field_t { - char* name; - char* value; - char* as; - kazoo_list_t list; - switch_bool_t exclude_prefix; - kazoo_field_type in_type; - kazoo_json_field_type out_type; - int out_type_as_array; - kazoo_filter_ptr filter; - - kazoo_definition_ptr ref; - kazoo_field_ptr next; - kazoo_fields_ptr children; -}; - -struct kazoo_fields_t { - kazoo_field_ptr head; - int verbose; -}; - - -struct kazoo_definition_t { - char* name; - kazoo_field_ptr head; - kazoo_filter_ptr filter; -}; - -struct kazoo_event { - kazoo_event_profile_ptr profile; - char *name; - kazoo_fields_ptr fields; - kazoo_filter_ptr filter; - kazoo_loglevels_ptr logging; - - kazoo_event_t* next; -}; - -struct kazoo_event_profile { - char *name; - kazoo_config_ptr root; - switch_bool_t running; - switch_memory_pool_t *pool; - kazoo_filter_ptr filter; - kazoo_fields_ptr fields; - kazoo_event_ptr events; - - kazoo_loglevels_ptr logging; -}; - -struct kazoo_fetch_profile { - char *name; - kazoo_config_ptr root; - switch_bool_t running; - switch_memory_pool_t *pool; - kazoo_fields_ptr fields; - int fetch_timeout; - switch_mutex_t *fetch_reply_mutex; - switch_hash_t *fetch_reply_hash; - switch_xml_binding_t *fetch_binding; - switch_xml_section_t section; - - kazoo_loglevels_ptr logging; -}; - -#endif /* KAZOO_FIELDS_H */ - diff --git a/src/mod/event_handlers/mod_kazoo/kazoo_message.c b/src/mod/event_handlers/mod_kazoo/kazoo_message.c deleted file mode 100644 index 43716a8e027..00000000000 --- a/src/mod/event_handlers/mod_kazoo/kazoo_message.c +++ /dev/null @@ -1,488 +0,0 @@ -/* -* FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application -* Copyright (C) 2005-2012, Anthony Minessale II -* -* 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 -* Portions created by the Initial Developer are Copyright (C) -* the Initial Developer. All Rights Reserved. -* -* Based on mod_skel by -* Anthony Minessale II -* -* Contributor(s): -* -* Daniel Bryars -* Tim Brown -* Anthony Minessale II -* William King -* Mike Jerris -* -* kazoo.c -- Sends FreeSWITCH events to an AMQP broker -* -*/ - -#include "mod_kazoo.h" - -/* deletes then add */ -void kazoo_cJSON_AddItemToObject(cJSON *object, const char *string, cJSON *item) -{ - cJSON_DeleteItemFromObject(object, string); - cJSON_AddItemToObject(object, string, item); -} - -static int inline filter_compare(switch_event_t* evt, kazoo_filter_ptr filter, kazoo_logging_ptr logging) -{ - switch_event_header_t *header; - int hasValue = 0, n; - char *value = NULL, *expr = NULL; - - switch(filter->compare) { - - case FILTER_COMPARE_EXISTS: - hasValue = switch_event_get_header(evt, filter->name) != NULL ? 1 : 0; - switch_log_printf(SWITCH_CHANNEL_LOG, logging->levels->trace_log_level, "profile[%s] event %s checking if %s exists => %s\n", logging->profile_name, logging->event_name, filter->name, hasValue ? "true" : "false"); - break; - - case FILTER_COMPARE_VALUE: - if (*filter->name == '$') { - value = expr = kz_event_expand_headers(evt, filter->name); - } else { - value = switch_event_get_header(evt, filter->name); - } - hasValue = value ? !strcmp(value, filter->value) : 0; - switch_log_printf(SWITCH_CHANNEL_LOG, logging->levels->trace_log_level, "profile[%s] event %s compare value %s to %s => %s == %s => %s\n", logging->profile_name, logging->event_name, filter->name, filter->value, value, filter->value, hasValue ? "true" : "false"); - break; - - case FILTER_COMPARE_FIELD: - if (*filter->name == '$') { - value = expr = kz_event_expand_headers(evt, filter->name); - } else { - value = switch_event_get_header(evt, filter->name); - } - hasValue = value ? !strcmp(value, switch_event_get_header_nil(evt, filter->value)) : 0; - switch_log_printf(SWITCH_CHANNEL_LOG, logging->levels->trace_log_level, "profile[%s] event %s compare field %s to %s => %s == %s => %s\n", logging->profile_name, logging->event_name, filter->name, filter->value, value, switch_event_get_header_nil(evt, filter->value), hasValue ? "true" : "false"); - break; - - case FILTER_COMPARE_PREFIX: - for (header = evt->headers; header; header = header->next) { - if(!strncmp(header->name, filter->value, strlen(filter->value))) { - hasValue = 1; - break; - } - } - break; - - case FILTER_COMPARE_LIST: - if (*filter->name == '$') { - value = expr = kz_event_expand_headers(evt, filter->name); - } else { - value = switch_event_get_header(evt, filter->name); - } - if(value) { - for(n = 0; n < filter->list.size; n++) { - if(!strncmp(value, filter->list.value[n], strlen(filter->list.value[n]))) { - hasValue = 1; - break; - } - } - } - break; - - case FILTER_COMPARE_REGEX: - break; - - default: - break; - } - - switch_safe_free(expr); - - return hasValue; -} - -static kazoo_filter_ptr inline filter_event(switch_event_t* evt, kazoo_filter_ptr filter, kazoo_logging_ptr logging) -{ - while(filter) { - int hasValue = filter_compare(evt, filter, logging); - if(filter->type == FILTER_EXCLUDE) { - if(hasValue) - break; - } else if(filter->type == FILTER_INCLUDE) { - if(!hasValue) - break; - } - filter = filter->next; - } - return filter; -} - -static void kazoo_event_init_json_fields(switch_event_t *event, cJSON *json) -{ - switch_event_header_t *hp; - for (hp = event->headers; hp; hp = hp->next) { - if (strncmp(hp->name, "_json_", 6)) { - if (hp->idx) { - cJSON *a = cJSON_CreateArray(); - int i; - - for(i = 0; i < hp->idx; i++) { - cJSON_AddItemToArray(a, cJSON_CreateString(hp->array[i])); - } - - cJSON_AddItemToObject(json, hp->name, a); - - } else { - cJSON_AddItemToObject(json, hp->name, cJSON_CreateString(hp->value)); - } - } - } -} - -static switch_status_t kazoo_event_init_json(kazoo_fields_ptr fields1, kazoo_fields_ptr fields2, switch_event_t* evt, cJSON** clone) -{ - switch_status_t status = SWITCH_STATUS_SUCCESS; - if( (fields2 && fields2->verbose) - || (fields1 && fields1->verbose) - || ( (!fields2) && (!fields1)) ) { - *clone = cJSON_CreateObject(); - if((*clone) == NULL) { - status = SWITCH_STATUS_GENERR; - } else { - kazoo_event_init_json_fields(evt, *clone); - } - } else { - *clone = cJSON_CreateObject(); - if((*clone) == NULL) { - status = SWITCH_STATUS_GENERR; - } - } - return status; -} - -static cJSON * kazoo_event_json_value(kazoo_json_field_type type, const char *value) { - cJSON *item = NULL; - switch(type) { - case JSON_STRING: - item = cJSON_CreateString(value); - break; - - case JSON_NUMBER: - item = cJSON_CreateNumber(strtod(value, NULL)); - break; - - case JSON_BOOLEAN: - item = cJSON_CreateBool(switch_true(value)); - break; - - case JSON_OBJECT: - item = cJSON_CreateObject(); - break; - - case JSON_RAW: - item = cJSON_Parse(value); - if (!item) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "parse from raw error!\n"); - item = cJSON_CreateRaw(value); - } - break; - - default: - break; - }; - - return item; -} - -static cJSON * kazoo_event_add_json_value(cJSON *dst, kazoo_field_ptr field, const char *as, const char *value) { - cJSON *item = NULL; - if(value || field->out_type == JSON_OBJECT) { - if((item = kazoo_event_json_value(field->out_type, value)) != NULL) { - kazoo_cJSON_AddItemToObject(dst, as, item); - } - } - return item; -} - - -cJSON * kazoo_event_add_field_to_json(cJSON *dst, switch_event_t *src, kazoo_field_ptr field) -{ - switch_event_header_t *header; - char *expanded; - int i, n; - cJSON *item = NULL; - - switch(field->in_type) { - case FIELD_COPY: - if (!strcmp(field->name, "_body")) { - item = kazoo_event_add_json_value(dst, field, field->as ? field->as : field->name, src->body); - } else if((header = switch_event_get_header_ptr(src, field->name)) != NULL) { - if (header->idx) { - item = cJSON_CreateArray(); - - for(i = 0; i < header->idx; i++) { - cJSON_AddItemToArray(item, kazoo_event_json_value(field->out_type, header->array[i])); - } - - kazoo_cJSON_AddItemToObject(dst, field->as ? field->as : field->name, item); - } else if (field->out_type_as_array) { - item = cJSON_CreateArray(); - cJSON_AddItemToArray(item, kazoo_event_json_value(field->out_type, header->value)); - kazoo_cJSON_AddItemToObject(dst, field->as ? field->as : field->name, item); - } else { - item = kazoo_event_add_json_value(dst, field, field->as ? field->as : field->name, header->value); - } - } - break; - - case FIELD_EXPAND: - expanded = kz_event_expand_headers(src, field->value); - if(expanded != NULL && !zstr(expanded)) { - item = kazoo_event_add_json_value(dst, field, field->as ? field->as : field->name, expanded); - } - - if (expanded != field->value) { - switch_safe_free(expanded); - } - - break; - - case FIELD_FIRST_OF: - - for(n = 0; n < field->list.size; n++) { - if(*field->list.value[n] == '#') { - item = kazoo_event_add_json_value(dst, field, field->as ? field->as : field->name, ++field->list.value[n]); - break; - } else { - header = switch_event_get_header_ptr(src, field->list.value[n]); - if(header) { - if (header->idx) { - item = cJSON_CreateArray(); - - for(i = 0; i < header->idx; i++) { - cJSON_AddItemToArray(item, kazoo_event_json_value(field->out_type, header->array[i])); - } - - kazoo_cJSON_AddItemToObject(dst, field->as ? field->as : field->name, item); - } else { - item = kazoo_event_add_json_value(dst, field, field->as ? field->as : field->name, header->value); - } - - break; - } - } - } - - break; - - case FIELD_PREFIX: - - for (header = src->headers; header; header = header->next) { - if(!strncmp(header->name, field->name, strlen(field->name))) { - if (header->idx) { - cJSON *array = cJSON_CreateArray(); - - for(i = 0; i < header->idx; i++) { - cJSON_AddItemToArray(array, kazoo_event_json_value(field->out_type, header->array[i])); - } - - kazoo_cJSON_AddItemToObject(dst, field->exclude_prefix ? header->name+strlen(field->name) : header->name, array); - } else { - kazoo_event_add_json_value(dst, field, field->exclude_prefix ? header->name+strlen(field->name) : header->name, header->value); - } - } - } - - break; - - case FIELD_STATIC: - item = kazoo_event_add_json_value(dst, field, field->name, field->value); - break; - - case FIELD_GROUP: - item = dst; - break; - - default: - break; - } - - return item; -} - -static switch_status_t kazoo_event_add_fields_to_json(kazoo_logging_ptr logging, cJSON *dst, switch_event_t *src, kazoo_field_ptr field) { - - kazoo_filter_ptr filter; - cJSON *item = NULL; - while(field) { - if(field->in_type == FIELD_REFERENCE) { - if(field->ref) { - if((filter = filter_event(src, field->ref->filter, logging)) != NULL) { - switch_log_printf(SWITCH_CHANNEL_LOG, logging->levels->filtered_field_log_level, "profile[%s] event %s, referenced field %s filtered by settings %s : %s\n", logging->profile_name, logging->event_name, field->ref->name, filter->name, filter->value); - } else { - kazoo_event_add_fields_to_json(logging, dst, src, field->ref->head); - } - } else { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "profile[%s] event %s, referenced field %s not found\n", logging->profile_name, logging->event_name, field->name); - } - } else { - if((filter = filter_event(src, field->filter, logging)) != NULL) { - switch_log_printf(SWITCH_CHANNEL_LOG, logging->levels->filtered_field_log_level, "profile[%s] event %s, field %s filtered by settings %s : %s\n", logging->profile_name, logging->event_name, field->name, filter->name, filter->value); - } else { - item = kazoo_event_add_field_to_json(dst, src, field); - if(field->children && item != NULL) { - if(field->children->verbose && field->out_type == JSON_OBJECT) { - kazoo_event_init_json_fields(src, item); - } - kazoo_event_add_fields_to_json(logging, field->out_type == JSON_OBJECT ? item : dst, src, field->children->head); - } - } - } - - field = field->next; - } - - return SWITCH_STATUS_SUCCESS; -} - -#define EVENT_TIMESTAMP_FIELD "Event-Date-Timestamp" -#define JSON_TIMESTAMP_FIELD "Event-Timestamp" - -static switch_status_t kazoo_event_add_timestamp(switch_event_t* evt, cJSON* JObj) -{ - switch_event_header_t *header; - cJSON *item = NULL; - if((header = switch_event_get_header_ptr(evt, EVENT_TIMESTAMP_FIELD)) != NULL) { - if ((item = kazoo_event_json_value(JSON_NUMBER, header->value)) != NULL) { - kazoo_cJSON_AddItemToObject(JObj, JSON_TIMESTAMP_FIELD, item); - return SWITCH_STATUS_SUCCESS; - } - } - return SWITCH_STATUS_NOTFOUND; -} - -kazoo_message_ptr kazoo_message_create_event(switch_event_t* evt, kazoo_event_ptr event, kazoo_event_profile_ptr profile) -{ - kazoo_message_ptr message; - cJSON *JObj = NULL; - kazoo_filter_ptr filtered; - kazoo_logging_t logging; - - logging.levels = profile->logging; - logging.event_name = evt->subclass_name ? evt->subclass_name : switch_event_get_header_nil(evt, "Event-Name"); - logging.profile_name = profile->name; - - message = malloc(sizeof(kazoo_message_t)); - if(message == NULL) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "error allocating memory for serializing event to json\n"); - return NULL; - } - memset(message, 0, sizeof(kazoo_message_t)); - - if(profile->filter) { - // filtering - if((filtered = filter_event(evt, profile->filter, &logging)) != NULL) { - switch_log_printf(SWITCH_CHANNEL_LOG, logging.levels->filtered_event_log_level, "profile[%s] event %s filtered by profile settings %s : %s\n", logging.profile_name, logging.event_name, filtered->name, filtered->value); - kazoo_message_destroy(&message); - return NULL; - } - } - - if (event->logging) { - logging.levels = event->logging; - } - - if (event && event->filter) { - if((filtered = filter_event(evt, event->filter, &logging)) != NULL) { - switch_log_printf(SWITCH_CHANNEL_LOG, logging.levels->filtered_event_log_level, "profile[%s] event %s filtered by event settings %s : %s\n", logging.profile_name, logging.event_name, filtered->name, filtered->value); - kazoo_message_destroy(&message); - return NULL; - } - } - - kazoo_event_init_json(profile->fields, event ? event->fields : NULL, evt, &JObj); - - kazoo_event_add_timestamp(evt, JObj); - - if(profile->fields) - kazoo_event_add_fields_to_json(&logging, JObj, evt, profile->fields->head); - - if(event && event->fields) - kazoo_event_add_fields_to_json(&logging, JObj, evt, event->fields->head); - - message->JObj = JObj; - - - return message; - - -} - -kazoo_message_ptr kazoo_message_create_fetch(switch_event_t* evt, kazoo_fetch_profile_ptr profile) -{ - kazoo_message_ptr message; - cJSON *JObj = NULL; - kazoo_logging_t logging; - - logging.levels = profile->logging; - logging.event_name = switch_event_get_header_nil(evt, "Event-Name"); - logging.profile_name = profile->name; - - message = malloc(sizeof(kazoo_message_t)); - if(message == NULL) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "error allocating memory for serializing event to json\n"); - return NULL; - } - memset(message, 0, sizeof(kazoo_message_t)); - - - kazoo_event_init_json(profile->fields, NULL, evt, &JObj); - - kazoo_event_add_timestamp(evt, JObj); - - if(profile->fields) - kazoo_event_add_fields_to_json(&logging, JObj, evt, profile->fields->head); - - message->JObj = JObj; - - - return message; - - -} - - -void kazoo_message_destroy(kazoo_message_ptr *msg) -{ - if (!msg || !*msg) return; - if((*msg)->JObj != NULL) - cJSON_Delete((*msg)->JObj); - switch_safe_free(*msg); - -} - - -/* For Emacs: - * Local Variables: - * mode:c - * indent-tabs-mode:t - * tab-width:4 - * c-basic-offset:4 - * End: - * For VIM: - * vim:set softtabstop=4 shiftwidth=4 tabstop=4 - */ diff --git a/src/mod/event_handlers/mod_kazoo/kazoo_message.h b/src/mod/event_handlers/mod_kazoo/kazoo_message.h deleted file mode 100644 index eade6c4e7b9..00000000000 --- a/src/mod/event_handlers/mod_kazoo/kazoo_message.h +++ /dev/null @@ -1,66 +0,0 @@ -/* -* FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application -* Copyright (C) 2005-2012, Anthony Minessale II -* -* 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 -* Portions created by the Initial Developer are Copyright (C) -* the Initial Developer. All Rights Reserved. -* -* Based on mod_skel by -* Anthony Minessale II -* -* Contributor(s): -* -* Daniel Bryars -* Tim Brown -* Anthony Minessale II -* William King -* Mike Jerris -* -* kazoo.c -- Sends FreeSWITCH events to an AMQP broker -* -*/ - -#ifndef KAZOO_MESSAGE_H -#define KAZOO_MESSAGE_H - -#include - -typedef struct { - uint64_t timestamp; - uint64_t start; - uint64_t filter; - uint64_t serialize; - uint64_t print; - uint64_t rk; -} kazoo_message_times_t, *kazoo_message_times_ptr; - -typedef struct { - cJSON *JObj; -} kazoo_message_t, *kazoo_message_ptr; - -void kazoo_cJSON_AddItemToObject(cJSON *object, const char *string, cJSON *item); -cJSON * kazoo_event_add_field_to_json(cJSON *dst, switch_event_t *src, kazoo_field_ptr field); -kazoo_message_ptr kazoo_message_create_event(switch_event_t* evt, kazoo_event_ptr event, kazoo_event_profile_ptr profile); -kazoo_message_ptr kazoo_message_create_fetch(switch_event_t* evt, kazoo_fetch_profile_ptr profile); - -void kazoo_message_destroy(kazoo_message_ptr *msg); - - -#endif /* KAZOO_MESSAGE_H */ - diff --git a/src/mod/event_handlers/mod_kazoo/kazoo_node.c b/src/mod/event_handlers/mod_kazoo/kazoo_node.c deleted file mode 100644 index f75c3270234..00000000000 --- a/src/mod/event_handlers/mod_kazoo/kazoo_node.c +++ /dev/null @@ -1,1694 +0,0 @@ -/* - * FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application - * Copyright (C) 2005-2012, Anthony Minessale II - * - * 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 - * Portions created by the Initial Developer are Copyright (C) - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * - * Anthony Minessale II - * Andrew Thompson - * Rob Charlton - * Darren Schreiber - * Mike Jerris - * Tamas Cseke - * - * - * handle_msg.c -- handle messages received from erlang nodes - * - */ -#include "mod_kazoo.h" - -struct api_command_struct_s { - char *cmd; - char *arg; - ei_node_t *ei_node; - char uuid_str[SWITCH_UUID_FORMATTED_LENGTH + 1]; - erlang_pid pid; - switch_memory_pool_t *pool; -}; -typedef struct api_command_struct_s api_command_struct_t; - -static char *REQUEST_ATOMS[] = { - "noevents", - "exit", - "link", - "nixevent", - "sendevent", - "sendmsg", - "commands", - "command", - "bind", - "getpid", - "version", - "bgapi", - "api", - "event", - "fetch_reply", - "config", - "bgapi4", - "api4", - "json_api" -}; - -typedef enum { - REQUEST_NOEVENTS, - REQUEST_EXIT, - REQUEST_LINK, - REQUEST_NIXEVENT, - REQUEST_SENDEVENT, - REQUEST_SENDMSG, - REQUEST_COMMANDS, - REQUEST_COMMAND, - REQUEST_BIND, - REQUEST_GETPID, - REQUEST_VERSION, - REQUEST_BGAPI, - REQUEST_API, - REQUEST_EVENT, - REQUEST_FETCH_REPLY, - REQUEST_CONFIG, - REQUEST_BGAPI4, - REQUEST_API4, - REQUEST_JSON_API, - REQUEST_MAX -} request_atoms_t; - -static switch_status_t find_request(char *atom, int *request) { - int i; - for (i = 0; i < REQUEST_MAX; i++) { - if(!strncmp(atom, REQUEST_ATOMS[i], MAXATOMLEN)) { - *request = i; - return SWITCH_STATUS_SUCCESS; - } - } - - return SWITCH_STATUS_FALSE; -} - -static void destroy_node_handler(ei_node_t *ei_node) { - int pending = 0; - void *pop; - switch_memory_pool_t *pool = ei_node->pool; - - switch_clear_flag(ei_node, LFLAG_RUNNING); - - /* wait for pending bgapi requests to complete */ - while ((pending = switch_atomic_read(&ei_node->pending_bgapi))) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Waiting for %d pending bgapi requests to complete\n", pending); - switch_yield(500000); - } - - /* wait for receive handlers to complete */ - while ((pending = switch_atomic_read(&ei_node->receive_handlers))) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Waiting for %d receive handlers to complete\n", pending); - switch_yield(500000); - } - - switch_mutex_lock(ei_node->event_streams_mutex); - remove_event_streams(&ei_node->event_streams); - switch_mutex_unlock(ei_node->event_streams_mutex); - - remove_xml_clients(ei_node); - - while (switch_queue_trypop(ei_node->received_msgs, &pop) == SWITCH_STATUS_SUCCESS) { - ei_received_msg_t *received_msg = (ei_received_msg_t *) pop; - - ei_x_free(&received_msg->buf); - switch_safe_free(received_msg); - } - - while (switch_queue_trypop(ei_node->send_msgs, &pop) == SWITCH_STATUS_SUCCESS) { - ei_send_msg_t *send_msg = (ei_send_msg_t *) pop; - - ei_x_free(&send_msg->buf); - switch_safe_free(send_msg); - } - - close_socketfd(&ei_node->nodefd); - - switch_mutex_destroy(ei_node->event_streams_mutex); - - switch_core_destroy_memory_pool(&pool); -} - -static switch_status_t add_to_ei_nodes(ei_node_t *this_ei_node) { - switch_thread_rwlock_wrlock(kazoo_globals.ei_nodes_lock); - - if (!kazoo_globals.ei_nodes) { - kazoo_globals.ei_nodes = this_ei_node; - } else { - this_ei_node->next = kazoo_globals.ei_nodes; - kazoo_globals.ei_nodes = this_ei_node; - } - - switch_thread_rwlock_unlock(kazoo_globals.ei_nodes_lock); - - return SWITCH_STATUS_SUCCESS; -} - -static switch_status_t remove_from_ei_nodes(ei_node_t *this_ei_node) { - ei_node_t *ei_node, *prev = NULL; - int found = 0; - - switch_thread_rwlock_wrlock(kazoo_globals.ei_nodes_lock); - - /* try to find the event bindings list for the requestor */ - ei_node = kazoo_globals.ei_nodes; - while(ei_node != NULL) { - if (ei_node == this_ei_node) { - found = 1; - break; - } - - prev = ei_node; - ei_node = ei_node->next; - } - - if (found) { - if (!prev) { - kazoo_globals.ei_nodes = this_ei_node->next; - } else { - prev->next = ei_node->next; - } - } - - switch_thread_rwlock_unlock(kazoo_globals.ei_nodes_lock); - - return SWITCH_STATUS_SUCCESS; -} - -void kazoo_event_add_unique_header_string(switch_event_t *event, switch_stack_t stack, const char *header_name, const char *data) { - if(!switch_event_get_header_ptr(event, header_name)) - switch_event_add_header_string(event, stack, header_name, data); -} - - -SWITCH_DECLARE(switch_status_t) kazoo_api_execute(const char *cmd, const char *arg, switch_core_session_t *session, switch_stream_handle_t *stream, char** reply) -{ - switch_api_interface_t *api; - switch_status_t status; - char *arg_used; - char *cmd_used; - int fire_event = 0; - char *arg_expanded = NULL; - switch_event_t* evt; - - switch_assert(stream != NULL); - switch_assert(stream->data != NULL); - switch_assert(stream->write_function != NULL); - - switch_event_create(&evt, SWITCH_EVENT_GENERAL); - arg_expanded = switch_event_expand_headers(evt, arg); - switch_event_destroy(&evt); - - cmd_used = (char *) cmd; - arg_used = arg_expanded; - - if (!stream->param_event) { - switch_event_create(&stream->param_event, SWITCH_EVENT_API); - fire_event = 1; - } - - if (stream->param_event) { - if (cmd_used && *cmd_used) { - switch_event_add_header_string(stream->param_event, SWITCH_STACK_BOTTOM, "API-Command", cmd_used); - } - if (arg_used && *arg_used) { - switch_event_add_header_string(stream->param_event, SWITCH_STACK_BOTTOM, "API-Command-Argument", arg_used); - } - if (arg_expanded && *arg_expanded) { - switch_event_add_header_string(stream->param_event, SWITCH_STACK_BOTTOM, "API-Command-Argument-Expanded", arg_expanded); - } - } - - - if (cmd_used && (api = switch_loadable_module_get_api_interface(cmd_used)) != 0) { - if ((status = api->function(arg_used, session, stream)) != SWITCH_STATUS_SUCCESS) { - kazoo_event_add_unique_header_string(stream->param_event, SWITCH_STACK_BOTTOM, "API-Result", "error"); - kazoo_event_add_unique_header_string(stream->param_event, SWITCH_STACK_BOTTOM, "API-Error", stream->data); - } else { - kazoo_event_add_unique_header_string(stream->param_event, SWITCH_STACK_BOTTOM, "API-Result", "success"); - kazoo_event_add_unique_header_string(stream->param_event, SWITCH_STACK_BOTTOM, "API-Output", stream->data); - } - UNPROTECT_INTERFACE(api); - } else { - status = SWITCH_STATUS_FALSE; - kazoo_event_add_unique_header_string(stream->param_event, SWITCH_STACK_BOTTOM, "API-Result", "error"); - kazoo_event_add_unique_header_string(stream->param_event, SWITCH_STACK_BOTTOM, "API-Error", "invalid command"); - } - - if (stream->param_event && fire_event) { - switch_event_fire(&stream->param_event); - } - - if (cmd_used != cmd) { - switch_safe_free(cmd_used); - } - - if (arg_used != arg_expanded) { - switch_safe_free(arg_used); - } - - if (arg_expanded != arg) { - switch_safe_free(arg_expanded); - } - - return status; -} - -static switch_status_t api_exec_stream(char *cmd, char *arg, switch_stream_handle_t *stream, char **reply) { - switch_status_t status = SWITCH_STATUS_FALSE; - - if (kazoo_api_execute(cmd, arg, NULL, stream, reply) != SWITCH_STATUS_SUCCESS) { - if(stream->data && strlen(stream->data)) { - *reply = strdup(stream->data); - status = SWITCH_STATUS_FALSE; - } else { - *reply = switch_mprintf("%s: Command not found", cmd); - status = SWITCH_STATUS_NOTFOUND; - } - } else if (!stream->data || !strlen(stream->data)) { - *reply = switch_mprintf("%s: Command returned no output", cmd); - status = SWITCH_STATUS_SUCCESS; - } else { - *reply = strdup(stream->data); - status = SWITCH_STATUS_SUCCESS; - } - - return status; -} - -static switch_status_t api_exec(char *cmd, char *arg, char **reply) { - switch_stream_handle_t stream = { 0 }; - switch_status_t status = SWITCH_STATUS_FALSE; - - SWITCH_STANDARD_STREAM(stream); - - status = api_exec_stream(cmd, arg, &stream, reply); - - switch_safe_free(stream.data); - - return status; -} - -static void *SWITCH_THREAD_FUNC bgapi3_exec(switch_thread_t *thread, void *obj) { - api_command_struct_t *acs = (api_command_struct_t *) obj; - switch_memory_pool_t *pool = acs->pool; - char *reply = NULL; - char *cmd = acs->cmd; - char *arg = acs->arg; - ei_node_t *ei_node = acs->ei_node; - ei_send_msg_t *send_msg; - - if(!switch_test_flag(ei_node, LFLAG_RUNNING) || !switch_test_flag(&kazoo_globals, LFLAG_RUNNING)) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Ignoring command while shuting down\n"); - switch_atomic_dec(&ei_node->pending_bgapi); - return NULL; - } - - switch_malloc(send_msg, sizeof(*send_msg)); - memcpy(&send_msg->pid, &acs->pid, sizeof(erlang_pid)); - - ei_x_new_with_version(&send_msg->buf); - - ei_x_encode_tuple_header(&send_msg->buf, 3); - - if (api_exec(cmd, arg, &reply) == SWITCH_STATUS_SUCCESS) { - ei_x_encode_atom(&send_msg->buf, "bgok"); - } else { - ei_x_encode_atom(&send_msg->buf, "bgerror"); - } - - _ei_x_encode_string(&send_msg->buf, acs->uuid_str); - _ei_x_encode_string(&send_msg->buf, reply); - - if (switch_queue_trypush(ei_node->send_msgs, send_msg) != SWITCH_STATUS_SUCCESS) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Failed to send bgapi response %s to %s <%d.%d.%d>\n" - ,acs->uuid_str - ,acs->pid.node - ,acs->pid.creation - ,acs->pid.num - ,acs->pid.serial); - ei_x_free(&send_msg->buf); - switch_safe_free(send_msg); - } - - switch_atomic_dec(&ei_node->pending_bgapi); - - switch_safe_free(reply); - switch_safe_free(acs->arg); - switch_core_destroy_memory_pool(&pool); - - return NULL; -} - - -static void *SWITCH_THREAD_FUNC bgapi4_exec(switch_thread_t *thread, void *obj) { - api_command_struct_t *acs = (api_command_struct_t *) obj; - switch_memory_pool_t *pool = acs->pool; - char *reply = NULL; - char *cmd = acs->cmd; - char *arg = acs->arg; - ei_node_t *ei_node = acs->ei_node; - ei_send_msg_t *send_msg; - switch_stream_handle_t stream = { 0 }; - - if(!switch_test_flag(ei_node, LFLAG_RUNNING) || !switch_test_flag(&kazoo_globals, LFLAG_RUNNING)) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Ignoring command while shuting down\n"); - switch_atomic_dec(&ei_node->pending_bgapi); - return NULL; - } - - SWITCH_STANDARD_STREAM(stream); - switch_event_create(&stream.param_event, SWITCH_EVENT_API); - - switch_malloc(send_msg, sizeof(*send_msg)); - memcpy(&send_msg->pid, &acs->pid, sizeof(erlang_pid)); - - ei_x_new_with_version(&send_msg->buf); - ei_x_encode_tuple_header(&send_msg->buf, (stream.param_event ? 4 : 3)); - - if (api_exec_stream(cmd, arg, &stream, &reply) == SWITCH_STATUS_SUCCESS) { - ei_x_encode_atom(&send_msg->buf, "bgok"); - } else { - ei_x_encode_atom(&send_msg->buf, "bgerror"); - } - - _ei_x_encode_string(&send_msg->buf, acs->uuid_str); - _ei_x_encode_string(&send_msg->buf, reply); - - if (stream.param_event) { - ei_encode_switch_event_headers_2(&send_msg->buf, stream.param_event, 0); - } - - if (switch_queue_trypush(ei_node->send_msgs, send_msg) != SWITCH_STATUS_SUCCESS) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Failed to send bgapi response %s to %s <%d.%d.%d>\n" - ,acs->uuid_str - ,acs->pid.node - ,acs->pid.creation - ,acs->pid.num - ,acs->pid.serial); - ei_x_free(&send_msg->buf); - switch_safe_free(send_msg); - } - - switch_atomic_dec(&ei_node->pending_bgapi); - - if (stream.param_event) { - switch_event_fire(&stream.param_event); - } - - switch_safe_free(reply); - switch_safe_free(acs->arg); - switch_core_destroy_memory_pool(&pool); - switch_safe_free(stream.data); - - return NULL; -} - -static void log_sendmsg_request(char *uuid, switch_event_t *event) -{ - char *cmd = switch_event_get_header(event, "call-command"); - unsigned long cmd_hash; - switch_ssize_t hlen = -1; - unsigned long CMD_EXECUTE = switch_hashfunc_default("execute", &hlen); - unsigned long CMD_XFEREXT = switch_hashfunc_default("xferext", &hlen); - - if (zstr(cmd)) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "log|%s|invalid \n", uuid); - DUMP_EVENT(event); - return; - } - - cmd_hash = switch_hashfunc_default(cmd, &hlen); - - if (cmd_hash == CMD_EXECUTE) { - char *app_name = switch_event_get_header(event, "execute-app-name"); - char *app_arg = switch_event_get_header(event, "execute-app-arg"); - - if(app_name) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "log|%s|executing %s %s \n", uuid, app_name, switch_str_nil(app_arg)); - } - } else if (cmd_hash == CMD_XFEREXT) { - switch_event_header_t *hp; - - for (hp = event->headers; hp; hp = hp->next) { - char *app_name; - char *app_arg; - - if (!strcasecmp(hp->name, "application")) { - app_name = strdup(hp->value); - app_arg = strchr(app_name, ' '); - - if (app_arg) { - *app_arg++ = '\0'; - } - - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "log|%s|building xferext extension: %s %s\n", uuid, app_name, app_arg); - switch_safe_free(app_name); - } - } - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "log|%s|transfered call to xferext extension\n", uuid); - } -} - -static switch_status_t build_event(switch_event_t *event, ei_x_buff * buf) { - int propslist_length, arity; - int n=0; - - if(!event) { - return SWITCH_STATUS_FALSE; - } - - if (ei_decode_list_header(buf->buff, &buf->index, &propslist_length)) { - return SWITCH_STATUS_FALSE; - } - - while (!ei_decode_tuple_header(buf->buff, &buf->index, &arity) && n < propslist_length) { - char key[1024]; - char *value; - - if (arity != 2) { - return SWITCH_STATUS_FALSE; - } - - if (ei_decode_string_or_binary_limited(buf->buff, &buf->index, sizeof(key), key)) { - return SWITCH_STATUS_FALSE; - } - - if (ei_decode_string_or_binary(buf->buff, &buf->index, &value)) { - return SWITCH_STATUS_FALSE; - } - - if (!strcmp(key, "body")) { - switch_safe_free(event->body); - event->body = value; - } else { - if(!strcasecmp(key, "Call-ID")) { - switch_core_session_t *session = NULL; - if(!zstr(value)) { - if ((session = switch_core_session_locate(value)) != NULL) { - switch_channel_t *channel = switch_core_session_get_channel(session); - switch_channel_event_set_data(channel, event); - switch_core_session_rwunlock(session); - } - } - } - switch_event_add_header_string_nodup(event, SWITCH_STACK_BOTTOM, key, value); - } - n++; - } - ei_skip_term(buf->buff, &buf->index); - - return SWITCH_STATUS_SUCCESS; -} - -static switch_status_t erlang_response_badarg(ei_x_buff * rbuf) { - if (rbuf) { - ei_x_encode_tuple_header(rbuf, 2); - ei_x_encode_atom(rbuf, "error"); - ei_x_encode_atom(rbuf, "badarg"); - } - - return SWITCH_STATUS_GENERR; -} - -static switch_status_t erlang_response_baduuid(ei_x_buff * rbuf) { - if (rbuf) { - ei_x_format_wo_ver(rbuf, "{~a,~a}", "error", "baduuid"); - } - - return SWITCH_STATUS_NOTFOUND; -} - -static switch_status_t erlang_response_notimplemented(ei_x_buff * rbuf) { - if (rbuf) { - ei_x_encode_tuple_header(rbuf, 2); - ei_x_encode_atom(rbuf, "error"); - ei_x_encode_atom(rbuf, "not_implemented"); - } - - return SWITCH_STATUS_NOTFOUND; -} - -static switch_status_t erlang_response_ok(ei_x_buff *rbuf) { - if (rbuf) { - ei_x_encode_atom(rbuf, "ok"); - } - - return SWITCH_STATUS_SUCCESS; -} - -static switch_status_t erlang_response_ok_uuid(ei_x_buff *rbuf, const char * uuid) { - if (rbuf) { - ei_x_encode_tuple_header(rbuf, 2); - ei_x_encode_atom(rbuf, "ok"); - ei_x_encode_binary(rbuf, uuid, strlen(uuid)); - } - - return SWITCH_STATUS_SUCCESS; -} - -static switch_status_t handle_request_noevents(ei_node_t *ei_node, erlang_pid *pid, ei_x_buff *buf, ei_x_buff *rbuf) { - ei_event_stream_t *event_stream; - - switch_mutex_lock(ei_node->event_streams_mutex); - if ((event_stream = find_event_stream(ei_node->event_streams, pid))) { - remove_event_bindings(event_stream); - } - switch_mutex_unlock(ei_node->event_streams_mutex); - - return erlang_response_ok(rbuf); -} - -static switch_status_t handle_request_exit(ei_node_t *ei_node, erlang_pid *pid, ei_x_buff *buf, ei_x_buff *rbuf) { - switch_clear_flag(ei_node, LFLAG_RUNNING); - - return erlang_response_ok(rbuf); -} - -static switch_status_t handle_request_link(ei_node_t *ei_node, erlang_pid *pid, ei_x_buff *buf, ei_x_buff *rbuf) { - ei_link(ei_node, ei_self(&kazoo_globals.ei_cnode), pid); - - return erlang_response_ok(rbuf); -} - -static switch_status_t handle_request_nixevent(ei_node_t *ei_node, erlang_pid *pid, ei_x_buff *buf, ei_x_buff *rbuf) { - char event_name[MAXATOMLEN + 1]; - switch_event_types_t event_type; - ei_event_stream_t *event_stream; - int custom = 0, length = 0; - int i; - - if (ei_decode_list_header(buf->buff, &buf->index, &length) - || length == 0) { - return erlang_response_badarg(rbuf); - } - - switch_mutex_lock(ei_node->event_streams_mutex); - if (!(event_stream = find_event_stream(ei_node->event_streams, pid))) { - switch_mutex_unlock(ei_node->event_streams_mutex); - return erlang_response_ok(rbuf); - } - - for (i = 1; i <= length; i++) { - if (ei_decode_atom_safe(buf->buff, &buf->index, event_name)) { - switch_mutex_unlock(ei_node->event_streams_mutex); - return erlang_response_badarg(rbuf); - } - - if (custom) { - remove_event_binding(event_stream, SWITCH_EVENT_CUSTOM, event_name); - } else if (switch_name_event(event_name, &event_type) == SWITCH_STATUS_SUCCESS) { - switch (event_type) { - - case SWITCH_EVENT_CUSTOM: - custom++; - break; - - case SWITCH_EVENT_ALL: - { - switch_event_types_t type; - for (type = 0; type < SWITCH_EVENT_ALL; type++) { - if(type != SWITCH_EVENT_CUSTOM) { - remove_event_binding(event_stream, type, NULL); - } - } - break; - } - - default: - remove_event_binding(event_stream, event_type, NULL); - } - } else { - switch_mutex_unlock(ei_node->event_streams_mutex); - return erlang_response_badarg(rbuf); - } - } - switch_mutex_unlock(ei_node->event_streams_mutex); - - return erlang_response_ok(rbuf); -} - -static switch_status_t handle_request_sendevent(ei_node_t *ei_node, erlang_pid *pid, ei_x_buff *buf, ei_x_buff *rbuf) { - char event_name[MAXATOMLEN + 1]; - char subclass_name[MAXATOMLEN + 1]; - switch_event_types_t event_type; - switch_event_t *event = NULL; - - if (ei_decode_atom_safe(buf->buff, &buf->index, event_name) - || switch_name_event(event_name, &event_type) != SWITCH_STATUS_SUCCESS) - { - return erlang_response_badarg(rbuf); - } - - if (!strncasecmp(event_name, "CUSTOM", MAXATOMLEN)) { - if(ei_decode_atom(buf->buff, &buf->index, subclass_name)) { - return erlang_response_badarg(rbuf); - } - switch_event_create_subclass(&event, event_type, subclass_name); - } else { - switch_event_create(&event, event_type); - } - - if (build_event(event, buf) == SWITCH_STATUS_SUCCESS) { - switch_event_fire(&event); - return erlang_response_ok(rbuf); - } - - if(event) { - switch_event_destroy(&event); - } - - return erlang_response_badarg(rbuf); -} - -static switch_status_t handle_request_command(ei_node_t *ei_node, erlang_pid *pid, ei_x_buff *buf, ei_x_buff *rbuf) { - switch_core_session_t *session; - switch_event_t *event = NULL; - char uuid_str[SWITCH_UUID_FORMATTED_LENGTH + 1]; - switch_uuid_t cmd_uuid; - char cmd_uuid_str[SWITCH_UUID_FORMATTED_LENGTH + 1]; - - if (ei_decode_string_or_binary_limited(buf->buff, &buf->index, sizeof(uuid_str), uuid_str)) { - return erlang_response_badarg(rbuf); - } - - if (zstr_buf(uuid_str) || !(session = switch_core_session_locate(uuid_str))) { - return erlang_response_baduuid(rbuf); - } - - switch_uuid_get(&cmd_uuid); - switch_uuid_format(cmd_uuid_str, &cmd_uuid); - - switch_event_create(&event, SWITCH_EVENT_COMMAND); - if (build_event(event, buf) != SWITCH_STATUS_SUCCESS) { - switch_core_session_rwunlock(session); - return erlang_response_badarg(rbuf); - } - - log_sendmsg_request(uuid_str, event); - switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "event-uuid", cmd_uuid_str); - - switch_core_session_queue_private_event(session, &event, SWITCH_FALSE); - switch_core_session_rwunlock(session); - - return erlang_response_ok_uuid(rbuf, cmd_uuid_str); -} - -static switch_status_t handle_request_commands(ei_node_t *ei_node, erlang_pid *pid, ei_x_buff *buf, ei_x_buff *rbuf) { - switch_core_session_t *session; - char uuid_str[SWITCH_UUID_FORMATTED_LENGTH + 1]; - int propslist_length, n; - switch_uuid_t cmd_uuid; - char cmd_uuid_str[SWITCH_UUID_FORMATTED_LENGTH + 1]; - - if (ei_decode_string_or_binary_limited(buf->buff, &buf->index, sizeof(uuid_str), uuid_str)) { - return erlang_response_badarg(rbuf); - } - - if (zstr_buf(uuid_str) || !(session = switch_core_session_locate(uuid_str))) { - return erlang_response_baduuid(rbuf); - } - - switch_uuid_get(&cmd_uuid); - switch_uuid_format(cmd_uuid_str, &cmd_uuid); - - if (ei_decode_list_header(buf->buff, &buf->index, &propslist_length)) { - switch_core_session_rwunlock(session); - return SWITCH_STATUS_FALSE; - } - - for(n = 0; n < propslist_length; n++) { - switch_event_t *event = NULL; - switch_event_create(&event, SWITCH_EVENT_COMMAND); - if (build_event(event, buf) != SWITCH_STATUS_SUCCESS) { - switch_core_session_rwunlock(session); - return erlang_response_badarg(rbuf); - } - log_sendmsg_request(uuid_str, event); - if(n == (propslist_length - 1)) { - switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "event-uuid", cmd_uuid_str); - } else { - switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "event-uuid", "null"); -// switch_event_del_header_val(event, "event-uuid-name", NULL); - } - switch_core_session_queue_private_event(session, &event, SWITCH_FALSE); - } - - switch_core_session_rwunlock(session); - - return erlang_response_ok_uuid(rbuf, cmd_uuid_str); - -} - -static switch_status_t handle_request_sendmsg(ei_node_t *ei_node, erlang_pid *pid, ei_x_buff *buf, ei_x_buff *rbuf) { - switch_core_session_t *session; - switch_event_t *event = NULL; - char uuid_str[SWITCH_UUID_FORMATTED_LENGTH + 1]; - - if (ei_decode_string_or_binary_limited(buf->buff, &buf->index, sizeof(uuid_str), uuid_str)) { - return erlang_response_badarg(rbuf); - } - - if (zstr_buf(uuid_str) || !(session = switch_core_session_locate(uuid_str))) { - return erlang_response_baduuid(rbuf); - } - - switch_event_create(&event, SWITCH_EVENT_SEND_MESSAGE); - if (build_event(event, buf) != SWITCH_STATUS_SUCCESS) { - switch_core_session_rwunlock(session); - return erlang_response_badarg(rbuf); - } - - log_sendmsg_request(uuid_str, event); - - switch_core_session_queue_private_event(session, &event, SWITCH_FALSE); - switch_core_session_rwunlock(session); - - return erlang_response_ok(rbuf); -} - -static switch_status_t handle_request_config(ei_node_t *ei_node, erlang_pid *pid, ei_x_buff *buf, ei_x_buff *rbuf) { - - fetch_config(); - return erlang_response_ok(rbuf); -} - -static switch_status_t handle_request_bind(ei_node_t *ei_node, erlang_pid *pid, ei_x_buff *buf, ei_x_buff *rbuf) { - char section_str[MAXATOMLEN + 1]; - switch_xml_section_t section; - - if (ei_decode_atom_safe(buf->buff, &buf->index, section_str) - || !(section = switch_xml_parse_section_string(section_str))) { - return erlang_response_badarg(rbuf); - } - - switch(section) { - case SWITCH_XML_SECTION_CONFIG: - add_fetch_handler(ei_node, pid, kazoo_globals.config_fetch_binding); - if(!kazoo_globals.config_fetched) { - kazoo_globals.config_fetched = 1; - fetch_config(); - } - break; - case SWITCH_XML_SECTION_DIRECTORY: - add_fetch_handler(ei_node, pid, kazoo_globals.directory_fetch_binding); - break; - case SWITCH_XML_SECTION_DIALPLAN: - add_fetch_handler(ei_node, pid, kazoo_globals.dialplan_fetch_binding); - break; - case SWITCH_XML_SECTION_CHANNELS: - add_fetch_handler(ei_node, pid, kazoo_globals.channels_fetch_binding); - break; - case SWITCH_XML_SECTION_LANGUAGES: - add_fetch_handler(ei_node, pid, kazoo_globals.languages_fetch_binding); - break; - case SWITCH_XML_SECTION_CHATPLAN: - add_fetch_handler(ei_node, pid, kazoo_globals.chatplan_fetch_binding); - break; - default: - return erlang_response_badarg(rbuf); - } - - return erlang_response_ok(rbuf); -} - -static switch_status_t handle_request_getpid(ei_node_t *ei_node, erlang_pid *pid, ei_x_buff *buf, ei_x_buff *rbuf) { - if (rbuf) { - ei_x_encode_tuple_header(rbuf, 2); - ei_x_encode_atom(rbuf, "ok"); - ei_x_encode_pid(rbuf, ei_self(&kazoo_globals.ei_cnode)); - } - - return SWITCH_STATUS_SUCCESS; -} - -static switch_status_t handle_request_version(ei_node_t *ei_node, erlang_pid *pid, ei_x_buff *buf, ei_x_buff *rbuf) { - if (rbuf) { - ei_x_encode_tuple_header(rbuf, 2); - ei_x_encode_atom(rbuf, "ok"); - _ei_x_encode_string(rbuf, VERSION); - } - - return SWITCH_STATUS_SUCCESS; -} - -static switch_status_t handle_request_bgapi(switch_thread_start_t func, ei_node_t *ei_node, erlang_pid *pid, ei_x_buff *buf, ei_x_buff *rbuf) { - api_command_struct_t *acs = NULL; - switch_memory_pool_t *pool; - switch_thread_t *thread; - switch_threadattr_t *thd_attr = NULL; - switch_uuid_t uuid; - char cmd[MAXATOMLEN + 1]; - - if (ei_decode_atom_safe(buf->buff, &buf->index, cmd)) { - return erlang_response_badarg(rbuf); - } - - switch_core_new_memory_pool(&pool); - acs = switch_core_alloc(pool, sizeof(*acs)); - - if (ei_decode_string_or_binary(buf->buff, &buf->index, &acs->arg)) { - switch_core_destroy_memory_pool(&pool); - return erlang_response_badarg(rbuf); - } - - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "bgexec: %s(%s)\n", cmd, acs->arg); - - acs->pool = pool; - acs->ei_node = ei_node; - acs->cmd = switch_core_strdup(pool, cmd); - memcpy(&acs->pid, pid, sizeof(erlang_pid)); - - switch_threadattr_create(&thd_attr, acs->pool); - switch_threadattr_detach_set(thd_attr, 1); - switch_threadattr_stacksize_set(thd_attr, SWITCH_THREAD_STACKSIZE); - - switch_uuid_get(&uuid); - switch_uuid_format(acs->uuid_str, &uuid); - switch_thread_create(&thread, thd_attr, func, acs, acs->pool); - - switch_atomic_inc(&ei_node->pending_bgapi); - - if (rbuf) { - ei_x_encode_tuple_header(rbuf, 2); - ei_x_encode_atom(rbuf, "ok"); - _ei_x_encode_string(rbuf, acs->uuid_str); - } - - return SWITCH_STATUS_SUCCESS; -} - -static switch_status_t handle_request_bgapi3(ei_node_t *ei_node, erlang_pid *pid, ei_x_buff *buf, ei_x_buff *rbuf) { - return handle_request_bgapi(bgapi3_exec, ei_node, pid, buf, rbuf); -} - -static switch_status_t handle_request_bgapi4(ei_node_t *ei_node, erlang_pid *pid, ei_x_buff *buf, ei_x_buff *rbuf) { - return handle_request_bgapi(bgapi4_exec, ei_node, pid, buf, rbuf); -} - -static switch_status_t handle_request_api4(ei_node_t *ei_node, erlang_pid *pid, ei_x_buff *buf, ei_x_buff *rbuf) { - char cmd[MAXATOMLEN + 1]; - char *arg; - switch_stream_handle_t stream = { 0 }; - - SWITCH_STANDARD_STREAM(stream); - switch_event_create(&stream.param_event, SWITCH_EVENT_API); - - if (ei_decode_atom_safe(buf->buff, &buf->index, cmd)) { - return erlang_response_badarg(rbuf); - } - - if (ei_decode_string_or_binary(buf->buff, &buf->index, &arg)) { - return erlang_response_badarg(rbuf); - } - - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "exec: %s(%s)\n", cmd, arg); - - if (rbuf) { - char *reply; - switch_status_t status; - - status = api_exec_stream(cmd, arg, &stream, &reply); - - if (status == SWITCH_STATUS_SUCCESS) { - ei_x_encode_tuple_header(rbuf, 2); - ei_x_encode_atom(rbuf, "ok"); - } else { - ei_x_encode_tuple_header(rbuf, (stream.param_event ? 3 : 2)); - ei_x_encode_atom(rbuf, "error"); - } - - _ei_x_encode_string(rbuf, reply); - - if (stream.param_event && status != SWITCH_STATUS_SUCCESS) { - ei_encode_switch_event_headers(rbuf, stream.param_event); - } - - switch_safe_free(reply); - } - - if (stream.param_event) { - switch_event_fire(&stream.param_event); - } - - switch_safe_free(arg); - switch_safe_free(stream.data); - - return SWITCH_STATUS_SUCCESS; -} - -static switch_status_t handle_request_json_api(ei_node_t *ei_node, erlang_pid *pid, ei_x_buff *buf, ei_x_buff *rbuf) -{ - char *arg; - cJSON *jcmd = NULL; - switch_core_session_t *session = NULL; - const char *uuid = NULL; - char *response = NULL; - const char *parse_end = NULL; - switch_status_t status = SWITCH_STATUS_SUCCESS; - - if (ei_decode_string_or_binary(buf->buff, &buf->index, &arg)) { - return erlang_response_badarg(rbuf); - } - - jcmd = cJSON_ParseWithOpts(arg, &parse_end, 0); - - if (!jcmd) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "json api error: %s\n", parse_end); - ei_x_encode_tuple_header(rbuf, 2); - ei_x_encode_atom(rbuf, "error"); - ei_x_encode_tuple_header(rbuf, 2); - ei_x_encode_atom(rbuf, "parse_error"); - _ei_x_encode_string(rbuf, parse_end); - switch_safe_free(arg); - return status; - } - - if ((uuid = cJSON_GetObjectCstr(jcmd, "uuid"))) { - if (!(session = switch_core_session_locate(uuid))) { - cJSON_Delete(jcmd); - switch_safe_free(arg); - return erlang_response_baduuid(rbuf); - } - } - - status = switch_json_api_execute(jcmd, session, NULL); - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "json api (%i): %s\n", status , arg); - - response = cJSON_PrintUnformatted(jcmd); - ei_x_encode_tuple_header(rbuf, 2); - if (status == SWITCH_STATUS_SUCCESS) { - ei_x_encode_atom(rbuf, "ok"); - } else { - ei_x_encode_atom(rbuf, "error"); - } - _ei_x_encode_string(rbuf, response); - switch_safe_free(response); - - cJSON_Delete(jcmd); - switch_safe_free(arg); - - if (session) { - switch_core_session_rwunlock(session); - } - - return SWITCH_STATUS_SUCCESS; -} - -static switch_status_t handle_request_api(ei_node_t *ei_node, erlang_pid *pid, ei_x_buff *buf, ei_x_buff *rbuf) { - char cmd[MAXATOMLEN + 1]; - char *arg; - - if (ei_decode_atom_safe(buf->buff, &buf->index, cmd)) { - return erlang_response_badarg(rbuf); - } - - if (ei_decode_string_or_binary(buf->buff, &buf->index, &arg)) { - return erlang_response_badarg(rbuf); - } - - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "exec: %s(%s)\n", cmd, arg); - - if (rbuf) { - char *reply; - - ei_x_encode_tuple_header(rbuf, 2); - - if (api_exec(cmd, arg, &reply) == SWITCH_STATUS_SUCCESS) { - ei_x_encode_atom(rbuf, "ok"); - } else { - ei_x_encode_atom(rbuf, "error"); - } - - _ei_x_encode_string(rbuf, reply); - switch_safe_free(reply); - } - - switch_safe_free(arg); - - return SWITCH_STATUS_SUCCESS; -} - -static switch_status_t handle_request_event(ei_node_t *ei_node, erlang_pid *pid, ei_x_buff *buf, ei_x_buff *rbuf) { - char event_name[MAXATOMLEN + 1]; - ei_event_stream_t *event_stream; - int length = 0; - int i; - - if (ei_decode_list_header(buf->buff, &buf->index, &length) || !length) { - return erlang_response_badarg(rbuf); - } - - switch_mutex_lock(ei_node->event_streams_mutex); - if (!(event_stream = find_event_stream(ei_node->event_streams, pid))) { - event_stream = new_event_stream(ei_node, pid); - /* ensure we are notified if the requesting processes dies so we can clean up */ - ei_link(ei_node, ei_self(&kazoo_globals.ei_cnode), pid); - } - - for (i = 1; i <= length; i++) { - if (ei_decode_atom_safe(buf->buff, &buf->index, event_name)) { - switch_mutex_unlock(ei_node->event_streams_mutex); - return erlang_response_badarg(rbuf); - } - add_event_binding(event_stream, event_name); - } - switch_mutex_unlock(ei_node->event_streams_mutex); - - if (rbuf) { - ei_x_encode_tuple_header(rbuf, 2); - ei_x_encode_atom(rbuf, "ok"); - - ei_x_encode_tuple_header(rbuf, 2); - ei_x_encode_string(rbuf, ei_node->local_ip); - ei_x_encode_ulong(rbuf, get_stream_port(event_stream)); - } - - return SWITCH_STATUS_SUCCESS; -} - -static switch_status_t handle_request_fetch_reply(ei_node_t *ei_node, erlang_pid *pid, ei_x_buff *buf, ei_x_buff *rbuf) { - char section_str[MAXATOMLEN + 1]; - char uuid_str[SWITCH_UUID_FORMATTED_LENGTH + 1]; - char *xml_str; - switch_xml_section_t section; - switch_status_t result; - - if (ei_decode_atom_safe(buf->buff, &buf->index, section_str) - || !(section = switch_xml_parse_section_string(section_str))) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Ignoring a fetch reply without a configuration section\n"); - - return erlang_response_badarg(rbuf); - } - - if (ei_decode_string_or_binary_limited(buf->buff, &buf->index, sizeof(uuid_str), uuid_str) - || zstr_buf(uuid_str)) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Ignoring a fetch reply without request UUID\n"); - - return erlang_response_badarg(rbuf); - } - - if (ei_decode_string_or_binary(buf->buff, &buf->index, &xml_str)) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Ignoring a fetch reply without XML : %s \n", uuid_str); - - return erlang_response_badarg(rbuf); - } - - if (zstr(xml_str)) { - switch_safe_free(xml_str); - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Ignoring an empty fetch reply : %s\n", uuid_str); - - return erlang_response_badarg(rbuf); - } - - switch(section) { - case SWITCH_XML_SECTION_CONFIG: - result = fetch_reply(uuid_str, xml_str, kazoo_globals.config_fetch_binding); - break; - case SWITCH_XML_SECTION_DIRECTORY: - result = fetch_reply(uuid_str, xml_str, kazoo_globals.directory_fetch_binding); - break; - case SWITCH_XML_SECTION_DIALPLAN: - result = fetch_reply(uuid_str, xml_str, kazoo_globals.dialplan_fetch_binding); - break; - case SWITCH_XML_SECTION_CHANNELS: - result = fetch_reply(uuid_str, xml_str, kazoo_globals.channels_fetch_binding); - break; - case SWITCH_XML_SECTION_LANGUAGES: - result = fetch_reply(uuid_str, xml_str, kazoo_globals.languages_fetch_binding); - break; - case SWITCH_XML_SECTION_CHATPLAN: - result = fetch_reply(uuid_str, xml_str, kazoo_globals.chatplan_fetch_binding); - break; - default: - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Received fetch reply %s for an unknown configuration section: %s : %s\n", uuid_str, section_str, xml_str); - switch_safe_free(xml_str); - - return erlang_response_badarg(rbuf); - } - - if (result == SWITCH_STATUS_SUCCESS) { - switch_safe_free(xml_str); - - return erlang_response_ok(rbuf); - } else { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Received fetch reply %s is unknown or has expired : %s\n", uuid_str, xml_str); - switch_safe_free(xml_str); - - return erlang_response_baduuid(rbuf); - } -} - -static switch_status_t handle_kazoo_request(ei_node_t *ei_node, erlang_pid *pid, ei_x_buff *buf, ei_x_buff *rbuf) { - char atom[MAXATOMLEN + 1]; - int type, size, arity = 0, request; - - /* ...{_, _}} | ...atom()} = Buf */ - ei_get_type(buf->buff, &buf->index, &type, &size); - - /* is_tuple(Type) */ - if (type == ERL_SMALL_TUPLE_EXT) { - /* ..._, _} = Buf */ - ei_decode_tuple_header(buf->buff, &buf->index, &arity); - } - - if (ei_decode_atom_safe(buf->buff, &buf->index, atom)) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Received mod_kazoo message that did not contain a command (ensure you are using Kazoo v2.14+).\n"); - return erlang_response_badarg(rbuf); - } - - if (find_request(atom, &request) != SWITCH_STATUS_SUCCESS) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Received mod_kazoo message for unimplemented feature (ensure you are using Kazoo v2.14+): %s\n", atom); - return erlang_response_badarg(rbuf); - } - - switch(request) { - case REQUEST_NOEVENTS: - return handle_request_noevents(ei_node, pid, buf, rbuf); - case REQUEST_EXIT: - return handle_request_exit(ei_node, pid, buf, rbuf); - case REQUEST_LINK: - return handle_request_link(ei_node, pid, buf, rbuf); - case REQUEST_NIXEVENT: - return handle_request_nixevent(ei_node, pid, buf, rbuf); - case REQUEST_SENDEVENT: - return handle_request_sendevent(ei_node, pid, buf, rbuf); - case REQUEST_SENDMSG: - return handle_request_sendmsg(ei_node, pid, buf, rbuf); - case REQUEST_COMMAND: - return handle_request_command(ei_node, pid, buf, rbuf); - case REQUEST_COMMANDS: - return handle_request_commands(ei_node, pid, buf, rbuf); - case REQUEST_BIND: - return handle_request_bind(ei_node, pid, buf, rbuf); - case REQUEST_GETPID: - return handle_request_getpid(ei_node, pid, buf, rbuf); - case REQUEST_VERSION: - return handle_request_version(ei_node, pid, buf, rbuf); - case REQUEST_BGAPI: - return handle_request_bgapi3(ei_node, pid, buf, rbuf); - case REQUEST_API: - return handle_request_api(ei_node, pid, buf, rbuf); - case REQUEST_EVENT: - return handle_request_event(ei_node, pid, buf, rbuf); - case REQUEST_FETCH_REPLY: - return handle_request_fetch_reply(ei_node, pid, buf, rbuf); - case REQUEST_CONFIG: - return handle_request_config(ei_node, pid, buf, rbuf); - case REQUEST_BGAPI4: - return handle_request_bgapi4(ei_node, pid, buf, rbuf); - case REQUEST_API4: - return handle_request_api4(ei_node, pid, buf, rbuf); - case REQUEST_JSON_API: - return handle_request_json_api(ei_node, pid, buf, rbuf); - default: - return erlang_response_notimplemented(rbuf); - } -} - -static switch_status_t handle_mod_kazoo_request(ei_node_t *ei_node, erlang_msg *msg, ei_x_buff *buf) { - char atom[MAXATOMLEN + 1]; - int version, type, size, arity; - - buf->index = 0; - ei_decode_version(buf->buff, &buf->index, &version); - ei_get_type(buf->buff, &buf->index, &type, &size); - - /* is_tuple(Type) */ - if (type != ERL_SMALL_TUPLE_EXT) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Received erlang message of an unexpected type (ensure you are using Kazoo v2.14+).\n"); - return SWITCH_STATUS_GENERR; - } - - ei_decode_tuple_header(buf->buff, &buf->index, &arity); - - if (ei_decode_atom_safe(buf->buff, &buf->index, atom)) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Received erlang message tuple that did not start with an atom (ensure you are using Kazoo v2.14+).\n"); - return SWITCH_STATUS_GENERR; - } - - /* {'$gen_cast', {_, _}} = Buf */ - if (arity == 2 && !strncmp(atom, "$gen_cast", 9)) { - return handle_kazoo_request(ei_node, &msg->from, buf, NULL); - /* {'$gen_call', {_, _}, {_, _}} = Buf */ - } else if (arity == 3 && !strncmp(atom, "$gen_call", 9)) { - switch_status_t status; - ei_send_msg_t *send_msg = NULL; - erlang_ref ref; - - switch_malloc(send_msg, sizeof(*send_msg)); - ei_x_new_with_version(&send_msg->buf); - - /* ...{_, _}, {_, _}} = Buf */ - ei_get_type(buf->buff, &buf->index, &type, &size); - - /* is_tuple(Type) */ - if (type != ERL_SMALL_TUPLE_EXT) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Received erlang call message of an unexpected type (ensure you are using Kazoo v2.14+).\n"); - ei_x_free(&send_msg->buf); - switch_safe_free(send_msg); - return SWITCH_STATUS_GENERR; - } - - /* ..._, _}, {_, _}} = Buf */ - ei_decode_tuple_header(buf->buff, &buf->index, &arity); - - /* ...pid(), _}, {_, _}} = Buf */ - if (ei_decode_pid(buf->buff, &buf->index, &send_msg->pid)) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Received erlang call without a reply pid (ensure you are using Kazoo v2.14+).\n"); - ei_x_free(&send_msg->buf); - switch_safe_free(send_msg); - return SWITCH_STATUS_GENERR; - } - - /* ...ref()}, {_, _}} = Buf */ - if (ei_decode_ref(buf->buff, &buf->index, &ref)) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Received erlang call without a reply tag (ensure you are using Kazoo v2.14+).\n"); - ei_x_free(&send_msg->buf); - switch_safe_free(send_msg); - return SWITCH_STATUS_GENERR; - } - - /* send_msg->buf = {ref(), ... */ - ei_x_encode_tuple_header(&send_msg->buf, 2); - ei_x_encode_ref(&send_msg->buf, &ref); - - status = handle_kazoo_request(ei_node, &msg->from, buf, &send_msg->buf); - - if (switch_queue_trypush(ei_node->send_msgs, send_msg) != SWITCH_STATUS_SUCCESS) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "error queuing reply\n"); - ei_x_free(&send_msg->buf); - switch_safe_free(send_msg); - } - - return status; - } else { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Received inappropriate erlang message (ensure you are using Kazoo v2.14+)\n"); - return SWITCH_STATUS_GENERR; - } -} - -/* fake enough of the net_kernel module to be able to respond to net_adm:ping */ -static switch_status_t handle_net_kernel_request(ei_node_t *ei_node, erlang_msg *msg, ei_x_buff *buf) { - int version, size, type, arity; - char atom[MAXATOMLEN + 1]; - ei_send_msg_t *send_msg = NULL; - erlang_ref ref; - - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Received net_kernel message, attempting to reply\n"); - - switch_malloc(send_msg, sizeof(*send_msg)); - ei_x_new_with_version(&send_msg->buf); - - buf->index = 0; - ei_decode_version(buf->buff, &buf->index, &version); - ei_get_type(buf->buff, &buf->index, &type, &size); - - /* is_tuple(Buff) */ - if (type != ERL_SMALL_TUPLE_EXT) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Received net_kernel message of an unexpected type\n"); - goto error; - } - - ei_decode_tuple_header(buf->buff, &buf->index, &arity); - - /* {_, _, _} = Buf */ - if (arity != 3) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Received net_kernel tuple has an unexpected arity\n"); - goto error; - } - - /* {'$gen_call', _, _} = Buf */ - if (ei_decode_atom_safe(buf->buff, &buf->index, atom) || strncmp(atom, "$gen_call", 9)) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Received net_kernel message tuple does not begin with the atom '$gen_call'\n"); - goto error; - } - - ei_get_type(buf->buff, &buf->index, &type, &size); - - /* {_, Sender, _}=Buff, is_tuple(Sender) */ - if (type != ERL_SMALL_TUPLE_EXT) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Second element of the net_kernel tuple is an unexpected type\n"); - goto error; - } - - ei_decode_tuple_header(buf->buff, &buf->index, &arity); - - /* {_, _}=Sender */ - if (arity != 2) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Second element of the net_kernel message has an unexpected arity\n"); - goto error; - } - - /* {Pid, Ref}=Sender */ - if (ei_decode_pid(buf->buff, &buf->index, &send_msg->pid) || ei_decode_ref(buf->buff, &buf->index, &ref)) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Unable to decode erlang pid or ref of the net_kernel tuple second element\n"); - goto error; - } - - ei_get_type(buf->buff, &buf->index, &type, &size); - - /* {_, _, Request}=Buff, is_tuple(Request) */ - if (type != ERL_SMALL_TUPLE_EXT) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Third element of the net_kernel message is an unexpected type\n"); - goto error; - } - - ei_decode_tuple_header(buf->buff, &buf->index, &arity); - - /* {_, _}=Request */ - if (arity != 2) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Third element of the net_kernel message has an unexpected arity\n"); - goto error; - } - - /* {is_auth, _}=Request */ - if (ei_decode_atom_safe(buf->buff, &buf->index, atom) || strncmp(atom, "is_auth", MAXATOMLEN)) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "The net_kernel message third element does not begin with the atom 'is_auth'\n"); - goto error; - } - - /* To ! {Tag, Reply} */ - ei_x_encode_tuple_header(&send_msg->buf, 2); - ei_x_encode_ref(&send_msg->buf, &ref); - ei_x_encode_atom(&send_msg->buf, "yes"); - - if (switch_queue_trypush(ei_node->send_msgs, send_msg) != SWITCH_STATUS_SUCCESS) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "unable to queue net kernel message\n"); - goto error; - } - - return SWITCH_STATUS_SUCCESS; - -error: - ei_x_free(&send_msg->buf); - switch_safe_free(send_msg); - return SWITCH_STATUS_GENERR; -} - -static switch_status_t handle_erl_send(ei_node_t *ei_node, erlang_msg *msg, ei_x_buff *buf) { - if (!strncmp(msg->toname, "net_kernel", MAXATOMLEN)) { - return handle_net_kernel_request(ei_node, msg, buf); - } else if (!strncmp(msg->toname, "mod_kazoo", MAXATOMLEN)) { - return handle_mod_kazoo_request(ei_node, msg, buf); - } else { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Received erlang message to unknown process \"%s\" (ensure you are using Kazoo v2.14+).\n", msg->toname); - return SWITCH_STATUS_GENERR; - } -} - -static switch_status_t handle_erl_msg(ei_node_t *ei_node, erlang_msg *msg, ei_x_buff *buf) { - switch (msg->msgtype) { - case ERL_SEND: - case ERL_REG_SEND: - return handle_erl_send(ei_node, msg, buf); - case ERL_LINK: - /* we received an erlang link request? Should we be linking or are they linking to us and this just informs us? */ - return SWITCH_STATUS_SUCCESS; - case ERL_UNLINK: - /* we received an erlang unlink request? Same question as the ERL_LINK, are we expected to do something? */ - return SWITCH_STATUS_SUCCESS; - case ERL_EXIT: - /* we received a notice that a process we were linked to has exited, clean up any bindings */ - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Received erlang exit notice for %s <%d.%d.%d>\n", msg->from.node, msg->from.creation, msg->from.num, msg->from.serial); - - switch_mutex_lock(ei_node->event_streams_mutex); - remove_event_stream(&ei_node->event_streams, &msg->from); - switch_mutex_unlock(ei_node->event_streams_mutex); - - remove_fetch_handlers(ei_node, &msg->from); - return SWITCH_STATUS_SUCCESS; - case ERL_EXIT2: - /* erlang nodes appear to send both the old and new style exit notices so just ignore these */ - return SWITCH_STATUS_FALSE; - default: - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "Received unexpected erlang message type %d\n", (int) (msg->msgtype)); - return SWITCH_STATUS_FALSE; - } -} - -static void *SWITCH_THREAD_FUNC receive_handler(switch_thread_t *thread, void *obj) { - ei_node_t *ei_node = (ei_node_t *) obj; - - switch_atomic_inc(&kazoo_globals.threads); - switch_atomic_inc(&ei_node->receive_handlers); - - switch_assert(ei_node != NULL); - - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Starting erlang receive handler %p: %s (%s:%d)\n", (void *)ei_node, ei_node->peer_nodename, ei_node->remote_ip, ei_node->remote_port); - - while (switch_test_flag(ei_node, LFLAG_RUNNING) && switch_test_flag(&kazoo_globals, LFLAG_RUNNING)) { - void *pop = NULL; - - if (ei_queue_pop(ei_node->received_msgs, &pop, ei_node->receiver_queue_timeout) == SWITCH_STATUS_SUCCESS) { - ei_received_msg_t *received_msg = (ei_received_msg_t *) pop; - handle_erl_msg(ei_node, &received_msg->msg, &received_msg->buf); - ei_x_free(&received_msg->buf); - switch_safe_free(received_msg); - } - } - - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Shutdown erlang receive handler %p: %s (%s:%d)\n", (void *)ei_node, ei_node->peer_nodename, ei_node->remote_ip, ei_node->remote_port); - - switch_atomic_dec(&ei_node->receive_handlers); - switch_atomic_dec(&kazoo_globals.threads); - - return NULL; -} - -static void *SWITCH_THREAD_FUNC handle_node(switch_thread_t *thread, void *obj) { - ei_node_t *ei_node = (ei_node_t *) obj; - ei_received_msg_t *received_msg = NULL; - int fault_count = 0; - - switch_atomic_inc(&kazoo_globals.threads); - - switch_assert(ei_node != NULL); - - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Starting node request handler %p: %s (%s:%d)\n", (void *)ei_node, ei_node->peer_nodename, ei_node->remote_ip, ei_node->remote_port); - - add_to_ei_nodes(ei_node); - - while (switch_test_flag(ei_node, LFLAG_RUNNING) && switch_test_flag(&kazoo_globals, LFLAG_RUNNING)) { - int status; - int send_msg_count = 0; - void *pop = NULL; - - if (!received_msg) { - switch_malloc(received_msg, sizeof(*received_msg)); - /* create a new buf for the erlang message and a rbuf for the reply */ - if(kazoo_globals.receive_msg_preallocate > 0) { - switch_malloc(received_msg->buf.buff, kazoo_globals.receive_msg_preallocate); - received_msg->buf.buffsz = kazoo_globals.receive_msg_preallocate; - received_msg->buf.index = 0; - if(received_msg->buf.buff == NULL) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Could not pre-allocate memory for mod_kazoo message\n"); - goto exit; - } - } else { - ei_x_new(&received_msg->buf); - } - } else { - received_msg->buf.index = 0; - } - - while (++send_msg_count <= kazoo_globals.send_msg_batch - && ei_queue_pop(ei_node->send_msgs, &pop, ei_node->sender_queue_timeout) == SWITCH_STATUS_SUCCESS) { - ei_send_msg_t *send_msg = (ei_send_msg_t *) pop; - ei_helper_send(ei_node, &send_msg->pid, &send_msg->buf); - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Sent erlang message to %s <%d.%d.%d>\n" - ,send_msg->pid.node - ,send_msg->pid.creation - ,send_msg->pid.num - ,send_msg->pid.serial); - ei_x_free(&send_msg->buf); - switch_safe_free(send_msg); - } - - /* wait for a erlang message, or timeout to check if the module is still running */ - status = ei_xreceive_msg_tmo(ei_node->nodefd, &received_msg->msg, &received_msg->buf, kazoo_globals.ei_receive_timeout); - - switch (status) { - case ERL_TICK: - /* erlang nodes send ticks to eachother to validate they are still reachable, we dont have to do anything here */ - fault_count = 0; - break; - case ERL_MSG: - fault_count = 0; - - if (kazoo_globals.receive_msg_preallocate > 0 && received_msg->buf.buffsz > kazoo_globals.receive_msg_preallocate) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "increased received message buffer size to %d\n", received_msg->buf.buffsz); - } - - if (switch_queue_trypush(ei_node->received_msgs, received_msg) != SWITCH_STATUS_SUCCESS) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "failed to push erlang received message from %s <%d.%d.%d> into queue\n", received_msg->msg.from.node, received_msg->msg.from.creation, received_msg->msg.from.num, received_msg->msg.from.serial); - ei_x_free(&received_msg->buf); - switch_safe_free(received_msg); - } - - received_msg = NULL; - break; - case ERL_ERROR: - switch (erl_errno) { - case ETIMEDOUT: - case EAGAIN: - /* if ei_xreceive_msg_tmo just timed out, ignore it and let the while loop check if we are still running */ - /* the erlang lib just wants us to try to receive again, so we will! */ - fault_count = 0; - break; - case EMSGSIZE: - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Erlang communication fault with node %p %s (%s:%d): my spoon is too big\n", (void *)ei_node, ei_node->peer_nodename, ei_node->remote_ip, ei_node->remote_port); - switch_clear_flag(ei_node, LFLAG_RUNNING); - break; - case EIO: - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "Erlang communication fault with node %p %s (%s:%d): socket closed or I/O error [fault count %d]\n", (void *)ei_node, ei_node->peer_nodename, ei_node->remote_ip, ei_node->remote_port, ++fault_count); - - if (fault_count >= kazoo_globals.io_fault_tolerance) { - switch_clear_flag(ei_node, LFLAG_RUNNING); - } else { - switch_sleep(kazoo_globals.io_fault_tolerance_sleep); - } - - break; - default: - /* OH NOS! something has gone horribly wrong, shutdown the connection if status set by ei_xreceive_msg_tmo is less than or equal to 0 */ - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Erlang communication fault with node %p %s (%s:%d): erl_errno=%d errno=%d\n", (void *)ei_node, ei_node->peer_nodename, ei_node->remote_ip, ei_node->remote_port, erl_errno, errno); - if (status < 0) { - switch_clear_flag(ei_node, LFLAG_RUNNING); - } - break; - } - break; - default: - /* HUH? didnt plan for this, whatevs shutdown the connection if status set by ei_xreceive_msg_tmo is less than or equal to 0 */ - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Unexpected erlang receive status %p %s (%s:%d): %d\n", (void *)ei_node, ei_node->peer_nodename, ei_node->remote_ip, ei_node->remote_port, status); - if (status < 0) { - switch_clear_flag(ei_node, LFLAG_RUNNING); - } - break; - } - } - - exit: - - if (received_msg) { - ei_x_free(&received_msg->buf); - switch_safe_free(received_msg); - } - - remove_from_ei_nodes(ei_node); - - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Shutdown erlang node handler %p: %s (%s:%d)\n", (void *)ei_node, ei_node->peer_nodename, ei_node->remote_ip, ei_node->remote_port); - - destroy_node_handler(ei_node); - - switch_atomic_dec(&kazoo_globals.threads); - - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Shutdown Complete for erlang node handler %p: %s (%s:%d)\n", (void *)ei_node, ei_node->peer_nodename, ei_node->remote_ip, ei_node->remote_port); - - return NULL; -} - -/* Create a thread to wait for messages from an erlang node and process them */ -switch_status_t new_kazoo_node(int nodefd, ErlConnect *conn) { - switch_thread_t *thread; - switch_threadattr_t *thd_attr = NULL; - switch_memory_pool_t *pool = NULL; - switch_sockaddr_t *sa; - ei_node_t *ei_node; - int i = 0; - - /* create memory pool for this erlang node */ - if (switch_core_new_memory_pool(&pool) != SWITCH_STATUS_SUCCESS) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Out of memory: Too bad drinking scotch isn't a paying job or Kenny's dad would be a millionare!\n"); - return SWITCH_STATUS_MEMERR; - } - - /* from the erlang node's memory pool, allocate some memory for the structure */ - if (!(ei_node = switch_core_alloc(pool, sizeof (*ei_node)))) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Out of memory: Stan, don't you know the first law of physics? Anything that's fun costs at least eight dollars.\n"); - return SWITCH_STATUS_MEMERR; - } - - memset(ei_node, 0, sizeof(*ei_node)); - - /* store the location of our pool */ - ei_node->pool = pool; - - /* save the file descriptor that the erlang interface lib uses to communicate with the new node */ - ei_node->nodefd = nodefd; - ei_node->peer_nodename = switch_core_strdup(ei_node->pool, conn->nodename); - ei_node->created_time = switch_micro_time_now(); - ei_node->legacy = kazoo_globals.legacy_events; - ei_node->event_stream_framing = kazoo_globals.event_stream_framing; - ei_node->event_stream_keepalive = kazoo_globals.event_stream_keepalive; - ei_node->event_stream_queue_timeout = kazoo_globals.event_stream_queue_timeout; - ei_node->receiver_queue_timeout = kazoo_globals.node_receiver_queue_timeout; - ei_node->sender_queue_timeout = kazoo_globals.node_sender_queue_timeout; - - /* store the IP and node name we are talking with */ - switch_os_sock_put(&ei_node->socket, (switch_os_socket_t *)&nodefd, pool); - - switch_socket_addr_get(&sa, SWITCH_TRUE, ei_node->socket); - ei_node->remote_port = switch_sockaddr_get_port(sa); - switch_get_addr(ei_node->remote_ip, sizeof (ei_node->remote_ip), sa); - - switch_socket_addr_get(&sa, SWITCH_FALSE, ei_node->socket); - ei_node->local_port = switch_sockaddr_get_port(sa); - switch_get_addr(ei_node->local_ip, sizeof (ei_node->local_ip), sa); - - switch_queue_create(&ei_node->send_msgs, MAX_QUEUE_LEN, pool); - switch_queue_create(&ei_node->received_msgs, MAX_QUEUE_LEN, pool); - - switch_mutex_init(&ei_node->event_streams_mutex, SWITCH_MUTEX_DEFAULT, pool); - - /* when we start we are running */ - switch_set_flag(ei_node, LFLAG_RUNNING); - - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "New erlang connection from node %s (%s:%d) -> (%s:%d)\n", ei_node->peer_nodename, ei_node->remote_ip, ei_node->remote_port, ei_node->local_ip, ei_node->local_port); - - for(i = 0; i < kazoo_globals.node_worker_threads; i++) { - switch_threadattr_create(&thd_attr, ei_node->pool); - switch_threadattr_detach_set(thd_attr, 1); - switch_threadattr_stacksize_set(thd_attr, SWITCH_THREAD_STACKSIZE); - switch_thread_create(&thread, thd_attr, receive_handler, ei_node, ei_node->pool); - } - - switch_threadattr_create(&thd_attr, ei_node->pool); - switch_threadattr_detach_set(thd_attr, 1); - switch_threadattr_stacksize_set(thd_attr, SWITCH_THREAD_STACKSIZE); - switch_thread_create(&thread, thd_attr, handle_node, ei_node, ei_node->pool); - - return SWITCH_STATUS_SUCCESS; -} - -/* For Emacs: - * Local Variables: - * mode:c - * indent-tabs-mode:t - * tab-width:4 - * c-basic-offset:4 - * End: - * For VIM: - * vim:set softtabstop=4 shiftwidth=4 tabstop=4: - */ diff --git a/src/mod/event_handlers/mod_kazoo/kazoo_tweaks.c b/src/mod/event_handlers/mod_kazoo/kazoo_tweaks.c deleted file mode 100644 index e647871855a..00000000000 --- a/src/mod/event_handlers/mod_kazoo/kazoo_tweaks.c +++ /dev/null @@ -1,666 +0,0 @@ -/* - * FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application - * Copyright (C) 2005-2012, Anthony Minessale II - * - * 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 - * Portions created by the Initial Developer are Copyright (C) - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * - * Luis Azedo - * - * mod_hacks.c -- hacks with state handlers - * - */ -#include "mod_kazoo.h" - -static char *TWEAK_NAMES[] = { - "interaction-id", - "export-vars", - "switch-uri", - "replaces-call-id", - "loopback-vars", - "caller-id", - "transfers", - "bridge", - "bridge-replaces-aleg", - "bridge-replaces-call-id", - "bridge-variables", - "restore-caller-id-on-blind-xfer" -}; - -static const char *bridge_variables[] = { - "Call-Control-Queue", - "Call-Control-PID", - "Call-Control-Node", - INTERACTION_VARIABLE, - "ecallmgr_Ecallmgr-Node", - "sip_h_k-cid", - "Switch-URI", - "Switch-URL", - NULL -}; - -static switch_status_t kz_tweaks_signal_bridge_on_hangup(switch_core_session_t *session) -{ - switch_channel_t *channel = switch_core_session_get_channel(session); - switch_event_t *my_event; - - const char *peer_uuid = switch_channel_get_variable(channel, "Bridge-B-Unique-ID"); - - 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)); - 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); - } - - return SWITCH_STATUS_SUCCESS; -} - -static const switch_state_handler_table_t kz_tweaks_signal_bridge_state_handlers = { - /*.on_init */ NULL, - /*.on_routing */ NULL, - /*.on_execute */ NULL, - /*.on_hangup */ kz_tweaks_signal_bridge_on_hangup, - /*.on_exchange_media */ NULL, - /*.on_soft_execute */ NULL, - /*.on_consume_media */ NULL, - /*.on_hibernate */ NULL, - /*.on_reset */ NULL, - /*.on_park */ NULL, - /*.on_reporting */ NULL, - /*.on_destroy */ NULL -}; - -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; - - 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); - 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); - } - switch_core_session_rwunlock(a_session); - } else { - 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) -{ - switch_event_t *my_event; - - const char *replaced_call_id = switch_event_get_header(event, "variable_sip_replaces_call_id"); - 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(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) { - switch_channel_t *call_channel = switch_core_session_get_channel(call_session); - 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); - } - switch_channel_set_variable(call_channel, "Bridge-B-Unique-ID", peer_uuid); - switch_channel_add_state_handler(call_channel, &kz_tweaks_signal_bridge_state_handlers); - switch_core_session_rwunlock(call_session); - } else { - 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) -{ - if (!kz_test_tweak(KZ_TWEAK_BRIDGE)) return; - - kz_tweaks_handle_bridge_replaces_call_id(event); - kz_tweaks_handle_bridge_variables(event); -} - -// TRANSFERS - -static void kz_tweaks_channel_replaced_event_handler(switch_event_t *event) -{ - const char *uuid = switch_event_get_header(event, "Unique-ID"); - const char *replaced_by = switch_event_get_header(event, "att_xfer_replaced_by"); - - if (!kz_test_tweak(KZ_TWEAK_TRANSFERS)) return; - - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "REPLACED : %s , %s\n", uuid, replaced_by); -} - -static void kz_tweaks_channel_intercepted_event_handler(switch_event_t *event) -{ - const char *uuid = switch_event_get_header(event, "Unique-ID"); - const char *peer_uuid = switch_event_get_header(event, "intercepted_by"); - - if (!kz_test_tweak(KZ_TWEAK_TRANSFERS)) return; - - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "INTERCEPTED : %s => %s\n", uuid, peer_uuid); -} - -static void kz_tweaks_channel_transferor_event_handler(switch_event_t *event) -{ - switch_core_session_t *uuid_session = NULL; - switch_event_t *evt = NULL; - const char *uuid = switch_event_get_header(event, "Unique-ID"); - - const char *orig_call_id = switch_event_get_header(event, "att_xfer_original_call_id"); - const char *dest_peer_uuid = switch_event_get_header(event, "att_xfer_destination_peer_uuid"); - const char *dest_call_id = switch_event_get_header(event, "att_xfer_destination_call_id"); - - const char *file = switch_event_get_header(event, "Event-Calling-File"); - const char *func = switch_event_get_header(event, "Event-Calling-Function"); - const char *line = switch_event_get_header(event, "Event-Calling-Line-Number"); - - if (!kz_test_tweak(KZ_TWEAK_TRANSFERS)) return; - - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "TRANSFEROR : %s , %s , %s, %s, %s , %s , %s \n", uuid, orig_call_id, dest_peer_uuid, dest_call_id, file, func, line); - if ((uuid_session = switch_core_session_locate(uuid)) != NULL) { - switch_channel_t *uuid_channel = switch_core_session_get_channel(uuid_session); - const char* interaction_id = switch_channel_get_variable_dup(uuid_channel, INTERACTION_VARIABLE, SWITCH_TRUE, -1); - // set to uuid & peer_uuid - if(interaction_id != NULL) { - switch_core_session_t *session = NULL; - if(dest_call_id && (session = switch_core_session_locate(dest_call_id)) != NULL) { - switch_channel_t *channel = switch_core_session_get_channel(session); - const char* prv_interaction_id = switch_channel_get_variable_dup(channel, INTERACTION_VARIABLE, SWITCH_TRUE, -1); - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "LOCATING UUID PRV : %s : %s\n", prv_interaction_id, interaction_id); - switch_channel_set_variable(channel, INTERACTION_VARIABLE, interaction_id); - if (switch_event_create(&evt, SWITCH_EVENT_CHANNEL_DATA) == SWITCH_STATUS_SUCCESS) { - switch_channel_event_set_data(channel, evt); - switch_event_fire(&evt); - } - switch_core_session_rwunlock(session); - } else { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "TRANSFEROR NO UUID SESSION: %s , %s , %s \n", uuid, dest_call_id, dest_peer_uuid); - } - if(dest_peer_uuid && (session = switch_core_session_locate(dest_peer_uuid)) != NULL) { - switch_channel_t *channel = switch_core_session_get_channel(session); - const char* prv_interaction_id = switch_channel_get_variable_dup(channel, INTERACTION_VARIABLE, SWITCH_TRUE, -1); - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "LOCATING PEER UUID PRV : %s : %s\n", prv_interaction_id, interaction_id); - switch_channel_set_variable(channel, INTERACTION_VARIABLE, interaction_id); - if (switch_event_create(&evt, SWITCH_EVENT_CHANNEL_DATA) == SWITCH_STATUS_SUCCESS) { - switch_channel_event_set_data(channel, evt); - switch_event_fire(&evt); - } - switch_core_session_rwunlock(session); - } else { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "TRANSFEROR NO PEER SESSION: %s , %s , %s \n", uuid, dest_call_id, dest_peer_uuid); - } - if(orig_call_id && (session = switch_core_session_locate(orig_call_id)) != NULL) { - switch_channel_t *channel = switch_core_session_get_channel(session); - const char* prv_interaction_id = switch_channel_get_variable_dup(channel, INTERACTION_VARIABLE, SWITCH_TRUE, -1); - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "LOCATING PEER UUID PRV : %s : %s\n", prv_interaction_id, interaction_id); - switch_channel_set_variable(channel, INTERACTION_VARIABLE, interaction_id); - if (switch_event_create(&evt, SWITCH_EVENT_CHANNEL_DATA) == SWITCH_STATUS_SUCCESS) { - switch_channel_event_set_data(channel, evt); - switch_event_fire(&evt); - } - switch_core_session_rwunlock(session); - } else { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "TRANSFEROR NO PEER SESSION: %s , %s , %s \n", uuid, dest_call_id, dest_peer_uuid); - } - } else { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "TRANSFEROR ID = NULL : %s , %s , %s \n", uuid, dest_call_id, dest_peer_uuid); - } - switch_core_session_rwunlock(uuid_session); - } else { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "SESSION NOT FOUND : %s\n", uuid); - } -} - -static void kz_tweaks_channel_transferee_event_handler(switch_event_t *event) -{ - const char *uuid = switch_event_get_header(event, "Unique-ID"); - const char *replaced_by_uuid = switch_event_get_header(event, "att_xfer_replaced_call_id"); - - if (!kz_test_tweak(KZ_TWEAK_TRANSFERS)) return; - - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "TRANSFEREE : %s replaced by %s\n", uuid, replaced_by_uuid); -} - -// END TRANSFERS - - -static switch_status_t kz_tweaks_handle_loopback(switch_core_session_t *session) -{ - switch_channel_t *channel = switch_core_session_get_channel(session); - switch_channel_t *a_channel = NULL; - const char * loopback_leg = NULL; - const char * loopback_aleg = NULL; - switch_core_session_t *a_session = NULL; - switch_event_t *event = NULL; - switch_event_header_t *header = NULL; - switch_event_t *to_add = NULL; - switch_event_t *to_remove = NULL; - switch_caller_profile_t *caller; - int n = 0; - - if (!kz_test_tweak(KZ_TWEAK_LOOPBACK_VARS)) { - return SWITCH_STATUS_SUCCESS; - } - - caller = switch_channel_get_caller_profile(channel); - if(strncmp(caller->source, "mod_loopback", 12)) - return SWITCH_STATUS_SUCCESS; - - if((loopback_leg = switch_channel_get_variable(channel, "loopback_leg")) == NULL) - return SWITCH_STATUS_SUCCESS; - - if(strncmp(loopback_leg, "B", 1)) - return SWITCH_STATUS_SUCCESS; - - switch_channel_get_variables(channel, &event); - switch_event_create_plain(&to_add, SWITCH_EVENT_CHANNEL_DATA); - switch_event_create_plain(&to_remove, SWITCH_EVENT_CHANNEL_DATA); - - for(header = event->headers; header; header = header->next) { - if(!strncmp(header->name, "Export-Loopback-", 16)) { - kz_switch_event_add_variable_name_printf(to_add, SWITCH_STACK_BOTTOM, header->value, "%s", header->name+16); - switch_channel_set_variable(channel, header->name, NULL); - n++; - } else if(!strncmp(header->name, "sip_loopback_", 13)) { - kz_switch_event_add_variable_name_printf(to_add, SWITCH_STACK_BOTTOM, header->value, "sip_%s", header->name+13); - } else if(!strncmp(header->name, "ecallmgr_", 9)) { - switch_event_add_header_string(to_remove, SWITCH_STACK_BOTTOM, header->name, header->value); - } - } - if(n) { - for(header = to_remove->headers; header; header = header->next) { - switch_channel_set_variable(channel, header->name, NULL); - } - } - - for(header = to_add->headers; header; header = header->next) { - switch_channel_set_variable(channel, header->name, header->value); - } - - // cleanup leg A - loopback_aleg = switch_channel_get_variable(channel, "other_loopback_leg_uuid"); - if(loopback_aleg != NULL) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "found loopback a-leg uuid - %s\n", loopback_aleg); - if ((a_session = switch_core_session_locate(loopback_aleg))) { - a_channel = switch_core_session_get_channel(a_session); - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "found loopback session a - %s\n", loopback_aleg); - switch_channel_del_variable_prefix(a_channel, "Export-Loopback-"); - } else { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Couldn't locate loopback session a - %s\n", loopback_aleg); - } - } else { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Couldn't find loopback a-leg uuid!\n"); - } - - /* - * set Interaction-ID - * if we're not crossing account boundaries - */ - if (kz_test_tweak(KZ_TWEAK_INTERACTION_ID)) { - if (a_channel) { - const char *interaction_id = switch_channel_get_variable_dup(a_channel, INTERACTION_VARIABLE, SWITCH_FALSE, -1); - const char *a_account_id = switch_channel_get_variable_dup(a_channel, "ecallmgr_Account-ID", SWITCH_FALSE, -1); - const char *b_account_id = switch_channel_get_variable_dup(channel, "ecallmgr_Account-ID", SWITCH_FALSE, -1); - if ((!a_account_id) || (!b_account_id) || (!strcmp(a_account_id, b_account_id))) { - switch_channel_set_variable(channel, INTERACTION_VARIABLE, interaction_id); - } - } - } - - if (a_session){ - switch_core_session_rwunlock(a_session); - } - switch_event_destroy(&event); - switch_event_destroy(&to_add); - switch_event_destroy(&to_remove); - - return SWITCH_STATUS_SUCCESS; - -} - -static void kz_tweaks_handle_caller_id(switch_core_session_t *session) -{ - if (kz_test_tweak(KZ_TWEAK_CALLER_ID)) { - switch_channel_t *channel = switch_core_session_get_channel(session); - switch_caller_profile_t* caller = switch_channel_get_caller_profile(channel); - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG1, "CHECKING CALLER-ID\n"); - if (caller && switch_channel_direction(channel) == SWITCH_CALL_DIRECTION_INBOUND) { - const char* val = NULL; - if((val=switch_caller_get_field_by_name(caller, "Endpoint-Caller-ID-Name"))) { - caller->caller_id_name = val; - caller->orig_caller_id_name = val; - } - if((val=switch_caller_get_field_by_name(caller, "Endpoint-Caller-ID-Number"))) { - caller->caller_id_number = val; - caller->orig_caller_id_number = val; - } - } - } -} - -static switch_status_t kz_tweaks_handle_nightmare_xfer_interaction_id(switch_core_session_t *session) -{ - if (kz_test_tweak(KZ_TWEAK_INTERACTION_ID)) { - switch_core_session_t *replace_session = NULL; - switch_channel_t *channel = switch_core_session_get_channel(session); - 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"); - const char *partner_uuid = switch_channel_get_variable(channel, "sip_h_X-FS-Refer-Partner-UUID"); - const char *interaction_id = switch_channel_get_variable(channel, "sip_h_X-FS-Call-Interaction-ID"); - if(core_uuid && partner_uuid && replaced_call_id && interaction_id) { - switch_channel_set_variable(channel, INTERACTION_VARIABLE, interaction_id); - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "checking nightmare xfer tweak for %s\n", switch_channel_get_uuid(channel)); - if ((replace_session = switch_core_session_locate(replaced_call_id))) { - switch_channel_t *replaced_call_channel = switch_core_session_get_channel(replace_session); - switch_channel_set_variable(replaced_call_channel, INTERACTION_VARIABLE, interaction_id); - switch_core_session_rwunlock(replace_session); - } - if ((replace_session = switch_core_session_locate(partner_uuid))) { - switch_channel_t *replaced_call_channel = switch_core_session_get_channel(replace_session); - switch_channel_set_variable(replaced_call_channel, INTERACTION_VARIABLE, interaction_id); - switch_core_session_rwunlock(replace_session); - } - } - } - - return SWITCH_STATUS_SUCCESS; - -} - -static switch_status_t kz_tweaks_handle_replaces_call_id(switch_core_session_t *session) -{ - if (kz_test_tweak(KZ_TWEAK_REPLACES_CALL_ID)) { - switch_core_session_t *replace_call_session = NULL; - switch_event_t *event; - switch_channel_t *channel = switch_core_session_get_channel(session); - 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_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; - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "setting bridge variables from %s to %s\n", replaced_call_id, switch_channel_get_uuid(channel)); - for(i = 0; bridge_variables[i] != NULL; i++) { - const char *val = switch_channel_get_variable_dup(replaced_call_channel, bridge_variables[i], SWITCH_TRUE, -1); - switch_channel_set_variable(channel, bridge_variables[i], val); - } - if (switch_event_create(&event, SWITCH_EVENT_CHANNEL_DATA) == SWITCH_STATUS_SUCCESS) { - switch_channel_event_set_data(channel, event); - switch_event_fire(&event); - } - switch_core_session_rwunlock(replace_call_session); - } - } - } - - return SWITCH_STATUS_SUCCESS; - -} - - -static switch_status_t kz_tweaks_handle_switch_uri(switch_core_session_t *session) -{ - switch_channel_t *channel = switch_core_session_get_channel(session); - if (kz_test_tweak(KZ_TWEAK_SWITCH_URI)) { - const char *profile_url = switch_channel_get_variable(channel, "sofia_profile_url"); - if(profile_url) { - int n = strcspn(profile_url, "@"); - switch_channel_set_variable(channel, "Switch-URL", profile_url); - switch_channel_set_variable_printf(channel, "Switch-URI", "sip:%s", n > 0 ? profile_url + n + 1 : profile_url); - } - } - - return SWITCH_STATUS_SUCCESS; - -} - -static char * kz_tweaks_new_interaction_id() -{ - long int first = (switch_micro_time_now() / 1000000) + UNIX_EPOCH_IN_GREGORIAN; - char uuid_str[SWITCH_UUID_FORMATTED_LENGTH + 1]; - switch_uuid_t uuid; - switch_uuid_get(&uuid); - switch_uuid_format(uuid_str, &uuid); - uuid_str[8] = '\0'; - return switch_mprintf("%ld-%s", first, uuid_str); -} - -static void kz_tweaks_handle_interaction_id(switch_core_session_t *session) -{ - switch_channel_t *channel = switch_core_session_get_channel(session); - char * val = NULL; - switch_core_session_t *peer_session = NULL; - const char* peer_interaction_id = NULL; - - if (kz_test_tweak(KZ_TWEAK_INTERACTION_ID)) { - val = kz_tweaks_new_interaction_id(); - if (val) { - switch_channel_set_variable(channel, "Original-"INTERACTION_VARIABLE, val); - if(switch_core_session_get_partner(session, &peer_session) == SWITCH_STATUS_SUCCESS) { - switch_channel_t *peer_channel = switch_core_session_get_channel(peer_session); - peer_interaction_id = switch_channel_get_variable_dup(peer_channel, INTERACTION_VARIABLE, SWITCH_FALSE, -1); - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "PEER_SESSION => %s\n", peer_interaction_id); - if(peer_interaction_id) { - switch_channel_set_variable(channel, INTERACTION_VARIABLE, peer_interaction_id); - } - switch_core_session_rwunlock(peer_session); - } else if (!switch_channel_get_variable_dup(channel, INTERACTION_VARIABLE, SWITCH_FALSE, -1)) { - switch_channel_set_variable(channel, INTERACTION_VARIABLE, val); - } - } - - switch_safe_free(val); - } - -} - -static switch_status_t kz_outgoing_channel(switch_core_session_t * session, switch_event_t * event, switch_caller_profile_t * cp, switch_core_session_t * peer_session, switch_originate_flag_t flag) -{ - if (kz_test_tweak(KZ_TWEAK_INTERACTION_ID)) { - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "GOT OUTGOING\n"); - if (peer_session) { - switch_channel_t *channel = switch_core_session_get_channel(session); - const char* interaction_id = switch_channel_get_variable_dup(channel, INTERACTION_VARIABLE, SWITCH_FALSE, -1); - switch_channel_t *peer_channel = switch_core_session_get_channel(peer_session); - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "SESSION && PEER_SESSION => %s\n", interaction_id ); - if (interaction_id) { - switch_channel_set_variable(peer_channel, INTERACTION_VARIABLE, interaction_id); - } - } else { - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "NO SESSION && PEER_SESSION\n"); - } - } - return SWITCH_STATUS_SUCCESS; -} - -static switch_status_t kz_tweaks_register_handle_blind_xfer(switch_core_session_t *session) -{ - if (kz_test_tweak(KZ_TWEAK_RESTORE_CALLER_ID_ON_BLIND_XFER)) { - switch_channel_t *channel = switch_core_session_get_channel(session); - switch_channel_set_variable(channel, "execute_on_blind_transfer", "kz_restore_caller_id"); - } - return SWITCH_STATUS_SUCCESS; -} - -static switch_status_t kz_tweaks_on_init(switch_core_session_t *session) -{ - switch_channel_t *channel = switch_core_session_get_channel(session); - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG1, "checking tweaks for %s\n", switch_channel_get_uuid(channel)); - switch_channel_set_flag(channel, CF_VERBOSE_EVENTS); - switch_core_event_hook_add_outgoing_channel(session, kz_outgoing_channel); - kz_tweaks_handle_interaction_id(session); - kz_tweaks_handle_switch_uri(session); - kz_tweaks_handle_caller_id(session); - kz_tweaks_handle_nightmare_xfer_interaction_id(session); - kz_tweaks_handle_replaces_call_id(session); - kz_tweaks_handle_loopback(session); - kz_tweaks_register_handle_blind_xfer(session); - - return SWITCH_STATUS_SUCCESS; -} - -static switch_state_handler_table_t kz_tweaks_state_handlers = { - /*.on_init */ kz_tweaks_on_init, - /*.on_routing */ NULL, - /*.on_execute */ NULL, - /*.on_hangup */ NULL, - /*.on_exchange_media */ NULL, - /*.on_soft_execute */ NULL, - /*.on_consume_media */ NULL, - /*.on_hibernate */ NULL, - /*.on_reset */ NULL, - /*.on_park */ NULL, - /*.on_reporting */ NULL, - /*.on_destroy */ NULL -}; - - -static void kz_tweaks_register_state_handlers() -{ -/* - * we may need two handlers - * one with SSH_FLAG_PRE_EXEC - * and another without it - * mod_loopback tweaks needs post-init (SSH_FLAG_PRE_EXEC off) - * - * kz_tweaks_state_handlers.flags = SSH_FLAG_PRE_EXEC; - * - */ - switch_core_add_state_handler(&kz_tweaks_state_handlers); -} - -static void kz_tweaks_unregister_state_handlers() -{ - switch_core_remove_state_handler(&kz_tweaks_state_handlers); -} - -static void kz_tweaks_bind_events() -{ - if (switch_event_bind("kz_tweaks", SWITCH_EVENT_CHANNEL_BRIDGE, SWITCH_EVENT_SUBCLASS_ANY, kz_tweaks_channel_bridge_event_handler, NULL) != SWITCH_STATUS_SUCCESS) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Couldn't bind to channel_bridge event!\n"); - } - if (switch_event_bind("kz_tweaks", SWITCH_EVENT_CUSTOM, "sofia::replaced", kz_tweaks_channel_replaced_event_handler, NULL) != SWITCH_STATUS_SUCCESS) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Couldn't bind to channel_bridge event!\n"); - } - if (switch_event_bind("kz_tweaks", SWITCH_EVENT_CUSTOM, "sofia::intercepted", kz_tweaks_channel_intercepted_event_handler, NULL) != SWITCH_STATUS_SUCCESS) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Couldn't bind to channel_bridge event!\n"); - } - if (switch_event_bind("kz_tweaks", SWITCH_EVENT_CUSTOM, "sofia::transferor", kz_tweaks_channel_transferor_event_handler, NULL) != SWITCH_STATUS_SUCCESS) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Couldn't bind to channel_bridge event!\n"); - } - if (switch_event_bind("kz_tweaks", SWITCH_EVENT_CUSTOM, "sofia::transferee", kz_tweaks_channel_transferee_event_handler, NULL) != SWITCH_STATUS_SUCCESS) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Couldn't bind to channel_bridge event!\n"); - } -} - -static void kz_tweaks_unbind_events() -{ - switch_event_unbind_callback(kz_tweaks_channel_bridge_event_handler); - switch_event_unbind_callback(kz_tweaks_channel_replaced_event_handler); - switch_event_unbind_callback(kz_tweaks_channel_intercepted_event_handler); - switch_event_unbind_callback(kz_tweaks_channel_transferor_event_handler); - switch_event_unbind_callback(kz_tweaks_channel_transferee_event_handler); -} - -void kz_tweaks_add_core_variables() -{ - switch_core_set_variable("UNIX_EPOCH_IN_GREGORIAN", UNIX_EPOCH_IN_GREGORIAN_STR); -} - -void kz_tweaks_start() -{ - kz_tweaks_add_core_variables(); - kz_tweaks_register_state_handlers(); - kz_tweaks_bind_events(); -} - -void kz_tweaks_stop() -{ - kz_tweaks_unbind_events(); - kz_tweaks_unregister_state_handlers(); -} - -SWITCH_DECLARE(const char *) kz_tweak_name(kz_tweak_t tweak) -{ - return TWEAK_NAMES[tweak]; -} - -SWITCH_DECLARE(switch_status_t) kz_name_tweak(const char *name, kz_tweak_t *type) -{ - kz_tweak_t x; - for (x = 0; x < KZ_TWEAK_MAX; x++) { - if (!strcasecmp(name, TWEAK_NAMES[x])) { - *type = x; - return SWITCH_STATUS_SUCCESS; - } - } - - return SWITCH_STATUS_FALSE; -} - -/* For Emacs: - * Local Variables: - * mode:c - * indent-tabs-mode:t - * tab-width:4 - * c-basic-offset:4 - * End: - * For VIM: - * vim:set softtabstop=4 shiftwidth=4 tabstop=4: - */ - - diff --git a/src/mod/event_handlers/mod_kazoo/kazoo_tweaks.h b/src/mod/event_handlers/mod_kazoo/kazoo_tweaks.h deleted file mode 100644 index 11cf5f65619..00000000000 --- a/src/mod/event_handlers/mod_kazoo/kazoo_tweaks.h +++ /dev/null @@ -1,32 +0,0 @@ -#pragma once - -#include - -typedef enum { - KZ_TWEAK_INTERACTION_ID, - KZ_TWEAK_EXPORT_VARS, - KZ_TWEAK_SWITCH_URI, - KZ_TWEAK_REPLACES_CALL_ID, - KZ_TWEAK_LOOPBACK_VARS, - KZ_TWEAK_CALLER_ID, - KZ_TWEAK_TRANSFERS, - KZ_TWEAK_BRIDGE, - KZ_TWEAK_BRIDGE_REPLACES_ALEG, - KZ_TWEAK_BRIDGE_REPLACES_CALL_ID, - KZ_TWEAK_BRIDGE_VARIABLES, - KZ_TWEAK_RESTORE_CALLER_ID_ON_BLIND_XFER, - - /* No new flags below this line */ - KZ_TWEAK_MAX -} kz_tweak_t; - -void kz_tweaks_start(); -void kz_tweaks_stop(); -SWITCH_DECLARE(const char *) kz_tweak_name(kz_tweak_t tweak); -SWITCH_DECLARE(switch_status_t) kz_name_tweak(const char *name, kz_tweak_t *type); - - -#define kz_test_tweak(flag) (kazoo_globals.tweaks[flag] ? 1 : 0) -#define kz_set_tweak(flag) kazoo_globals.tweaks[flag] = 1 -#define kz_clear_tweak(flag) kazoo_globals.tweaks[flag] = 0 - diff --git a/src/mod/event_handlers/mod_kazoo/kazoo_utils.c b/src/mod/event_handlers/mod_kazoo/kazoo_utils.c deleted file mode 100644 index 951707d179a..00000000000 --- a/src/mod/event_handlers/mod_kazoo/kazoo_utils.c +++ /dev/null @@ -1,700 +0,0 @@ -/* - * FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application - * Copyright (C) 2005-2012, Anthony Minessale II - * - * 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 - * Portions created by the Initial Developer are Copyright (C) - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * - * Anthony Minessale II - * Andrew Thompson - * Rob Charlton - * Karl Anderson - * - * Original from mod_erlang_event. - * ei_helpers.c -- helper functions for ei - * - */ -#include "mod_kazoo.h" - -#define kz_resize(l) {\ -char *dp;\ -olen += (len + l + block);\ -cpos = c - data;\ -if ((dp = realloc(data, olen))) {\ - data = dp;\ - c = data + cpos;\ - memset(c, 0, olen - cpos);\ - }} \ - - -void kz_check_set_profile_var(switch_channel_t *channel, char* var, char *val) -{ - int idx = 0; - while(kazoo_globals.profile_vars_prefixes[idx] != NULL) { - char *prefix = kazoo_globals.profile_vars_prefixes[idx]; - if (!strncasecmp(var, prefix, strlen(prefix))) { - switch_channel_set_profile_var(channel, var + strlen(prefix), val); - - } - idx++; - } -} - -SWITCH_DECLARE(switch_status_t) kz_switch_core_merge_variables(switch_event_t *event) -{ - switch_event_t *global_vars; - switch_status_t status = switch_core_get_variables(&global_vars); - if(status == SWITCH_STATUS_SUCCESS) { - switch_event_merge(event, global_vars); - switch_event_destroy(&global_vars); - } - return status; -} - -SWITCH_DECLARE(switch_status_t) kz_switch_core_base_headers_for_expand(switch_event_t **event) -{ - switch_status_t status = SWITCH_STATUS_GENERR; - *event = NULL; - if(switch_event_create(event, SWITCH_EVENT_GENERAL) == SWITCH_STATUS_SUCCESS) { - status = kz_switch_core_merge_variables(*event); - } - return status; -} - -SWITCH_DECLARE(switch_status_t) kz_expand_api_execute(const char *cmd, const char *arg, switch_core_session_t *session, switch_stream_handle_t *stream) -{ - switch_api_interface_t *api; - switch_status_t status; - char *arg_used; - char *cmd_used; - - switch_assert(stream != NULL); - switch_assert(stream->data != NULL); - switch_assert(stream->write_function != NULL); - - cmd_used = switch_strip_whitespace(cmd); - arg_used = switch_strip_whitespace(arg); - - if (cmd_used && (api = switch_loadable_module_get_api_interface(cmd_used)) != 0) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG1, "executing [%s] => [%s]\n", cmd_used, arg_used); - if ((status = api->function(arg_used, session, stream)) != SWITCH_STATUS_SUCCESS) { - stream->write_function(stream, "COMMAND RETURNED ERROR!\n"); - } - UNPROTECT_INTERFACE(api); - } else { - status = SWITCH_STATUS_FALSE; - stream->write_function(stream, "INVALID COMMAND!\n"); - } - - if (cmd_used != cmd) { - switch_safe_free(cmd_used); - } - - if (arg_used != arg) { - switch_safe_free(arg_used); - } - - return status; -} - - -SWITCH_DECLARE(char *) kz_event_expand_headers_check(switch_event_t *event, const char *in, switch_event_t *var_list, switch_event_t *api_list, uint32_t recur) -{ - char *p, *c = NULL; - char *data, *indup, *endof_indup; - size_t sp = 0, len = 0, olen = 0, vtype = 0, br = 0, cpos, block = 128; - const char *sub_val = NULL; - char *cloned_sub_val = NULL, *expanded_sub_val = NULL; - char *func_val = NULL; - int nv = 0; - char *gvar = NULL, *sb = NULL; - - if (recur > 100) { - return (char *) in; - } - - if (zstr(in)) { - return (char *) in; - } - - nv = switch_string_var_check_const(in) || switch_string_has_escaped_data(in); - - if (!nv) { - return (char *) in; - } - - nv = 0; - olen = strlen(in) + 1; - indup = strdup(in); - switch_assert(indup); - endof_indup = end_of_p(indup) + 1; - - if ((data = malloc(olen))) { - memset(data, 0, olen); - c = data; - for (p = indup; p && p < endof_indup && *p; p++) { - int global = 0; - vtype = 0; - - if (*p == '\\') { - if (*(p + 1) == '$') { - nv = 1; - p++; - if (*(p + 1) == '$') { - p++; - } - } else if (*(p + 1) == '\'') { - p++; - continue; - } else if (*(p + 1) == '\\') { - if (len + 1 >= olen) { - kz_resize(1); - } - - *c++ = *p++; - len++; - continue; - } - } - - if (*p == '$' && !nv) { - if (*(p + 1) == '$') { - p++; - global++; - } - - if (*(p + 1)) { - if (*(p + 1) == '{') { - vtype = global ? 3 : 1; - } else { - nv = 1; - } - } else { - nv = 1; - } - } - - if (nv) { - if (len + 1 >= olen) { - kz_resize(1); - } - - *c++ = *p; - len++; - nv = 0; - continue; - } - - if (vtype) { - char *s = p, *e, *vname, *vval = NULL; - size_t nlen; - - s++; - - if ((vtype == 1 || vtype == 3) && *s == '{') { - br = 1; - s++; - } - - e = s; - vname = s; - while (*e) { - if (br == 1 && *e == '}') { - br = 0; - *e++ = '\0'; - break; - } - - if (br > 0) { - if (e != s && *e == '{') { - br++; - } else if (br > 1 && *e == '}') { - br--; - } - } - - e++; - } - p = e > endof_indup ? endof_indup : e; - - vval = NULL; - for(sb = vname; sb && *sb; sb++) { - if (*sb == ' ') { - vval = sb; - break; - } else if (*sb == '(') { - vval = sb; - br = 1; - break; - } - } - - if (vval) { - e = vval - 1; - *vval++ = '\0'; - - while (*e == ' ') { - *e-- = '\0'; - } - e = vval; - - while (e && *e) { - if (*e == '(') { - br++; - } else if (br > 1 && *e == ')') { - br--; - } else if (br == 1 && *e == ')') { - *e = '\0'; - break; - } - e++; - } - - vtype = 2; - } - - if (vtype == 1 || vtype == 3) { - char *expanded = NULL; - int offset = 0; - int ooffset = 0; - char *ptr; - int idx = -1; - - if ((expanded = kz_event_expand_headers_check(event, (char *) vname, var_list, api_list, recur+1)) == vname) { - expanded = NULL; - } else { - vname = expanded; - } - if ((ptr = strchr(vname, ':'))) { - *ptr++ = '\0'; - offset = atoi(ptr); - if ((ptr = strchr(ptr, ':'))) { - ptr++; - ooffset = atoi(ptr); - } - } - - if ((ptr = strchr(vname, '[')) && strchr(ptr, ']')) { - *ptr++ = '\0'; - idx = atoi(ptr); - } - - if (vtype == 3 || !(sub_val = switch_event_get_header_idx(event, vname, idx))) { - switch_safe_free(gvar); - if ((gvar = switch_core_get_variable_dup(vname))) { - sub_val = gvar; - } - - if (var_list && !switch_event_check_permission_list(var_list, vname)) { - sub_val = ""; - } - - - if ((expanded_sub_val = kz_event_expand_headers_check(event, sub_val, var_list, api_list, recur+1)) == sub_val) { - expanded_sub_val = NULL; - } else { - sub_val = expanded_sub_val; - } - } - - if (sub_val) { - if (offset || ooffset) { - cloned_sub_val = strdup(sub_val); - switch_assert(cloned_sub_val); - sub_val = cloned_sub_val; - } - - if (offset >= 0) { - sub_val += offset; - } else if ((size_t) abs(offset) <= strlen(sub_val)) { - sub_val = cloned_sub_val + (strlen(cloned_sub_val) + offset); - } - - if (ooffset > 0 && (size_t) ooffset < strlen(sub_val)) { - if ((ptr = (char *) sub_val + ooffset)) { - *ptr = '\0'; - } - } - } - - switch_safe_free(expanded); - } else { - char *expanded = NULL; - char *expanded_vname = NULL; - - if ((expanded_vname = kz_event_expand_headers_check(event, (char *) vname, var_list, api_list, recur+1)) == vname) { - expanded_vname = NULL; - } else { - vname = expanded_vname; - } - - if ((expanded = kz_event_expand_headers_check(event, vval, var_list, api_list, recur+1)) == vval) { - expanded = NULL; - } else { - vval = expanded; - } - - if (!switch_core_test_flag(SCF_API_EXPANSION) || (api_list && !switch_event_check_permission_list(api_list, vname))) { - func_val = NULL; - sub_val = ""; - } else { - switch_stream_handle_t stream = { 0 }; - - SWITCH_STANDARD_STREAM(stream); - stream.param_event = event; - if (kz_expand_api_execute(vname, vval, NULL, &stream) == SWITCH_STATUS_SUCCESS) { - func_val = stream.data; - sub_val = func_val; - } else { - free(stream.data); - } - } - - switch_safe_free(expanded); - switch_safe_free(expanded_vname); - } - if ((nlen = sub_val ? strlen(sub_val) : 0)) { - if (len + nlen >= olen) { - kz_resize(nlen); - } - - len += nlen; - strcat(c, sub_val); - c += nlen; - } - - switch_safe_free(func_val); - switch_safe_free(cloned_sub_val); - switch_safe_free(expanded_sub_val); - sub_val = NULL; - vname = NULL; - br = 0; - } - - if (sp) { - if (len + 1 >= olen) { - kz_resize(1); - } - - *c++ = ' '; - sp = 0; - len++; - } - - if (*p == '$') { - p--; - } else { - if (len + 1 >= olen) { - kz_resize(1); - } - - *c++ = *p; - len++; - } - } - } - free(indup); - switch_safe_free(gvar); - - return data; -} - -SWITCH_DECLARE(char *) kz_event_expand_headers(switch_event_t *event, const char *in) -{ - return kz_event_expand_headers_check(event, in, NULL, NULL, 0); -} - -SWITCH_DECLARE(char *) kz_event_expand_headers_pool(switch_memory_pool_t *pool, switch_event_t *event, char *val) -{ - char *expanded; - char *dup = NULL; - - expanded = kz_event_expand_headers(event, val); - dup = switch_core_strdup(pool, expanded); - - if (expanded != val) { - free(expanded); - } - - return dup; -} - -SWITCH_DECLARE(char *) kz_expand(const char *in, const char *uuid) -{ - switch_event_t *event = NULL; - char *ret = NULL; - kz_switch_core_base_headers_for_expand(&event); - if (uuid != NULL) { - switch_core_session_t *nsession = NULL; - if ((nsession = switch_core_session_locate(uuid))) { - switch_channel_event_set_data(switch_core_session_get_channel(nsession), event); - switch_core_session_rwunlock(nsession); - } - } - ret = kz_event_expand_headers_check(event, in, NULL, NULL, 0); - switch_event_destroy(&event); - return ret; -} - -SWITCH_DECLARE(char *) kz_expand_pool(switch_memory_pool_t *pool, const char *in) -{ - char *expanded; - char *dup = NULL; - - if(!(expanded = kz_expand(in, NULL))) { - return NULL; - } - dup = switch_core_strdup(pool, expanded); - - if (expanded != in) { - switch_safe_free(expanded); - } - - return dup; -} - -char* kz_switch_event_get_first_of(switch_event_t *event, const char *list[]) -{ - switch_event_header_t *header = NULL; - int i = 0; - while(list[i] != NULL) { - if((header = switch_event_get_header_ptr(event, list[i])) != NULL) - break; - i++; - } - if(header != NULL) { - return header->value; - } else { - return "nodomain"; - } -} - -SWITCH_DECLARE(switch_status_t) kz_switch_event_add_variable_name_printf(switch_event_t *event, switch_stack_t stack, const char *val, const char *fmt, ...) -{ - int ret = 0; - char *varname; - va_list ap; - switch_status_t status = SWITCH_STATUS_SUCCESS; - - switch_assert(event != NULL); - - - va_start(ap, fmt); - ret = switch_vasprintf(&varname, fmt, ap); - va_end(ap); - - if (ret == -1) { - return SWITCH_STATUS_MEMERR; - } - - status = switch_event_add_header_string(event, stack, varname, val); - - free(varname); - - return status; -} - -SWITCH_DECLARE(switch_status_t) kz_expand_json_to_event(cJSON *json, switch_event_t *event, char * prefix) -{ - char * fmt = switch_mprintf("%s%s%%s", prefix ? prefix : "", prefix ? "_" : ""); - if (event) { - cJSON *item = NULL; - char *response = NULL; - cJSON_ArrayForEach(item, json) { - if (item->type == cJSON_String) { - response = strdup(item->valuestring); - } else if (item->type == cJSON_Object) { - char * fmt1 = switch_mprintf(fmt, item->string); - kz_expand_json_to_event(item, event, fmt1); - switch_safe_free(fmt1); - continue; - } else { - response = cJSON_PrintUnformatted(item); - } - kz_switch_event_add_variable_name_printf(event, SWITCH_STACK_BOTTOM, response, fmt, item->string); - switch_safe_free(response); - } - } - - switch_safe_free(fmt); - return SWITCH_STATUS_SUCCESS; -} - -SWITCH_DECLARE(switch_xml_t) kz_xml_child(switch_xml_t xml, const char *name) -{ - xml = (xml) ? xml->child : NULL; - while (xml && strcasecmp(name, xml->name)) - xml = xml->sibling; - return xml; -} - -void kz_xml_process(switch_xml_t cfg) -{ - switch_xml_t xml_process; - for (xml_process = kz_xml_child(cfg, "X-PRE-PROCESS"); xml_process; xml_process = xml_process->next) { - const char *cmd = switch_xml_attr(xml_process, "cmd"); - const char *data = switch_xml_attr(xml_process, "data"); - if(cmd != NULL && !strcasecmp(cmd, "set") && data) { - char *name = (char *) data; - char *val = strchr(name, '='); - - if (val) { - char *ve = val++; - while (*val && *val == ' ') { - val++; - } - *ve-- = '\0'; - while (*ve && *ve == ' ') { - *ve-- = '\0'; - } - } - - if (name && val) { - switch_core_set_variable(name, val); - } - } - } - -} - -void kz_event_decode(switch_event_t *event) -{ - switch_event_header_t *hp; - int i; - for (hp = event->headers; hp; hp = hp->next) { - if (strncmp(hp->name, "_json_", 6)) { - if (hp->idx) { - for(i = 0; i < hp->idx; i++) { - switch_url_decode(hp->array[i]); - } - } else { - switch_url_decode(hp->value); - } - } - } -} - -void kz_expand_headers(switch_event_t *resolver, switch_event_t *event) { - switch_event_t *clone = NULL; - switch_event_header_t *header = NULL; - switch_event_create_plain(&clone, event->event_id); - - for(header = event->headers; header; header = header->next) { - char *expanded = kz_event_expand_headers(resolver, header->value); - if (expanded != header->value) { - switch_event_add_header_string(clone, SWITCH_STACK_BOTTOM, header->name, expanded); - switch_safe_free(expanded); - } - } - - /* we don't want to force unique headers - * so we delete and then merge - */ - for(header = clone->headers; header; header = header->next) { - switch_event_del_header(event, header->name); - } - - switch_event_merge(event, clone); - - switch_event_destroy(&clone); -} - -void kz_expand_headers_self(switch_event_t *event) { - kz_expand_headers(event, event); -} - -char * kz_expand_vars(char *xml_str) { - return kz_expand_vars_pool(xml_str, NULL); -} - -char * kz_expand_vars_pool(char *xml_str, switch_memory_pool_t *pool) { - char *var, *val; - char *rp = xml_str; /* read pointer */ - char *ep, *wp, *buff; /* end pointer, write pointer, write buffer */ - - if (!(strstr(xml_str, "$${"))) { - return xml_str; - } - - switch_zmalloc(buff, strlen(xml_str) * 2); - wp = buff; - ep = buff + (strlen(xml_str) * 2) - 1; - - while (*rp && wp < ep) { - if (*rp == '$' && *(rp + 1) == '$' && *(rp + 2) == '{') { - char *e = switch_find_end_paren(rp + 2, '{', '}'); - - if (e) { - rp += 3; - var = rp; - *e++ = '\0'; - rp = e; - - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "trying to expand %s \n", var); - if ((val = switch_core_get_variable_dup(var))) { - char *p; - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "expanded %s to %s\n", var, val); - for (p = val; p && *p && wp <= ep; p++) { - *wp++ = *p; - } - switch_safe_free(val); - } - continue; - } - } - - *wp++ = *rp++; - } - - *wp++ = '\0'; - - if(pool) { - char * ret = switch_core_strdup(pool, buff); - switch_safe_free(buff); - return ret; - } else { - switch_safe_free(xml_str); - return buff; - } - -} - -switch_status_t kz_json_api(const char * command, cJSON *args, cJSON **res) -{ - switch_status_t status = SWITCH_STATUS_SUCCESS; - cJSON *req = cJSON_CreateObject(); - cJSON_AddItemToObject(req, "command", cJSON_CreateString(command)); - cJSON_AddItemToObject(req, "data", args ? args : cJSON_CreateObject()); - status = switch_json_api_execute(req, NULL, res); - cJSON_Delete(req); - return status; -} - -/* For Emacs: - * Local Variables: - * mode:c - * indent-tabs-mode:t - * tab-width:4 - * c-basic-offset:4 - * End: - * For VIM: - * vim:set softtabstop=4 shiftwidth=4 tabstop=4: - */ diff --git a/src/mod/event_handlers/mod_kazoo/kazoo_utils.h b/src/mod/event_handlers/mod_kazoo/kazoo_utils.h deleted file mode 100644 index cb5549c7600..00000000000 --- a/src/mod/event_handlers/mod_kazoo/kazoo_utils.h +++ /dev/null @@ -1,51 +0,0 @@ -#pragma once - -#include - -#ifdef __cplusplus -#define KZ_BEGIN_EXTERN_C extern "C" { -#define KZ_END_EXTERN_C } -#else -#define KZ_BEGIN_EXTERN_C -#define KZ_END_EXTERN_C -#endif - -KZ_BEGIN_EXTERN_C - -void kz_check_set_profile_var(switch_channel_t *channel, char* var, char *val); - -SWITCH_DECLARE(switch_status_t) kz_switch_core_merge_variables(switch_event_t *event); - -SWITCH_DECLARE(switch_status_t) kz_switch_core_base_headers_for_expand(switch_event_t **event); - -SWITCH_DECLARE(switch_status_t) kz_expand_api_execute(const char *cmd, const char *arg, switch_core_session_t *session, switch_stream_handle_t *stream); - -SWITCH_DECLARE(char *) kz_event_expand_headers_check(switch_event_t *event, const char *in, switch_event_t *var_list, switch_event_t *api_list, uint32_t recur); - -SWITCH_DECLARE(char *) kz_event_expand_headers(switch_event_t *event, const char *in); - -SWITCH_DECLARE(char *) kz_event_expand_headers_pool(switch_memory_pool_t *pool, switch_event_t *event, char *val); - -SWITCH_DECLARE(char *) kz_expand(const char *in, const char *uuid); - -SWITCH_DECLARE(char *) kz_expand_pool(switch_memory_pool_t *pool, const char *in); - -char* kz_switch_event_get_first_of(switch_event_t *event, const char *list[]); - -SWITCH_DECLARE(switch_status_t) kz_switch_event_add_variable_name_printf(switch_event_t *event, switch_stack_t stack, const char *val, const char *fmt, ...); - -SWITCH_DECLARE(switch_xml_t) kz_xml_child(switch_xml_t xml, const char *name); - -void kz_xml_process(switch_xml_t cfg); -void kz_event_decode(switch_event_t *event); - -char * kz_expand_vars(char *xml_str); -void kz_expand_headers(switch_event_t *resolver, switch_event_t *event); -void kz_expand_headers_self(switch_event_t *event); - -char * kz_expand_vars_pool(char *xml_str, switch_memory_pool_t *pool); -switch_status_t kz_json_api(const char * command, cJSON *args, cJSON **res); - -SWITCH_DECLARE(switch_status_t) kz_expand_json_to_event(cJSON *json, switch_event_t *event, char * prefix); - -KZ_END_EXTERN_C diff --git a/src/mod/event_handlers/mod_kazoo/kz_node.c b/src/mod/event_handlers/mod_kazoo/kz_node.c deleted file mode 100644 index 1c50d0586e9..00000000000 --- a/src/mod/event_handlers/mod_kazoo/kz_node.c +++ /dev/null @@ -1,91 +0,0 @@ -#include "mod_kazoo.h" - -static int kz_nodes_module_names_array_callback(void *pArg, const char *module_name) -{ - cJSON *json = (cJSON *) pArg; - if(!strstr(module_name, "CORE")) { - cJSON_AddItemToArray(json, cJSON_CreateString(module_name)); - } - return 0; -} - -void kz_nodes_collect_media_role(cJSON *container) -{ - cJSON *retval = NULL; - if(kz_json_api("sofia.status.info", NULL, &retval) == SWITCH_STATUS_SUCCESS) { - if(retval != NULL && (!(retval->type & cJSON_NULL))) { - cJSON_AddItemToObject(container, "Media", cJSON_Duplicate(retval, 1)); - } - } - if(retval) { - cJSON_Delete(retval); - } -} - -void kz_nodes_collect_modules(cJSON *container) -{ - cJSON *modules = cJSON_CreateObject(); - cJSON *loaded = cJSON_CreateArray(); - cJSON *available = cJSON_CreateArray(); - switch_loadable_module_enumerate_available(SWITCH_GLOBAL_dirs.mod_dir, kz_nodes_module_names_array_callback, available); - switch_loadable_module_enumerate_loaded(kz_nodes_module_names_array_callback, loaded); - cJSON_AddItemToObject(modules, "available", available); - cJSON_AddItemToObject(modules, "loaded", loaded); - cJSON_AddItemToObject(container, "Modules", modules); -} - -void kz_nodes_collect_runtime(cJSON *container) -{ - cJSON *retval = NULL; - if(kz_json_api("status", NULL, &retval) == SWITCH_STATUS_SUCCESS) { - if(retval != NULL && (!(retval->type & cJSON_NULL))) { - cJSON *val = cJSON_Duplicate(retval, 1); - cJSON_AddItemToObject(val, "Core-UUID", cJSON_CreateString(switch_core_get_uuid())); - cJSON_AddItemToObject(container, "Runtime-Info", val); - } - } - if(retval) { - cJSON_Delete(retval); - } -} - -void kz_nodes_collect_apps(cJSON *container) -{ - cJSON *apps = cJSON_CreateObject(); - cJSON *app = cJSON_CreateObject(); - cJSON_AddItemToObject(app, "Uptime", cJSON_CreateNumber(switch_core_uptime())); - cJSON_AddItemToObject(apps, "freeswitch", app); - cJSON_AddItemToObject(container, "WhApps", apps); -} - -void kz_nodes_collect_roles(cJSON *container) -{ - cJSON *roles = cJSON_CreateObject(); - cJSON_AddItemToObject(container, "Roles", roles); - kz_nodes_collect_media_role(roles); -} - -cJSON * kz_node_create() -{ - cJSON *node = cJSON_CreateObject(); - - kz_nodes_collect_apps(node); - kz_nodes_collect_runtime(node); - kz_nodes_collect_modules(node); - kz_nodes_collect_roles(node); - - return node; -} - -SWITCH_STANDARD_JSON_API(kz_node_info_json_function) -{ - cJSON * ret = kz_node_create(); - *json_reply = ret; - return SWITCH_STATUS_SUCCESS; -} - -void add_kz_node(switch_loadable_module_interface_t **module_interface) -{ - switch_json_api_interface_t *json_api_interface = NULL; - SWITCH_ADD_JSON_API(json_api_interface, "node.info", "JSON node API", kz_node_info_json_function, ""); -} diff --git a/src/mod/event_handlers/mod_kazoo/mod_kazoo.c b/src/mod/event_handlers/mod_kazoo/mod_kazoo.c deleted file mode 100644 index 15b8fb469ce..00000000000 --- a/src/mod/event_handlers/mod_kazoo/mod_kazoo.c +++ /dev/null @@ -1,152 +0,0 @@ -/* - * FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application - * Copyright (C) 2005-2012, Anthony Minessale II - * - * 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 - * Portions created by the Initial Developer are Copyright (C) - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * - * Karl Anderson - * Darren Schreiber - * - * - * mod_kazoo.c -- Socket Controlled Event Handler - * - */ -#include "mod_kazoo.h" - -kz_globals_t kazoo_globals = {0}; - - - -SWITCH_MODULE_DEFINITION(mod_kazoo, mod_kazoo_load, mod_kazoo_shutdown, mod_kazoo_runtime); - -SWITCH_MODULE_LOAD_FUNCTION(mod_kazoo_load) -{ - kz_erl_init(); - - memset(&kazoo_globals, 0, sizeof(kazoo_globals)); - kazoo_globals.pool = pool; - kz_set_hostname(); - if(kazoo_load_config() != SWITCH_STATUS_SUCCESS) { - // TODO: what would we need to clean up here? - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Improper configuration!\n"); - return SWITCH_STATUS_TERM; - } - - /* connect my internal structure to the blank pointer passed to me */ - *module_interface = switch_loadable_module_create_module_interface(pool, modname); - - switch_thread_rwlock_create(&kazoo_globals.ei_nodes_lock, pool); - - switch_set_flag(&kazoo_globals, LFLAG_RUNNING); - - /* create all XML fetch agents */ - bind_fetch_agents(); - - /* create an api for cli debug commands */ - add_cli_api(module_interface); - - /* add our modified commands */ - add_kz_commands(module_interface); - - /* add our modified dptools */ - add_kz_dptools(module_interface); - - /* add our endpoints */ - add_kz_endpoints(module_interface); - - /* add our kz_node api */ - add_kz_node(module_interface); - - /* add tweaks */ - kz_tweaks_start(); - - /* add our cdr */ - kz_cdr_start(); - - /* indicate that the module should continue to be loaded */ - return SWITCH_STATUS_SUCCESS; -} - -SWITCH_MODULE_SHUTDOWN_FUNCTION(mod_kazoo_shutdown) { - int sanity = 0; - - remove_cli_api(); - - kz_cdr_stop(); - - kz_tweaks_stop(); - - /* stop taking new requests and start shuting down the threads */ - switch_clear_flag(&kazoo_globals, LFLAG_RUNNING); - - /* give everyone time to cleanly shutdown */ - while (switch_atomic_read(&kazoo_globals.threads)) { - switch_yield(100000); - if (++sanity >= 200) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Unable to kill all threads, continuing. This probably wont end well.....good luck!\n"); - break; - } - } - - /* close the connection to epmd and the acceptor */ - close_socketfd(&kazoo_globals.epmdfd); - close_socket(&kazoo_globals.acceptor); - - /* remove all XML fetch agents */ - unbind_fetch_agents(); - - if (kazoo_globals.event_filter) { - switch_core_hash_destroy(&kazoo_globals.event_filter); - } - - switch_thread_rwlock_wrlock(kazoo_globals.ei_nodes_lock); - switch_thread_rwlock_unlock(kazoo_globals.ei_nodes_lock); - switch_thread_rwlock_destroy(kazoo_globals.ei_nodes_lock); - - /* Close the port we reserved for uPnP/Switch behind firewall, if necessary */ - if (kazoo_globals.nat_map && switch_nat_get_type()) { - switch_nat_del_mapping(kazoo_globals.port, SWITCH_NAT_TCP); - } - - kazoo_destroy_config(); - - /* clean up our allocated preferences */ - switch_safe_free(kazoo_globals.ip); - switch_safe_free(kazoo_globals.ei_cookie); - switch_safe_free(kazoo_globals.ei_nodename); - - kz_erl_shutdown(); - - return SWITCH_STATUS_SUCCESS; -} - - -/* For Emacs: - * Local Variables: - * mode:c - * indent-tabs-mode:t - * tab-width:4 - * c-basic-offset:4 - * End: - * For VIM: - * vim:set softtabstop=4 shiftwidth=4 tabstop=4: - */ diff --git a/src/mod/event_handlers/mod_kazoo/mod_kazoo.h b/src/mod/event_handlers/mod_kazoo/mod_kazoo.h deleted file mode 100644 index 37fdd861e78..00000000000 --- a/src/mod/event_handlers/mod_kazoo/mod_kazoo.h +++ /dev/null @@ -1,87 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#define MAX_ACL 100 -#define CMD_BUFLEN 1024 * 1000 -#define MAX_QUEUE_LEN 25000 -#define MAX_MISSED 500 -#define MAX_PID_CHARS 255 - -extern const char kz_default_config[]; -extern const int kz_default_config_size; - -#include "kazoo_defs.h" -#include "kazoo_tweaks.h" -#include "kazoo_ei.h" -#include "kazoo_message.h" -#include "kazoo_utils.h" - -typedef enum { - LFLAG_RUNNING = (1 << 0) -} event_flag_t; - - -/* kazoo_commands.c */ -void add_kz_commands(switch_loadable_module_interface_t **module_interface); - -/* kazoo_dptools.c */ -void add_kz_dptools(switch_loadable_module_interface_t **module_interface); - -/* kazoo_api.c */ -void add_cli_api(switch_loadable_module_interface_t **module_interface); -void remove_cli_api(); - -/* kazoo_utils.c */ -/* -SWITCH_DECLARE(switch_status_t) kz_switch_core_merge_variables(switch_event_t *event); -SWITCH_DECLARE(switch_status_t) kz_switch_core_base_headers_for_expand(switch_event_t **event); -void kz_check_set_profile_var(switch_channel_t *channel, char* var, char *val); -char* kz_switch_event_get_first_of(switch_event_t *event, const char *list[]); -SWITCH_DECLARE(switch_status_t) kz_switch_event_add_variable_name_printf(switch_event_t *event, switch_stack_t stack, const char *val, const char *fmt, ...); -void kz_xml_process(switch_xml_t cfg); -void kz_event_decode(switch_event_t *event); -char * kz_expand_vars(char *xml_str); -char * kz_expand_vars_pool(char *xml_str, switch_memory_pool_t *pool); -SWITCH_DECLARE(char *) kz_event_expand_headers(switch_event_t *event, const char *in); -SWITCH_DECLARE(char *) kz_expand(const char *in); -SWITCH_DECLARE(char *) kz_expand_pool(switch_memory_pool_t *pool, const char *in); -switch_status_t kz_json_api(const char * command, cJSON *args, cJSON **res); -*/ - -/* kazoo_endpoints.c */ -void add_kz_endpoints(switch_loadable_module_interface_t **module_interface); - -/* kazoo_cdr.c */ -void kz_cdr_start(); -void kz_cdr_stop(); - -/* kazoo_tweaks.c */ -void kz_tweaks_start(); -void kz_tweaks_stop(); -SWITCH_DECLARE(const char *) kz_tweak_name(kz_tweak_t tweak); -SWITCH_DECLARE(switch_status_t) kz_name_tweak(const char *name, kz_tweak_t *type); - -/* kazoo_node.c */ -void add_kz_node(switch_loadable_module_interface_t **module_interface); - -SWITCH_MODULE_LOAD_FUNCTION(mod_kazoo_load); -SWITCH_MODULE_SHUTDOWN_FUNCTION(mod_kazoo_shutdown); - - -/* For Emacs: - * Local Variables: - * mode:c - * indent-tabs-mode:t - * tab-width:4 - * c-basic-offset:4 - * End: - * For VIM: - * vim:set softtabstop=4 shiftwidth=4 tabstop=4: - */ From 49029c8575891b4f3a637d43214d5df323760171 Mon Sep 17 00:00:00 2001 From: Jakub Karolczyk Date: Wed, 21 Feb 2024 01:47:45 +0000 Subject: [PATCH 12/56] [mod_sofia] Set missing CF_3PCC flag --- src/mod/endpoints/mod_sofia/sofia.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/mod/endpoints/mod_sofia/sofia.c b/src/mod/endpoints/mod_sofia/sofia.c index 311052a6198..43bd68b9237 100644 --- a/src/mod/endpoints/mod_sofia/sofia.c +++ b/src/mod/endpoints/mod_sofia/sofia.c @@ -7992,6 +7992,7 @@ static void sofia_handle_sip_i_state(switch_core_session_t *session, int status, switch_channel_hangup(channel, SWITCH_CAUSE_MANDATORY_IE_MISSING); } else { switch_channel_set_variable(channel, SWITCH_ENDPOINT_DISPOSITION_VARIABLE, "RECEIVED_NOSDP"); + switch_channel_set_flag(channel, CF_3PCC); switch_core_media_choose_port(tech_pvt->session, SWITCH_MEDIA_TYPE_AUDIO, 0); switch_core_media_prepare_codecs(session, 1); switch_channel_set_state(channel, CS_HIBERNATE); From d5ad504723a6bf80fbf80b3c35a2e14ab4111582 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Had=C5=BEem=20Had=C5=BEi=C4=87?= Date: Thu, 18 Apr 2024 11:06:40 +0200 Subject: [PATCH 13/56] [mod_vlc] Resolve double mutex lock --- src/mod/formats/mod_vlc/mod_vlc.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/mod/formats/mod_vlc/mod_vlc.c b/src/mod/formats/mod_vlc/mod_vlc.c index af83330d07d..6b725515f44 100644 --- a/src/mod/formats/mod_vlc/mod_vlc.c +++ b/src/mod/formats/mod_vlc/mod_vlc.c @@ -1096,7 +1096,8 @@ static switch_status_t vlc_file_read(switch_file_handle_t *handle, void *data, s switch_thread_cond_wait(context->cond, context->cond_mutex); status = libvlc_media_get_state(context->m); } - switch_mutex_lock(context->cond_mutex); + + switch_mutex_unlock(context->cond_mutex); if (context->err == 1) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "VLC error\n"); From ef32d90e91001c39ed261518db423868844a32fd Mon Sep 17 00:00:00 2001 From: Jakub Karolczyk Date: Fri, 26 Apr 2024 12:41:07 +0000 Subject: [PATCH 14/56] [mod_av] Fix scan-build 14 --- src/mod/applications/mod_av/avcodec.c | 1 - src/mod/applications/mod_av/avformat.c | 10 ++++------ 2 files changed, 4 insertions(+), 7 deletions(-) diff --git a/src/mod/applications/mod_av/avcodec.c b/src/mod/applications/mod_av/avcodec.c index 16d268273b2..4f0057264e2 100644 --- a/src/mod/applications/mod_av/avcodec.c +++ b/src/mod/applications/mod_av/avcodec.c @@ -1581,7 +1581,6 @@ GCC_DIAG_ON(deprecated-declarations) } else if (ret == AVERROR(EAGAIN)) { /* we fully drain all the output in each encode call, so this should not ever happen */ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG9, "Error sending frame to encoder - BUG, should never happen\n"); - ret = AVERROR_BUG; goto error; } else if (ret < 0) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Error sending frame to encoder\n"); diff --git a/src/mod/applications/mod_av/avformat.c b/src/mod/applications/mod_av/avformat.c index 69475c169f9..c1e00525300 100644 --- a/src/mod/applications/mod_av/avformat.c +++ b/src/mod/applications/mod_av/avformat.c @@ -1170,7 +1170,6 @@ GCC_DIAG_ON(deprecated-declarations) } else if (ret == AVERROR(EAGAIN)) { /* we fully drain all the output in each encode call, so this should not ever happen */ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG9, "Error sending frame to encoder on draining AVERROR_BUG - should never happen\n"); - ret = AVERROR_BUG; goto do_break; } else if (ret < 0) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG9, "Error sending frame to encoder on draining\n"); @@ -1426,7 +1425,7 @@ static switch_status_t open_input_file(av_file_context_t *context, switch_file_h av_dump_format(context->fc, 0, filename, 0); - for (i = 0; i< context->fc->nb_streams; i++) { + for (i = 0; i < context->fc->nb_streams; i++) { enum AVMediaType codec_type = av_get_codec_type(context->fc->streams[i]); if (codec_type == AVMEDIA_TYPE_AUDIO && context->has_audio < 2 && idx < 2) { @@ -1554,7 +1553,9 @@ static switch_status_t open_input_file(av_file_context_t *context, switch_file_h if (context->has_audio) { AVCodecContext *c[2] = { NULL }; - c[0] = av_get_codec_context(&context->audio_st[0]); + if (!(c[0] = av_get_codec_context(&context->audio_st[0]))) { + switch_goto_status(SWITCH_STATUS_FALSE, err); + } if ((cc = av_get_codec_context(&context->audio_st[1]))) { c[1] = cc; @@ -1568,9 +1569,7 @@ static switch_status_t open_input_file(av_file_context_t *context, switch_file_h if (c[1]) { context->audio_st[1].frame = av_frame_alloc(); switch_assert(context->audio_st[1].frame); - } - if (c[0] && c[1]) { context->audio_st[0].channels = 1; context->audio_st[1].channels = 1; } else { @@ -2016,7 +2015,6 @@ GCC_DIAG_ON(deprecated-declarations) } else if (dret == AVERROR(EAGAIN)) { /* we fully drain all the output in each decode call, so this should not ever happen */ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG9, "Error sending audio packet to decoder - BUG, should never happen\n"); - dret = AVERROR_BUG; goto do_continue; } else if (dret < 0) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG9, "Error sending audio packet to decoder\n"); From 597ee613de378c69abfdf4fe5133f29061d8ade7 Mon Sep 17 00:00:00 2001 From: Jakub Karolczyk Date: Fri, 26 Apr 2024 12:58:44 +0000 Subject: [PATCH 15/56] [mod_avmd] Fix scan-build 14 --- src/mod/applications/mod_avmd/mod_avmd.c | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/src/mod/applications/mod_avmd/mod_avmd.c b/src/mod/applications/mod_avmd/mod_avmd.c index e5076c15008..713f9158cd0 100644 --- a/src/mod/applications/mod_avmd/mod_avmd.c +++ b/src/mod/applications/mod_avmd/mod_avmd.c @@ -2130,9 +2130,7 @@ static enum avmd_detection_mode avmd_process_sample(avmd_session_t *s, circ_buff sma_buffer_t *sqa_amp_b = &buffer->sqa_amp_b; if (sample_to_skip_n > 0) { - sample_to_skip_n--; - valid_amplitude = 0; - valid_omega = 0; + return AVMD_DETECT_NONE; } @@ -2145,14 +2143,14 @@ static enum avmd_detection_mode avmd_process_sample(avmd_session_t *s, circ_buff RESET_SMA_BUFFER(sma_amp_b); RESET_SMA_BUFFER(sqa_amp_b); buffer->samples_streak_amp = s->settings.sample_n_continuous_streak_amp; - sample_to_skip_n = s->settings.sample_n_to_skip; } } else { if (ISINF(amplitude)) { amplitude = buffer->amplitude_max; } + if (valid_amplitude == 1) { - APPEND_SMA_VAL(sma_amp_b, amplitude); /* append amplitude */ + APPEND_SMA_VAL(sma_amp_b, amplitude); /* append amplitude */ APPEND_SMA_VAL(sqa_amp_b, amplitude * amplitude); if (s->settings.require_continuous_streak_amp == 1) { if (buffer->samples_streak_amp > 0) { @@ -2161,6 +2159,7 @@ static enum avmd_detection_mode avmd_process_sample(avmd_session_t *s, circ_buff } } } + if (sma_amp_b->sma > buffer->amplitude_max) { buffer->amplitude_max = sma_amp_b->sma; } @@ -2176,9 +2175,7 @@ static enum avmd_detection_mode avmd_process_sample(avmd_session_t *s, circ_buff RESET_SMA_BUFFER(sma_b_fir); RESET_SMA_BUFFER(sqa_b_fir); buffer->samples_streak = s->settings.sample_n_continuous_streak; - sample_to_skip_n = s->settings.sample_n_to_skip; } - sample_to_skip_n = s->settings.sample_n_to_skip; } else if (omega < -0.99999 || omega > 0.99999) { valid_omega = 0; if (s->settings.require_continuous_streak == 1) { @@ -2187,7 +2184,6 @@ static enum avmd_detection_mode avmd_process_sample(avmd_session_t *s, circ_buff RESET_SMA_BUFFER(sma_b_fir); RESET_SMA_BUFFER(sqa_b_fir); buffer->samples_streak = s->settings.sample_n_continuous_streak; - sample_to_skip_n = s->settings.sample_n_to_skip; } } else { if (valid_omega) { @@ -2216,20 +2212,26 @@ static enum avmd_detection_mode avmd_process_sample(avmd_session_t *s, circ_buff if (((mode == AVMD_DETECT_AMP) || (mode == AVMD_DETECT_BOTH)) && (valid_amplitude == 1)) { v_amp = sqa_amp_b->sma - (sma_amp_b->sma * sma_amp_b->sma); /* calculate variance of amplitude (biased estimator) */ if ((mode == AVMD_DETECT_AMP) && (avmd_decision_amplitude(s, buffer, v_amp, AVMD_AMPLITUDE_RSD_THRESHOLD) == 1)) { + return AVMD_DETECT_AMP; } } + if (((mode == AVMD_DETECT_FREQ) || (mode == AVMD_DETECT_BOTH)) && (valid_omega == 1)) { v_fir = sqa_b_fir->sma - (sma_b_fir->sma * sma_b_fir->sma); /* calculate variance of filtered samples */ if ((mode == AVMD_DETECT_FREQ) && (avmd_decision_freq(s, buffer, v_fir, AVMD_VARIANCE_RSD_THRESHOLD) == 1)) { + return AVMD_DETECT_FREQ; } + if (mode == AVMD_DETECT_BOTH) { - if ((avmd_decision_amplitude(s, buffer, v_amp, AVMD_AMPLITUDE_RSD_THRESHOLD) == 1) && (avmd_decision_freq(s, buffer, v_fir, AVMD_VARIANCE_RSD_THRESHOLD) == 1)) { + if ((avmd_decision_amplitude(s, buffer, v_amp, AVMD_AMPLITUDE_RSD_THRESHOLD) == 1) && (avmd_decision_freq(s, buffer, v_fir, AVMD_VARIANCE_RSD_THRESHOLD) == 1)) { + return AVMD_DETECT_BOTH; } } } + return AVMD_DETECT_NONE; } From 84ab90895ab53cbbf60f0f214f4ca2c025d085e7 Mon Sep 17 00:00:00 2001 From: Jakub Karolczyk Date: Fri, 26 Apr 2024 13:11:54 +0000 Subject: [PATCH 16/56] [mod_amrwb] Fix scan-build 14 --- src/mod/codecs/mod_amrwb/amrwb_be.c | 6 +++--- src/mod/codecs/mod_amrwb/mod_amrwb.c | 8 ++++++-- 2 files changed, 9 insertions(+), 5 deletions(-) diff --git a/src/mod/codecs/mod_amrwb/amrwb_be.c b/src/mod/codecs/mod_amrwb/amrwb_be.c index 7b43b2b5837..e8f45cf7d74 100644 --- a/src/mod/codecs/mod_amrwb/amrwb_be.c +++ b/src/mod/codecs/mod_amrwb/amrwb_be.c @@ -95,23 +95,23 @@ extern switch_bool_t switch_amrwb_pack_be(unsigned char *shift_buf, int n) extern switch_bool_t switch_amrwb_unpack_be(unsigned char *encoded_buf, uint8_t *tmp, int encoded_len) { - int framesz, index, ft; + int framesz, index; uint8_t shift_tocs[2] = {0x00, 0x00}; uint8_t *shift_buf; memcpy(shift_tocs, encoded_buf, 2); /* shift for BE */ switch_amr_array_lshift(4, shift_tocs, 2); - ft = shift_tocs[0] >> 3; - ft &= ~(1 << 5); /* Frame Type*/ shift_buf = encoded_buf + 1; /* skip CMR */ /* shift for BE */ switch_amr_array_lshift(2, shift_buf, encoded_len - 1); /* get frame size */ index = ((shift_tocs[0] >> 3) & 0x0f); if (index > 10 && index != 0xe && index != 0xf) { + return SWITCH_FALSE; } + framesz = switch_amrwb_frame_sizes[index]; tmp[0] = shift_tocs[0]; /* save TOC */ memcpy(&tmp[1], shift_buf, framesz); diff --git a/src/mod/codecs/mod_amrwb/mod_amrwb.c b/src/mod/codecs/mod_amrwb/mod_amrwb.c index 4ac3f25f37a..d89ec5d62bb 100644 --- a/src/mod/codecs/mod_amrwb/mod_amrwb.c +++ b/src/mod/codecs/mod_amrwb/mod_amrwb.c @@ -191,6 +191,7 @@ static switch_status_t switch_amrwb_init(switch_codec_t *codec, switch_codec_fla if (codec->fmtp_in) { codec->fmtp_out = switch_core_strdup(codec->memory_pool, codec->fmtp_in); } + return SWITCH_STATUS_SUCCESS; #else struct amrwb_context *context = NULL; @@ -204,6 +205,7 @@ static switch_status_t switch_amrwb_init(switch_codec_t *codec, switch_codec_fla decoding = (flags & SWITCH_CODEC_FLAG_DECODE); if (!(encoding || decoding) || (!(context = switch_core_alloc(codec->memory_pool, sizeof(struct amrwb_context))))) { + return SWITCH_STATUS_FALSE; } else { @@ -296,6 +298,7 @@ static switch_status_t switch_amrwb_init(switch_codec_t *codec, switch_codec_fla /* re-create mode-set */ fmtptmp_pos = switch_snprintf(fmtptmp, sizeof(fmtptmp), "mode-set="); + for (i = 0; SWITCH_AMRWB_MODES-1 > i; ++i) { if (context->enc_modes & (1 << i)) { fmtptmp_pos += switch_snprintf(fmtptmp + fmtptmp_pos, sizeof(fmtptmp) - fmtptmp_pos, fmtptmp_pos > strlen("mode-set=") ? ",%d" : "%d", i); @@ -312,12 +315,13 @@ static switch_status_t switch_amrwb_init(switch_codec_t *codec, switch_codec_fla } if (!globals.volte) { - fmtptmp_pos += switch_snprintf(fmtptmp + fmtptmp_pos, sizeof(fmtptmp) - fmtptmp_pos, ";octet-align=%d", + switch_snprintf(fmtptmp + fmtptmp_pos, sizeof(fmtptmp) - fmtptmp_pos, ";octet-align=%d", switch_test_flag(context, AMRWB_OPT_OCTET_ALIGN) ? 1 : 0); } else { - fmtptmp_pos += switch_snprintf(fmtptmp + fmtptmp_pos, sizeof(fmtptmp) - fmtptmp_pos, ";octet-align=%d;max-red=0;mode-change-capability=2", + switch_snprintf(fmtptmp + fmtptmp_pos, sizeof(fmtptmp) - fmtptmp_pos, ";octet-align=%d;max-red=0;mode-change-capability=2", switch_test_flag(context, AMRWB_OPT_OCTET_ALIGN) ? 1 : 0); } + codec->fmtp_out = switch_core_strdup(codec->memory_pool, fmtptmp); context->encoder_state = NULL; From 91cc40d17038c4f9d5df6fbaa6f155f8b652258e Mon Sep 17 00:00:00 2001 From: Andrey Volk Date: Tue, 7 May 2024 10:24:07 +0300 Subject: [PATCH 17/56] [support-d] Add deadlock.py to tree. --- support-d/gdb/README.md | 76 ++++++ support-d/gdb/deadlock.py | 474 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 550 insertions(+) create mode 100644 support-d/gdb/README.md create mode 100644 support-d/gdb/deadlock.py diff --git a/support-d/gdb/README.md b/support-d/gdb/README.md new file mode 100644 index 00000000000..d3d198c5b5f --- /dev/null +++ b/support-d/gdb/README.md @@ -0,0 +1,76 @@ +`gdb` scripts +----------- + +Originally from: https://github.com/facebook/folly/tree/593b6e76881042031b7f21d898c8e0874ea79fe0/folly/experimental/gdb + +This directory contains a collection of `gdb` scripts that we have found helpful. +These scripts use the [gdb extension Python API](https://sourceware.org/gdb/current/onlinedocs/gdb/Python.html#Python). + +### How to run the scripts + +To run the scripts, fire up `gdb` and load a script with `source -v`. Example: + +```lang=bash +$ gdb -p 123456 +(gdb) source -v ./folly/experimental/gdb/deadlock.py +Type "deadlock" to detect deadlocks. +# At this point, any new commands defined in `deadlock.py` are available. +(gdb) deadlock +Found deadlock! +... +``` + +### What does each script do? + +#### `deadlock.py` - Detect deadlocks + +Consider the following program that always deadlocks: + +```lang=cpp +void deadlock3() { + std::mutex m1, m2, m3; + folly::Baton<> b1, b2, b3; + + auto t1 = std::thread([&m1, &m2, &b1, &b2] { + std::lock_guard g1(m1); + b1.post(); + b2.wait(); + std::lock_guard g2(m2); + }); + + auto t2 = std::thread([&m3, &m2, &b3, &b2] { + std::lock_guard g2(m2); + b2.post(); + b3.wait(); + std::lock_guard g3(m3); + }); + + auto t3 = std::thread([&m3, &m1, &b3, &b1] { + std::lock_guard g3(m3); + b3.post(); + b1.wait(); + std::lock_guard g1(m1); + }); + + t1.join(); + t2.join(); + t3.join(); +} +``` + +The `deadlock.py` script introduces a new `deadlock` command that can help +us identify the threads and mutexes involved with the deadlock. + +```lang=bash +$ gdb -p 2174496 +(gdb) source -v ./folly/experimental/gdb/deadlock.py +Type "deadlock" to detect deadlocks. +(gdb) deadlock +Found deadlock! +Thread 2 (LWP 2174497) is waiting on mutex (0x00007ffcff42a4c0) held by Thread 3 (LWP 2174498) +Thread 3 (LWP 2174498) is waiting on mutex (0x00007ffcff42a4f0) held by Thread 4 (LWP 2174499) +Thread 4 (LWP 2174499) is waiting on mutex (0x00007ffcff42a490) held by Thread 2 (LWP 2174497) +``` + +NOTE: This script only works on Linux and requires debug symbols to be installed +for the `pthread` library. diff --git a/support-d/gdb/deadlock.py b/support-d/gdb/deadlock.py new file mode 100644 index 00000000000..feeae0713fe --- /dev/null +++ b/support-d/gdb/deadlock.py @@ -0,0 +1,474 @@ +#!/usr/bin/env python3 +# Copyright (c) Meta Platforms, Inc. and affiliates. +# +# Licensed under the Apache License, Version 2.0 (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.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import re +from collections import defaultdict +from enum import Enum + +import gdb + + +class DiGraph: + """ + Adapted from networkx: http://networkx.github.io/ + Represents a directed graph. Edges can store (key, value) attributes. + """ + + def __init__(self): + # Map of node -> set of nodes + self.adjacency_map = {} + # Map of (node1, node2) -> map string -> arbitrary attribute + # This will not be copied in subgraph() + self.attributes_map = {} + + def neighbors(self, node): + return self.adjacency_map.get(node, set()) + + def edges(self): + edges = [] + for node, neighbors in self.adjacency_map.items(): + for neighbor in neighbors: + edges.append((node, neighbor)) + return edges + + def nodes(self): + return self.adjacency_map.keys() + + def attributes(self, node1, node2): + return self.attributes_map[(node1, node2)] + + def add_edge(self, node1, node2, **kwargs): + if node1 not in self.adjacency_map: + self.adjacency_map[node1] = set() + if node2 not in self.adjacency_map: + self.adjacency_map[node2] = set() + self.adjacency_map[node1].add(node2) + self.attributes_map[(node1, node2)] = kwargs + + def remove_node(self, node): + self.adjacency_map.pop(node, None) + for _, neighbors in self.adjacency_map.items(): + neighbors.discard(node) + + def subgraph(self, nodes): + graph = DiGraph() + for node in nodes: + for neighbor in self.neighbors(node): + if neighbor in nodes: + graph.add_edge(node, neighbor) + return graph + + def node_link_data(self): + """ + Returns the graph as a dictionary in a format that can be + serialized. + """ + data = { + "directed": True, + "multigraph": False, + "graph": {}, + "links": [], + "nodes": [], + } + + # Do one pass to build a map of node -> position in nodes + node_to_number = {} + for node in self.adjacency_map.keys(): + node_to_number[node] = len(data["nodes"]) + data["nodes"].append({"id": node}) + + # Do another pass to build the link information + for node, neighbors in self.adjacency_map.items(): + for neighbor in neighbors: + link = self.attributes_map[(node, neighbor)].copy() + link["source"] = node_to_number[node] + link["target"] = node_to_number[neighbor] + data["links"].append(link) + return data + + +def strongly_connected_components(G): # noqa: C901 + """ + Adapted from networkx: http://networkx.github.io/ + Parameters + ---------- + G : DiGraph + Returns + ------- + comp : generator of sets + A generator of sets of nodes, one for each strongly connected + component of G. + """ + preorder = {} + lowlink = {} + scc_found = {} + scc_queue = [] + i = 0 # Preorder counter + for source in G.nodes(): + if source not in scc_found: + queue = [source] + while queue: + v = queue[-1] + if v not in preorder: + i = i + 1 + preorder[v] = i + done = 1 + v_nbrs = G.neighbors(v) + for w in v_nbrs: + if w not in preorder: + queue.append(w) + done = 0 + break + if done == 1: + lowlink[v] = preorder[v] + for w in v_nbrs: + if w not in scc_found: + if preorder[w] > preorder[v]: + lowlink[v] = min([lowlink[v], lowlink[w]]) + else: + lowlink[v] = min([lowlink[v], preorder[w]]) + queue.pop() + if lowlink[v] == preorder[v]: + scc_found[v] = True + scc = {v} + while scc_queue and preorder[scc_queue[-1]] > preorder[v]: + k = scc_queue.pop() + scc_found[k] = True + scc.add(k) + yield scc + else: + scc_queue.append(v) + + +def simple_cycles(G): # noqa: C901 + """ + Adapted from networkx: http://networkx.github.io/ + Parameters + ---------- + G : DiGraph + Returns + ------- + cycle_generator: generator + A generator that produces elementary cycles of the graph. + Each cycle is represented by a list of nodes along the cycle. + """ + + def _unblock(thisnode, blocked, B): + stack = {thisnode} + while stack: + node = stack.pop() + if node in blocked: + blocked.remove(node) + stack.update(B[node]) + B[node].clear() + + # Johnson's algorithm requires some ordering of the nodes. + # We assign the arbitrary ordering given by the strongly connected comps + # There is no need to track the ordering as each node removed as processed. + # save the actual graph so we can mutate it here + # We only take the edges because we do not want to + # copy edge and node attributes here. + subG = G.subgraph(G.nodes()) + sccs = list(strongly_connected_components(subG)) + while sccs: + scc = sccs.pop() + # order of scc determines ordering of nodes + startnode = scc.pop() + # Processing node runs 'circuit' routine from recursive version + path = [startnode] + blocked = set() # vertex: blocked from search? + closed = set() # nodes involved in a cycle + blocked.add(startnode) + B = defaultdict(set) # graph portions that yield no elementary circuit + stack = [(startnode, list(subG.neighbors(startnode)))] + while stack: + thisnode, nbrs = stack[-1] + if nbrs: + nextnode = nbrs.pop() + if nextnode == startnode: + yield path[:] + closed.update(path) + elif nextnode not in blocked: + path.append(nextnode) + stack.append((nextnode, list(subG.neighbors(nextnode)))) + closed.discard(nextnode) + blocked.add(nextnode) + continue + # done with nextnode... look for more neighbors + if not nbrs: # no more nbrs + if thisnode in closed: + _unblock(thisnode, blocked, B) + else: + for nbr in subG.neighbors(thisnode): + if thisnode not in B[nbr]: + B[nbr].add(thisnode) + stack.pop() + path.pop() + # done processing this node + subG.remove_node(startnode) + H = subG.subgraph(scc) # make smaller to avoid work in SCC routine + sccs.extend(list(strongly_connected_components(H))) + + +def find_cycle(graph): + """ + Looks for a cycle in the graph. If found, returns the first cycle. + If nodes a1, a2, ..., an are in a cycle, then this returns: + [(a1,a2), (a2,a3), ... (an-1,an), (an, a1)] + Otherwise returns an empty list. + """ + cycles = list(simple_cycles(graph)) + if cycles: + nodes = cycles[0] + nodes.append(nodes[0]) + edges = [] + prev = nodes[0] + for node in nodes[1:]: + edges.append((prev, node)) + prev = node + return edges + else: + return [] + + +def get_stacktrace(thread_id): + """ + Returns the stack trace for the thread id as a list of strings. + """ + gdb.execute("thread %d" % thread_id, from_tty=False, to_string=True) + output = gdb.execute("bt", from_tty=False, to_string=True) + stacktrace_lines = output.strip().split("\n") + return stacktrace_lines + + +def is_thread_blocked_with_frame( + thread_id, top_line, expected_top_lines, expected_frame +): + """ + Returns True if we found expected_top_line in top_line, and + we found the expected_frame in the thread's stack trace. + """ + if all(expected not in top_line for expected in expected_top_lines): + return False + stacktrace_lines = get_stacktrace(thread_id) + return any(expected_frame in line for line in stacktrace_lines) + + +class MutexType(Enum): + """Types of mutexes that we can detect deadlocks.""" + + PTHREAD_MUTEX_T = "pthread_mutex_t" + PTHREAD_RWLOCK_T = "pthread_rwlock_t" + + @staticmethod + def get_mutex_type(thread_id, top_line): + """ + Returns the probable mutex type, based on the first line + of the thread's stack. Returns None if not found. + """ + + WAITLIST = [ + "__lll_lock_wait", + "futex_abstimed_wait", + "futex_abstimed_wait_cancelable", + "futex_reltimed_wait", + "futex_reltimed_wait_cancelable", + "futex_wait", + "futex_wait_cancelable", + ] + + if is_thread_blocked_with_frame(thread_id, top_line, WAITLIST, "pthread_mutex"): + return MutexType.PTHREAD_MUTEX_T + if is_thread_blocked_with_frame( + thread_id, top_line, WAITLIST, "pthread_rwlock" + ): + return MutexType.PTHREAD_RWLOCK_T + return None + + @staticmethod + def get_mutex_owner_and_address_func_for_type(mutex_type): + """ + Returns a function to resolve the mutex owner and address for + the given type. The returned function f has the following + signature: + + f: args: (map of thread lwp -> thread id), blocked thread lwp + returns: (lwp of thread owning mutex, mutex address) + or (None, None) if not found. + + Returns None if there is no function for this mutex_type. + """ + if mutex_type == MutexType.PTHREAD_MUTEX_T: + return get_pthread_mutex_t_owner_and_address + if mutex_type == MutexType.PTHREAD_RWLOCK_T: + return get_pthread_rwlock_t_owner_and_address + return None + + +def print_cycle(graph, lwp_to_thread_id, cycle): + """Prints the threads and mutexes involved in the deadlock.""" + for m, n in cycle: + print( + "Thread %d (LWP %d) is waiting on %s (0x%016x) held by " + "Thread %d (LWP %d)" + % ( + lwp_to_thread_id[m], + m, + graph.attributes(m, n)["mutex_type"].value, + graph.attributes(m, n)["mutex"], + lwp_to_thread_id[n], + n, + ) + ) + + +def get_thread_info(): + """ + Returns a pair of: + - map of LWP -> thread ID + - map of blocked threads LWP -> potential mutex type + """ + # LWP -> thread ID + lwp_to_thread_id = {} + + # LWP -> potential mutex type it is blocked on + blocked_threads = {} + + output = gdb.execute("info threads", from_tty=False, to_string=True) + lines = output.strip().split("\n")[1:] + regex = re.compile(r"[\s\*]*(\d+).*Thread.*\(LWP (\d+)\).*") + for line in lines: + try: + thread_id = int(regex.match(line).group(1)) + thread_lwp = int(regex.match(line).group(2)) + lwp_to_thread_id[thread_lwp] = thread_id + mutex_type = MutexType.get_mutex_type(thread_id, line) + if mutex_type: + blocked_threads[thread_lwp] = mutex_type + except Exception: + continue + + return (lwp_to_thread_id, blocked_threads) + + +def get_pthread_mutex_t_owner_and_address(lwp_to_thread_id, thread_lwp): + """ + Finds the thread holding the mutex that this thread is blocked on. + Returns a pair of (lwp of thread owning mutex, mutex address), + or (None, None) if not found. + """ + # Go up the stack to the pthread_mutex_lock frame + gdb.execute( + "thread %d" % lwp_to_thread_id[thread_lwp], from_tty=False, to_string=True + ) + gdb.execute("frame 1", from_tty=False, to_string=True) + + # Get the owner of the mutex by inspecting the internal + # fields of the mutex. + try: + mutex_info = gdb.parse_and_eval("mutex").dereference() + mutex_owner_lwp = int(mutex_info["__data"]["__owner"]) + return (mutex_owner_lwp, int(mutex_info.address)) + except gdb.error: + return (None, None) + + +def get_pthread_rwlock_t_owner_and_address(lwp_to_thread_id, thread_lwp): + """ + If the thread is waiting on a write-locked pthread_rwlock_t, this will + return the pair of: + (lwp of thread that is write-owning the mutex, mutex address) + or (None, None) if not found, or if the mutex is read-locked. + """ + # Go up the stack to the pthread_rwlock_{rd|wr}lock frame + gdb.execute( + "thread %d" % lwp_to_thread_id[thread_lwp], from_tty=False, to_string=True + ) + gdb.execute("frame 2", from_tty=False, to_string=True) + + # Get the owner of the mutex by inspecting the internal + # fields of the mutex. + try: + rwlock_info = gdb.parse_and_eval("rwlock").dereference() + rwlock_data = rwlock_info["__data"] + field_names = ["__cur_writer", "__writer"] + fields = rwlock_data.type.fields() + field = [f for f in fields if f.name in field_names][0] + rwlock_owner_lwp = int(rwlock_data[field]) + # We can only track the owner if it is currently write-locked. + # If it is not write-locked or if it is currently read-locked, + # possibly by multiple threads, we cannot find the owner. + if rwlock_owner_lwp != 0: + return (rwlock_owner_lwp, int(rwlock_info.address)) + else: + return (None, None) + except gdb.error: + return (None, None) + + +class Deadlock(gdb.Command): + """Detects deadlocks""" + + def __init__(self): + super(Deadlock, self).__init__("deadlock", gdb.COMMAND_NONE) + + def invoke(self, arg, from_tty): + """Prints the threads and mutexes in a deadlock, if it exists.""" + lwp_to_thread_id, blocked_threads = get_thread_info() + + # Nodes represent threads. Edge (A,B) exists if thread A + # is waiting on a mutex held by thread B. + graph = DiGraph() + + # Go through all the blocked threads and see which threads + # they are blocked on, and build the thread wait graph. + for thread_lwp, mutex_type in blocked_threads.items(): + get_owner_and_address_func = ( + MutexType.get_mutex_owner_and_address_func_for_type(mutex_type) + ) + if not get_owner_and_address_func: + continue + mutex_owner_lwp, mutex_address = get_owner_and_address_func( + lwp_to_thread_id, thread_lwp + ) + if mutex_owner_lwp and mutex_address: + graph.add_edge( + thread_lwp, + mutex_owner_lwp, + mutex=mutex_address, + mutex_type=mutex_type, + ) + + # A deadlock exists if there is a cycle in the graph. + cycle = find_cycle(graph) + if cycle: + print("Found deadlock!") + print_cycle(graph, lwp_to_thread_id, cycle) + else: + print("No deadlock detected. " "Do you have debug symbols installed?") + + +def load(): + # instantiate the Deadlock command + Deadlock() + print('Type "deadlock" to detect deadlocks.') + + +def info(): + return "Detect deadlocks" + + +if __name__ == "__main__": + load() From 5b1c2688da6ffcddad4b54bb97408d8325ffa7b9 Mon Sep 17 00:00:00 2001 From: Andrey Volk Date: Tue, 30 Apr 2024 21:14:29 +0300 Subject: [PATCH 18/56] [Core, mod_sofia] Add switch_uint31_t type. Fix CSeq bigger than 2^31-1. --- src/include/switch_types.h | 4 ++++ src/mod/endpoints/mod_sofia/mod_sofia.h | 2 +- src/mod/endpoints/mod_sofia/sofia_presence.c | 19 +++++++++---------- tests/unit/switch_core.c | 20 ++++++++++++++++++++ 4 files changed, 34 insertions(+), 11 deletions(-) diff --git a/src/include/switch_types.h b/src/include/switch_types.h index d315e46fc8c..f8ae00790d9 100644 --- a/src/include/switch_types.h +++ b/src/include/switch_types.h @@ -255,6 +255,10 @@ SWITCH_BEGIN_EXTERN_C typedef uint8_t switch_byte_t; +typedef struct { + unsigned int value : 31; +} switch_uint31_t; + typedef enum { SWITCH_PVT_PRIMARY = 0, SWITCH_PVT_SECONDARY diff --git a/src/mod/endpoints/mod_sofia/mod_sofia.h b/src/mod/endpoints/mod_sofia/mod_sofia.h index bfd682c1f17..8e2b1b483cd 100644 --- a/src/mod/endpoints/mod_sofia/mod_sofia.h +++ b/src/mod/endpoints/mod_sofia/mod_sofia.h @@ -776,7 +776,7 @@ struct sofia_profile { int watchdog_enabled; switch_mutex_t *gw_mutex; uint32_t queued_events; - uint32_t last_cseq; + switch_uint31_t last_cseq; int tls_only; int tls_verify_date; enum tport_tls_verify_policy tls_verify_policy; diff --git a/src/mod/endpoints/mod_sofia/sofia_presence.c b/src/mod/endpoints/mod_sofia/sofia_presence.c index 579cea83e28..48ad5794111 100644 --- a/src/mod/endpoints/mod_sofia/sofia_presence.c +++ b/src/mod/endpoints/mod_sofia/sofia_presence.c @@ -2112,12 +2112,12 @@ static int sofia_dialog_probe_callback(void *pArg, int argc, char **argv, char * #define SOFIA_PRESENCE_COLLISION_DELTA 50 #define SOFIA_PRESENCE_ROLLOVER_YEAR (86400 * 365 * SOFIA_PRESENCE_COLLISION_DELTA) -static uint32_t check_presence_epoch(void) +static switch_uint31_t check_presence_epoch(void) { time_t now = switch_epoch_time_now(NULL); - uint32_t callsequence = (uint32_t)((now - mod_sofia_globals.presence_epoch) * SOFIA_PRESENCE_COLLISION_DELTA); + switch_uint31_t callsequence = { .value = (uint32_t)((now - mod_sofia_globals.presence_epoch) * SOFIA_PRESENCE_COLLISION_DELTA) }; - if (!mod_sofia_globals.presence_year || callsequence >= SOFIA_PRESENCE_ROLLOVER_YEAR) { + if (!mod_sofia_globals.presence_year || callsequence.value >= SOFIA_PRESENCE_ROLLOVER_YEAR) { struct tm tm; switch_mutex_lock(mod_sofia_globals.mutex); tm = *(localtime(&now)); @@ -2125,7 +2125,7 @@ static uint32_t check_presence_epoch(void) if (tm.tm_year != mod_sofia_globals.presence_year) { mod_sofia_globals.presence_epoch = (uint32_t)now - (tm.tm_yday * 86400) - (tm.tm_hour * 60 * 60) - (tm.tm_min * 60) - tm.tm_sec; mod_sofia_globals.presence_year = tm.tm_year; - callsequence = (uint32_t)(((uint32_t)now - mod_sofia_globals.presence_epoch) * SOFIA_PRESENCE_COLLISION_DELTA); + callsequence.value = (uint32_t)(((uint32_t)now - mod_sofia_globals.presence_epoch) * SOFIA_PRESENCE_COLLISION_DELTA); } switch_mutex_unlock(mod_sofia_globals.mutex); @@ -2136,17 +2136,17 @@ static uint32_t check_presence_epoch(void) uint32_t sofia_presence_get_cseq(sofia_profile_t *profile) { - uint32_t callsequence; + switch_uint31_t callsequence; int diff = 0; switch_mutex_lock(profile->ireg_mutex); callsequence = check_presence_epoch(); - if (profile->last_cseq) { - diff = callsequence - profile->last_cseq; + if (profile->last_cseq.value) { + diff = (int)callsequence.value - (int)profile->last_cseq.value; if (diff <= 0 && diff > -100000) { - callsequence = ++profile->last_cseq; + callsequence.value = ++profile->last_cseq.value; } } @@ -2154,8 +2154,7 @@ uint32_t sofia_presence_get_cseq(sofia_profile_t *profile) switch_mutex_unlock(profile->ireg_mutex); - return callsequence; - + return (uint32_t)callsequence.value; } diff --git a/tests/unit/switch_core.c b/tests/unit/switch_core.c index 1159017571e..2f06966582f 100644 --- a/tests/unit/switch_core.c +++ b/tests/unit/switch_core.c @@ -53,6 +53,26 @@ FST_CORE_BEGIN("./conf") } FST_TEARDOWN_END() + FST_TEST_BEGIN(test_switch_uint31_t_overflow) + { + switch_uint31_t x; + uint32_t overflow; + + x.value = 0x7fffffff; + x.value++; + + fst_check_int_equals(x.value, 0); + x.value++; + fst_check_int_equals(x.value, 1); + x.value -= 2; + fst_check_int_equals(x.value, 0x7fffffff); + + overflow = (uint32_t)0x7fffffff + 1; + x.value = overflow; + fst_check_int_equals(x.value, 0); + } + FST_TEST_END() + FST_TEST_BEGIN(test_switch_parse_cidr_v6) { ip_t ip, mask; From 681c61ad3203d3a560f85f548feb136cb93c57e1 Mon Sep 17 00:00:00 2001 From: Jakub Karolczyk Date: Sun, 19 May 2024 16:18:53 +0100 Subject: [PATCH 19/56] [libvpx] Fix scan-build 14 --- libs/libvpx/vp9/encoder/vp9_subexp.c | 3 +++ libs/libvpx/vpx_scale/generic/vpx_scale.c | 2 ++ libs/libvpx/vpx_scale/vpx_scale.h | 2 ++ 3 files changed, 7 insertions(+) diff --git a/libs/libvpx/vp9/encoder/vp9_subexp.c b/libs/libvpx/vp9/encoder/vp9_subexp.c index cf17fcdfcec..b5a23906628 100644 --- a/libs/libvpx/vp9/encoder/vp9_subexp.c +++ b/libs/libvpx/vp9/encoder/vp9_subexp.c @@ -64,6 +64,9 @@ static int remap_prob(int v, int m) { 228, 229, 17, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 18, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 19, }; + + assert(m > 0); + v--; m--; if ((m << 1) <= MAX_PROB) diff --git a/libs/libvpx/vpx_scale/generic/vpx_scale.c b/libs/libvpx/vpx_scale/generic/vpx_scale.c index 958bb320fc4..e20905e9ce3 100644 --- a/libs/libvpx/vpx_scale/generic/vpx_scale.c +++ b/libs/libvpx/vpx_scale/generic/vpx_scale.c @@ -167,6 +167,8 @@ static void scale1d_c(const unsigned char *source, int source_step, (void)source_length; + assert(dest_scale); + /* These asserts are needed if there are boundary issues... */ /*assert ( dest_scale > source_scale );*/ /*assert ( (source_length-1) * dest_scale >= (dest_length-1) * source_scale diff --git a/libs/libvpx/vpx_scale/vpx_scale.h b/libs/libvpx/vpx_scale/vpx_scale.h index fd5ba7ccdc1..96edb7af20d 100644 --- a/libs/libvpx/vpx_scale/vpx_scale.h +++ b/libs/libvpx/vpx_scale/vpx_scale.h @@ -11,6 +11,8 @@ #ifndef VPX_VPX_SCALE_VPX_SCALE_H_ #define VPX_VPX_SCALE_VPX_SCALE_H_ +#include + #include "vpx_scale/yv12config.h" extern void vpx_scale_frame(YV12_BUFFER_CONFIG *src, YV12_BUFFER_CONFIG *dst, From 85400015b7eed420f49bfde85cd08acc44f48b28 Mon Sep 17 00:00:00 2001 From: Andrey Volk Date: Wed, 1 Jun 2022 00:09:48 +0300 Subject: [PATCH 20/56] [Core] VAD: Add a math sanity check to the switch_vad_process --- src/switch_vad.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/switch_vad.c b/src/switch_vad.c index 6118c0237e5..74d131331b7 100644 --- a/src/switch_vad.c +++ b/src/switch_vad.c @@ -206,7 +206,9 @@ SWITCH_DECLARE(switch_vad_state_t) switch_vad_process(switch_vad_t *vad, int16_t j += vad->channels; } - score = (uint32_t) (energy / (samples / vad->divisor)); + if (samples && vad->divisor && samples >= vad->divisor) { + score = (uint32_t)(energy / (samples / vad->divisor)); + } #ifdef SWITCH_HAVE_FVAD } #endif From 41bc763d800a9fef127d238e88a797470b1256f9 Mon Sep 17 00:00:00 2001 From: Jakub Karolczyk Date: Mon, 13 May 2024 12:25:47 +0100 Subject: [PATCH 21/56] [core] Fix scan-build 14 in port allocator --- src/switch_core_port_allocator.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/switch_core_port_allocator.c b/src/switch_core_port_allocator.c index 3bbed2a351c..074ce5f5ea5 100644 --- a/src/switch_core_port_allocator.c +++ b/src/switch_core_port_allocator.c @@ -150,7 +150,7 @@ SWITCH_DECLARE(switch_status_t) switch_core_port_allocator_request_port(switch_c switch_mutex_lock(alloc->mutex); srand((unsigned) ((unsigned) (intptr_t) port_ptr + (unsigned) (intptr_t) switch_thread_self() + switch_micro_time_now())); - while (alloc->track_used < alloc->track_len) { + while (alloc->track_len && alloc->track_used < alloc->track_len) { uint32_t index; uint32_t tries = 0; From 72eef5681fc03a4405eab26545ff09953a999094 Mon Sep 17 00:00:00 2001 From: Andrey Volk Date: Mon, 14 Aug 2023 18:14:28 +0300 Subject: [PATCH 22/56] [CI] Enable scan build 14 on Drone CI --- .drone.yml | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/.drone.yml b/.drone.yml index 07ccb34f27e..63838cfb73d 100644 --- a/.drone.yml +++ b/.drone.yml @@ -97,13 +97,14 @@ name: scan-build steps: - name: bootstrap - image: signalwire/freeswitch-public-base:bullseye + image: signalwire/freeswitch-public-base:bookworm pull: always commands: + - apt-get update && apt-get -yq install autoconf - ./bootstrap.sh -j - name: configure - image: signalwire/freeswitch-public-base:bullseye + image: signalwire/freeswitch-public-base:bookworm pull: always environment: REPOTOKEN: @@ -140,7 +141,7 @@ steps: - ./configure - name: scan-build - image: signalwire/freeswitch-public-base:bullseye + image: signalwire/freeswitch-public-base:bookworm pull: always environment: REPOTOKEN: @@ -152,7 +153,7 @@ steps: - export REPOTOKEN='' - rm -rf /etc/apt/auth.conf - mkdir -p scan-build - - echo '#!/bin/bash\nscan-build-11 -o ./scan-build/ make -j`nproc --all` |& tee ./scan-build-result.txt\nexitstatus=$${PIPESTATUS[0]}\necho $$exitstatus > ./scan-build-status.txt\n' > scan.sh + - echo '#!/bin/bash\nscan-build-14 --force-analyze-debug-code -o ./scan-build/ make -j`nproc --all` |& tee ./scan-build-result.txt\nexitstatus=$${PIPESTATUS[0]}\necho $$exitstatus > ./scan-build-status.txt\n' > scan.sh - chmod +x scan.sh - ./scan.sh - exitstatus=`cat ./scan-build-status.txt` @@ -178,6 +179,6 @@ trigger: --- kind: signature -hmac: 780e4aaee61e3683ea4a8d6fe5131f7c9e62ebad727546013f18df0fca80d705 +hmac: 7e5f6cafc88da0be59243daf47a2a5607ff00b45f441ce4c1041d4b690e8a853 ... From a92c1e4c4739cd9b0f7a456c5baf045df3dc4066 Mon Sep 17 00:00:00 2001 From: Andrey Volk Date: Thu, 7 Mar 2024 21:41:54 +0300 Subject: [PATCH 23/56] [Build-System] Fix crashing MSI packaging on Windows when Visual Studio 2022 is used. --- .gitignore | 2 +- w32/Setup/Setup.2017.wixproj | 7 +++++++ 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index 0461c273de0..135473c8dfe 100644 --- a/.gitignore +++ b/.gitignore @@ -187,7 +187,7 @@ ipch/ /w32/Setup/obj *dSYM* -/UpgradeLog.* +/UpgradeLog*.* /_UpgradeReport_Files/ *.aps /w32/Library/switch_version.inc diff --git a/w32/Setup/Setup.2017.wixproj b/w32/Setup/Setup.2017.wixproj index dd745e8438a..bf0aae04984 100644 --- a/w32/Setup/Setup.2017.wixproj +++ b/w32/Setup/Setup.2017.wixproj @@ -1032,6 +1032,7 @@ SuppressRegistry="true" SuppressCom="true" SuppressFragments="true" + RunAsSeparateProcess="true" PreprocessorVariable="var.FreeSWITCHConfFilesDir"> From c7e793c345218158df4feda7326f5925da6cccab Mon Sep 17 00:00:00 2001 From: Andrey Volk Date: Thu, 6 Jun 2024 21:05:33 +0300 Subject: [PATCH 24/56] [Core] Add new switch_rand() a compliant random number generator API. Add a unit-test. * [Core] Add new switch_rand() a compliant random number generator API. Add a unit-test. * Fall back to rand() on unsupported platforms compile time. --- src/include/switch_utils.h | 5 ++++ src/switch_utils.c | 57 ++++++++++++++++++++++++++++++++++++++ tests/unit/switch_core.c | 21 ++++++++++++++ 3 files changed, 83 insertions(+) diff --git a/src/include/switch_utils.h b/src/include/switch_utils.h index 1d33939f4c3..a0c91e6384f 100644 --- a/src/include/switch_utils.h +++ b/src/include/switch_utils.h @@ -1514,6 +1514,11 @@ SWITCH_DECLARE(switch_status_t) switch_digest_string(const char *digest_name, ch SWITCH_DECLARE(char *) switch_must_strdup(const char *_s); SWITCH_DECLARE(const char *) switch_memory_usage_stream(switch_stream_handle_t *stream); +/** +/ Compliant random number generator. Returns the value between 0 and 0x7fff (RAND_MAX). +**/ +SWITCH_DECLARE(int) switch_rand(void); + SWITCH_END_EXTERN_C #endif /* For Emacs: diff --git a/src/switch_utils.c b/src/switch_utils.c index faffc1cc048..25d0bf76eef 100644 --- a/src/switch_utils.c +++ b/src/switch_utils.c @@ -4811,6 +4811,63 @@ SWITCH_DECLARE(const char *) switch_memory_usage_stream(switch_stream_handle_t * return status; } +SWITCH_DECLARE(int) switch_rand(void) +{ + uint32_t random_number = 0; +#ifdef WIN32 + BCRYPT_ALG_HANDLE hAlgorithm = NULL; + NTSTATUS status = BCryptOpenAlgorithmProvider(&hAlgorithm, BCRYPT_RNG_ALGORITHM, NULL, 0); + + if (!BCRYPT_SUCCESS(status)) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "BCryptOpenAlgorithmProvider failed with status %d\n", status); + + return 1; + } + + status = BCryptGenRandom(hAlgorithm, (PUCHAR)&random_number, sizeof(random_number), 0); + if (!BCRYPT_SUCCESS(status)) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "BCryptGenRandom failed with status %d\n", status); + + return 1; + } + + BCryptCloseAlgorithmProvider(hAlgorithm, 0); + + /* Make sure we return from 0 to RAND_MAX */ + return (random_number & 0x7FFF); +#elif defined(__unix__) || defined(__APPLE__) + int random_fd = open("/dev/urandom", O_RDONLY); + ssize_t result; + char error_msg[100]; + + if (random_fd == -1) { + strncpy(error_msg, strerror(errno), sizeof(error_msg) - 1); + error_msg[sizeof(error_msg) - 1] = '\0'; + + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "open failed: %s\n", error_msg); + + return 1; + } + + result = read(random_fd, &random_number, sizeof(random_number)); + if (result < 0) { + strncpy(error_msg, strerror(errno), sizeof(error_msg) - 1); + error_msg[sizeof(error_msg) - 1] = '\0'; + + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "read failed: %s\n", error_msg); + + return 1; + } + + close(random_fd); + + /* Make sure we return from 0 to RAND_MAX */ + return (random_number & 0x7FFF); +#else + return rand(); +#endif +} + /* For Emacs: * Local Variables: * mode:c diff --git a/tests/unit/switch_core.c b/tests/unit/switch_core.c index 2f06966582f..295e4e0ff15 100644 --- a/tests/unit/switch_core.c +++ b/tests/unit/switch_core.c @@ -53,6 +53,27 @@ FST_CORE_BEGIN("./conf") } FST_TEARDOWN_END() + FST_TEST_BEGIN(test_switch_rand) + { + int i, c = 0; + + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "\nLet's generate a few random numbers.\n"); + + for (i = 0; i < 10; i++) { + uint32_t rnd = switch_rand(); + + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Random number %d\n", rnd); + + if (rnd == 1) { + c++; + } + } + + /* We do not expect all random numbers to be 1 all 10 times. That would mean we have an error OR we are lucky to have 10 random ones! */ + fst_check(c < 10); + } + FST_TEST_END() + FST_TEST_BEGIN(test_switch_uint31_t_overflow) { switch_uint31_t x; From 3b65e271164006affd327d2f42e39d76ac97c32d Mon Sep 17 00:00:00 2001 From: Andrey Volk Date: Thu, 16 May 2024 23:48:28 +0300 Subject: [PATCH 25/56] [mod_av] Fix use of switch_size_t in fs_rtp_parse_h263_rfc2190(). --- src/mod/applications/mod_av/avcodec.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/mod/applications/mod_av/avcodec.c b/src/mod/applications/mod_av/avcodec.c index 4f0057264e2..0293b834467 100644 --- a/src/mod/applications/mod_av/avcodec.c +++ b/src/mod/applications/mod_av/avcodec.c @@ -906,7 +906,7 @@ static void fs_rtp_parse_h263_rfc2190(h264_codec_context_t *context, AVPacket *p #if (LIBAVCODEC_VERSION_MAJOR < LIBAVCODEC_V) switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Should Not Happen!!! mb_info_pos=%d mb_info_count=%d mb_info_size=%d\n", mb_info_pos, mb_info_count, mb_info_size); #else - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Should Not Happen!!! mb_info_pos=%d mb_info_count=%d mb_info_size=%ld\n", mb_info_pos, mb_info_count, mb_info_size); + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Should Not Happen!!! mb_info_pos=%d mb_info_count=%d mb_info_size=%"SWITCH_SIZE_T_FMT"\n", mb_info_pos, mb_info_count, mb_info_size); #endif } } From 0c8b5987f04ac3753ebb0d8680f30512d3593776 Mon Sep 17 00:00:00 2001 From: Andrey Volk Date: Fri, 17 May 2024 16:44:51 +0300 Subject: [PATCH 26/56] [mod_fsv] Fix use of 2gb of memory. Fix compiler warnings preventing builds on Bookworm. --- src/mod/applications/mod_fsv/mod_fsv.c | 32 ++++++++++++++++---------- 1 file changed, 20 insertions(+), 12 deletions(-) diff --git a/src/mod/applications/mod_fsv/mod_fsv.c b/src/mod/applications/mod_fsv/mod_fsv.c index 90d64972ad6..37f413d6b2e 100644 --- a/src/mod/applications/mod_fsv/mod_fsv.c +++ b/src/mod/applications/mod_fsv/mod_fsv.c @@ -40,6 +40,11 @@ SWITCH_MODULE_DEFINITION(mod_fsv, mod_fsv_load, NULL, NULL); #define VID_BIT (1 << 31) #define VERSION 4202 +typedef struct fsv_video_data_s { + uint32_t size; + uint8_t data[]; +} fsv_video_data_t; + struct file_header { int32_t version; char video_codec_name[32]; @@ -983,15 +988,16 @@ static switch_status_t fsv_file_read(switch_file_handle_t *handle, void *data, s } if (size & VID_BIT) { /* video */ - uint8_t *video_data = malloc(sizeof(size) + size); + fsv_video_data_t *video_data; switch_size_t read_size; - switch_assert(video_data); size &= ~VID_BIT; + video_data = malloc(sizeof(fsv_video_data_t) + size); + switch_assert(video_data); read_size = size; - *(uint32_t *)video_data = size; + video_data->size = size; - status = switch_file_read(context->fd, video_data + sizeof(size), &read_size); + status = switch_file_read(context->fd, video_data->data, &read_size); if (status != SWITCH_STATUS_SUCCESS || read_size != size) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, @@ -1033,7 +1039,7 @@ static switch_status_t fsv_file_read_video(switch_file_handle_t *handle, switch_ fsv_file_context *context = handle->private_info; switch_image_t *dup = NULL; switch_status_t status = SWITCH_STATUS_SUCCESS; - void *video_packet = NULL; + fsv_video_data_t *video_packet = NULL; switch_time_t start = switch_time_now(); switch_status_t decode_status = SWITCH_STATUS_MORE_DATA; int new_img = 0; @@ -1047,8 +1053,9 @@ static switch_status_t fsv_file_read_video(switch_file_handle_t *handle, switch_ switch_rtp_hdr_t *rtp; while (1) { + video_packet = NULL; switch_mutex_lock(context->mutex); - status = switch_queue_trypop(context->video_queue, &video_packet); + status = switch_queue_trypop(context->video_queue, (void**)&video_packet); switch_mutex_unlock(context->mutex); if (status != SWITCH_STATUS_SUCCESS || !video_packet) { @@ -1065,13 +1072,13 @@ static switch_status_t fsv_file_read_video(switch_file_handle_t *handle, switch_ break; } - size = *(uint32_t *)video_packet; + size = video_packet->size; if (size > sizeof(context->video_packet_buffer)) { free(video_packet); return SWITCH_STATUS_BREAK; } - memcpy(context->video_packet_buffer, (uint8_t *)video_packet + sizeof(uint32_t), size); + memcpy(context->video_packet_buffer, video_packet->data, size); free(video_packet); video_packet = NULL; @@ -1093,14 +1100,15 @@ static switch_status_t fsv_file_read_video(switch_file_handle_t *handle, switch_ uint32_t size; switch_rtp_hdr_t *rtp; - switch_mutex_lock(context->mutex); - status = switch_queue_trypop(context->video_queue, &video_packet); + video_packet = NULL; + switch_mutex_lock(context->mutex); + status = switch_queue_trypop(context->video_queue, (void**)&video_packet); switch_mutex_unlock(context->mutex); if (status != SWITCH_STATUS_SUCCESS || !video_packet) break; - size = *(uint32_t *)video_packet; - rtp = (switch_rtp_hdr_t *)((uint8_t *)video_packet + sizeof(uint32_t)); + size = video_packet->size; + rtp = (switch_rtp_hdr_t *)(video_packet->data); rtp_frame.packet = rtp; rtp_frame.packetlen = size; From 9f362ea3154501b93b276b82c7a3aa44d7111cfb Mon Sep 17 00:00:00 2001 From: Andrey Volk Date: Fri, 7 Jun 2024 16:07:15 +0300 Subject: [PATCH 27/56] [Core] Better handle error cases in switch_rand(). --- src/switch_utils.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/switch_utils.c b/src/switch_utils.c index 25d0bf76eef..64577d3997d 100644 --- a/src/switch_utils.c +++ b/src/switch_utils.c @@ -4828,6 +4828,8 @@ SWITCH_DECLARE(int) switch_rand(void) if (!BCRYPT_SUCCESS(status)) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "BCryptGenRandom failed with status %d\n", status); + BCryptCloseAlgorithmProvider(hAlgorithm, 0); + return 1; } @@ -4856,6 +4858,8 @@ SWITCH_DECLARE(int) switch_rand(void) switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "read failed: %s\n", error_msg); + close(random_fd); + return 1; } From 74f386bf94a3b793c466a14c71f267daa7fd96d2 Mon Sep 17 00:00:00 2001 From: Andrey Volk Date: Mon, 10 Jun 2024 15:48:30 +0000 Subject: [PATCH 28/56] swigall --- .../languages/mod_managed/freeswitch_wrap.cxx | 50 ++++++++++++ src/mod/languages/mod_managed/managed/swig.cs | 78 +++++++++++++++++++ 2 files changed, 128 insertions(+) diff --git a/src/mod/languages/mod_managed/freeswitch_wrap.cxx b/src/mod/languages/mod_managed/freeswitch_wrap.cxx index bba26c8f9ba..7cec120fbe9 100644 --- a/src/mod/languages/mod_managed/freeswitch_wrap.cxx +++ b/src/mod/languages/mod_managed/freeswitch_wrap.cxx @@ -2129,6 +2129,46 @@ SWIGEXPORT int SWIGSTDCALL CSharp_FreeSWITCHfNative_LOST_BURST_CAPTURE_get___() } +SWIGEXPORT void SWIGSTDCALL CSharp_FreeSWITCHfNative_switch_uint31_t_value_set___(void * jarg1, unsigned int jarg2) { + switch_uint31_t *arg1 = (switch_uint31_t *) 0 ; + unsigned int arg2 ; + + arg1 = (switch_uint31_t *)jarg1; + arg2 = (unsigned int)jarg2; + if (arg1) (arg1)->value = arg2; +} + + +SWIGEXPORT unsigned int SWIGSTDCALL CSharp_FreeSWITCHfNative_switch_uint31_t_value_get___(void * jarg1) { + unsigned int jresult ; + switch_uint31_t *arg1 = (switch_uint31_t *) 0 ; + unsigned int result; + + arg1 = (switch_uint31_t *)jarg1; + result = (unsigned int) ((arg1)->value); + jresult = result; + return jresult; +} + + +SWIGEXPORT void * SWIGSTDCALL CSharp_FreeSWITCHfNative_new_switch_uint31_t___() { + void * jresult ; + switch_uint31_t *result = 0 ; + + result = (switch_uint31_t *)new switch_uint31_t(); + jresult = (void *)result; + return jresult; +} + + +SWIGEXPORT void SWIGSTDCALL CSharp_FreeSWITCHfNative_delete_switch_uint31_t___(void * jarg1) { + switch_uint31_t *arg1 = (switch_uint31_t *) 0 ; + + arg1 = (switch_uint31_t *)jarg1; + delete arg1; +} + + SWIGEXPORT void SWIGSTDCALL CSharp_FreeSWITCHfNative_switch_dtmf_t_digit_set___(void * jarg1, char jarg2) { switch_dtmf_t *arg1 = (switch_dtmf_t *) 0 ; char arg2 ; @@ -23521,6 +23561,16 @@ SWIGEXPORT char * SWIGSTDCALL CSharp_FreeSWITCHfNative_switch_memory_usage_strea } +SWIGEXPORT int SWIGSTDCALL CSharp_FreeSWITCHfNative_switch_rand___() { + int jresult ; + int result; + + result = (int)switch_rand(); + jresult = result; + return jresult; +} + + SWIGEXPORT void SWIGSTDCALL CSharp_FreeSWITCHfNative_profile_node_t_var_set___(void * jarg1, char * jarg2) { profile_node_s *arg1 = (profile_node_s *) 0 ; char *arg2 = (char *) 0 ; diff --git a/src/mod/languages/mod_managed/managed/swig.cs b/src/mod/languages/mod_managed/managed/swig.cs index dc3926cbbb6..6ca27764cf2 100644 --- a/src/mod/languages/mod_managed/managed/swig.cs +++ b/src/mod/languages/mod_managed/managed/swig.cs @@ -11585,6 +11585,11 @@ public static string switch_memory_usage_stream(switch_stream_handle stream) { return ret; } + public static int switch_rand() { + int ret = freeswitchPINVOKE.switch_rand(); + return ret; + } + public static switch_caller_extension switch_caller_extension_new(SWIGTYPE_p_switch_core_session session, string extension_name, string extension_number) { global::System.IntPtr cPtr = freeswitchPINVOKE.switch_caller_extension_new(SWIGTYPE_p_switch_core_session.getCPtr(session), extension_name, extension_number); switch_caller_extension ret = (cPtr == global::System.IntPtr.Zero) ? null : new switch_caller_extension(cPtr, false); @@ -15975,6 +15980,18 @@ static SWIGStringHelper() { [global::System.Runtime.InteropServices.DllImport("mod_managed", EntryPoint="CSharp_FreeSWITCHfNative_LOST_BURST_CAPTURE_get___")] public static extern int LOST_BURST_CAPTURE_get(); + [global::System.Runtime.InteropServices.DllImport("mod_managed", EntryPoint="CSharp_FreeSWITCHfNative_switch_uint31_t_value_set___")] + public static extern void switch_uint31_t_value_set(global::System.Runtime.InteropServices.HandleRef jarg1, uint jarg2); + + [global::System.Runtime.InteropServices.DllImport("mod_managed", EntryPoint="CSharp_FreeSWITCHfNative_switch_uint31_t_value_get___")] + public static extern uint switch_uint31_t_value_get(global::System.Runtime.InteropServices.HandleRef jarg1); + + [global::System.Runtime.InteropServices.DllImport("mod_managed", EntryPoint="CSharp_FreeSWITCHfNative_new_switch_uint31_t___")] + public static extern global::System.IntPtr new_switch_uint31_t(); + + [global::System.Runtime.InteropServices.DllImport("mod_managed", EntryPoint="CSharp_FreeSWITCHfNative_delete_switch_uint31_t___")] + public static extern void delete_switch_uint31_t(global::System.Runtime.InteropServices.HandleRef jarg1); + [global::System.Runtime.InteropServices.DllImport("mod_managed", EntryPoint="CSharp_FreeSWITCHfNative_switch_dtmf_t_digit_set___")] public static extern void switch_dtmf_t_digit_set(global::System.Runtime.InteropServices.HandleRef jarg1, char jarg2); @@ -21099,6 +21116,9 @@ static SWIGStringHelper() { [global::System.Runtime.InteropServices.DllImport("mod_managed", EntryPoint="CSharp_FreeSWITCHfNative_switch_memory_usage_stream___")] public static extern string switch_memory_usage_stream(global::System.Runtime.InteropServices.HandleRef jarg1); + [global::System.Runtime.InteropServices.DllImport("mod_managed", EntryPoint="CSharp_FreeSWITCHfNative_switch_rand___")] + public static extern int switch_rand(); + [global::System.Runtime.InteropServices.DllImport("mod_managed", EntryPoint="CSharp_FreeSWITCHfNative_profile_node_t_var_set___")] public static extern void profile_node_t_var_set(global::System.Runtime.InteropServices.HandleRef jarg1, string jarg2); @@ -47333,6 +47353,64 @@ public switch_timer_interface() : this(freeswitchPINVOKE.new_switch_timer_interf namespace FreeSWITCH.Native { +public class switch_uint31_t : global::System.IDisposable { + private global::System.Runtime.InteropServices.HandleRef swigCPtr; + protected bool swigCMemOwn; + + internal switch_uint31_t(global::System.IntPtr cPtr, bool cMemoryOwn) { + swigCMemOwn = cMemoryOwn; + swigCPtr = new global::System.Runtime.InteropServices.HandleRef(this, cPtr); + } + + internal static global::System.Runtime.InteropServices.HandleRef getCPtr(switch_uint31_t obj) { + return (obj == null) ? new global::System.Runtime.InteropServices.HandleRef(null, global::System.IntPtr.Zero) : obj.swigCPtr; + } + + ~switch_uint31_t() { + Dispose(); + } + + public virtual void Dispose() { + lock(this) { + if (swigCPtr.Handle != global::System.IntPtr.Zero) { + if (swigCMemOwn) { + swigCMemOwn = false; + freeswitchPINVOKE.delete_switch_uint31_t(swigCPtr); + } + swigCPtr = new global::System.Runtime.InteropServices.HandleRef(null, global::System.IntPtr.Zero); + } + global::System.GC.SuppressFinalize(this); + } + } + + public uint value { + set { + freeswitchPINVOKE.switch_uint31_t_value_set(swigCPtr, value); + } + get { + uint ret = freeswitchPINVOKE.switch_uint31_t_value_get(swigCPtr); + return ret; + } + } + + public switch_uint31_t() : this(freeswitchPINVOKE.new_switch_uint31_t(), true) { + } + +} + +} +//------------------------------------------------------------------------------ +// +// +// This file was automatically generated by SWIG (http://www.swig.org). +// Version 3.0.12 +// +// Do not make changes to this file unless you know what you are doing--modify +// the SWIG interface file instead. +//------------------------------------------------------------------------------ + +namespace FreeSWITCH.Native { + public class switch_unicast_conninfo : global::System.IDisposable { private global::System.Runtime.InteropServices.HandleRef swigCPtr; protected bool swigCMemOwn; From 8224bb8e65bd876ead46b21db57ccf09a7478404 Mon Sep 17 00:00:00 2001 From: Andrey Volk Date: Sat, 11 May 2024 12:37:32 +0300 Subject: [PATCH 29/56] [Build-System] Add ARM64 support, extend Debian helper scripts. Co-authored-by: s3rj1k --- debian/bootstrap.sh | 63 +++++++++++++++++---------------- debian/util.sh | 48 ++++++++++++++++++------- debian/version-omit_revision.pl | 22 ++++++++++++ 3 files changed, 91 insertions(+), 42 deletions(-) create mode 100755 debian/version-omit_revision.pl diff --git a/debian/bootstrap.sh b/debian/bootstrap.sh index aba9e38bf70..fa407029385 100755 --- a/debian/bootstrap.sh +++ b/debian/bootstrap.sh @@ -65,6 +65,9 @@ avoid_mods=( avoid_mods_armhf=( languages/mod_v8 ) +avoid_mods_arm64=( + languages/mod_v8 +) avoid_mods_sid=( directories/mod_ldap ) @@ -352,7 +355,7 @@ EOF print_core_control () { cat <= 1.13.17) Recommends: Suggests: libfreeswitch1-dbg @@ -385,7 +388,7 @@ Description: Cross-Platform Scalable Multi-Protocol Soft Switch Package: python-esl Section: python -Architecture: amd64 armhf +Architecture: amd64 armhf arm64 Depends: \${shlibs:Depends}, \${misc:Depends}, \${python:Depends} Description: Cross-Platform Scalable Multi-Protocol Soft Switch $(debian_wrap "${fs_description}") @@ -394,7 +397,7 @@ Description: Cross-Platform Scalable Multi-Protocol Soft Switch Package: libesl-perl Section: perl -Architecture: amd64 armhf +Architecture: amd64 armhf arm64 Depends: \${shlibs:Depends}, \${misc:Depends}, \${perl:Depends} Description: Cross-Platform Scalable Multi-Protocol Soft Switch $(debian_wrap "${fs_description}") @@ -402,7 +405,7 @@ Description: Cross-Platform Scalable Multi-Protocol Soft Switch This package contains the Perl binding for FreeSWITCH Event Socket Library (ESL). Package: freeswitch-meta-bare -Architecture: amd64 armhf +Architecture: amd64 armhf arm64 Depends: \${misc:Depends}, freeswitch (= \${binary:Version}) Recommends: freeswitch-doc (= \${binary:Version}), @@ -420,7 +423,7 @@ Description: Cross-Platform Scalable Multi-Protocol Soft Switch bare FreeSWITCH install. Package: freeswitch-meta-default -Architecture: amd64 armhf +Architecture: amd64 armhf arm64 Depends: \${misc:Depends}, freeswitch (= \${binary:Version}), freeswitch-mod-commands (= \${binary:Version}), freeswitch-mod-conference (= \${binary:Version}), @@ -462,7 +465,7 @@ Description: Cross-Platform Scalable Multi-Protocol Soft Switch reasonably basic FreeSWITCH install. Package: freeswitch-meta-vanilla -Architecture: amd64 armhf +Architecture: amd64 armhf arm64 Depends: \${misc:Depends}, freeswitch (= \${binary:Version}), freeswitch-init, freeswitch-mod-console (= \${binary:Version}), @@ -511,7 +514,7 @@ Description: Cross-Platform Scalable Multi-Protocol Soft Switch running the FreeSWITCH vanilla example configuration. Package: freeswitch-meta-sorbet -Architecture: amd64 armhf +Architecture: amd64 armhf arm64 Depends: \${misc:Depends}, freeswitch (= \${binary:Version}), Recommends: freeswitch-init, @@ -594,7 +597,7 @@ Description: Cross-Platform Scalable Multi-Protocol Soft Switch modules except a few which aren't recommended. Package: freeswitch-meta-all -Architecture: amd64 armhf +Architecture: amd64 armhf arm64 Depends: \${misc:Depends}, freeswitch (= \${binary:Version}), freeswitch-init, freeswitch-lang (= \${binary:Version}), @@ -705,7 +708,7 @@ Description: Cross-Platform Scalable Multi-Protocol Soft Switch FreeSWITCH modules. Package: freeswitch-meta-codecs -Architecture: amd64 armhf +Architecture: amd64 armhf arm64 Depends: \${misc:Depends}, freeswitch (= \${binary:Version}), freeswitch-mod-amr (= \${binary:Version}), freeswitch-mod-amrwb (= \${binary:Version}), @@ -732,7 +735,7 @@ Description: Cross-Platform Scalable Multi-Protocol Soft Switch most FreeSWITCH codecs. Package: freeswitch-meta-codecs-dbg -Architecture: amd64 armhf +Architecture: amd64 armhf arm64 Depends: \${misc:Depends}, freeswitch (= \${binary:Version}), freeswitch-mod-amr-dbg (= \${binary:Version}), freeswitch-mod-amrwb-dbg (= \${binary:Version}), @@ -759,7 +762,7 @@ Description: Cross-Platform Scalable Multi-Protocol Soft Switch most FreeSWITCH codecs. Package: freeswitch-meta-conf -Architecture: amd64 armhf +Architecture: amd64 armhf arm64 Depends: \${misc:Depends}, freeswitch-conf-curl (= \${binary:Version}), freeswitch-conf-insideout (= \${binary:Version}), @@ -773,7 +776,7 @@ Description: Cross-Platform Scalable Multi-Protocol Soft Switch examples for FreeSWITCH. Package: freeswitch-meta-lang -Architecture: amd64 armhf +Architecture: amd64 armhf arm64 Depends: \${misc:Depends}, freeswitch-lang-de (= \${binary:Version}), freeswitch-lang-en (= \${binary:Version}), @@ -789,7 +792,7 @@ Description: Cross-Platform Scalable Multi-Protocol Soft Switch FreeSWITCH. Package: freeswitch-meta-mod-say -Architecture: amd64 armhf +Architecture: amd64 armhf arm64 Depends: \${misc:Depends}, freeswitch-mod-say-de (= \${binary:Version}), freeswitch-mod-say-en (= \${binary:Version}), @@ -814,7 +817,7 @@ Description: Cross-Platform Scalable Multi-Protocol Soft Switch FreeSWITCH. Package: freeswitch-meta-mod-say-dbg -Architecture: amd64 armhf +Architecture: amd64 armhf arm64 Depends: \${misc:Depends}, freeswitch-mod-say-de-dbg (= \${binary:Version}), freeswitch-mod-say-en-dbg (= \${binary:Version}), @@ -839,7 +842,7 @@ Description: Cross-Platform Scalable Multi-Protocol Soft Switch FreeSWITCH. Package: freeswitch-meta-all-dbg -Architecture: amd64 armhf +Architecture: amd64 armhf arm64 Depends: \${misc:Depends}, freeswitch (= \${binary:Version}), freeswitch-meta-codecs-dbg (= \${binary:Version}), freeswitch-meta-mod-say (= \${binary:Version}), @@ -943,7 +946,7 @@ Description: Cross-Platform Scalable Multi-Protocol Soft Switch Package: freeswitch-all-dbg Section: debug Priority: optional -Architecture: amd64 armhf +Architecture: amd64 armhf arm64 Depends: \${misc:Depends}, freeswitch-meta-all (= \${binary:Version}), freeswitch-meta-all-dbg (= \${binary:Version}) Description: debugging symbols for FreeSWITCH $(debian_wrap "${fs_description}") @@ -953,7 +956,7 @@ Description: debugging symbols for FreeSWITCH Package: freeswitch-dbg Section: debug Priority: optional -Architecture: amd64 armhf +Architecture: amd64 armhf arm64 Depends: \${misc:Depends}, freeswitch (= \${binary:Version}) Description: debugging symbols for FreeSWITCH $(debian_wrap "${fs_description}") @@ -963,7 +966,7 @@ Description: debugging symbols for FreeSWITCH Package: libfreeswitch1-dbg Section: debug Priority: optional -Architecture: amd64 armhf +Architecture: amd64 armhf arm64 Depends: \${misc:Depends}, libfreeswitch1 (= \${binary:Version}) Description: debugging symbols for FreeSWITCH $(debian_wrap "${fs_description}") @@ -972,7 +975,7 @@ Description: debugging symbols for FreeSWITCH Package: libfreeswitch-dev Section: libdevel -Architecture: amd64 armhf +Architecture: amd64 armhf arm64 Depends: \${misc:Depends}, freeswitch Description: development libraries and header files for FreeSWITCH $(debian_wrap "${fs_description}") @@ -981,7 +984,7 @@ Description: development libraries and header files for FreeSWITCH Package: freeswitch-doc Section: doc -Architecture: amd64 armhf +Architecture: amd64 armhf arm64 Depends: \${misc:Depends} Description: documentation for FreeSWITCH $(debian_wrap "${fs_description}") @@ -994,7 +997,7 @@ Description: documentation for FreeSWITCH ## languages Package: freeswitch-lang -Architecture: amd64 armhf +Architecture: amd64 armhf arm64 Depends: \${misc:Depends}, freeswitch-lang-en (= \${binary:Version}) Description: Language files for FreeSWITCH @@ -1006,7 +1009,7 @@ Description: Language files for FreeSWITCH ## timezones Package: freeswitch-timezones -Architecture: amd64 armhf +Architecture: amd64 armhf arm64 Depends: \${misc:Depends} Description: Timezone files for FreeSWITCH $(debian_wrap "${fs_description}") @@ -1020,7 +1023,7 @@ EOF if [ ${use_sysvinit} = "true" ]; then cat <= 3.0-6), sysvinit | sysvinit-utils Conflicts: freeswitch-init Provides: freeswitch-init @@ -1033,7 +1036,7 @@ EOF else cat <&2 echo $orig } @@ -292,9 +308,9 @@ create_dsc () { prep_create_dsc "$@" - local OPTIND OPTARG suite_postfix="" suite_postfix_p=false zl=9 + local OPTIND OPTARG suite_postfix="" suite_postfix_p=false soft_reset=false zl=9 - while getopts 'a:f:m:p:s:u:z:' o "$@"; do + while getopts 'a:f:m:p:s:u:xz:' o "$@"; do case "$o" in a) ;; f) ;; @@ -302,6 +318,7 @@ create_dsc () { p) ;; s) ;; u) suite_postfix="$OPTARG"; suite_postfix_p=true;; + x) soft_reset=true;; z) zl="$OPTARG";; esac done @@ -328,7 +345,11 @@ create_dsc () { local dsc="../$(dsc_base).dsc" - git reset --hard HEAD^ && git clean -fdx + if $soft_reset; then + git reset --soft HEAD^ + else + git reset --hard HEAD^ && git clean -fdx + fi } 1>&2 echo $dsc } @@ -686,6 +707,7 @@ commands: Set FS bootstrap/build -j flags -u Specify a custom suite postfix + -x Use git soft reset instead of hard reset -z Set compression level create-orig (same for 'prep_create_orig') @@ -694,6 +716,8 @@ commands: Choose custom list of modules to build -n Nightly build -v Set version + -V Set version (without replacing every '-' to '~') + -x Use git soft reset instead of hard reset -z Set compression level EOF diff --git a/debian/version-omit_revision.pl b/debian/version-omit_revision.pl new file mode 100755 index 00000000000..c6f5767a29a --- /dev/null +++ b/debian/version-omit_revision.pl @@ -0,0 +1,22 @@ +#!/usr/bin/perl +use strict; +use warnings; +use Dpkg::Version; + +my $version; + +open(my $fh, '-|', 'dpkg-parsechangelog -S version') or die "Failed to execute dpkg-parsechangelog: $!"; +{ + local $/; + $version = <$fh>; +} +close $fh; + +$version =~ s/\s+$//; + +die "No version found or empty output from dpkg-parsechangelog" unless defined $version and $version ne ''; + +my $v = Dpkg::Version->new($version); +my $vs = $v->as_string(omit_epoch => 1, omit_revision => 1); + +print "$vs\n"; From 72d17ccf5c559947de2e2c08b0778f677e3e5051 Mon Sep 17 00:00:00 2001 From: s3rj1k Date: Thu, 6 Jun 2024 23:59:10 +0200 Subject: [PATCH 30/56] [GHA] Add build workflow. --- .../docker/debian/bookworm/amd64/Dockerfile | 97 ++++++++++++++++ .../docker/debian/bookworm/arm32v7/Dockerfile | 96 ++++++++++++++++ .../docker/debian/bookworm/arm64v8/Dockerfile | 96 ++++++++++++++++ .../docker/debian/bullseye/amd64/Dockerfile | 96 ++++++++++++++++ .../docker/debian/bullseye/arm32v7/Dockerfile | 96 ++++++++++++++++ .../docker/debian/bullseye/arm64v8/Dockerfile | 96 ++++++++++++++++ .github/docker/debian/buster/amd64/Dockerfile | 97 ++++++++++++++++ .../docker/debian/buster/arm32v7/Dockerfile | 96 ++++++++++++++++ .../docker/debian/buster/arm64v8/Dockerfile | 96 ++++++++++++++++ .github/workflows/build.yml | 107 ++++++++++++++++++ 10 files changed, 973 insertions(+) create mode 100644 .github/docker/debian/bookworm/amd64/Dockerfile create mode 100644 .github/docker/debian/bookworm/arm32v7/Dockerfile create mode 100644 .github/docker/debian/bookworm/arm64v8/Dockerfile create mode 100644 .github/docker/debian/bullseye/amd64/Dockerfile create mode 100644 .github/docker/debian/bullseye/arm32v7/Dockerfile create mode 100644 .github/docker/debian/bullseye/arm64v8/Dockerfile create mode 100644 .github/docker/debian/buster/amd64/Dockerfile create mode 100644 .github/docker/debian/buster/arm32v7/Dockerfile create mode 100644 .github/docker/debian/buster/arm64v8/Dockerfile create mode 100644 .github/workflows/build.yml diff --git a/.github/docker/debian/bookworm/amd64/Dockerfile b/.github/docker/debian/bookworm/amd64/Dockerfile new file mode 100644 index 00000000000..b5008301487 --- /dev/null +++ b/.github/docker/debian/bookworm/amd64/Dockerfile @@ -0,0 +1,97 @@ +ARG BUILDER_IMAGE=debian:bookworm-20240513 + +FROM ${BUILDER_IMAGE} AS builder + +ARG MAINTAINER_NAME="Andrey Volk" +ARG MAINTAINER_EMAIL="andrey@signalwire.com" + +# Credentials +ARG REPO_DOMAIN=freeswitch.signalwire.com +ARG REPO_USERNAME=user +ARG REPO_PASSWORD=password + +ARG BUILD_NUMBER=42 +ARG GIT_SHA=0000000000 + +ARG DATA_DIR=/data +ARG CODENAME=bookworm +ARG GPG_KEY="/usr/share/keyrings/signalwire-freeswitch-repo.gpg" + +MAINTAINER "${MAINTAINER_NAME} <${MAINTAINER_EMAIL}>" + +SHELL ["/bin/bash", "-c"] + +RUN apt-get -q update && \ + DEBIAN_FRONTEND=noninteractive apt-get -yq install \ + apt-transport-https \ + build-essential \ + ca-certificates \ + cmake \ + curl \ + debhelper \ + devscripts \ + dh-autoreconf \ + dos2unix \ + doxygen \ + git \ + graphviz \ + libglib2.0-dev \ + libssl-dev \ + lsb-release \ + pkg-config \ + wget + +RUN update-ca-certificates --fresh + +RUN echo "export CODENAME=${CODENAME}" | tee ~/.env && \ + chmod +x ~/.env + +RUN . ~/.env && cat < /etc/apt/sources.list.d/freeswitch.list +deb [signed-by=${GPG_KEY}] https://${REPO_DOMAIN}/repo/deb/debian-unstable ${CODENAME} main +deb-src [signed-by=${GPG_KEY}] https://${REPO_DOMAIN}/repo/deb/debian-unstable ${CODENAME} main +EOF + +RUN --mount=type=secret,id=REPO_PASSWORD \ + printf "machine ${REPO_DOMAIN} " > ~/.netrc && \ + printf "login ${REPO_USERNAME} " >> ~/.netrc && \ + printf "password " >> ~/.netrc && \ + cat /run/secrets/REPO_PASSWORD >> ~/.netrc && \ + cp -f ~/.netrc /etc/apt/auth.conf + +RUN git config --global --add safe.directory '*' \ + && git config --global user.name "${MAINTAINER_NAME}" \ + && git config --global user.email "${MAINTAINER_EMAIL}" + +RUN curl --netrc -o ${GPG_KEY} https://${REPO_DOMAIN}/repo/deb/debian-unstable/signalwire-freeswitch-repo.gpg + +# Bootstrap and Build +COPY . ${DATA_DIR} +WORKDIR ${DATA_DIR} +RUN echo "export VERSION=$(cat ./build/next-release.txt | tr -d '\n')" | tee -a ~/.env + +RUN . ~/.env && ./debian/util.sh prep-create-orig -n -V${VERSION}-${BUILD_NUMBER}-${GIT_SHA} -x +RUN . ~/.env && ./debian/util.sh prep-create-dsc ${CODENAME} + +RUN apt-get -q update && \ + mk-build-deps --install --remove debian/control --tool "apt-get -y --no-install-recommends" && \ + apt-get -y -f install + +ENV DEB_BUILD_OPTIONS="parallel=1" +RUN . ~/.env && dch -b -M -v "${VERSION}-${BUILD_NUMBER}-${GIT_SHA}~${CODENAME}" \ + --force-distribution -D "${CODENAME}" "Nightly build, ${GIT_SHA}" + +RUN . ~/.env && ./debian/util.sh create-orig -n -V${VERSION}-${BUILD_NUMBER}-${GIT_SHA} -x + +RUN dpkg-source \ + --diff-ignore=.* \ + --compression=xz \ + --compression-level=9 \ + --build \ + . \ + && debuild -b -us -uc \ + && mkdir OUT \ + && mv -v ../*.{deb,dsc,changes,tar.*} OUT/. + +# Artifacts image (mandatory part, the resulting image must have a single filesystem layer) +FROM scratch +COPY --from=builder /data/OUT/ / diff --git a/.github/docker/debian/bookworm/arm32v7/Dockerfile b/.github/docker/debian/bookworm/arm32v7/Dockerfile new file mode 100644 index 00000000000..43b4778b3e8 --- /dev/null +++ b/.github/docker/debian/bookworm/arm32v7/Dockerfile @@ -0,0 +1,96 @@ +ARG BUILDER_IMAGE=arm32v7/debian:bookworm-20240513 + +FROM --platform=linux/arm32 ${BUILDER_IMAGE} AS builder + +ARG MAINTAINER_NAME="Andrey Volk" +ARG MAINTAINER_EMAIL="andrey@signalwire.com" + +# Credentials +ARG REPO_DOMAIN=freeswitch.signalwire.com +ARG REPO_USERNAME=user +ARG REPO_PASSWORD=password + +ARG BUILD_NUMBER=42 +ARG GIT_SHA=0000000000 + +ARG DATA_DIR=/data +ARG CODENAME=bookworm +ARG GPG_KEY="/usr/share/keyrings/signalwire-freeswitch-repo.gpg" + +MAINTAINER "${MAINTAINER_NAME} <${MAINTAINER_EMAIL}>" + +SHELL ["/bin/bash", "-c"] + +RUN apt-get -q update && \ + DEBIAN_FRONTEND=noninteractive apt-get -yq install \ + apt-transport-https \ + build-essential \ + ca-certificates \ + cmake \ + curl \ + debhelper \ + devscripts \ + dh-autoreconf \ + dos2unix \ + doxygen \ + git \ + graphviz \ + libglib2.0-dev \ + libssl-dev \ + lsb-release \ + pkg-config \ + wget + +RUN update-ca-certificates --fresh + +RUN echo "export CODENAME=${CODENAME}" | tee ~/.env && \ + chmod +x ~/.env + +RUN . ~/.env && cat < /etc/apt/sources.list.d/freeswitch.list +deb [signed-by=${GPG_KEY}] https://${REPO_DOMAIN}/repo/deb/rpi/debian-dev ${CODENAME} main +deb-src [signed-by=${GPG_KEY}] https://${REPO_DOMAIN}/repo/deb/rpi/debian-dev ${CODENAME} main +EOF + +RUN --mount=type=secret,id=REPO_PASSWORD \ + printf "machine ${REPO_DOMAIN} " > ~/.netrc && \ + printf "login ${REPO_USERNAME} " >> ~/.netrc && \ + printf "password " >> ~/.netrc && \ + cat /run/secrets/REPO_PASSWORD >> ~/.netrc && \ + cp -f ~/.netrc /etc/apt/auth.conf + +RUN git config --global --add safe.directory '*' \ + && git config --global user.name "${MAINTAINER_NAME}" \ + && git config --global user.email "${MAINTAINER_EMAIL}" + +RUN curl --netrc -o ${GPG_KEY} https://${REPO_DOMAIN}/repo/deb/rpi/debian-dev/signalwire-freeswitch-repo.gpg + +# Bootstrap and Build +COPY . ${DATA_DIR} +WORKDIR ${DATA_DIR} +RUN echo "export VERSION=$(cat ./build/next-release.txt | tr -d '\n')" | tee -a ~/.env + +RUN . ~/.env && ./debian/util.sh prep-create-orig -n -V${VERSION}-${BUILD_NUMBER}-${GIT_SHA} -x +RUN . ~/.env && ./debian/util.sh prep-create-dsc -a armhf ${CODENAME} + +RUN apt-get -q update && \ + mk-build-deps --install --remove debian/control --tool "apt-get -y --no-install-recommends" && \ + apt-get -y -f install + +ENV DEB_BUILD_OPTIONS="parallel=1" +RUN . ~/.env && dch -b -M -v "${VERSION}-${BUILD_NUMBER}-${GIT_SHA}~${CODENAME}" \ + --force-distribution -D "${CODENAME}" "Nightly build, ${GIT_SHA}" +RUN . ~/.env && ./debian/util.sh create-orig -n -V${VERSION}-${BUILD_NUMBER}-${GIT_SHA} -x + +RUN dpkg-source \ + --diff-ignore=.* \ + --compression=xz \ + --compression-level=9 \ + --build \ + . \ + && debuild -b -us -uc \ + && mkdir OUT \ + && mv -v ../*.{deb,dsc,changes,tar.*} OUT/. + +# Artifacts image (mandatory part, the resulting image must have a single filesystem layer) +FROM scratch +COPY --from=builder /data/OUT/ / diff --git a/.github/docker/debian/bookworm/arm64v8/Dockerfile b/.github/docker/debian/bookworm/arm64v8/Dockerfile new file mode 100644 index 00000000000..50c24957f17 --- /dev/null +++ b/.github/docker/debian/bookworm/arm64v8/Dockerfile @@ -0,0 +1,96 @@ +ARG BUILDER_IMAGE=arm64v8/debian:bookworm-20240513 + +FROM --platform=linux/arm64 ${BUILDER_IMAGE} AS builder + +ARG MAINTAINER_NAME="Andrey Volk" +ARG MAINTAINER_EMAIL="andrey@signalwire.com" + +# Credentials +ARG REPO_DOMAIN=freeswitch.signalwire.com +ARG REPO_USERNAME=user +ARG REPO_PASSWORD=password + +ARG BUILD_NUMBER=42 +ARG GIT_SHA=0000000000 + +ARG DATA_DIR=/data +ARG CODENAME=bookworm +ARG GPG_KEY="/usr/share/keyrings/signalwire-freeswitch-repo.gpg" + +MAINTAINER "${MAINTAINER_NAME} <${MAINTAINER_EMAIL}>" + +SHELL ["/bin/bash", "-c"] + +RUN apt-get -q update && \ + DEBIAN_FRONTEND=noninteractive apt-get -yq install \ + apt-transport-https \ + build-essential \ + ca-certificates \ + cmake \ + curl \ + debhelper \ + devscripts \ + dh-autoreconf \ + dos2unix \ + doxygen \ + git \ + graphviz \ + libglib2.0-dev \ + libssl-dev \ + lsb-release \ + pkg-config \ + wget + +RUN update-ca-certificates --fresh + +RUN echo "export CODENAME=${CODENAME}" | tee ~/.env && \ + chmod +x ~/.env + +RUN . ~/.env && cat < /etc/apt/sources.list.d/freeswitch.list +deb [signed-by=${GPG_KEY}] https://${REPO_DOMAIN}/repo/deb/debian-unstable ${CODENAME} main +deb-src [signed-by=${GPG_KEY}] https://${REPO_DOMAIN}/repo/deb/debian-unstable ${CODENAME} main +EOF + +RUN --mount=type=secret,id=REPO_PASSWORD \ + printf "machine ${REPO_DOMAIN} " > ~/.netrc && \ + printf "login ${REPO_USERNAME} " >> ~/.netrc && \ + printf "password " >> ~/.netrc && \ + cat /run/secrets/REPO_PASSWORD >> ~/.netrc && \ + cp -f ~/.netrc /etc/apt/auth.conf + +RUN git config --global --add safe.directory '*' \ + && git config --global user.name "${MAINTAINER_NAME}" \ + && git config --global user.email "${MAINTAINER_EMAIL}" + +RUN curl --netrc -o ${GPG_KEY} https://${REPO_DOMAIN}/repo/deb/debian-unstable/signalwire-freeswitch-repo.gpg + +# Bootstrap and Build +COPY . ${DATA_DIR} +WORKDIR ${DATA_DIR} +RUN echo "export VERSION=$(cat ./build/next-release.txt | tr -d '\n')" | tee -a ~/.env + +RUN . ~/.env && ./debian/util.sh prep-create-orig -n -V${VERSION}-${BUILD_NUMBER}-${GIT_SHA} -x +RUN . ~/.env && ./debian/util.sh prep-create-dsc -a arm64 ${CODENAME} + +RUN apt-get -q update && \ + mk-build-deps --install --remove debian/control --tool "apt-get -y --no-install-recommends" && \ + apt-get -y -f install + +ENV DEB_BUILD_OPTIONS="parallel=1" +RUN . ~/.env && dch -b -M -v "${VERSION}-${BUILD_NUMBER}-${GIT_SHA}~${CODENAME}" \ + --force-distribution -D "${CODENAME}" "Nightly build, ${GIT_SHA}" +RUN . ~/.env && ./debian/util.sh create-orig -n -V${VERSION}-${BUILD_NUMBER}-${GIT_SHA} -x + +RUN dpkg-source \ + --diff-ignore=.* \ + --compression=xz \ + --compression-level=9 \ + --build \ + . \ + && debuild -b -us -uc \ + && mkdir OUT \ + && mv -v ../*.{deb,dsc,changes,tar.*} OUT/. + +# Artifacts image (mandatory part, the resulting image must have a single filesystem layer) +FROM scratch +COPY --from=builder /data/OUT/ / diff --git a/.github/docker/debian/bullseye/amd64/Dockerfile b/.github/docker/debian/bullseye/amd64/Dockerfile new file mode 100644 index 00000000000..aefbd382242 --- /dev/null +++ b/.github/docker/debian/bullseye/amd64/Dockerfile @@ -0,0 +1,96 @@ +ARG BUILDER_IMAGE=debian:bullseye-20240513 + +FROM ${BUILDER_IMAGE} AS builder + +ARG MAINTAINER_NAME="Andrey Volk" +ARG MAINTAINER_EMAIL="andrey@signalwire.com" + +# Credentials +ARG REPO_DOMAIN=freeswitch.signalwire.com +ARG REPO_USERNAME=user +ARG REPO_PASSWORD=password + +ARG BUILD_NUMBER=42 +ARG GIT_SHA=0000000000 + +ARG DATA_DIR=/data +ARG CODENAME=bullseye +ARG GPG_KEY="/usr/share/keyrings/signalwire-freeswitch-repo.gpg" + +MAINTAINER "${MAINTAINER_NAME} <${MAINTAINER_EMAIL}>" + +SHELL ["/bin/bash", "-c"] + +RUN apt-get -q update && \ + DEBIAN_FRONTEND=noninteractive apt-get -yq install \ + apt-transport-https \ + build-essential \ + ca-certificates \ + cmake \ + curl \ + debhelper \ + devscripts \ + dh-autoreconf \ + dos2unix \ + doxygen \ + git \ + graphviz \ + libglib2.0-dev \ + libssl-dev \ + lsb-release \ + pkg-config \ + wget + +RUN update-ca-certificates --fresh + +RUN echo "export CODENAME=${CODENAME}" | tee ~/.env && \ + chmod +x ~/.env + +RUN . ~/.env && cat < /etc/apt/sources.list.d/freeswitch.list +deb [signed-by=${GPG_KEY}] https://${REPO_DOMAIN}/repo/deb/debian-unstable ${CODENAME} main +deb-src [signed-by=${GPG_KEY}] https://${REPO_DOMAIN}/repo/deb/debian-unstable ${CODENAME} main +EOF + +RUN --mount=type=secret,id=REPO_PASSWORD \ + printf "machine ${REPO_DOMAIN} " > ~/.netrc && \ + printf "login ${REPO_USERNAME} " >> ~/.netrc && \ + printf "password " >> ~/.netrc && \ + cat /run/secrets/REPO_PASSWORD >> ~/.netrc && \ + cp -f ~/.netrc /etc/apt/auth.conf + +RUN git config --global --add safe.directory '*' \ + && git config --global user.name "${MAINTAINER_NAME}" \ + && git config --global user.email "${MAINTAINER_EMAIL}" + +RUN curl --netrc -o ${GPG_KEY} https://${REPO_DOMAIN}/repo/deb/debian-unstable/signalwire-freeswitch-repo.gpg + +# Bootstrap and Build +COPY . ${DATA_DIR} +WORKDIR ${DATA_DIR} +RUN echo "export VERSION=$(cat ./build/next-release.txt | tr -d '\n')" | tee -a ~/.env + +RUN . ~/.env && ./debian/util.sh prep-create-orig -n -V${VERSION}-${BUILD_NUMBER}-${GIT_SHA} -x +RUN . ~/.env && ./debian/util.sh prep-create-dsc ${CODENAME} + +RUN apt-get -q update && \ + mk-build-deps --install --remove debian/control --tool "apt-get -y --no-install-recommends" && \ + apt-get -y -f install + +ENV DEB_BUILD_OPTIONS="parallel=1" +RUN . ~/.env && dch -b -M -v "${VERSION}-${BUILD_NUMBER}-${GIT_SHA}~${CODENAME}" \ + --force-distribution -D "${CODENAME}" "Nightly build, ${GIT_SHA}" +RUN . ~/.env && ./debian/util.sh create-orig -n -V${VERSION}-${BUILD_NUMBER}-${GIT_SHA} -x + +RUN dpkg-source \ + --diff-ignore=.* \ + --compression=xz \ + --compression-level=9 \ + --build \ + . \ + && debuild -b -us -uc \ + && mkdir OUT \ + && mv -v ../*.{deb,dsc,changes,tar.*} OUT/. + +# Artifacts image (mandatory part, the resulting image must have a single filesystem layer) +FROM scratch +COPY --from=builder /data/OUT/ / diff --git a/.github/docker/debian/bullseye/arm32v7/Dockerfile b/.github/docker/debian/bullseye/arm32v7/Dockerfile new file mode 100644 index 00000000000..b3a6f00c360 --- /dev/null +++ b/.github/docker/debian/bullseye/arm32v7/Dockerfile @@ -0,0 +1,96 @@ +ARG BUILDER_IMAGE=arm32v7/debian:bullseye-20240513 + +FROM --platform=linux/arm32 ${BUILDER_IMAGE} AS builder + +ARG MAINTAINER_NAME="Andrey Volk" +ARG MAINTAINER_EMAIL="andrey@signalwire.com" + +# Credentials +ARG REPO_DOMAIN=freeswitch.signalwire.com +ARG REPO_USERNAME=user +ARG REPO_PASSWORD=password + +ARG BUILD_NUMBER=42 +ARG GIT_SHA=0000000000 + +ARG DATA_DIR=/data +ARG CODENAME=bullseye +ARG GPG_KEY="/usr/share/keyrings/signalwire-freeswitch-repo.gpg" + +MAINTAINER "${MAINTAINER_NAME} <${MAINTAINER_EMAIL}>" + +SHELL ["/bin/bash", "-c"] + +RUN apt-get -q update && \ + DEBIAN_FRONTEND=noninteractive apt-get -yq install \ + apt-transport-https \ + build-essential \ + ca-certificates \ + cmake \ + curl \ + debhelper \ + devscripts \ + dh-autoreconf \ + dos2unix \ + doxygen \ + git \ + graphviz \ + libglib2.0-dev \ + libssl-dev \ + lsb-release \ + pkg-config \ + wget + +RUN update-ca-certificates --fresh + +RUN echo "export CODENAME=${CODENAME}" | tee ~/.env && \ + chmod +x ~/.env + +RUN . ~/.env && cat < /etc/apt/sources.list.d/freeswitch.list +deb [signed-by=${GPG_KEY}] https://${REPO_DOMAIN}/repo/deb/rpi/debian-dev ${CODENAME} main +deb-src [signed-by=${GPG_KEY}] https://${REPO_DOMAIN}/repo/deb/rpi/debian-dev ${CODENAME} main +EOF + +RUN --mount=type=secret,id=REPO_PASSWORD \ + printf "machine ${REPO_DOMAIN} " > ~/.netrc && \ + printf "login ${REPO_USERNAME} " >> ~/.netrc && \ + printf "password " >> ~/.netrc && \ + cat /run/secrets/REPO_PASSWORD >> ~/.netrc && \ + cp -f ~/.netrc /etc/apt/auth.conf + +RUN git config --global --add safe.directory '*' \ + && git config --global user.name "${MAINTAINER_NAME}" \ + && git config --global user.email "${MAINTAINER_EMAIL}" + +RUN curl --netrc -o ${GPG_KEY} https://${REPO_DOMAIN}/repo/deb/rpi/debian-dev/signalwire-freeswitch-repo.gpg + +# Bootstrap and Build +COPY . ${DATA_DIR} +WORKDIR ${DATA_DIR} +RUN echo "export VERSION=$(cat ./build/next-release.txt | tr -d '\n')" | tee -a ~/.env + +RUN . ~/.env && ./debian/util.sh prep-create-orig -n -V${VERSION}-${BUILD_NUMBER}-${GIT_SHA} -x +RUN . ~/.env && ./debian/util.sh prep-create-dsc -a armhf ${CODENAME} + +RUN apt-get -q update && \ + mk-build-deps --install --remove debian/control --tool "apt-get -y --no-install-recommends" && \ + apt-get -y -f install + +ENV DEB_BUILD_OPTIONS="parallel=1" +RUN . ~/.env && dch -b -M -v "${VERSION}-${BUILD_NUMBER}-${GIT_SHA}~${CODENAME}" \ + --force-distribution -D "${CODENAME}" "Nightly build, ${GIT_SHA}" +RUN . ~/.env && ./debian/util.sh create-orig -n -V${VERSION}-${BUILD_NUMBER}-${GIT_SHA} -x + +RUN dpkg-source \ + --diff-ignore=.* \ + --compression=xz \ + --compression-level=9 \ + --build \ + . \ + && debuild -b -us -uc \ + && mkdir OUT \ + && mv -v ../*.{deb,dsc,changes,tar.*} OUT/. + +# Artifacts image (mandatory part, the resulting image must have a single filesystem layer) +FROM scratch +COPY --from=builder /data/OUT/ / diff --git a/.github/docker/debian/bullseye/arm64v8/Dockerfile b/.github/docker/debian/bullseye/arm64v8/Dockerfile new file mode 100644 index 00000000000..dfa899540ef --- /dev/null +++ b/.github/docker/debian/bullseye/arm64v8/Dockerfile @@ -0,0 +1,96 @@ +ARG BUILDER_IMAGE=arm64v8/debian:bullseye-20240513 + +FROM --platform=linux/arm64 ${BUILDER_IMAGE} AS builder + +ARG MAINTAINER_NAME="Andrey Volk" +ARG MAINTAINER_EMAIL="andrey@signalwire.com" + +# Credentials +ARG REPO_DOMAIN=freeswitch.signalwire.com +ARG REPO_USERNAME=user +ARG REPO_PASSWORD=password + +ARG BUILD_NUMBER=42 +ARG GIT_SHA=0000000000 + +ARG DATA_DIR=/data +ARG CODENAME=bullseye +ARG GPG_KEY="/usr/share/keyrings/signalwire-freeswitch-repo.gpg" + +MAINTAINER "${MAINTAINER_NAME} <${MAINTAINER_EMAIL}>" + +SHELL ["/bin/bash", "-c"] + +RUN apt-get -q update && \ + DEBIAN_FRONTEND=noninteractive apt-get -yq install \ + apt-transport-https \ + build-essential \ + ca-certificates \ + cmake \ + curl \ + debhelper \ + devscripts \ + dh-autoreconf \ + dos2unix \ + doxygen \ + git \ + graphviz \ + libglib2.0-dev \ + libssl-dev \ + lsb-release \ + pkg-config \ + wget + +RUN update-ca-certificates --fresh + +RUN echo "export CODENAME=${CODENAME}" | tee ~/.env && \ + chmod +x ~/.env + +RUN . ~/.env && cat < /etc/apt/sources.list.d/freeswitch.list +deb [signed-by=${GPG_KEY}] https://${REPO_DOMAIN}/repo/deb/debian-unstable ${CODENAME} main +deb-src [signed-by=${GPG_KEY}] https://${REPO_DOMAIN}/repo/deb/debian-unstable ${CODENAME} main +EOF + +RUN --mount=type=secret,id=REPO_PASSWORD \ + printf "machine ${REPO_DOMAIN} " > ~/.netrc && \ + printf "login ${REPO_USERNAME} " >> ~/.netrc && \ + printf "password " >> ~/.netrc && \ + cat /run/secrets/REPO_PASSWORD >> ~/.netrc && \ + cp -f ~/.netrc /etc/apt/auth.conf + +RUN git config --global --add safe.directory '*' \ + && git config --global user.name "${MAINTAINER_NAME}" \ + && git config --global user.email "${MAINTAINER_EMAIL}" + +RUN curl --netrc -o ${GPG_KEY} https://${REPO_DOMAIN}/repo/deb/debian-unstable/signalwire-freeswitch-repo.gpg + +# Bootstrap and Build +COPY . ${DATA_DIR} +WORKDIR ${DATA_DIR} +RUN echo "export VERSION=$(cat ./build/next-release.txt | tr -d '\n')" | tee -a ~/.env + +RUN . ~/.env && ./debian/util.sh prep-create-orig -n -V${VERSION}-${BUILD_NUMBER}-${GIT_SHA} -x +RUN . ~/.env && ./debian/util.sh prep-create-dsc -a arm64 ${CODENAME} + +RUN apt-get -q update && \ + mk-build-deps --install --remove debian/control --tool "apt-get -y --no-install-recommends" && \ + apt-get -y -f install + +ENV DEB_BUILD_OPTIONS="parallel=1" +RUN . ~/.env && dch -b -M -v "${VERSION}-${BUILD_NUMBER}-${GIT_SHA}~${CODENAME}" \ + --force-distribution -D "${CODENAME}" "Nightly build, ${GIT_SHA}" +RUN . ~/.env && ./debian/util.sh create-orig -n -V${VERSION}-${BUILD_NUMBER}-${GIT_SHA} -x + +RUN dpkg-source \ + --diff-ignore=.* \ + --compression=xz \ + --compression-level=9 \ + --build \ + . \ + && debuild -b -us -uc \ + && mkdir OUT \ + && mv -v ../*.{deb,dsc,changes,tar.*} OUT/. + +# Artifacts image (mandatory part, the resulting image must have a single filesystem layer) +FROM scratch +COPY --from=builder /data/OUT/ / diff --git a/.github/docker/debian/buster/amd64/Dockerfile b/.github/docker/debian/buster/amd64/Dockerfile new file mode 100644 index 00000000000..119a18076e8 --- /dev/null +++ b/.github/docker/debian/buster/amd64/Dockerfile @@ -0,0 +1,97 @@ +ARG BUILDER_IMAGE=debian:buster-20240513 + +FROM ${BUILDER_IMAGE} AS builder + +ARG MAINTAINER_NAME="Andrey Volk" +ARG MAINTAINER_EMAIL="andrey@signalwire.com" + +# Credentials +ARG REPO_DOMAIN=freeswitch.signalwire.com +ARG REPO_USERNAME=user +ARG REPO_PASSWORD=password + +ARG BUILD_NUMBER=42 +ARG GIT_SHA=0000000000 + +ARG DATA_DIR=/data +ARG CODENAME=buster +ARG GPG_KEY="/usr/share/keyrings/signalwire-freeswitch-repo.gpg" + +MAINTAINER "${MAINTAINER_NAME} <${MAINTAINER_EMAIL}>" + +SHELL ["/bin/bash", "-c"] + +RUN apt-get -q update && \ + DEBIAN_FRONTEND=noninteractive apt-get -yq install \ + apt-transport-https \ + build-essential \ + ca-certificates \ + cmake \ + curl \ + debhelper \ + devscripts \ + dh-autoreconf \ + dos2unix \ + doxygen \ + git \ + graphviz \ + libglib2.0-dev \ + libssl-dev \ + lsb-release \ + pkg-config \ + wget + +RUN update-ca-certificates --fresh + +RUN echo "export CODENAME=${CODENAME}" | tee ~/.env && \ + chmod +x ~/.env + +RUN . ~/.env && cat < /etc/apt/sources.list.d/freeswitch.list +deb [signed-by=${GPG_KEY}] https://${REPO_DOMAIN}/repo/deb/debian-unstable ${CODENAME} main +deb-src [signed-by=${GPG_KEY}] https://${REPO_DOMAIN}/repo/deb/debian-unstable ${CODENAME} main +EOF + +RUN --mount=type=secret,id=REPO_PASSWORD \ + printf "machine ${REPO_DOMAIN} " > ~/.netrc && \ + printf "login ${REPO_USERNAME} " >> ~/.netrc && \ + printf "password " >> ~/.netrc && \ + cat /run/secrets/REPO_PASSWORD >> ~/.netrc && \ + cp -f ~/.netrc /etc/apt/auth.conf + +RUN git config --global --add safe.directory '*' \ + && git config --global user.name "${MAINTAINER_NAME}" \ + && git config --global user.email "${MAINTAINER_EMAIL}" + +RUN curl --netrc -o ${GPG_KEY} https://${REPO_DOMAIN}/repo/deb/debian-unstable/signalwire-freeswitch-repo.gpg + +# Bootstrap and Build +COPY . ${DATA_DIR} +WORKDIR ${DATA_DIR} + +RUN echo "export VERSION=$(cat ./build/next-release.txt | tr -d '\n')" | tee -a ~/.env + +RUN . ~/.env && ./debian/util.sh prep-create-orig -n -V${VERSION}-${BUILD_NUMBER}-${GIT_SHA} -x +RUN . ~/.env && ./debian/util.sh prep-create-dsc ${CODENAME} + +RUN apt-get -q update && \ + mk-build-deps --install --remove debian/control --tool "apt-get -y --no-install-recommends" && \ + apt-get -y -f install + +ENV DEB_BUILD_OPTIONS="parallel=1" +RUN . ~/.env && dch -b -M -v "${VERSION}-${BUILD_NUMBER}-${GIT_SHA}~${CODENAME}" \ + --force-distribution -D "${CODENAME}" "Nightly build, ${GIT_SHA}" +RUN . ~/.env && ./debian/util.sh create-orig -n -V${VERSION}-${BUILD_NUMBER}-${GIT_SHA} -x + +RUN dpkg-source \ + --diff-ignore=.* \ + --compression=xz \ + --compression-level=9 \ + --build \ + . \ + && debuild -b -us -uc \ + && mkdir OUT \ + && mv -v ../*.{deb,dsc,changes,tar.*} OUT/. + +# Artifacts image (mandatory part, the resulting image must have a single filesystem layer) +FROM scratch +COPY --from=builder /data/OUT/ / diff --git a/.github/docker/debian/buster/arm32v7/Dockerfile b/.github/docker/debian/buster/arm32v7/Dockerfile new file mode 100644 index 00000000000..2113f55bd8d --- /dev/null +++ b/.github/docker/debian/buster/arm32v7/Dockerfile @@ -0,0 +1,96 @@ +ARG BUILDER_IMAGE=arm32v7/debian:buster-20240513 + +FROM --platform=linux/arm32 ${BUILDER_IMAGE} AS builder + +ARG MAINTAINER_NAME="Andrey Volk" +ARG MAINTAINER_EMAIL="andrey@signalwire.com" + +# Credentials +ARG REPO_DOMAIN=freeswitch.signalwire.com +ARG REPO_USERNAME=user +ARG REPO_PASSWORD=password + +ARG BUILD_NUMBER=42 +ARG GIT_SHA=0000000000 + +ARG DATA_DIR=/data +ARG CODENAME=buster +ARG GPG_KEY="/usr/share/keyrings/signalwire-freeswitch-repo.gpg" + +MAINTAINER "${MAINTAINER_NAME} <${MAINTAINER_EMAIL}>" + +SHELL ["/bin/bash", "-c"] + +RUN apt-get -q update && \ + DEBIAN_FRONTEND=noninteractive apt-get -yq install \ + apt-transport-https \ + build-essential \ + ca-certificates \ + cmake \ + curl \ + debhelper \ + devscripts \ + dh-autoreconf \ + dos2unix \ + doxygen \ + git \ + graphviz \ + libglib2.0-dev \ + libssl-dev \ + lsb-release \ + pkg-config \ + wget + +RUN update-ca-certificates --fresh + +RUN echo "export CODENAME=${CODENAME}" | tee ~/.env && \ + chmod +x ~/.env + +RUN . ~/.env && cat < /etc/apt/sources.list.d/freeswitch.list +deb [signed-by=${GPG_KEY}] https://${REPO_DOMAIN}/repo/deb/rpi/debian-dev ${CODENAME} main +deb-src [signed-by=${GPG_KEY}] https://${REPO_DOMAIN}/repo/deb/rpi/debian-dev ${CODENAME} main +EOF + +RUN --mount=type=secret,id=REPO_PASSWORD \ + printf "machine ${REPO_DOMAIN} " > ~/.netrc && \ + printf "login ${REPO_USERNAME} " >> ~/.netrc && \ + printf "password " >> ~/.netrc && \ + cat /run/secrets/REPO_PASSWORD >> ~/.netrc && \ + cp -f ~/.netrc /etc/apt/auth.conf + +RUN git config --global --add safe.directory '*' \ + && git config --global user.name "${MAINTAINER_NAME}" \ + && git config --global user.email "${MAINTAINER_EMAIL}" + +RUN curl --netrc -o ${GPG_KEY} https://${REPO_DOMAIN}/repo/deb/rpi/debian-dev/signalwire-freeswitch-repo.gpg + +# Bootstrap and Build +COPY . ${DATA_DIR} +WORKDIR ${DATA_DIR} +RUN echo "export VERSION=$(cat ./build/next-release.txt | tr -d '\n')" | tee -a ~/.env + +RUN . ~/.env && ./debian/util.sh prep-create-orig -n -V${VERSION}-${BUILD_NUMBER}-${GIT_SHA} -x +RUN . ~/.env && ./debian/util.sh prep-create-dsc -a armhf ${CODENAME} + +RUN apt-get -q update && \ + mk-build-deps --install --remove debian/control --tool "apt-get -y --no-install-recommends" && \ + apt-get -y -f install + +ENV DEB_BUILD_OPTIONS="parallel=1" +RUN . ~/.env && dch -b -M -v "${VERSION}-${BUILD_NUMBER}-${GIT_SHA}~${CODENAME}" \ + --force-distribution -D "${CODENAME}" "Nightly build, ${GIT_SHA}" +RUN . ~/.env && ./debian/util.sh create-orig -n -V${VERSION}-${BUILD_NUMBER}-${GIT_SHA} -x + +RUN dpkg-source \ + --diff-ignore=.* \ + --compression=xz \ + --compression-level=9 \ + --build \ + . \ + && debuild -b -us -uc \ + && mkdir OUT \ + && mv -v ../*.{deb,dsc,changes,tar.*} OUT/. + +# Artifacts image (mandatory part, the resulting image must have a single filesystem layer) +FROM scratch +COPY --from=builder /data/OUT/ / diff --git a/.github/docker/debian/buster/arm64v8/Dockerfile b/.github/docker/debian/buster/arm64v8/Dockerfile new file mode 100644 index 00000000000..150a77fec2e --- /dev/null +++ b/.github/docker/debian/buster/arm64v8/Dockerfile @@ -0,0 +1,96 @@ +ARG BUILDER_IMAGE=arm64v8/debian:buster-20240513 + +FROM --platform=linux/arm64 ${BUILDER_IMAGE} AS builder + +ARG MAINTAINER_NAME="Andrey Volk" +ARG MAINTAINER_EMAIL="andrey@signalwire.com" + +# Credentials +ARG REPO_DOMAIN=freeswitch.signalwire.com +ARG REPO_USERNAME=user +ARG REPO_PASSWORD=password + +ARG BUILD_NUMBER=42 +ARG GIT_SHA=0000000000 + +ARG DATA_DIR=/data +ARG CODENAME=buster +ARG GPG_KEY="/usr/share/keyrings/signalwire-freeswitch-repo.gpg" + +MAINTAINER "${MAINTAINER_NAME} <${MAINTAINER_EMAIL}>" + +SHELL ["/bin/bash", "-c"] + +RUN apt-get -q update && \ + DEBIAN_FRONTEND=noninteractive apt-get -yq install \ + apt-transport-https \ + build-essential \ + ca-certificates \ + cmake \ + curl \ + debhelper \ + devscripts \ + dh-autoreconf \ + dos2unix \ + doxygen \ + git \ + graphviz \ + libglib2.0-dev \ + libssl-dev \ + lsb-release \ + pkg-config \ + wget + +RUN update-ca-certificates --fresh + +RUN echo "export CODENAME=${CODENAME}" | tee ~/.env && \ + chmod +x ~/.env + +RUN . ~/.env && cat < /etc/apt/sources.list.d/freeswitch.list +deb [signed-by=${GPG_KEY}] https://${REPO_DOMAIN}/repo/deb/debian-unstable ${CODENAME} main +deb-src [signed-by=${GPG_KEY}] https://${REPO_DOMAIN}/repo/deb/debian-unstable ${CODENAME} main +EOF + +RUN --mount=type=secret,id=REPO_PASSWORD \ + printf "machine ${REPO_DOMAIN} " > ~/.netrc && \ + printf "login ${REPO_USERNAME} " >> ~/.netrc && \ + printf "password " >> ~/.netrc && \ + cat /run/secrets/REPO_PASSWORD >> ~/.netrc && \ + cp -f ~/.netrc /etc/apt/auth.conf + +RUN git config --global --add safe.directory '*' \ + && git config --global user.name "${MAINTAINER_NAME}" \ + && git config --global user.email "${MAINTAINER_EMAIL}" + +RUN curl --netrc -o ${GPG_KEY} https://${REPO_DOMAIN}/repo/deb/debian-unstable/signalwire-freeswitch-repo.gpg + +# Bootstrap and Build +COPY . ${DATA_DIR} +WORKDIR ${DATA_DIR} +RUN echo "export VERSION=$(cat ./build/next-release.txt | tr -d '\n')" | tee -a ~/.env + +RUN . ~/.env && ./debian/util.sh prep-create-orig -n -V${VERSION}-${BUILD_NUMBER}-${GIT_SHA} -x +RUN . ~/.env && ./debian/util.sh prep-create-dsc -a arm64 ${CODENAME} + +RUN apt-get -q update && \ + mk-build-deps --install --remove debian/control --tool "apt-get -y --no-install-recommends" && \ + apt-get -y -f install + +ENV DEB_BUILD_OPTIONS="parallel=1" +RUN . ~/.env && dch -b -M -v "${VERSION}-${BUILD_NUMBER}-${GIT_SHA}~${CODENAME}" \ + --force-distribution -D "${CODENAME}" "Nightly build, ${GIT_SHA}" +RUN . ~/.env && ./debian/util.sh create-orig -n -V${VERSION}-${BUILD_NUMBER}-${GIT_SHA} -x + +RUN dpkg-source \ + --diff-ignore=.* \ + --compression=xz \ + --compression-level=9 \ + --build \ + . \ + && debuild -b -us -uc \ + && mkdir OUT \ + && mv -v ../*.{deb,dsc,changes,tar.*} OUT/. + +# Artifacts image (mandatory part, the resulting image must have a single filesystem layer) +FROM scratch +COPY --from=builder /data/OUT/ / diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml new file mode 100644 index 00000000000..e16da9a3648 --- /dev/null +++ b/.github/workflows/build.yml @@ -0,0 +1,107 @@ +name: Build and Distribute + +on: + pull_request: + push: + branches: + - master + paths: + - "**" + workflow_dispatch: + +concurrency: + group: ${{ github.head_ref || github.ref }} + +jobs: + excludes: + runs-on: ubuntu-latest + outputs: + deb: ${{ steps.deb.outputs.excludes }} + steps: + - id: deb + name: Generate Matrix excludes for DEB + run: | + JSON="[]" + + if [[ "${{ github.event_name }}" == "pull_request" ]]; then + JSON=$(jq -n '[ + { + "version": "bookworm", + "platform": { + "name": "amd64" + } + }, + { + "version": "bookworm", + "platform": { + "name": "arm64v8" + } + }, + { + "version": "bullseye" + } + ]') + fi + + echo "excludes=$(echo $JSON | jq -c .)" | tee -a $GITHUB_OUTPUT + + deb: + name: 'DEB' + permissions: + id-token: write + contents: read + needs: + - excludes + uses: signalwire/actions-template/.github/workflows/cicd-docker-build-and-distribute.yml@main + strategy: + # max-parallel: 1 + fail-fast: false + matrix: + os: + - debian + version: + - bookworm + - bullseye + - buster + platform: + - name: amd64 + runner: ubuntu-latest + - name: arm32v7 + runner: linux-arm64-4-core-public + - name: arm64v8 + runner: linux-arm64-4-core-public + exclude: ${{ fromJson(needs.excludes.outputs.deb) }} + with: + RUNNER: ${{ matrix.platform.runner }} + ARTIFACTS_PATTERN: '.*\.(deb|dsc|changes|tar.bz2|tar.gz|tar.lzma|tar.xz)$' + DOCKERFILE: .github/docker/${{ matrix.os }}/${{ matrix.version }}/${{ matrix.platform.name }}/Dockerfile + MAINTAINER: 'Andrey Volk ' + META_FILE_PATH_PREFIX: /var/www/freeswitch/${{ github.ref_name }}/${{ github.run_id }}-${{ github.run_number }} + PLATFORM: ${{ matrix.platform.name }} + REPO_DOMAIN: freeswitch.signalwire.com + TARGET_ARTIFACT_NAME: ${{ matrix.os }}-${{ matrix.version }}-${{ matrix.platform.name }}-artifact + UPLOAD_BUILD_ARTIFACTS: ${{ github.event_name != 'pull_request' || contains(github.event.pull_request.title, ':upload-artifacts') }} + secrets: + GH_BOT_DEPLOY_TOKEN: ${{ secrets.PAT }} + HOSTNAME: ${{ secrets.HOSTNAME }} + PROXY_URL: ${{ secrets.PROXY_URL }} + USERNAME: ${{ secrets.USERNAME }} + TELEPORT_TOKEN: ${{ secrets.TELEPORT_TOKEN }} + REPO_USERNAME: 'signalwire' + REPO_PASSWORD: ${{ secrets.REPOTOKEN }} + + meta: + name: 'Publish build data to meta-repo' + if: ${{ github.event_name != 'pull_request' || contains(github.event.pull_request.title, ':upload-artifacts') }} + needs: + - deb + permissions: + id-token: write + contents: read + uses: signalwire/actions-template/.github/workflows/meta-repo-content.yml@main + with: + META_CONTENT: '/var/www/freeswitch/${{ github.ref_name }}/${{ github.run_id }}-${{ github.run_number }}' + META_REPO: signalwire/bamboo_gha_trigger + META_REPO_BRANCH: trigger/freeswitch/${{ github.ref_name }} + secrets: + GH_BOT_DEPLOY_TOKEN: ${{ secrets.PAT }} From a0e7fb8e7112cfaf413c6f26c7fa7709279ebc21 Mon Sep 17 00:00:00 2001 From: Andrey Volk Date: Thu, 7 Mar 2024 21:45:13 +0300 Subject: [PATCH 31/56] [Build-System] Update expired Certificate Thumbprint on Windows. --- w32/Setup/Setup.2017.wixproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/w32/Setup/Setup.2017.wixproj b/w32/Setup/Setup.2017.wixproj index bf0aae04984..ef66d7c2e88 100644 --- a/w32/Setup/Setup.2017.wixproj +++ b/w32/Setup/Setup.2017.wixproj @@ -13,7 +13,7 @@ 2.0 FreeSWITCH Package - bf386393c880967b00adbc438aee534de6211774 + 076ce3c57198fc39443bd87f4aab86dac0aab62d http://timestamp.comodoca.com $(WindowsSDK80Path)bin\x86\signtool.exe $(WindowsSDK80Path)bin\x64\signtool.exe From 453b18d893e01a4351aac0cf9517439ca077eca8 Mon Sep 17 00:00:00 2001 From: s3rj1k Date: Sat, 22 Jun 2024 16:26:28 +0200 Subject: [PATCH 32/56] [GHA] Rework how secrets are used inside Dockerfiles. --- .../docker/debian/bookworm/amd64/Dockerfile | 31 ++++++++++++------- .../docker/debian/bookworm/arm32v7/Dockerfile | 31 ++++++++++++------- .../docker/debian/bookworm/arm64v8/Dockerfile | 31 ++++++++++++------- .../docker/debian/bullseye/amd64/Dockerfile | 31 ++++++++++++------- .../docker/debian/bullseye/arm32v7/Dockerfile | 31 ++++++++++++------- .../docker/debian/bullseye/arm64v8/Dockerfile | 31 ++++++++++++------- .github/docker/debian/buster/amd64/Dockerfile | 31 ++++++++++++------- .../docker/debian/buster/arm32v7/Dockerfile | 31 ++++++++++++------- .../docker/debian/buster/arm64v8/Dockerfile | 31 ++++++++++++------- 9 files changed, 171 insertions(+), 108 deletions(-) diff --git a/.github/docker/debian/bookworm/amd64/Dockerfile b/.github/docker/debian/bookworm/amd64/Dockerfile index b5008301487..844d9494a4b 100644 --- a/.github/docker/debian/bookworm/amd64/Dockerfile +++ b/.github/docker/debian/bookworm/amd64/Dockerfile @@ -51,19 +51,10 @@ deb [signed-by=${GPG_KEY}] https://${REPO_DOMAIN}/repo/deb/debian-unstable ${COD deb-src [signed-by=${GPG_KEY}] https://${REPO_DOMAIN}/repo/deb/debian-unstable ${CODENAME} main EOF -RUN --mount=type=secret,id=REPO_PASSWORD \ - printf "machine ${REPO_DOMAIN} " > ~/.netrc && \ - printf "login ${REPO_USERNAME} " >> ~/.netrc && \ - printf "password " >> ~/.netrc && \ - cat /run/secrets/REPO_PASSWORD >> ~/.netrc && \ - cp -f ~/.netrc /etc/apt/auth.conf - RUN git config --global --add safe.directory '*' \ && git config --global user.name "${MAINTAINER_NAME}" \ && git config --global user.email "${MAINTAINER_EMAIL}" -RUN curl --netrc -o ${GPG_KEY} https://${REPO_DOMAIN}/repo/deb/debian-unstable/signalwire-freeswitch-repo.gpg - # Bootstrap and Build COPY . ${DATA_DIR} WORKDIR ${DATA_DIR} @@ -72,9 +63,25 @@ RUN echo "export VERSION=$(cat ./build/next-release.txt | tr -d '\n')" | tee -a RUN . ~/.env && ./debian/util.sh prep-create-orig -n -V${VERSION}-${BUILD_NUMBER}-${GIT_SHA} -x RUN . ~/.env && ./debian/util.sh prep-create-dsc ${CODENAME} -RUN apt-get -q update && \ - mk-build-deps --install --remove debian/control --tool "apt-get -y --no-install-recommends" && \ - apt-get -y -f install +RUN --mount=type=secret,id=REPO_PASSWORD \ + printf "machine ${REPO_DOMAIN} " > /etc/apt/auth.conf && \ + printf "login ${REPO_USERNAME} " >> /etc/apt/auth.conf && \ + printf "password " >> /etc/apt/auth.conf && \ + cat /run/secrets/REPO_PASSWORD >> /etc/apt/auth.conf && \ + curl \ + --fail \ + --netrc-file /etc/apt/auth.conf \ + --output ${GPG_KEY} \ + --silent \ + https://${REPO_DOMAIN}/repo/deb/debian-unstable/signalwire-freeswitch-repo.gpg && \ + file ${GPG_KEY} && \ + apt-get --quiet update && \ + mk-build-deps \ + --install \ + --remove debian/control \ + --tool "apt-get --yes --no-install-recommends" && \ + apt-get --yes --fix-broken install && \ + rm -f /etc/apt/auth.conf ENV DEB_BUILD_OPTIONS="parallel=1" RUN . ~/.env && dch -b -M -v "${VERSION}-${BUILD_NUMBER}-${GIT_SHA}~${CODENAME}" \ diff --git a/.github/docker/debian/bookworm/arm32v7/Dockerfile b/.github/docker/debian/bookworm/arm32v7/Dockerfile index 43b4778b3e8..164e6023562 100644 --- a/.github/docker/debian/bookworm/arm32v7/Dockerfile +++ b/.github/docker/debian/bookworm/arm32v7/Dockerfile @@ -51,19 +51,10 @@ deb [signed-by=${GPG_KEY}] https://${REPO_DOMAIN}/repo/deb/rpi/debian-dev ${CODE deb-src [signed-by=${GPG_KEY}] https://${REPO_DOMAIN}/repo/deb/rpi/debian-dev ${CODENAME} main EOF -RUN --mount=type=secret,id=REPO_PASSWORD \ - printf "machine ${REPO_DOMAIN} " > ~/.netrc && \ - printf "login ${REPO_USERNAME} " >> ~/.netrc && \ - printf "password " >> ~/.netrc && \ - cat /run/secrets/REPO_PASSWORD >> ~/.netrc && \ - cp -f ~/.netrc /etc/apt/auth.conf - RUN git config --global --add safe.directory '*' \ && git config --global user.name "${MAINTAINER_NAME}" \ && git config --global user.email "${MAINTAINER_EMAIL}" -RUN curl --netrc -o ${GPG_KEY} https://${REPO_DOMAIN}/repo/deb/rpi/debian-dev/signalwire-freeswitch-repo.gpg - # Bootstrap and Build COPY . ${DATA_DIR} WORKDIR ${DATA_DIR} @@ -72,9 +63,25 @@ RUN echo "export VERSION=$(cat ./build/next-release.txt | tr -d '\n')" | tee -a RUN . ~/.env && ./debian/util.sh prep-create-orig -n -V${VERSION}-${BUILD_NUMBER}-${GIT_SHA} -x RUN . ~/.env && ./debian/util.sh prep-create-dsc -a armhf ${CODENAME} -RUN apt-get -q update && \ - mk-build-deps --install --remove debian/control --tool "apt-get -y --no-install-recommends" && \ - apt-get -y -f install +RUN --mount=type=secret,id=REPO_PASSWORD \ + printf "machine ${REPO_DOMAIN} " > /etc/apt/auth.conf && \ + printf "login ${REPO_USERNAME} " >> /etc/apt/auth.conf && \ + printf "password " >> /etc/apt/auth.conf && \ + cat /run/secrets/REPO_PASSWORD >> /etc/apt/auth.conf && \ + curl \ + --fail \ + --netrc-file /etc/apt/auth.conf \ + --output ${GPG_KEY} \ + --silent \ + https://${REPO_DOMAIN}/repo/deb/rpi/debian-dev/signalwire-freeswitch-repo.gpg && \ + file ${GPG_KEY} && \ + apt-get --quiet update && \ + mk-build-deps \ + --install \ + --remove debian/control \ + --tool "apt-get --yes --no-install-recommends" && \ + apt-get --yes --fix-broken install && \ + rm -f /etc/apt/auth.conf ENV DEB_BUILD_OPTIONS="parallel=1" RUN . ~/.env && dch -b -M -v "${VERSION}-${BUILD_NUMBER}-${GIT_SHA}~${CODENAME}" \ diff --git a/.github/docker/debian/bookworm/arm64v8/Dockerfile b/.github/docker/debian/bookworm/arm64v8/Dockerfile index 50c24957f17..0e30f8504e6 100644 --- a/.github/docker/debian/bookworm/arm64v8/Dockerfile +++ b/.github/docker/debian/bookworm/arm64v8/Dockerfile @@ -51,19 +51,10 @@ deb [signed-by=${GPG_KEY}] https://${REPO_DOMAIN}/repo/deb/debian-unstable ${COD deb-src [signed-by=${GPG_KEY}] https://${REPO_DOMAIN}/repo/deb/debian-unstable ${CODENAME} main EOF -RUN --mount=type=secret,id=REPO_PASSWORD \ - printf "machine ${REPO_DOMAIN} " > ~/.netrc && \ - printf "login ${REPO_USERNAME} " >> ~/.netrc && \ - printf "password " >> ~/.netrc && \ - cat /run/secrets/REPO_PASSWORD >> ~/.netrc && \ - cp -f ~/.netrc /etc/apt/auth.conf - RUN git config --global --add safe.directory '*' \ && git config --global user.name "${MAINTAINER_NAME}" \ && git config --global user.email "${MAINTAINER_EMAIL}" -RUN curl --netrc -o ${GPG_KEY} https://${REPO_DOMAIN}/repo/deb/debian-unstable/signalwire-freeswitch-repo.gpg - # Bootstrap and Build COPY . ${DATA_DIR} WORKDIR ${DATA_DIR} @@ -72,9 +63,25 @@ RUN echo "export VERSION=$(cat ./build/next-release.txt | tr -d '\n')" | tee -a RUN . ~/.env && ./debian/util.sh prep-create-orig -n -V${VERSION}-${BUILD_NUMBER}-${GIT_SHA} -x RUN . ~/.env && ./debian/util.sh prep-create-dsc -a arm64 ${CODENAME} -RUN apt-get -q update && \ - mk-build-deps --install --remove debian/control --tool "apt-get -y --no-install-recommends" && \ - apt-get -y -f install +RUN --mount=type=secret,id=REPO_PASSWORD \ + printf "machine ${REPO_DOMAIN} " > /etc/apt/auth.conf && \ + printf "login ${REPO_USERNAME} " >> /etc/apt/auth.conf && \ + printf "password " >> /etc/apt/auth.conf && \ + cat /run/secrets/REPO_PASSWORD >> /etc/apt/auth.conf && \ + curl \ + --fail \ + --netrc-file /etc/apt/auth.conf \ + --output ${GPG_KEY} \ + --silent \ + https://${REPO_DOMAIN}/repo/deb/debian-unstable/signalwire-freeswitch-repo.gpg && \ + file ${GPG_KEY} && \ + apt-get --quiet update && \ + mk-build-deps \ + --install \ + --remove debian/control \ + --tool "apt-get --yes --no-install-recommends" && \ + apt-get --yes --fix-broken install && \ + rm -f /etc/apt/auth.conf ENV DEB_BUILD_OPTIONS="parallel=1" RUN . ~/.env && dch -b -M -v "${VERSION}-${BUILD_NUMBER}-${GIT_SHA}~${CODENAME}" \ diff --git a/.github/docker/debian/bullseye/amd64/Dockerfile b/.github/docker/debian/bullseye/amd64/Dockerfile index aefbd382242..e4557f1ed66 100644 --- a/.github/docker/debian/bullseye/amd64/Dockerfile +++ b/.github/docker/debian/bullseye/amd64/Dockerfile @@ -51,19 +51,10 @@ deb [signed-by=${GPG_KEY}] https://${REPO_DOMAIN}/repo/deb/debian-unstable ${COD deb-src [signed-by=${GPG_KEY}] https://${REPO_DOMAIN}/repo/deb/debian-unstable ${CODENAME} main EOF -RUN --mount=type=secret,id=REPO_PASSWORD \ - printf "machine ${REPO_DOMAIN} " > ~/.netrc && \ - printf "login ${REPO_USERNAME} " >> ~/.netrc && \ - printf "password " >> ~/.netrc && \ - cat /run/secrets/REPO_PASSWORD >> ~/.netrc && \ - cp -f ~/.netrc /etc/apt/auth.conf - RUN git config --global --add safe.directory '*' \ && git config --global user.name "${MAINTAINER_NAME}" \ && git config --global user.email "${MAINTAINER_EMAIL}" -RUN curl --netrc -o ${GPG_KEY} https://${REPO_DOMAIN}/repo/deb/debian-unstable/signalwire-freeswitch-repo.gpg - # Bootstrap and Build COPY . ${DATA_DIR} WORKDIR ${DATA_DIR} @@ -72,9 +63,25 @@ RUN echo "export VERSION=$(cat ./build/next-release.txt | tr -d '\n')" | tee -a RUN . ~/.env && ./debian/util.sh prep-create-orig -n -V${VERSION}-${BUILD_NUMBER}-${GIT_SHA} -x RUN . ~/.env && ./debian/util.sh prep-create-dsc ${CODENAME} -RUN apt-get -q update && \ - mk-build-deps --install --remove debian/control --tool "apt-get -y --no-install-recommends" && \ - apt-get -y -f install +RUN --mount=type=secret,id=REPO_PASSWORD \ + printf "machine ${REPO_DOMAIN} " > /etc/apt/auth.conf && \ + printf "login ${REPO_USERNAME} " >> /etc/apt/auth.conf && \ + printf "password " >> /etc/apt/auth.conf && \ + cat /run/secrets/REPO_PASSWORD >> /etc/apt/auth.conf && \ + curl \ + --fail \ + --netrc-file /etc/apt/auth.conf \ + --output ${GPG_KEY} \ + --silent \ + https://${REPO_DOMAIN}/repo/deb/debian-unstable/signalwire-freeswitch-repo.gpg && \ + file ${GPG_KEY} && \ + apt-get --quiet update && \ + mk-build-deps \ + --install \ + --remove debian/control \ + --tool "apt-get --yes --no-install-recommends" && \ + apt-get --yes --fix-broken install && \ + rm -f /etc/apt/auth.conf ENV DEB_BUILD_OPTIONS="parallel=1" RUN . ~/.env && dch -b -M -v "${VERSION}-${BUILD_NUMBER}-${GIT_SHA}~${CODENAME}" \ diff --git a/.github/docker/debian/bullseye/arm32v7/Dockerfile b/.github/docker/debian/bullseye/arm32v7/Dockerfile index b3a6f00c360..03eb59b40f8 100644 --- a/.github/docker/debian/bullseye/arm32v7/Dockerfile +++ b/.github/docker/debian/bullseye/arm32v7/Dockerfile @@ -51,19 +51,10 @@ deb [signed-by=${GPG_KEY}] https://${REPO_DOMAIN}/repo/deb/rpi/debian-dev ${CODE deb-src [signed-by=${GPG_KEY}] https://${REPO_DOMAIN}/repo/deb/rpi/debian-dev ${CODENAME} main EOF -RUN --mount=type=secret,id=REPO_PASSWORD \ - printf "machine ${REPO_DOMAIN} " > ~/.netrc && \ - printf "login ${REPO_USERNAME} " >> ~/.netrc && \ - printf "password " >> ~/.netrc && \ - cat /run/secrets/REPO_PASSWORD >> ~/.netrc && \ - cp -f ~/.netrc /etc/apt/auth.conf - RUN git config --global --add safe.directory '*' \ && git config --global user.name "${MAINTAINER_NAME}" \ && git config --global user.email "${MAINTAINER_EMAIL}" -RUN curl --netrc -o ${GPG_KEY} https://${REPO_DOMAIN}/repo/deb/rpi/debian-dev/signalwire-freeswitch-repo.gpg - # Bootstrap and Build COPY . ${DATA_DIR} WORKDIR ${DATA_DIR} @@ -72,9 +63,25 @@ RUN echo "export VERSION=$(cat ./build/next-release.txt | tr -d '\n')" | tee -a RUN . ~/.env && ./debian/util.sh prep-create-orig -n -V${VERSION}-${BUILD_NUMBER}-${GIT_SHA} -x RUN . ~/.env && ./debian/util.sh prep-create-dsc -a armhf ${CODENAME} -RUN apt-get -q update && \ - mk-build-deps --install --remove debian/control --tool "apt-get -y --no-install-recommends" && \ - apt-get -y -f install +RUN --mount=type=secret,id=REPO_PASSWORD \ + printf "machine ${REPO_DOMAIN} " > /etc/apt/auth.conf && \ + printf "login ${REPO_USERNAME} " >> /etc/apt/auth.conf && \ + printf "password " >> /etc/apt/auth.conf && \ + cat /run/secrets/REPO_PASSWORD >> /etc/apt/auth.conf && \ + curl \ + --fail \ + --netrc-file /etc/apt/auth.conf \ + --output ${GPG_KEY} \ + --silent \ + https://${REPO_DOMAIN}/repo/deb/rpi/debian-dev/signalwire-freeswitch-repo.gpg && \ + file ${GPG_KEY} && \ + apt-get --quiet update && \ + mk-build-deps \ + --install \ + --remove debian/control \ + --tool "apt-get --yes --no-install-recommends" && \ + apt-get --yes --fix-broken install && \ + rm -f /etc/apt/auth.conf ENV DEB_BUILD_OPTIONS="parallel=1" RUN . ~/.env && dch -b -M -v "${VERSION}-${BUILD_NUMBER}-${GIT_SHA}~${CODENAME}" \ diff --git a/.github/docker/debian/bullseye/arm64v8/Dockerfile b/.github/docker/debian/bullseye/arm64v8/Dockerfile index dfa899540ef..ca216a82d7e 100644 --- a/.github/docker/debian/bullseye/arm64v8/Dockerfile +++ b/.github/docker/debian/bullseye/arm64v8/Dockerfile @@ -51,19 +51,10 @@ deb [signed-by=${GPG_KEY}] https://${REPO_DOMAIN}/repo/deb/debian-unstable ${COD deb-src [signed-by=${GPG_KEY}] https://${REPO_DOMAIN}/repo/deb/debian-unstable ${CODENAME} main EOF -RUN --mount=type=secret,id=REPO_PASSWORD \ - printf "machine ${REPO_DOMAIN} " > ~/.netrc && \ - printf "login ${REPO_USERNAME} " >> ~/.netrc && \ - printf "password " >> ~/.netrc && \ - cat /run/secrets/REPO_PASSWORD >> ~/.netrc && \ - cp -f ~/.netrc /etc/apt/auth.conf - RUN git config --global --add safe.directory '*' \ && git config --global user.name "${MAINTAINER_NAME}" \ && git config --global user.email "${MAINTAINER_EMAIL}" -RUN curl --netrc -o ${GPG_KEY} https://${REPO_DOMAIN}/repo/deb/debian-unstable/signalwire-freeswitch-repo.gpg - # Bootstrap and Build COPY . ${DATA_DIR} WORKDIR ${DATA_DIR} @@ -72,9 +63,25 @@ RUN echo "export VERSION=$(cat ./build/next-release.txt | tr -d '\n')" | tee -a RUN . ~/.env && ./debian/util.sh prep-create-orig -n -V${VERSION}-${BUILD_NUMBER}-${GIT_SHA} -x RUN . ~/.env && ./debian/util.sh prep-create-dsc -a arm64 ${CODENAME} -RUN apt-get -q update && \ - mk-build-deps --install --remove debian/control --tool "apt-get -y --no-install-recommends" && \ - apt-get -y -f install +RUN --mount=type=secret,id=REPO_PASSWORD \ + printf "machine ${REPO_DOMAIN} " > /etc/apt/auth.conf && \ + printf "login ${REPO_USERNAME} " >> /etc/apt/auth.conf && \ + printf "password " >> /etc/apt/auth.conf && \ + cat /run/secrets/REPO_PASSWORD >> /etc/apt/auth.conf && \ + curl \ + --fail \ + --netrc-file /etc/apt/auth.conf \ + --output ${GPG_KEY} \ + --silent \ + https://${REPO_DOMAIN}/repo/deb/debian-unstable/signalwire-freeswitch-repo.gpg && \ + file ${GPG_KEY} && \ + apt-get --quiet update && \ + mk-build-deps \ + --install \ + --remove debian/control \ + --tool "apt-get --yes --no-install-recommends" && \ + apt-get --yes --fix-broken install && \ + rm -f /etc/apt/auth.conf ENV DEB_BUILD_OPTIONS="parallel=1" RUN . ~/.env && dch -b -M -v "${VERSION}-${BUILD_NUMBER}-${GIT_SHA}~${CODENAME}" \ diff --git a/.github/docker/debian/buster/amd64/Dockerfile b/.github/docker/debian/buster/amd64/Dockerfile index 119a18076e8..a0da4dbe7cc 100644 --- a/.github/docker/debian/buster/amd64/Dockerfile +++ b/.github/docker/debian/buster/amd64/Dockerfile @@ -51,19 +51,10 @@ deb [signed-by=${GPG_KEY}] https://${REPO_DOMAIN}/repo/deb/debian-unstable ${COD deb-src [signed-by=${GPG_KEY}] https://${REPO_DOMAIN}/repo/deb/debian-unstable ${CODENAME} main EOF -RUN --mount=type=secret,id=REPO_PASSWORD \ - printf "machine ${REPO_DOMAIN} " > ~/.netrc && \ - printf "login ${REPO_USERNAME} " >> ~/.netrc && \ - printf "password " >> ~/.netrc && \ - cat /run/secrets/REPO_PASSWORD >> ~/.netrc && \ - cp -f ~/.netrc /etc/apt/auth.conf - RUN git config --global --add safe.directory '*' \ && git config --global user.name "${MAINTAINER_NAME}" \ && git config --global user.email "${MAINTAINER_EMAIL}" -RUN curl --netrc -o ${GPG_KEY} https://${REPO_DOMAIN}/repo/deb/debian-unstable/signalwire-freeswitch-repo.gpg - # Bootstrap and Build COPY . ${DATA_DIR} WORKDIR ${DATA_DIR} @@ -73,9 +64,25 @@ RUN echo "export VERSION=$(cat ./build/next-release.txt | tr -d '\n')" | tee -a RUN . ~/.env && ./debian/util.sh prep-create-orig -n -V${VERSION}-${BUILD_NUMBER}-${GIT_SHA} -x RUN . ~/.env && ./debian/util.sh prep-create-dsc ${CODENAME} -RUN apt-get -q update && \ - mk-build-deps --install --remove debian/control --tool "apt-get -y --no-install-recommends" && \ - apt-get -y -f install +RUN --mount=type=secret,id=REPO_PASSWORD \ + printf "machine ${REPO_DOMAIN} " > /etc/apt/auth.conf && \ + printf "login ${REPO_USERNAME} " >> /etc/apt/auth.conf && \ + printf "password " >> /etc/apt/auth.conf && \ + cat /run/secrets/REPO_PASSWORD >> /etc/apt/auth.conf && \ + curl \ + --fail \ + --netrc-file /etc/apt/auth.conf \ + --output ${GPG_KEY} \ + --silent \ + https://${REPO_DOMAIN}/repo/deb/debian-unstable/signalwire-freeswitch-repo.gpg && \ + file ${GPG_KEY} && \ + apt-get --quiet update && \ + mk-build-deps \ + --install \ + --remove debian/control \ + --tool "apt-get --yes --no-install-recommends" && \ + apt-get --yes --fix-broken install && \ + rm -f /etc/apt/auth.conf ENV DEB_BUILD_OPTIONS="parallel=1" RUN . ~/.env && dch -b -M -v "${VERSION}-${BUILD_NUMBER}-${GIT_SHA}~${CODENAME}" \ diff --git a/.github/docker/debian/buster/arm32v7/Dockerfile b/.github/docker/debian/buster/arm32v7/Dockerfile index 2113f55bd8d..c283d9c6ce2 100644 --- a/.github/docker/debian/buster/arm32v7/Dockerfile +++ b/.github/docker/debian/buster/arm32v7/Dockerfile @@ -51,19 +51,10 @@ deb [signed-by=${GPG_KEY}] https://${REPO_DOMAIN}/repo/deb/rpi/debian-dev ${CODE deb-src [signed-by=${GPG_KEY}] https://${REPO_DOMAIN}/repo/deb/rpi/debian-dev ${CODENAME} main EOF -RUN --mount=type=secret,id=REPO_PASSWORD \ - printf "machine ${REPO_DOMAIN} " > ~/.netrc && \ - printf "login ${REPO_USERNAME} " >> ~/.netrc && \ - printf "password " >> ~/.netrc && \ - cat /run/secrets/REPO_PASSWORD >> ~/.netrc && \ - cp -f ~/.netrc /etc/apt/auth.conf - RUN git config --global --add safe.directory '*' \ && git config --global user.name "${MAINTAINER_NAME}" \ && git config --global user.email "${MAINTAINER_EMAIL}" -RUN curl --netrc -o ${GPG_KEY} https://${REPO_DOMAIN}/repo/deb/rpi/debian-dev/signalwire-freeswitch-repo.gpg - # Bootstrap and Build COPY . ${DATA_DIR} WORKDIR ${DATA_DIR} @@ -72,9 +63,25 @@ RUN echo "export VERSION=$(cat ./build/next-release.txt | tr -d '\n')" | tee -a RUN . ~/.env && ./debian/util.sh prep-create-orig -n -V${VERSION}-${BUILD_NUMBER}-${GIT_SHA} -x RUN . ~/.env && ./debian/util.sh prep-create-dsc -a armhf ${CODENAME} -RUN apt-get -q update && \ - mk-build-deps --install --remove debian/control --tool "apt-get -y --no-install-recommends" && \ - apt-get -y -f install +RUN --mount=type=secret,id=REPO_PASSWORD \ + printf "machine ${REPO_DOMAIN} " > /etc/apt/auth.conf && \ + printf "login ${REPO_USERNAME} " >> /etc/apt/auth.conf && \ + printf "password " >> /etc/apt/auth.conf && \ + cat /run/secrets/REPO_PASSWORD >> /etc/apt/auth.conf && \ + curl \ + --fail \ + --netrc-file /etc/apt/auth.conf \ + --output ${GPG_KEY} \ + --silent \ + https://${REPO_DOMAIN}/repo/deb/rpi/debian-dev/signalwire-freeswitch-repo.gpg && \ + file ${GPG_KEY} && \ + apt-get --quiet update && \ + mk-build-deps \ + --install \ + --remove debian/control \ + --tool "apt-get --yes --no-install-recommends" && \ + apt-get --yes --fix-broken install && \ + rm -f /etc/apt/auth.conf ENV DEB_BUILD_OPTIONS="parallel=1" RUN . ~/.env && dch -b -M -v "${VERSION}-${BUILD_NUMBER}-${GIT_SHA}~${CODENAME}" \ diff --git a/.github/docker/debian/buster/arm64v8/Dockerfile b/.github/docker/debian/buster/arm64v8/Dockerfile index 150a77fec2e..ac1f77959fd 100644 --- a/.github/docker/debian/buster/arm64v8/Dockerfile +++ b/.github/docker/debian/buster/arm64v8/Dockerfile @@ -51,19 +51,10 @@ deb [signed-by=${GPG_KEY}] https://${REPO_DOMAIN}/repo/deb/debian-unstable ${COD deb-src [signed-by=${GPG_KEY}] https://${REPO_DOMAIN}/repo/deb/debian-unstable ${CODENAME} main EOF -RUN --mount=type=secret,id=REPO_PASSWORD \ - printf "machine ${REPO_DOMAIN} " > ~/.netrc && \ - printf "login ${REPO_USERNAME} " >> ~/.netrc && \ - printf "password " >> ~/.netrc && \ - cat /run/secrets/REPO_PASSWORD >> ~/.netrc && \ - cp -f ~/.netrc /etc/apt/auth.conf - RUN git config --global --add safe.directory '*' \ && git config --global user.name "${MAINTAINER_NAME}" \ && git config --global user.email "${MAINTAINER_EMAIL}" -RUN curl --netrc -o ${GPG_KEY} https://${REPO_DOMAIN}/repo/deb/debian-unstable/signalwire-freeswitch-repo.gpg - # Bootstrap and Build COPY . ${DATA_DIR} WORKDIR ${DATA_DIR} @@ -72,9 +63,25 @@ RUN echo "export VERSION=$(cat ./build/next-release.txt | tr -d '\n')" | tee -a RUN . ~/.env && ./debian/util.sh prep-create-orig -n -V${VERSION}-${BUILD_NUMBER}-${GIT_SHA} -x RUN . ~/.env && ./debian/util.sh prep-create-dsc -a arm64 ${CODENAME} -RUN apt-get -q update && \ - mk-build-deps --install --remove debian/control --tool "apt-get -y --no-install-recommends" && \ - apt-get -y -f install +RUN --mount=type=secret,id=REPO_PASSWORD \ + printf "machine ${REPO_DOMAIN} " > /etc/apt/auth.conf && \ + printf "login ${REPO_USERNAME} " >> /etc/apt/auth.conf && \ + printf "password " >> /etc/apt/auth.conf && \ + cat /run/secrets/REPO_PASSWORD >> /etc/apt/auth.conf && \ + curl \ + --fail \ + --netrc-file /etc/apt/auth.conf \ + --output ${GPG_KEY} \ + --silent \ + https://${REPO_DOMAIN}/repo/deb/debian-unstable/signalwire-freeswitch-repo.gpg && \ + file ${GPG_KEY} && \ + apt-get --quiet update && \ + mk-build-deps \ + --install \ + --remove debian/control \ + --tool "apt-get --yes --no-install-recommends" && \ + apt-get --yes --fix-broken install && \ + rm -f /etc/apt/auth.conf ENV DEB_BUILD_OPTIONS="parallel=1" RUN . ~/.env && dch -b -M -v "${VERSION}-${BUILD_NUMBER}-${GIT_SHA}~${CODENAME}" \ From 1c7163e2ce5bc404551bcc15224d3a1c37b7ab68 Mon Sep 17 00:00:00 2001 From: s3rj1k Date: Sat, 22 Jun 2024 18:49:55 +0200 Subject: [PATCH 33/56] [GHA] Fail early when required secret not set. --- .github/docker/debian/bookworm/amd64/Dockerfile | 3 +-- .github/docker/debian/bookworm/arm32v7/Dockerfile | 3 +-- .github/docker/debian/bookworm/arm64v8/Dockerfile | 3 +-- .github/docker/debian/bullseye/amd64/Dockerfile | 3 +-- .github/docker/debian/bullseye/arm32v7/Dockerfile | 3 +-- .github/docker/debian/bullseye/arm64v8/Dockerfile | 3 +-- .github/docker/debian/buster/amd64/Dockerfile | 3 +-- .github/docker/debian/buster/arm32v7/Dockerfile | 3 +-- .github/docker/debian/buster/arm64v8/Dockerfile | 3 +-- .github/workflows/build.yml | 8 +++++++- 10 files changed, 16 insertions(+), 19 deletions(-) diff --git a/.github/docker/debian/bookworm/amd64/Dockerfile b/.github/docker/debian/bookworm/amd64/Dockerfile index 844d9494a4b..7b1dc8bf38b 100644 --- a/.github/docker/debian/bookworm/amd64/Dockerfile +++ b/.github/docker/debian/bookworm/amd64/Dockerfile @@ -63,7 +63,7 @@ RUN echo "export VERSION=$(cat ./build/next-release.txt | tr -d '\n')" | tee -a RUN . ~/.env && ./debian/util.sh prep-create-orig -n -V${VERSION}-${BUILD_NUMBER}-${GIT_SHA} -x RUN . ~/.env && ./debian/util.sh prep-create-dsc ${CODENAME} -RUN --mount=type=secret,id=REPO_PASSWORD \ +RUN --mount=type=secret,id=REPO_PASSWORD,required=true \ printf "machine ${REPO_DOMAIN} " > /etc/apt/auth.conf && \ printf "login ${REPO_USERNAME} " >> /etc/apt/auth.conf && \ printf "password " >> /etc/apt/auth.conf && \ @@ -72,7 +72,6 @@ RUN --mount=type=secret,id=REPO_PASSWORD \ --fail \ --netrc-file /etc/apt/auth.conf \ --output ${GPG_KEY} \ - --silent \ https://${REPO_DOMAIN}/repo/deb/debian-unstable/signalwire-freeswitch-repo.gpg && \ file ${GPG_KEY} && \ apt-get --quiet update && \ diff --git a/.github/docker/debian/bookworm/arm32v7/Dockerfile b/.github/docker/debian/bookworm/arm32v7/Dockerfile index 164e6023562..08608032a4d 100644 --- a/.github/docker/debian/bookworm/arm32v7/Dockerfile +++ b/.github/docker/debian/bookworm/arm32v7/Dockerfile @@ -63,7 +63,7 @@ RUN echo "export VERSION=$(cat ./build/next-release.txt | tr -d '\n')" | tee -a RUN . ~/.env && ./debian/util.sh prep-create-orig -n -V${VERSION}-${BUILD_NUMBER}-${GIT_SHA} -x RUN . ~/.env && ./debian/util.sh prep-create-dsc -a armhf ${CODENAME} -RUN --mount=type=secret,id=REPO_PASSWORD \ +RUN --mount=type=secret,id=REPO_PASSWORD,required=true \ printf "machine ${REPO_DOMAIN} " > /etc/apt/auth.conf && \ printf "login ${REPO_USERNAME} " >> /etc/apt/auth.conf && \ printf "password " >> /etc/apt/auth.conf && \ @@ -72,7 +72,6 @@ RUN --mount=type=secret,id=REPO_PASSWORD \ --fail \ --netrc-file /etc/apt/auth.conf \ --output ${GPG_KEY} \ - --silent \ https://${REPO_DOMAIN}/repo/deb/rpi/debian-dev/signalwire-freeswitch-repo.gpg && \ file ${GPG_KEY} && \ apt-get --quiet update && \ diff --git a/.github/docker/debian/bookworm/arm64v8/Dockerfile b/.github/docker/debian/bookworm/arm64v8/Dockerfile index 0e30f8504e6..e509a587e6d 100644 --- a/.github/docker/debian/bookworm/arm64v8/Dockerfile +++ b/.github/docker/debian/bookworm/arm64v8/Dockerfile @@ -63,7 +63,7 @@ RUN echo "export VERSION=$(cat ./build/next-release.txt | tr -d '\n')" | tee -a RUN . ~/.env && ./debian/util.sh prep-create-orig -n -V${VERSION}-${BUILD_NUMBER}-${GIT_SHA} -x RUN . ~/.env && ./debian/util.sh prep-create-dsc -a arm64 ${CODENAME} -RUN --mount=type=secret,id=REPO_PASSWORD \ +RUN --mount=type=secret,id=REPO_PASSWORD,required=true \ printf "machine ${REPO_DOMAIN} " > /etc/apt/auth.conf && \ printf "login ${REPO_USERNAME} " >> /etc/apt/auth.conf && \ printf "password " >> /etc/apt/auth.conf && \ @@ -72,7 +72,6 @@ RUN --mount=type=secret,id=REPO_PASSWORD \ --fail \ --netrc-file /etc/apt/auth.conf \ --output ${GPG_KEY} \ - --silent \ https://${REPO_DOMAIN}/repo/deb/debian-unstable/signalwire-freeswitch-repo.gpg && \ file ${GPG_KEY} && \ apt-get --quiet update && \ diff --git a/.github/docker/debian/bullseye/amd64/Dockerfile b/.github/docker/debian/bullseye/amd64/Dockerfile index e4557f1ed66..0d11c84dec1 100644 --- a/.github/docker/debian/bullseye/amd64/Dockerfile +++ b/.github/docker/debian/bullseye/amd64/Dockerfile @@ -63,7 +63,7 @@ RUN echo "export VERSION=$(cat ./build/next-release.txt | tr -d '\n')" | tee -a RUN . ~/.env && ./debian/util.sh prep-create-orig -n -V${VERSION}-${BUILD_NUMBER}-${GIT_SHA} -x RUN . ~/.env && ./debian/util.sh prep-create-dsc ${CODENAME} -RUN --mount=type=secret,id=REPO_PASSWORD \ +RUN --mount=type=secret,id=REPO_PASSWORD,required=true \ printf "machine ${REPO_DOMAIN} " > /etc/apt/auth.conf && \ printf "login ${REPO_USERNAME} " >> /etc/apt/auth.conf && \ printf "password " >> /etc/apt/auth.conf && \ @@ -72,7 +72,6 @@ RUN --mount=type=secret,id=REPO_PASSWORD \ --fail \ --netrc-file /etc/apt/auth.conf \ --output ${GPG_KEY} \ - --silent \ https://${REPO_DOMAIN}/repo/deb/debian-unstable/signalwire-freeswitch-repo.gpg && \ file ${GPG_KEY} && \ apt-get --quiet update && \ diff --git a/.github/docker/debian/bullseye/arm32v7/Dockerfile b/.github/docker/debian/bullseye/arm32v7/Dockerfile index 03eb59b40f8..7ea36d1bcc9 100644 --- a/.github/docker/debian/bullseye/arm32v7/Dockerfile +++ b/.github/docker/debian/bullseye/arm32v7/Dockerfile @@ -63,7 +63,7 @@ RUN echo "export VERSION=$(cat ./build/next-release.txt | tr -d '\n')" | tee -a RUN . ~/.env && ./debian/util.sh prep-create-orig -n -V${VERSION}-${BUILD_NUMBER}-${GIT_SHA} -x RUN . ~/.env && ./debian/util.sh prep-create-dsc -a armhf ${CODENAME} -RUN --mount=type=secret,id=REPO_PASSWORD \ +RUN --mount=type=secret,id=REPO_PASSWORD,required=true \ printf "machine ${REPO_DOMAIN} " > /etc/apt/auth.conf && \ printf "login ${REPO_USERNAME} " >> /etc/apt/auth.conf && \ printf "password " >> /etc/apt/auth.conf && \ @@ -72,7 +72,6 @@ RUN --mount=type=secret,id=REPO_PASSWORD \ --fail \ --netrc-file /etc/apt/auth.conf \ --output ${GPG_KEY} \ - --silent \ https://${REPO_DOMAIN}/repo/deb/rpi/debian-dev/signalwire-freeswitch-repo.gpg && \ file ${GPG_KEY} && \ apt-get --quiet update && \ diff --git a/.github/docker/debian/bullseye/arm64v8/Dockerfile b/.github/docker/debian/bullseye/arm64v8/Dockerfile index ca216a82d7e..ae3429cff72 100644 --- a/.github/docker/debian/bullseye/arm64v8/Dockerfile +++ b/.github/docker/debian/bullseye/arm64v8/Dockerfile @@ -63,7 +63,7 @@ RUN echo "export VERSION=$(cat ./build/next-release.txt | tr -d '\n')" | tee -a RUN . ~/.env && ./debian/util.sh prep-create-orig -n -V${VERSION}-${BUILD_NUMBER}-${GIT_SHA} -x RUN . ~/.env && ./debian/util.sh prep-create-dsc -a arm64 ${CODENAME} -RUN --mount=type=secret,id=REPO_PASSWORD \ +RUN --mount=type=secret,id=REPO_PASSWORD,required=true \ printf "machine ${REPO_DOMAIN} " > /etc/apt/auth.conf && \ printf "login ${REPO_USERNAME} " >> /etc/apt/auth.conf && \ printf "password " >> /etc/apt/auth.conf && \ @@ -72,7 +72,6 @@ RUN --mount=type=secret,id=REPO_PASSWORD \ --fail \ --netrc-file /etc/apt/auth.conf \ --output ${GPG_KEY} \ - --silent \ https://${REPO_DOMAIN}/repo/deb/debian-unstable/signalwire-freeswitch-repo.gpg && \ file ${GPG_KEY} && \ apt-get --quiet update && \ diff --git a/.github/docker/debian/buster/amd64/Dockerfile b/.github/docker/debian/buster/amd64/Dockerfile index a0da4dbe7cc..9f3d03f14c8 100644 --- a/.github/docker/debian/buster/amd64/Dockerfile +++ b/.github/docker/debian/buster/amd64/Dockerfile @@ -64,7 +64,7 @@ RUN echo "export VERSION=$(cat ./build/next-release.txt | tr -d '\n')" | tee -a RUN . ~/.env && ./debian/util.sh prep-create-orig -n -V${VERSION}-${BUILD_NUMBER}-${GIT_SHA} -x RUN . ~/.env && ./debian/util.sh prep-create-dsc ${CODENAME} -RUN --mount=type=secret,id=REPO_PASSWORD \ +RUN --mount=type=secret,id=REPO_PASSWORD,required=true \ printf "machine ${REPO_DOMAIN} " > /etc/apt/auth.conf && \ printf "login ${REPO_USERNAME} " >> /etc/apt/auth.conf && \ printf "password " >> /etc/apt/auth.conf && \ @@ -73,7 +73,6 @@ RUN --mount=type=secret,id=REPO_PASSWORD \ --fail \ --netrc-file /etc/apt/auth.conf \ --output ${GPG_KEY} \ - --silent \ https://${REPO_DOMAIN}/repo/deb/debian-unstable/signalwire-freeswitch-repo.gpg && \ file ${GPG_KEY} && \ apt-get --quiet update && \ diff --git a/.github/docker/debian/buster/arm32v7/Dockerfile b/.github/docker/debian/buster/arm32v7/Dockerfile index c283d9c6ce2..362c2a66027 100644 --- a/.github/docker/debian/buster/arm32v7/Dockerfile +++ b/.github/docker/debian/buster/arm32v7/Dockerfile @@ -63,7 +63,7 @@ RUN echo "export VERSION=$(cat ./build/next-release.txt | tr -d '\n')" | tee -a RUN . ~/.env && ./debian/util.sh prep-create-orig -n -V${VERSION}-${BUILD_NUMBER}-${GIT_SHA} -x RUN . ~/.env && ./debian/util.sh prep-create-dsc -a armhf ${CODENAME} -RUN --mount=type=secret,id=REPO_PASSWORD \ +RUN --mount=type=secret,id=REPO_PASSWORD,required=true \ printf "machine ${REPO_DOMAIN} " > /etc/apt/auth.conf && \ printf "login ${REPO_USERNAME} " >> /etc/apt/auth.conf && \ printf "password " >> /etc/apt/auth.conf && \ @@ -72,7 +72,6 @@ RUN --mount=type=secret,id=REPO_PASSWORD \ --fail \ --netrc-file /etc/apt/auth.conf \ --output ${GPG_KEY} \ - --silent \ https://${REPO_DOMAIN}/repo/deb/rpi/debian-dev/signalwire-freeswitch-repo.gpg && \ file ${GPG_KEY} && \ apt-get --quiet update && \ diff --git a/.github/docker/debian/buster/arm64v8/Dockerfile b/.github/docker/debian/buster/arm64v8/Dockerfile index ac1f77959fd..ed678405a92 100644 --- a/.github/docker/debian/buster/arm64v8/Dockerfile +++ b/.github/docker/debian/buster/arm64v8/Dockerfile @@ -63,7 +63,7 @@ RUN echo "export VERSION=$(cat ./build/next-release.txt | tr -d '\n')" | tee -a RUN . ~/.env && ./debian/util.sh prep-create-orig -n -V${VERSION}-${BUILD_NUMBER}-${GIT_SHA} -x RUN . ~/.env && ./debian/util.sh prep-create-dsc -a arm64 ${CODENAME} -RUN --mount=type=secret,id=REPO_PASSWORD \ +RUN --mount=type=secret,id=REPO_PASSWORD,required=true \ printf "machine ${REPO_DOMAIN} " > /etc/apt/auth.conf && \ printf "login ${REPO_USERNAME} " >> /etc/apt/auth.conf && \ printf "password " >> /etc/apt/auth.conf && \ @@ -72,7 +72,6 @@ RUN --mount=type=secret,id=REPO_PASSWORD \ --fail \ --netrc-file /etc/apt/auth.conf \ --output ${GPG_KEY} \ - --silent \ https://${REPO_DOMAIN}/repo/deb/debian-unstable/signalwire-freeswitch-repo.gpg && \ file ${GPG_KEY} && \ apt-get --quiet update && \ diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index e16da9a3648..ec183137b43 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -1,6 +1,12 @@ name: Build and Distribute on: + pull_request_target: + types: + - ready_for_review + paths: + - '**' + - '!.github/' pull_request: push: branches: @@ -23,7 +29,7 @@ jobs: run: | JSON="[]" - if [[ "${{ github.event_name }}" == "pull_request" ]]; then + if [[ "${{ github.event_name }}" == "pull_request" || "${{ github.event_name }}" == "pull_request_target" ]]; then JSON=$(jq -n '[ { "version": "bookworm", From 89a2db91c823086237600cfa3ce6bddfe92006e5 Mon Sep 17 00:00:00 2001 From: s3rj1k Date: Tue, 25 Jun 2024 17:00:45 +0200 Subject: [PATCH 34/56] [GHA] Increase verbosity for `mount=type=secret`. --- .github/docker/debian/bookworm/amd64/Dockerfile | 2 +- .github/docker/debian/bookworm/arm32v7/Dockerfile | 2 +- .github/docker/debian/bookworm/arm64v8/Dockerfile | 2 +- .github/docker/debian/bullseye/amd64/Dockerfile | 2 +- .github/docker/debian/bullseye/arm32v7/Dockerfile | 2 +- .github/docker/debian/bullseye/arm64v8/Dockerfile | 2 +- .github/docker/debian/buster/amd64/Dockerfile | 2 +- .github/docker/debian/buster/arm32v7/Dockerfile | 2 +- .github/docker/debian/buster/arm64v8/Dockerfile | 2 +- .github/workflows/build.yml | 2 +- 10 files changed, 10 insertions(+), 10 deletions(-) diff --git a/.github/docker/debian/bookworm/amd64/Dockerfile b/.github/docker/debian/bookworm/amd64/Dockerfile index 7b1dc8bf38b..3ef7b38b38d 100644 --- a/.github/docker/debian/bookworm/amd64/Dockerfile +++ b/.github/docker/debian/bookworm/amd64/Dockerfile @@ -8,7 +8,6 @@ ARG MAINTAINER_EMAIL="andrey@signalwire.com" # Credentials ARG REPO_DOMAIN=freeswitch.signalwire.com ARG REPO_USERNAME=user -ARG REPO_PASSWORD=password ARG BUILD_NUMBER=42 ARG GIT_SHA=0000000000 @@ -68,6 +67,7 @@ RUN --mount=type=secret,id=REPO_PASSWORD,required=true \ printf "login ${REPO_USERNAME} " >> /etc/apt/auth.conf && \ printf "password " >> /etc/apt/auth.conf && \ cat /run/secrets/REPO_PASSWORD >> /etc/apt/auth.conf && \ + sha512sum /run/secrets/REPO_PASSWORD && \ curl \ --fail \ --netrc-file /etc/apt/auth.conf \ diff --git a/.github/docker/debian/bookworm/arm32v7/Dockerfile b/.github/docker/debian/bookworm/arm32v7/Dockerfile index 08608032a4d..6259c7e8e92 100644 --- a/.github/docker/debian/bookworm/arm32v7/Dockerfile +++ b/.github/docker/debian/bookworm/arm32v7/Dockerfile @@ -8,7 +8,6 @@ ARG MAINTAINER_EMAIL="andrey@signalwire.com" # Credentials ARG REPO_DOMAIN=freeswitch.signalwire.com ARG REPO_USERNAME=user -ARG REPO_PASSWORD=password ARG BUILD_NUMBER=42 ARG GIT_SHA=0000000000 @@ -68,6 +67,7 @@ RUN --mount=type=secret,id=REPO_PASSWORD,required=true \ printf "login ${REPO_USERNAME} " >> /etc/apt/auth.conf && \ printf "password " >> /etc/apt/auth.conf && \ cat /run/secrets/REPO_PASSWORD >> /etc/apt/auth.conf && \ + sha512sum /run/secrets/REPO_PASSWORD && \ curl \ --fail \ --netrc-file /etc/apt/auth.conf \ diff --git a/.github/docker/debian/bookworm/arm64v8/Dockerfile b/.github/docker/debian/bookworm/arm64v8/Dockerfile index e509a587e6d..0df5a178fe3 100644 --- a/.github/docker/debian/bookworm/arm64v8/Dockerfile +++ b/.github/docker/debian/bookworm/arm64v8/Dockerfile @@ -8,7 +8,6 @@ ARG MAINTAINER_EMAIL="andrey@signalwire.com" # Credentials ARG REPO_DOMAIN=freeswitch.signalwire.com ARG REPO_USERNAME=user -ARG REPO_PASSWORD=password ARG BUILD_NUMBER=42 ARG GIT_SHA=0000000000 @@ -68,6 +67,7 @@ RUN --mount=type=secret,id=REPO_PASSWORD,required=true \ printf "login ${REPO_USERNAME} " >> /etc/apt/auth.conf && \ printf "password " >> /etc/apt/auth.conf && \ cat /run/secrets/REPO_PASSWORD >> /etc/apt/auth.conf && \ + sha512sum /run/secrets/REPO_PASSWORD && \ curl \ --fail \ --netrc-file /etc/apt/auth.conf \ diff --git a/.github/docker/debian/bullseye/amd64/Dockerfile b/.github/docker/debian/bullseye/amd64/Dockerfile index 0d11c84dec1..56586d338e3 100644 --- a/.github/docker/debian/bullseye/amd64/Dockerfile +++ b/.github/docker/debian/bullseye/amd64/Dockerfile @@ -8,7 +8,6 @@ ARG MAINTAINER_EMAIL="andrey@signalwire.com" # Credentials ARG REPO_DOMAIN=freeswitch.signalwire.com ARG REPO_USERNAME=user -ARG REPO_PASSWORD=password ARG BUILD_NUMBER=42 ARG GIT_SHA=0000000000 @@ -68,6 +67,7 @@ RUN --mount=type=secret,id=REPO_PASSWORD,required=true \ printf "login ${REPO_USERNAME} " >> /etc/apt/auth.conf && \ printf "password " >> /etc/apt/auth.conf && \ cat /run/secrets/REPO_PASSWORD >> /etc/apt/auth.conf && \ + sha512sum /run/secrets/REPO_PASSWORD && \ curl \ --fail \ --netrc-file /etc/apt/auth.conf \ diff --git a/.github/docker/debian/bullseye/arm32v7/Dockerfile b/.github/docker/debian/bullseye/arm32v7/Dockerfile index 7ea36d1bcc9..24c5804b68f 100644 --- a/.github/docker/debian/bullseye/arm32v7/Dockerfile +++ b/.github/docker/debian/bullseye/arm32v7/Dockerfile @@ -8,7 +8,6 @@ ARG MAINTAINER_EMAIL="andrey@signalwire.com" # Credentials ARG REPO_DOMAIN=freeswitch.signalwire.com ARG REPO_USERNAME=user -ARG REPO_PASSWORD=password ARG BUILD_NUMBER=42 ARG GIT_SHA=0000000000 @@ -68,6 +67,7 @@ RUN --mount=type=secret,id=REPO_PASSWORD,required=true \ printf "login ${REPO_USERNAME} " >> /etc/apt/auth.conf && \ printf "password " >> /etc/apt/auth.conf && \ cat /run/secrets/REPO_PASSWORD >> /etc/apt/auth.conf && \ + sha512sum /run/secrets/REPO_PASSWORD && \ curl \ --fail \ --netrc-file /etc/apt/auth.conf \ diff --git a/.github/docker/debian/bullseye/arm64v8/Dockerfile b/.github/docker/debian/bullseye/arm64v8/Dockerfile index ae3429cff72..f5a6a906c48 100644 --- a/.github/docker/debian/bullseye/arm64v8/Dockerfile +++ b/.github/docker/debian/bullseye/arm64v8/Dockerfile @@ -8,7 +8,6 @@ ARG MAINTAINER_EMAIL="andrey@signalwire.com" # Credentials ARG REPO_DOMAIN=freeswitch.signalwire.com ARG REPO_USERNAME=user -ARG REPO_PASSWORD=password ARG BUILD_NUMBER=42 ARG GIT_SHA=0000000000 @@ -68,6 +67,7 @@ RUN --mount=type=secret,id=REPO_PASSWORD,required=true \ printf "login ${REPO_USERNAME} " >> /etc/apt/auth.conf && \ printf "password " >> /etc/apt/auth.conf && \ cat /run/secrets/REPO_PASSWORD >> /etc/apt/auth.conf && \ + sha512sum /run/secrets/REPO_PASSWORD && \ curl \ --fail \ --netrc-file /etc/apt/auth.conf \ diff --git a/.github/docker/debian/buster/amd64/Dockerfile b/.github/docker/debian/buster/amd64/Dockerfile index 9f3d03f14c8..8e88ce56e69 100644 --- a/.github/docker/debian/buster/amd64/Dockerfile +++ b/.github/docker/debian/buster/amd64/Dockerfile @@ -8,7 +8,6 @@ ARG MAINTAINER_EMAIL="andrey@signalwire.com" # Credentials ARG REPO_DOMAIN=freeswitch.signalwire.com ARG REPO_USERNAME=user -ARG REPO_PASSWORD=password ARG BUILD_NUMBER=42 ARG GIT_SHA=0000000000 @@ -69,6 +68,7 @@ RUN --mount=type=secret,id=REPO_PASSWORD,required=true \ printf "login ${REPO_USERNAME} " >> /etc/apt/auth.conf && \ printf "password " >> /etc/apt/auth.conf && \ cat /run/secrets/REPO_PASSWORD >> /etc/apt/auth.conf && \ + sha512sum /run/secrets/REPO_PASSWORD && \ curl \ --fail \ --netrc-file /etc/apt/auth.conf \ diff --git a/.github/docker/debian/buster/arm32v7/Dockerfile b/.github/docker/debian/buster/arm32v7/Dockerfile index 362c2a66027..9326979622a 100644 --- a/.github/docker/debian/buster/arm32v7/Dockerfile +++ b/.github/docker/debian/buster/arm32v7/Dockerfile @@ -8,7 +8,6 @@ ARG MAINTAINER_EMAIL="andrey@signalwire.com" # Credentials ARG REPO_DOMAIN=freeswitch.signalwire.com ARG REPO_USERNAME=user -ARG REPO_PASSWORD=password ARG BUILD_NUMBER=42 ARG GIT_SHA=0000000000 @@ -68,6 +67,7 @@ RUN --mount=type=secret,id=REPO_PASSWORD,required=true \ printf "login ${REPO_USERNAME} " >> /etc/apt/auth.conf && \ printf "password " >> /etc/apt/auth.conf && \ cat /run/secrets/REPO_PASSWORD >> /etc/apt/auth.conf && \ + sha512sum /run/secrets/REPO_PASSWORD && \ curl \ --fail \ --netrc-file /etc/apt/auth.conf \ diff --git a/.github/docker/debian/buster/arm64v8/Dockerfile b/.github/docker/debian/buster/arm64v8/Dockerfile index ed678405a92..71aca460522 100644 --- a/.github/docker/debian/buster/arm64v8/Dockerfile +++ b/.github/docker/debian/buster/arm64v8/Dockerfile @@ -8,7 +8,6 @@ ARG MAINTAINER_EMAIL="andrey@signalwire.com" # Credentials ARG REPO_DOMAIN=freeswitch.signalwire.com ARG REPO_USERNAME=user -ARG REPO_PASSWORD=password ARG BUILD_NUMBER=42 ARG GIT_SHA=0000000000 @@ -68,6 +67,7 @@ RUN --mount=type=secret,id=REPO_PASSWORD,required=true \ printf "login ${REPO_USERNAME} " >> /etc/apt/auth.conf && \ printf "password " >> /etc/apt/auth.conf && \ cat /run/secrets/REPO_PASSWORD >> /etc/apt/auth.conf && \ + sha512sum /run/secrets/REPO_PASSWORD && \ curl \ --fail \ --netrc-file /etc/apt/auth.conf \ diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index ec183137b43..a3be4b2c2c4 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -93,7 +93,7 @@ jobs: PROXY_URL: ${{ secrets.PROXY_URL }} USERNAME: ${{ secrets.USERNAME }} TELEPORT_TOKEN: ${{ secrets.TELEPORT_TOKEN }} - REPO_USERNAME: 'signalwire' + REPO_USERNAME: 'SWUSERNAME' REPO_PASSWORD: ${{ secrets.REPOTOKEN }} meta: From c8b8f0d9614987fef2b07b48ba4d5ac9ddbf9e44 Mon Sep 17 00:00:00 2001 From: s3rj1k Date: Tue, 25 Jun 2024 20:35:43 +0200 Subject: [PATCH 35/56] [GHA] Rework `pull_request_target` workflow. --- .github/workflows/build-from-fork.yml | 75 +++++++++++++++++++++++++++ .github/workflows/build.yml | 8 +-- 2 files changed, 76 insertions(+), 7 deletions(-) create mode 100644 .github/workflows/build-from-fork.yml diff --git a/.github/workflows/build-from-fork.yml b/.github/workflows/build-from-fork.yml new file mode 100644 index 00000000000..0fe53c239a3 --- /dev/null +++ b/.github/workflows/build-from-fork.yml @@ -0,0 +1,75 @@ +name: Build from fork + +on: + pull_request_target: + types: + - ready_for_review + paths: + - '**' + - '!.github/' + workflow_dispatch: + +concurrency: + group: ${{ github.head_ref || github.ref }} + +jobs: + deb: + name: 'DEB' + strategy: + max-parallel: 1 + fail-fast: true + matrix: + os: + - debian + version: + - bookworm + - bullseye + - buster + platform: + - name: amd64 + runner: ubuntu-latest + - name: arm32v7 + runner: linux-arm64-4-core-public + - name: arm64v8 + runner: linux-arm64-4-core-public + exclude: + - version: bookworm + platform: + name: amd64 + - version: bookworm + platform: + name: arm64v8 + - version: bullseye + + runs-on: ${{ matrix.platform.runner }} + + steps: + - name: Checkout code + uses: actions/checkout@v4 + with: + ref: ${{ github.event.pull_request.head.sha }} + fetch-depth: 0 + path: code + + - name: Checkout reusable actions + uses: actions/checkout@v4 + with: + repository: signalwire/actions-template + ref: main + fetch-depth: 1 + path: actions + sparse-checkout: | + .github/actions/docker-build-artifacts/action.yml + sparse-checkout-cone-mode: false + + - name: Build artifacts via Docker + uses: ./actions/.github/actions/docker-build-artifacts + with: + REPO_DOMAIN: freeswitch.signalwire.com + PLATFORM: ${{ matrix.platform.name }} + DOCKERFILE: .github/docker/${{ matrix.os }}/${{ matrix.version }}/${{ matrix.platform.name }}/Dockerfile + MAINTAINER: 'Andrey Volk ' + WORKING_DIRECTORY: code + env: + REPO_USERNAME: 'SWUSERNAME' + REPO_PASSWORD: ${{ secrets.REPO_PASSWORD }} diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index a3be4b2c2c4..df3baa49924 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -1,12 +1,6 @@ name: Build and Distribute on: - pull_request_target: - types: - - ready_for_review - paths: - - '**' - - '!.github/' pull_request: push: branches: @@ -29,7 +23,7 @@ jobs: run: | JSON="[]" - if [[ "${{ github.event_name }}" == "pull_request" || "${{ github.event_name }}" == "pull_request_target" ]]; then + if [[ "${{ github.event_name }}" == "pull_request" ]]; then JSON=$(jq -n '[ { "version": "bookworm", From 4a15dc1a6252a53ba18c76d595509c083de7d197 Mon Sep 17 00:00:00 2001 From: s3rj1k Date: Tue, 25 Jun 2024 21:38:29 +0200 Subject: [PATCH 36/56] [GHA] Pin workflow to repository. --- .github/workflows/build-from-fork.yml | 1 - .github/workflows/build.yml | 3 +++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/.github/workflows/build-from-fork.yml b/.github/workflows/build-from-fork.yml index 0fe53c239a3..b98cadb1344 100644 --- a/.github/workflows/build-from-fork.yml +++ b/.github/workflows/build-from-fork.yml @@ -7,7 +7,6 @@ on: paths: - '**' - '!.github/' - workflow_dispatch: concurrency: group: ${{ github.head_ref || github.ref }} diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index df3baa49924..5b7cfb36657 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -14,6 +14,8 @@ concurrency: jobs: excludes: + name: 'Excludes' + if: github.repository == 'signalwire/freeswitch' runs-on: ubuntu-latest outputs: deb: ${{ steps.deb.outputs.excludes }} @@ -47,6 +49,7 @@ jobs: deb: name: 'DEB' + if: github.repository == 'signalwire/freeswitch' permissions: id-token: write contents: read From 318953d078c1b109120cac24af231eaf8e7b63f1 Mon Sep 17 00:00:00 2001 From: s3rj1k Date: Tue, 25 Jun 2024 22:15:53 +0200 Subject: [PATCH 37/56] [GHA] Pin workflow to repository. --- .github/workflows/build.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 5b7cfb36657..59958dfc0a5 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -15,7 +15,7 @@ concurrency: jobs: excludes: name: 'Excludes' - if: github.repository == 'signalwire/freeswitch' + if: github.event.pull_request.head.repo.full_name == github.repository runs-on: ubuntu-latest outputs: deb: ${{ steps.deb.outputs.excludes }} @@ -49,7 +49,7 @@ jobs: deb: name: 'DEB' - if: github.repository == 'signalwire/freeswitch' + if: github.event.pull_request.head.repo.full_name == github.repository permissions: id-token: write contents: read From 460d1c19cfb191e73396650727b93ee8936d744d Mon Sep 17 00:00:00 2001 From: s3rj1k Date: Thu, 27 Jun 2024 13:25:53 +0200 Subject: [PATCH 38/56] [GHA] Remove `build-from-fork.yml`. --- .github/workflows/build-from-fork.yml | 74 --------------------------- 1 file changed, 74 deletions(-) delete mode 100644 .github/workflows/build-from-fork.yml diff --git a/.github/workflows/build-from-fork.yml b/.github/workflows/build-from-fork.yml deleted file mode 100644 index b98cadb1344..00000000000 --- a/.github/workflows/build-from-fork.yml +++ /dev/null @@ -1,74 +0,0 @@ -name: Build from fork - -on: - pull_request_target: - types: - - ready_for_review - paths: - - '**' - - '!.github/' - -concurrency: - group: ${{ github.head_ref || github.ref }} - -jobs: - deb: - name: 'DEB' - strategy: - max-parallel: 1 - fail-fast: true - matrix: - os: - - debian - version: - - bookworm - - bullseye - - buster - platform: - - name: amd64 - runner: ubuntu-latest - - name: arm32v7 - runner: linux-arm64-4-core-public - - name: arm64v8 - runner: linux-arm64-4-core-public - exclude: - - version: bookworm - platform: - name: amd64 - - version: bookworm - platform: - name: arm64v8 - - version: bullseye - - runs-on: ${{ matrix.platform.runner }} - - steps: - - name: Checkout code - uses: actions/checkout@v4 - with: - ref: ${{ github.event.pull_request.head.sha }} - fetch-depth: 0 - path: code - - - name: Checkout reusable actions - uses: actions/checkout@v4 - with: - repository: signalwire/actions-template - ref: main - fetch-depth: 1 - path: actions - sparse-checkout: | - .github/actions/docker-build-artifacts/action.yml - sparse-checkout-cone-mode: false - - - name: Build artifacts via Docker - uses: ./actions/.github/actions/docker-build-artifacts - with: - REPO_DOMAIN: freeswitch.signalwire.com - PLATFORM: ${{ matrix.platform.name }} - DOCKERFILE: .github/docker/${{ matrix.os }}/${{ matrix.version }}/${{ matrix.platform.name }}/Dockerfile - MAINTAINER: 'Andrey Volk ' - WORKING_DIRECTORY: code - env: - REPO_USERNAME: 'SWUSERNAME' - REPO_PASSWORD: ${{ secrets.REPO_PASSWORD }} From 5f4036eaac7ca52b3b511ac4eeecd267f8d4d454 Mon Sep 17 00:00:00 2001 From: s3rj1k Date: Mon, 22 Jul 2024 16:39:05 +0200 Subject: [PATCH 39/56] [GHA] Disable repo name check. --- .github/workflows/build.yml | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 59958dfc0a5..2d1ddf07fc9 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -5,6 +5,7 @@ on: push: branches: - master + - v1.10 paths: - "**" workflow_dispatch: @@ -15,7 +16,7 @@ concurrency: jobs: excludes: name: 'Excludes' - if: github.event.pull_request.head.repo.full_name == github.repository + # if: github.event.pull_request.head.repo.full_name == github.repository runs-on: ubuntu-latest outputs: deb: ${{ steps.deb.outputs.excludes }} @@ -49,7 +50,7 @@ jobs: deb: name: 'DEB' - if: github.event.pull_request.head.repo.full_name == github.repository + # if: github.event.pull_request.head.repo.full_name == github.repository permissions: id-token: write contents: read From 19270516bf9bf8b2854aa9788b8cba7de55c9314 Mon Sep 17 00:00:00 2001 From: s3rj1k Date: Mon, 22 Jul 2024 16:57:32 +0200 Subject: [PATCH 40/56] [UTIL] Generate reproducible source archive. --- debian/util.sh | 33 +++++++++++++++++++++++++++++---- 1 file changed, 29 insertions(+), 4 deletions(-) diff --git a/debian/util.sh b/debian/util.sh index 46c1f953461..dab53b1d47a 100755 --- a/debian/util.sh +++ b/debian/util.sh @@ -203,11 +203,16 @@ create_orig () { done shift $(($OPTIND-1)) - local orig + local commit_epoch=$(git log -1 --format=%ct) + local source_date=$(date -u -d @$commit_epoch +'%Y-%m-%d %H:%M:%S') + + local orig git_archive_prefix if $auto_orig; then orig="../freeswitch_$(debian/version-omit_revision.pl).orig.tar.xz" + git_archive_prefix="freeswitch/" else orig="../freeswitch_$(mk_dver "$uver")~$(lsb_release -sc).orig.tar.xz" + git_archive_prefix="freeswitch-$uver/" fi mv .gitattributes .gitattributes.orig @@ -226,12 +231,32 @@ create_orig () { git add -f configure.ac .version git commit --allow-empty -m "nightly v$uver" + local tmpsrcdir="$(mktemp -d)" git archive -v \ --worktree-attributes \ --format=tar \ - --prefix=freeswitch-$uver/ \ - HEAD \ - | xz -c -${zl}v > $orig + --prefix=$git_archive_prefix \ + HEAD | tar --extract --directory="$tmpsrcdir" + + # https://www.gnu.org/software/tar/manual/html_section/Reproducibility.html + tar \ + --sort=name \ + --format=posix \ + --pax-option='exthdr.name=%d/PaxHeaders/%f' \ + --pax-option='delete=atime,delete=ctime' \ + --clamp-mtime \ + --mtime="$source_date" \ + --numeric-owner \ + --owner=0 \ + --group=0 \ + --mode='go+u,go-w' \ + --create \ + --directory="$tmpsrcdir" \ + . | xz -v -c -${zl} > "$orig" && \ + rm -rf "$tmpsrcdir" + + echo "Source archive checksum:" + sha256sum $orig mv .gitattributes.orig .gitattributes From 93072c9503ed737303d0995ddeb7db330f17bdde Mon Sep 17 00:00:00 2001 From: Andrey Volk Date: Thu, 25 Jul 2024 21:46:40 +0300 Subject: [PATCH 41/56] [core] check_rtcp_and_ice() - stringop-overflow: Fix build on Debian Bookworm. --- src/switch_rtp.c | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/src/switch_rtp.c b/src/switch_rtp.c index 1125e2f59bc..3d9e2ae6240 100644 --- a/src/switch_rtp.c +++ b/src/switch_rtp.c @@ -185,6 +185,10 @@ typedef struct { char body[SWITCH_RTCP_MAX_BUF_LEN]; } rtcp_msg_t; +typedef struct { + switch_rtcp_hdr_t header; + uint32_t ssrc; +} sdes_ssrc_t; typedef enum { VAD_FIRE_TALK = (1 << 0), @@ -2228,9 +2232,9 @@ static int check_rtcp_and_ice(switch_rtp_t *rtp_session) struct switch_rtcp_report_block *rtcp_report_block = NULL; switch_size_t rtcp_bytes = sizeof(struct switch_rtcp_hdr_s)+sizeof(uint32_t); /* add size of the packet header and the ssrc */ switch_rtcp_hdr_t *sdes; + sdes_ssrc_t *sdes_ssrc; uint8_t *p; switch_size_t sdes_bytes = sizeof(struct switch_rtcp_hdr_s); - uint32_t *ssrc; switch_rtcp_sdes_unit_t *unit; switch_bool_t is_only_receiver = FALSE; @@ -2426,14 +2430,13 @@ static int check_rtcp_and_ice(switch_rtp_t *rtp_session) //SDES + CNAME p = (uint8_t *) (&rtp_session->rtcp_send_msg) + rtcp_bytes; - sdes = (switch_rtcp_hdr_t *) p; + sdes_ssrc = (sdes_ssrc_t *) p; + sdes = &sdes_ssrc->header; sdes->version = 2; sdes->type = _RTCP_PT_SDES; sdes->count = 1; sdes->p = 0; - p = (uint8_t *) (sdes) + sdes_bytes; - ssrc = (uint32_t *) p; - *ssrc = htonl(rtp_session->ssrc); + sdes_ssrc->ssrc = htonl(rtp_session->ssrc); sdes_bytes += sizeof(uint32_t); From b38d87941351b509382d6d83afbbcc1a7f150a44 Mon Sep 17 00:00:00 2001 From: Andrey Volk Date: Fri, 7 Jun 2024 14:50:56 +0300 Subject: [PATCH 42/56] [Core] rtp_common_write: Coverity 1227609 Calling risky function --- src/switch_rtp.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/switch_rtp.c b/src/switch_rtp.c index 3d9e2ae6240..a27703f4497 100644 --- a/src/switch_rtp.c +++ b/src/switch_rtp.c @@ -8267,11 +8267,11 @@ static int rtp_common_write(switch_rtp_t *rtp_session, if (switch_rtp_test_flag(rtp_session, SWITCH_RTP_FLAG_VIDEO)) { int external = (flags && *flags & SFF_EXTERNAL); /* Normalize the timestamps to our own base by generating a made up starting point then adding the measured deltas to that base - so if the timestamps and ssrc of the source change, it will not break the other end's jitter bufffer / decoder etc *cough* CHROME *cough* + so if the timestamps and ssrc of the source change, it will not break the other end's jitter buffer / decoder etc *cough* CHROME *cough* */ if (!rtp_session->ts_norm.ts) { - rtp_session->ts_norm.ts = (uint32_t) rand() % 1000000 + 1; + rtp_session->ts_norm.ts = (uint32_t) switch_rand() % 1000000 + 1; } if (!rtp_session->ts_norm.last_ssrc || send_msg->header.ssrc != rtp_session->ts_norm.last_ssrc || rtp_session->ts_norm.last_external != external) { From a99ed5c46f03094703befa056e1c95e84cbf9a14 Mon Sep 17 00:00:00 2001 From: Andrey Volk Date: Mon, 29 Jul 2024 21:50:13 +0300 Subject: [PATCH 43/56] [Core] Introduce SWITCH_RAND_MAX to switch_rand() --- src/include/switch_types.h | 7 +++++++ src/switch_utils.c | 8 ++++---- 2 files changed, 11 insertions(+), 4 deletions(-) diff --git a/src/include/switch_types.h b/src/include/switch_types.h index f8ae00790d9..c4c9131bd6c 100644 --- a/src/include/switch_types.h +++ b/src/include/switch_types.h @@ -599,6 +599,13 @@ SWITCH_DECLARE_DATA extern switch_filenames SWITCH_GLOBAL_filenames; #define SWITCH_ACCEPTABLE_INTERVAL(_i) (_i && _i <= SWITCH_MAX_INTERVAL && (_i % 10) == 0) +/* Check if RAND_MAX is a power of 2 minus 1 or in other words all bits set */ +#if ((RAND_MAX) & ((RAND_MAX) + 1)) == 0 && (RAND_MAX) != 0 +#define SWITCH_RAND_MAX RAND_MAX +#else +#define SWITCH_RAND_MAX 0x7fff +#endif + typedef enum { SWITCH_RW_READ, SWITCH_RW_WRITE diff --git a/src/switch_utils.c b/src/switch_utils.c index 64577d3997d..90c5de059a5 100644 --- a/src/switch_utils.c +++ b/src/switch_utils.c @@ -4835,8 +4835,8 @@ SWITCH_DECLARE(int) switch_rand(void) BCryptCloseAlgorithmProvider(hAlgorithm, 0); - /* Make sure we return from 0 to RAND_MAX */ - return (random_number & 0x7FFF); + /* Make sure we return from 0 to SWITCH_RAND_MAX */ + return (random_number & (SWITCH_RAND_MAX)); #elif defined(__unix__) || defined(__APPLE__) int random_fd = open("/dev/urandom", O_RDONLY); ssize_t result; @@ -4865,8 +4865,8 @@ SWITCH_DECLARE(int) switch_rand(void) close(random_fd); - /* Make sure we return from 0 to RAND_MAX */ - return (random_number & 0x7FFF); + /* Make sure we return from 0 to SWITCH_RAND_MAX */ + return (random_number & (SWITCH_RAND_MAX)); #else return rand(); #endif From b43ae84564a971fe446759e3c9fce49be65b2bee Mon Sep 17 00:00:00 2001 From: Andrey Volk Date: Fri, 7 Jun 2024 14:53:44 +0300 Subject: [PATCH 44/56] [Core] switch_rtp_create: Coverity 1227620 Calling risky function --- src/switch_rtp.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/switch_rtp.c b/src/switch_rtp.c index a27703f4497..6f33b479926 100644 --- a/src/switch_rtp.c +++ b/src/switch_rtp.c @@ -4517,7 +4517,7 @@ SWITCH_DECLARE(switch_status_t) switch_rtp_create(switch_rtp_t **new_rtp_session switch_sockaddr_create(&rtp_session->rtcp_from_addr, pool); } - rtp_session->seq = (uint16_t) rand(); + rtp_session->seq = (uint16_t) switch_rand(); rtp_session->ssrc = (uint32_t) ((intptr_t) rtp_session + (switch_time_t) switch_epoch_time_now(NULL)); #ifdef DEBUG_TS_ROLLOVER rtp_session->last_write_ts = TS_ROLLOVER_START; From 1ff5a6593cedc8c14855d314f614f9460fdcf7ad Mon Sep 17 00:00:00 2001 From: Andrey Volk Date: Thu, 6 Jun 2024 12:16:42 +0300 Subject: [PATCH 45/56] [Core] switch_rtp.c: Coverity 1500271, 1500287: Out-of-bounds access (OVERRUN) --- src/switch_rtp.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/switch_rtp.c b/src/switch_rtp.c index 6f33b479926..46e13253b73 100644 --- a/src/switch_rtp.c +++ b/src/switch_rtp.c @@ -8520,9 +8520,9 @@ static int rtp_common_write(switch_rtp_t *rtp_session, } if (!rtp_session->flags[SWITCH_RTP_FLAG_SECURE_SEND_MKI]) { - stat = srtp_protect(rtp_session->send_ctx[rtp_session->srtp_idx_rtp], &send_msg->header, &sbytes); + stat = srtp_protect(rtp_session->send_ctx[rtp_session->srtp_idx_rtp], send_msg, &sbytes); } else { - stat = srtp_protect_mki(rtp_session->send_ctx[rtp_session->srtp_idx_rtp], &send_msg->header, &sbytes, 1, SWITCH_CRYPTO_MKI_INDEX); + stat = srtp_protect_mki(rtp_session->send_ctx[rtp_session->srtp_idx_rtp], send_msg, &sbytes, 1, SWITCH_CRYPTO_MKI_INDEX); } if (stat) { @@ -9044,9 +9044,9 @@ SWITCH_DECLARE(switch_status_t) switch_rtp_write_raw(switch_rtp_t *rtp_session, } if (!rtp_session->flags[SWITCH_RTP_FLAG_SECURE_SEND_MKI]) { - stat = srtp_protect(rtp_session->send_ctx[rtp_session->srtp_idx_rtp], &rtp_session->write_msg.header, &sbytes); + stat = srtp_protect(rtp_session->send_ctx[rtp_session->srtp_idx_rtp], &rtp_session->write_msg, &sbytes); } else { - stat = srtp_protect_mki(rtp_session->send_ctx[rtp_session->srtp_idx_rtp], &rtp_session->write_msg.header, &sbytes, 1, SWITCH_CRYPTO_MKI_INDEX); + stat = srtp_protect_mki(rtp_session->send_ctx[rtp_session->srtp_idx_rtp], &rtp_session->write_msg, &sbytes, 1, SWITCH_CRYPTO_MKI_INDEX); } if (stat) { From 11e3cff7cb9097c347663fe3092947648eadef91 Mon Sep 17 00:00:00 2001 From: Andrey Volk Date: Thu, 6 Jun 2024 12:58:57 +0300 Subject: [PATCH 46/56] [Core] switch_find_local_ip: Coverity 1024290 Resource leak. --- src/switch_utils.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/switch_utils.c b/src/switch_utils.c index 90c5de059a5..1af2011dbd2 100644 --- a/src/switch_utils.c +++ b/src/switch_utils.c @@ -2015,7 +2015,7 @@ SWITCH_DECLARE(switch_status_t) switch_find_local_ip(char *buf, int len, int *ma } doh: - if (tmp_socket > 0) { + if (tmp_socket >= 0) { close(tmp_socket); } #endif From 9f7c64b6fafa1afb53c6ce4c3d944767382f4544 Mon Sep 17 00:00:00 2001 From: Andrey Volk Date: Thu, 6 Jun 2024 12:47:07 +0300 Subject: [PATCH 47/56] [Core] switch_stun.c: Coverity 1468480: Out-of-bounds access (OVERRUN) --- src/include/switch_stun.h | 7 +++++++ src/switch_stun.c | 6 +++++- 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/src/include/switch_stun.h b/src/include/switch_stun.h index 54b03088e81..ca612c06aab 100644 --- a/src/include/switch_stun.h +++ b/src/include/switch_stun.h @@ -141,6 +141,13 @@ typedef struct { uint32_t address; } switch_stun_ip_t; +typedef struct { + uint8_t wasted; + uint8_t family; + uint16_t port; + uint8_t address[16]; +} switch_stun_ipv6_t; + #if SWITCH_BYTE_ORDER == __BIG_ENDIAN typedef struct { diff --git a/src/switch_stun.c b/src/switch_stun.c index d4a2c965032..2ab1f41d5a1 100644 --- a/src/switch_stun.c +++ b/src/switch_stun.c @@ -401,13 +401,17 @@ SWITCH_DECLARE(uint8_t) switch_stun_packet_attribute_get_mapped_address(switch_s SWITCH_DECLARE(uint8_t) switch_stun_packet_attribute_get_xor_mapped_address(switch_stun_packet_attribute_t *attribute, switch_stun_packet_header_t *header, char *ipstr, switch_size_t iplen, uint16_t *port) { switch_stun_ip_t *ip; + switch_stun_ipv6_t *ipv6; uint8_t x, *i; char *p = ipstr; ip = (switch_stun_ip_t *) attribute->value; if (ip->family == 2) { - uint8_t *v6addr = (uint8_t *) &ip->address; + uint8_t *v6addr; + + ipv6 = (switch_stun_ipv6_t *)attribute->value; + v6addr = (uint8_t *) &ipv6->address; v6_xor(v6addr, (uint8_t *)header->id); inet_ntop(AF_INET6, v6addr, ipstr, iplen); } else { From 6fbb49d66cdd6a630b30ad0b731707fc1f8c2903 Mon Sep 17 00:00:00 2001 From: Andrey Volk Date: Sun, 9 Jun 2024 13:12:11 +0300 Subject: [PATCH 48/56] [mod_mariadb] mariadb_dsn: Coverity 1546237 COPY_INSTEAD_OF_MOVE --- src/mod/databases/mod_mariadb/mariadb_dsn.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/mod/databases/mod_mariadb/mariadb_dsn.cpp b/src/mod/databases/mod_mariadb/mariadb_dsn.cpp index eb7bfeedbd7..06091eb4696 100644 --- a/src/mod/databases/mod_mariadb/mariadb_dsn.cpp +++ b/src/mod/databases/mod_mariadb/mariadb_dsn.cpp @@ -83,11 +83,11 @@ class mariadb_dsn { if ("server" == key || "host" == key) { _host = value; } else if ("uid" == key || "user" == key || "username" == key) { - _user = value; + _user = std::move(value); } else if ("pwd" == key || "passwd" == key || "password" == key) { - _passwd = value; + _passwd = std::move(value); } else if ("database" == key || "db" == key) { - _db = value; + _db = std::move(value); } else if ("port" == key) { _port = std::stoi(value); } else if ("option" == key || "options" == key) { From 3c47eadd28505640113a76c3b82e2216be22dbbe Mon Sep 17 00:00:00 2001 From: Andrey Volk Date: Sun, 9 Jun 2024 13:13:43 +0300 Subject: [PATCH 49/56] [mod_v8] SayPhrase: Coverity 1546153 COPY_INSTEAD_OF_MOVE --- src/mod/languages/mod_v8/src/fssession.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/mod/languages/mod_v8/src/fssession.cpp b/src/mod/languages/mod_v8/src/fssession.cpp index d3bc77ae13b..2510457175a 100644 --- a/src/mod/languages/mod_v8/src/fssession.cpp +++ b/src/mod/languages/mod_v8/src/fssession.cpp @@ -671,7 +671,7 @@ JS_SESSION_FUNCTION_IMPL(SayPhrase) String::Utf8Value str(info[2]); tmp = js_safe_str(*str); if (!zstr(tmp.c_str())) { - phrase_lang = tmp; + phrase_lang = std::move(tmp); } } From 0974bd112cb0489040386c68889ebf2964e8029c Mon Sep 17 00:00:00 2001 From: Andrey Volk Date: Fri, 7 Jun 2024 14:52:27 +0300 Subject: [PATCH 50/56] [Core] switch_simple_email: Coverity 1227612 Calling risky function --- src/switch_utils.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/switch_utils.c b/src/switch_utils.c index 1af2011dbd2..aa3fc74cae3 100644 --- a/src/switch_utils.c +++ b/src/switch_utils.c @@ -1160,7 +1160,7 @@ SWITCH_DECLARE(switch_bool_t) switch_simple_email(const char *to, switch_safe_free(dupfile); } - switch_snprintf(filename, 80, "%s%smail.%d%04x", SWITCH_GLOBAL_dirs.temp_dir, SWITCH_PATH_SEPARATOR, (int)(switch_time_t) switch_epoch_time_now(NULL), rand() & 0xffff); + switch_snprintf(filename, 80, "%s%smail.%d%04x", SWITCH_GLOBAL_dirs.temp_dir, SWITCH_PATH_SEPARATOR, (int)(switch_time_t) switch_epoch_time_now(NULL), switch_rand() & 0xffff); if ((fd = open(filename, O_WRONLY | O_CREAT | O_TRUNC, 0644)) > -1) { if (file) { From 844cce8595a9221e2620e1d61a4171a6a6f85524 Mon Sep 17 00:00:00 2001 From: Andrey Volk Date: Thu, 6 Jun 2024 13:07:43 +0300 Subject: [PATCH 51/56] [mod_mariadb] Coverity 1546237 COPY_INSTEAD_OF_MOVE --- src/mod/databases/mod_mariadb/mariadb_dsn.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/mod/databases/mod_mariadb/mariadb_dsn.cpp b/src/mod/databases/mod_mariadb/mariadb_dsn.cpp index 06091eb4696..aa7fb894122 100644 --- a/src/mod/databases/mod_mariadb/mariadb_dsn.cpp +++ b/src/mod/databases/mod_mariadb/mariadb_dsn.cpp @@ -81,7 +81,7 @@ class mariadb_dsn { std::string value = pair[1]; if ("server" == key || "host" == key) { - _host = value; + _host = std::move(value); } else if ("uid" == key || "user" == key || "username" == key) { _user = std::move(value); } else if ("pwd" == key || "passwd" == key || "password" == key) { From 9d379b707171b212dcc7d4b0f9db860719eeefa4 Mon Sep 17 00:00:00 2001 From: Andrey Volk Date: Fri, 7 Jun 2024 14:55:10 +0300 Subject: [PATCH 52/56] [Core] switch_core_port_allocator_request_port: Coverity 1227622 Calling risky function --- src/switch_core_port_allocator.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/switch_core_port_allocator.c b/src/switch_core_port_allocator.c index 074ce5f5ea5..2ed956c6fbd 100644 --- a/src/switch_core_port_allocator.c +++ b/src/switch_core_port_allocator.c @@ -155,7 +155,7 @@ SWITCH_DECLARE(switch_status_t) switch_core_port_allocator_request_port(switch_c uint32_t tries = 0; /* randomly pick a port */ - index = rand() % alloc->track_len; + index = switch_rand() % alloc->track_len; /* if it is used walk up the list to find a free one */ while (alloc->track[index] && tries < alloc->track_len) { From c736458a21368fba462957ba98aa3f948facc313 Mon Sep 17 00:00:00 2001 From: Andrey Volk Date: Fri, 7 Jun 2024 14:56:56 +0300 Subject: [PATCH 53/56] [Core] switch_stun_random_string: Coverity 1227623 Calling risky function --- src/switch_stun.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/switch_stun.c b/src/switch_stun.c index 2ab1f41d5a1..d58dd6fd93d 100644 --- a/src/switch_stun.c +++ b/src/switch_stun.c @@ -135,7 +135,7 @@ SWITCH_DECLARE(void) switch_stun_random_string(char *buf, uint16_t len, char *se max = (int) strlen(set); for (x = 0; x < len; x++) { - int j = (int) (max * 1.0 * rand() / (RAND_MAX + 1.0)); + int j = (int) (max * 1.0 * switch_rand() / (SWITCH_RAND_MAX + 1.0)); buf[x] = set[j]; } } From 251da2f905ed4585cea1e263f585a5dd9e42be05 Mon Sep 17 00:00:00 2001 From: Andrey Volk Date: Fri, 7 Jun 2024 14:57:53 +0300 Subject: [PATCH 54/56] [mod_mariadb] mariadb_send_query: Coverity 1518917 Calling risky function --- src/mod/databases/mod_mariadb/mod_mariadb.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/mod/databases/mod_mariadb/mod_mariadb.c b/src/mod/databases/mod_mariadb/mod_mariadb.c index 09b67468bb3..c39c2ce8188 100644 --- a/src/mod/databases/mod_mariadb/mod_mariadb.c +++ b/src/mod/databases/mod_mariadb/mod_mariadb.c @@ -641,7 +641,7 @@ switch_status_t mariadb_send_query(mariadb_handle_t *handle, const char* sql) switch_safe_free(err_str); /* We are waiting for 500 ms and random time is not more than 500 ms. This is necessary so that the delay on the primary and secondary servers does not coincide and deadlock does not occur again. */ - switch_yield(500 + (rand() & 511)); + switch_yield(500 + (switch_rand() & 511)); goto again; } From b39f14679f6e030ce6a9da0fb754b5cb03bd0bd5 Mon Sep 17 00:00:00 2001 From: s3rj1k Date: Fri, 2 Aug 2024 18:54:28 +0200 Subject: [PATCH 55/56] [GHA] Remove Debian `Buster`. --- .github/docker/debian/buster/amd64/Dockerfile | 103 ------------------ .../docker/debian/buster/arm32v7/Dockerfile | 102 ----------------- .../docker/debian/buster/arm64v8/Dockerfile | 102 ----------------- .github/workflows/build.yml | 12 +- 4 files changed, 7 insertions(+), 312 deletions(-) delete mode 100644 .github/docker/debian/buster/amd64/Dockerfile delete mode 100644 .github/docker/debian/buster/arm32v7/Dockerfile delete mode 100644 .github/docker/debian/buster/arm64v8/Dockerfile diff --git a/.github/docker/debian/buster/amd64/Dockerfile b/.github/docker/debian/buster/amd64/Dockerfile deleted file mode 100644 index 8e88ce56e69..00000000000 --- a/.github/docker/debian/buster/amd64/Dockerfile +++ /dev/null @@ -1,103 +0,0 @@ -ARG BUILDER_IMAGE=debian:buster-20240513 - -FROM ${BUILDER_IMAGE} AS builder - -ARG MAINTAINER_NAME="Andrey Volk" -ARG MAINTAINER_EMAIL="andrey@signalwire.com" - -# Credentials -ARG REPO_DOMAIN=freeswitch.signalwire.com -ARG REPO_USERNAME=user - -ARG BUILD_NUMBER=42 -ARG GIT_SHA=0000000000 - -ARG DATA_DIR=/data -ARG CODENAME=buster -ARG GPG_KEY="/usr/share/keyrings/signalwire-freeswitch-repo.gpg" - -MAINTAINER "${MAINTAINER_NAME} <${MAINTAINER_EMAIL}>" - -SHELL ["/bin/bash", "-c"] - -RUN apt-get -q update && \ - DEBIAN_FRONTEND=noninteractive apt-get -yq install \ - apt-transport-https \ - build-essential \ - ca-certificates \ - cmake \ - curl \ - debhelper \ - devscripts \ - dh-autoreconf \ - dos2unix \ - doxygen \ - git \ - graphviz \ - libglib2.0-dev \ - libssl-dev \ - lsb-release \ - pkg-config \ - wget - -RUN update-ca-certificates --fresh - -RUN echo "export CODENAME=${CODENAME}" | tee ~/.env && \ - chmod +x ~/.env - -RUN . ~/.env && cat < /etc/apt/sources.list.d/freeswitch.list -deb [signed-by=${GPG_KEY}] https://${REPO_DOMAIN}/repo/deb/debian-unstable ${CODENAME} main -deb-src [signed-by=${GPG_KEY}] https://${REPO_DOMAIN}/repo/deb/debian-unstable ${CODENAME} main -EOF - -RUN git config --global --add safe.directory '*' \ - && git config --global user.name "${MAINTAINER_NAME}" \ - && git config --global user.email "${MAINTAINER_EMAIL}" - -# Bootstrap and Build -COPY . ${DATA_DIR} -WORKDIR ${DATA_DIR} - -RUN echo "export VERSION=$(cat ./build/next-release.txt | tr -d '\n')" | tee -a ~/.env - -RUN . ~/.env && ./debian/util.sh prep-create-orig -n -V${VERSION}-${BUILD_NUMBER}-${GIT_SHA} -x -RUN . ~/.env && ./debian/util.sh prep-create-dsc ${CODENAME} - -RUN --mount=type=secret,id=REPO_PASSWORD,required=true \ - printf "machine ${REPO_DOMAIN} " > /etc/apt/auth.conf && \ - printf "login ${REPO_USERNAME} " >> /etc/apt/auth.conf && \ - printf "password " >> /etc/apt/auth.conf && \ - cat /run/secrets/REPO_PASSWORD >> /etc/apt/auth.conf && \ - sha512sum /run/secrets/REPO_PASSWORD && \ - curl \ - --fail \ - --netrc-file /etc/apt/auth.conf \ - --output ${GPG_KEY} \ - https://${REPO_DOMAIN}/repo/deb/debian-unstable/signalwire-freeswitch-repo.gpg && \ - file ${GPG_KEY} && \ - apt-get --quiet update && \ - mk-build-deps \ - --install \ - --remove debian/control \ - --tool "apt-get --yes --no-install-recommends" && \ - apt-get --yes --fix-broken install && \ - rm -f /etc/apt/auth.conf - -ENV DEB_BUILD_OPTIONS="parallel=1" -RUN . ~/.env && dch -b -M -v "${VERSION}-${BUILD_NUMBER}-${GIT_SHA}~${CODENAME}" \ - --force-distribution -D "${CODENAME}" "Nightly build, ${GIT_SHA}" -RUN . ~/.env && ./debian/util.sh create-orig -n -V${VERSION}-${BUILD_NUMBER}-${GIT_SHA} -x - -RUN dpkg-source \ - --diff-ignore=.* \ - --compression=xz \ - --compression-level=9 \ - --build \ - . \ - && debuild -b -us -uc \ - && mkdir OUT \ - && mv -v ../*.{deb,dsc,changes,tar.*} OUT/. - -# Artifacts image (mandatory part, the resulting image must have a single filesystem layer) -FROM scratch -COPY --from=builder /data/OUT/ / diff --git a/.github/docker/debian/buster/arm32v7/Dockerfile b/.github/docker/debian/buster/arm32v7/Dockerfile deleted file mode 100644 index 9326979622a..00000000000 --- a/.github/docker/debian/buster/arm32v7/Dockerfile +++ /dev/null @@ -1,102 +0,0 @@ -ARG BUILDER_IMAGE=arm32v7/debian:buster-20240513 - -FROM --platform=linux/arm32 ${BUILDER_IMAGE} AS builder - -ARG MAINTAINER_NAME="Andrey Volk" -ARG MAINTAINER_EMAIL="andrey@signalwire.com" - -# Credentials -ARG REPO_DOMAIN=freeswitch.signalwire.com -ARG REPO_USERNAME=user - -ARG BUILD_NUMBER=42 -ARG GIT_SHA=0000000000 - -ARG DATA_DIR=/data -ARG CODENAME=buster -ARG GPG_KEY="/usr/share/keyrings/signalwire-freeswitch-repo.gpg" - -MAINTAINER "${MAINTAINER_NAME} <${MAINTAINER_EMAIL}>" - -SHELL ["/bin/bash", "-c"] - -RUN apt-get -q update && \ - DEBIAN_FRONTEND=noninteractive apt-get -yq install \ - apt-transport-https \ - build-essential \ - ca-certificates \ - cmake \ - curl \ - debhelper \ - devscripts \ - dh-autoreconf \ - dos2unix \ - doxygen \ - git \ - graphviz \ - libglib2.0-dev \ - libssl-dev \ - lsb-release \ - pkg-config \ - wget - -RUN update-ca-certificates --fresh - -RUN echo "export CODENAME=${CODENAME}" | tee ~/.env && \ - chmod +x ~/.env - -RUN . ~/.env && cat < /etc/apt/sources.list.d/freeswitch.list -deb [signed-by=${GPG_KEY}] https://${REPO_DOMAIN}/repo/deb/rpi/debian-dev ${CODENAME} main -deb-src [signed-by=${GPG_KEY}] https://${REPO_DOMAIN}/repo/deb/rpi/debian-dev ${CODENAME} main -EOF - -RUN git config --global --add safe.directory '*' \ - && git config --global user.name "${MAINTAINER_NAME}" \ - && git config --global user.email "${MAINTAINER_EMAIL}" - -# Bootstrap and Build -COPY . ${DATA_DIR} -WORKDIR ${DATA_DIR} -RUN echo "export VERSION=$(cat ./build/next-release.txt | tr -d '\n')" | tee -a ~/.env - -RUN . ~/.env && ./debian/util.sh prep-create-orig -n -V${VERSION}-${BUILD_NUMBER}-${GIT_SHA} -x -RUN . ~/.env && ./debian/util.sh prep-create-dsc -a armhf ${CODENAME} - -RUN --mount=type=secret,id=REPO_PASSWORD,required=true \ - printf "machine ${REPO_DOMAIN} " > /etc/apt/auth.conf && \ - printf "login ${REPO_USERNAME} " >> /etc/apt/auth.conf && \ - printf "password " >> /etc/apt/auth.conf && \ - cat /run/secrets/REPO_PASSWORD >> /etc/apt/auth.conf && \ - sha512sum /run/secrets/REPO_PASSWORD && \ - curl \ - --fail \ - --netrc-file /etc/apt/auth.conf \ - --output ${GPG_KEY} \ - https://${REPO_DOMAIN}/repo/deb/rpi/debian-dev/signalwire-freeswitch-repo.gpg && \ - file ${GPG_KEY} && \ - apt-get --quiet update && \ - mk-build-deps \ - --install \ - --remove debian/control \ - --tool "apt-get --yes --no-install-recommends" && \ - apt-get --yes --fix-broken install && \ - rm -f /etc/apt/auth.conf - -ENV DEB_BUILD_OPTIONS="parallel=1" -RUN . ~/.env && dch -b -M -v "${VERSION}-${BUILD_NUMBER}-${GIT_SHA}~${CODENAME}" \ - --force-distribution -D "${CODENAME}" "Nightly build, ${GIT_SHA}" -RUN . ~/.env && ./debian/util.sh create-orig -n -V${VERSION}-${BUILD_NUMBER}-${GIT_SHA} -x - -RUN dpkg-source \ - --diff-ignore=.* \ - --compression=xz \ - --compression-level=9 \ - --build \ - . \ - && debuild -b -us -uc \ - && mkdir OUT \ - && mv -v ../*.{deb,dsc,changes,tar.*} OUT/. - -# Artifacts image (mandatory part, the resulting image must have a single filesystem layer) -FROM scratch -COPY --from=builder /data/OUT/ / diff --git a/.github/docker/debian/buster/arm64v8/Dockerfile b/.github/docker/debian/buster/arm64v8/Dockerfile deleted file mode 100644 index 71aca460522..00000000000 --- a/.github/docker/debian/buster/arm64v8/Dockerfile +++ /dev/null @@ -1,102 +0,0 @@ -ARG BUILDER_IMAGE=arm64v8/debian:buster-20240513 - -FROM --platform=linux/arm64 ${BUILDER_IMAGE} AS builder - -ARG MAINTAINER_NAME="Andrey Volk" -ARG MAINTAINER_EMAIL="andrey@signalwire.com" - -# Credentials -ARG REPO_DOMAIN=freeswitch.signalwire.com -ARG REPO_USERNAME=user - -ARG BUILD_NUMBER=42 -ARG GIT_SHA=0000000000 - -ARG DATA_DIR=/data -ARG CODENAME=buster -ARG GPG_KEY="/usr/share/keyrings/signalwire-freeswitch-repo.gpg" - -MAINTAINER "${MAINTAINER_NAME} <${MAINTAINER_EMAIL}>" - -SHELL ["/bin/bash", "-c"] - -RUN apt-get -q update && \ - DEBIAN_FRONTEND=noninteractive apt-get -yq install \ - apt-transport-https \ - build-essential \ - ca-certificates \ - cmake \ - curl \ - debhelper \ - devscripts \ - dh-autoreconf \ - dos2unix \ - doxygen \ - git \ - graphviz \ - libglib2.0-dev \ - libssl-dev \ - lsb-release \ - pkg-config \ - wget - -RUN update-ca-certificates --fresh - -RUN echo "export CODENAME=${CODENAME}" | tee ~/.env && \ - chmod +x ~/.env - -RUN . ~/.env && cat < /etc/apt/sources.list.d/freeswitch.list -deb [signed-by=${GPG_KEY}] https://${REPO_DOMAIN}/repo/deb/debian-unstable ${CODENAME} main -deb-src [signed-by=${GPG_KEY}] https://${REPO_DOMAIN}/repo/deb/debian-unstable ${CODENAME} main -EOF - -RUN git config --global --add safe.directory '*' \ - && git config --global user.name "${MAINTAINER_NAME}" \ - && git config --global user.email "${MAINTAINER_EMAIL}" - -# Bootstrap and Build -COPY . ${DATA_DIR} -WORKDIR ${DATA_DIR} -RUN echo "export VERSION=$(cat ./build/next-release.txt | tr -d '\n')" | tee -a ~/.env - -RUN . ~/.env && ./debian/util.sh prep-create-orig -n -V${VERSION}-${BUILD_NUMBER}-${GIT_SHA} -x -RUN . ~/.env && ./debian/util.sh prep-create-dsc -a arm64 ${CODENAME} - -RUN --mount=type=secret,id=REPO_PASSWORD,required=true \ - printf "machine ${REPO_DOMAIN} " > /etc/apt/auth.conf && \ - printf "login ${REPO_USERNAME} " >> /etc/apt/auth.conf && \ - printf "password " >> /etc/apt/auth.conf && \ - cat /run/secrets/REPO_PASSWORD >> /etc/apt/auth.conf && \ - sha512sum /run/secrets/REPO_PASSWORD && \ - curl \ - --fail \ - --netrc-file /etc/apt/auth.conf \ - --output ${GPG_KEY} \ - https://${REPO_DOMAIN}/repo/deb/debian-unstable/signalwire-freeswitch-repo.gpg && \ - file ${GPG_KEY} && \ - apt-get --quiet update && \ - mk-build-deps \ - --install \ - --remove debian/control \ - --tool "apt-get --yes --no-install-recommends" && \ - apt-get --yes --fix-broken install && \ - rm -f /etc/apt/auth.conf - -ENV DEB_BUILD_OPTIONS="parallel=1" -RUN . ~/.env && dch -b -M -v "${VERSION}-${BUILD_NUMBER}-${GIT_SHA}~${CODENAME}" \ - --force-distribution -D "${CODENAME}" "Nightly build, ${GIT_SHA}" -RUN . ~/.env && ./debian/util.sh create-orig -n -V${VERSION}-${BUILD_NUMBER}-${GIT_SHA} -x - -RUN dpkg-source \ - --diff-ignore=.* \ - --compression=xz \ - --compression-level=9 \ - --build \ - . \ - && debuild -b -us -uc \ - && mkdir OUT \ - && mv -v ../*.{deb,dsc,changes,tar.*} OUT/. - -# Artifacts image (mandatory part, the resulting image must have a single filesystem layer) -FROM scratch -COPY --from=builder /data/OUT/ / diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 2d1ddf07fc9..37e29568a85 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -31,17 +31,20 @@ jobs: { "version": "bookworm", "platform": { - "name": "amd64" + "name": "arm64v8" } }, { - "version": "bookworm", + "version": "bullseye", "platform": { - "name": "arm64v8" + "name": "amd64" } }, { - "version": "bullseye" + "version": "bullseye", + "platform": { + "name": "arm32v7" + } } ]') fi @@ -66,7 +69,6 @@ jobs: version: - bookworm - bullseye - - buster platform: - name: amd64 runner: ubuntu-latest From 6e8f30ea8b75033c7d5d56b957b142e5f53ec17b Mon Sep 17 00:00:00 2001 From: Andrey Volk Date: Fri, 2 Aug 2024 19:39:59 +0000 Subject: [PATCH 56/56] swigall --- src/mod/languages/mod_managed/freeswitch_wrap.cxx | 10 ++++++++++ src/mod/languages/mod_managed/managed/swig.cs | 4 ++++ 2 files changed, 14 insertions(+) diff --git a/src/mod/languages/mod_managed/freeswitch_wrap.cxx b/src/mod/languages/mod_managed/freeswitch_wrap.cxx index 7cec120fbe9..c09f650f5a0 100644 --- a/src/mod/languages/mod_managed/freeswitch_wrap.cxx +++ b/src/mod/languages/mod_managed/freeswitch_wrap.cxx @@ -3401,6 +3401,16 @@ SWIGEXPORT int SWIGSTDCALL CSharp_FreeSWITCHfNative_SWITCH_MAX_MANAGEMENT_BUFFER } +SWIGEXPORT int SWIGSTDCALL CSharp_FreeSWITCHfNative_SWITCH_RAND_MAX_get___() { + int jresult ; + int result; + + result = (int)(0x7fff); + jresult = result; + return jresult; +} + + SWIGEXPORT void SWIGSTDCALL CSharp_FreeSWITCHfNative_switch_error_period_t_start_set___(void * jarg1, long long jarg2) { error_period *arg1 = (error_period *) 0 ; int64_t arg2 ; diff --git a/src/mod/languages/mod_managed/managed/swig.cs b/src/mod/languages/mod_managed/managed/swig.cs index 6ca27764cf2..20bcbf42731 100644 --- a/src/mod/languages/mod_managed/managed/swig.cs +++ b/src/mod/languages/mod_managed/managed/swig.cs @@ -15184,6 +15184,7 @@ public static switch_status_t dtmf_callback(SWIGTYPE_p_switch_core_session sessi public static readonly int SWITCH_MAX_STATE_HANDLERS = freeswitchPINVOKE.SWITCH_MAX_STATE_HANDLERS_get(); public static readonly int SWITCH_CORE_QUEUE_LEN = freeswitchPINVOKE.SWITCH_CORE_QUEUE_LEN_get(); public static readonly int SWITCH_MAX_MANAGEMENT_BUFFER_LEN = freeswitchPINVOKE.SWITCH_MAX_MANAGEMENT_BUFFER_LEN_get(); + public static readonly int SWITCH_RAND_MAX = freeswitchPINVOKE.SWITCH_RAND_MAX_get(); public static readonly int SWITCH_RTP_CNG_PAYLOAD = freeswitchPINVOKE.SWITCH_RTP_CNG_PAYLOAD_get(); public static readonly int SWITCH_MEDIA_TYPE_TOTAL = freeswitchPINVOKE.SWITCH_MEDIA_TYPE_TOTAL_get(); public static readonly int SWITCH_SOCK_INVALID = freeswitchPINVOKE.SWITCH_SOCK_INVALID_get(); @@ -16292,6 +16293,9 @@ static SWIGStringHelper() { [global::System.Runtime.InteropServices.DllImport("mod_managed", EntryPoint="CSharp_FreeSWITCHfNative_SWITCH_MAX_MANAGEMENT_BUFFER_LEN_get___")] public static extern int SWITCH_MAX_MANAGEMENT_BUFFER_LEN_get(); + [global::System.Runtime.InteropServices.DllImport("mod_managed", EntryPoint="CSharp_FreeSWITCHfNative_SWITCH_RAND_MAX_get___")] + public static extern int SWITCH_RAND_MAX_get(); + [global::System.Runtime.InteropServices.DllImport("mod_managed", EntryPoint="CSharp_FreeSWITCHfNative_switch_error_period_t_start_set___")] public static extern void switch_error_period_t_start_set(global::System.Runtime.InteropServices.HandleRef jarg1, long jarg2);