From cc6ee0322e3de3522c051c825f63a214ce3d1c9f Mon Sep 17 00:00:00 2001 From: Moises Silva Date: Tue, 25 Jun 2013 22:19:24 -0400 Subject: [PATCH 01/63] Added ability to play a wav file as ringback tone during the COLLECT state of E&M signaling module This is configured through 2 new parameters: ringback-during-collect=yes|no ringback-file= You may not want to use this if your E&M lines are connected to traditional phones, otherwise you will hear ringback tone while pressing digits. This is mostly useful with old switches that do not provide ringback tone but the user is already done dialing (perhaps the signaling was converted from ISDN to E&M and the full number was received in a single SETUP message) --- .../ftmod/ftmod_analog_em/ftdm_analog_em.h | 3 + .../ftmod/ftmod_analog_em/ftmod_analog_em.c | 184 +++++++++++++++++- 2 files changed, 181 insertions(+), 6 deletions(-) diff --git a/libs/freetdm/src/ftmod/ftmod_analog_em/ftdm_analog_em.h b/libs/freetdm/src/ftmod/ftmod_analog_em/ftdm_analog_em.h index 37c90c3b4f..fb9959d061 100644 --- a/libs/freetdm/src/ftmod/ftmod_analog_em/ftdm_analog_em.h +++ b/libs/freetdm/src/ftmod/ftmod_analog_em/ftdm_analog_em.h @@ -33,6 +33,7 @@ * Contributor(s): * * John Wehle (john@feith.com) + * Moises Silva (moy@sangoma.com) * */ @@ -53,6 +54,8 @@ struct ftdm_analog_data { uint32_t digit_timeout; uint32_t dial_timeout; ftdm_bool_t answer_supervision; + ftdm_bool_t ringback_during_collect; + char ringback_file[512]; }; static void *ftdm_analog_em_run(ftdm_thread_t *me, void *obj); diff --git a/libs/freetdm/src/ftmod/ftmod_analog_em/ftmod_analog_em.c b/libs/freetdm/src/ftmod/ftmod_analog_em/ftmod_analog_em.c index 598a8cd302..13160ca8e6 100644 --- a/libs/freetdm/src/ftmod/ftmod_analog_em/ftmod_analog_em.c +++ b/libs/freetdm/src/ftmod/ftmod_analog_em/ftmod_analog_em.c @@ -33,6 +33,7 @@ * Contributor(s): * * John Wehle (john@feith.com) + * Moises Silva (moy@sangoma.com) * */ @@ -43,6 +44,106 @@ struct tm * localtime_r(const time_t *clock, struct tm *result); #endif +/* check if the given file is a wave file and skip the header if it is */ +#define WAVE_CHUNK_ID "RIFF" +#define WAVE_FMT "WAVEfmt " +#define WAVE_HEADER_LEN 44 +static int skip_wave_header(const char *fname, FILE *f) +{ + char rbuff[10] = { 0 }; + unsigned int hz = 0; + unsigned int hs = 0; + unsigned short fmt = 0; + unsigned short chans = 0; + unsigned int size = 0; + + /* check chunk id */ + if (fread(rbuff, 1, 4, f) != 4) { + ftdm_log(FTDM_LOG_ERROR, "Unable to read wav chunk id from file %s\n", fname); + goto error; + } + rbuff[4] = 0; + + if (strncasecmp(rbuff, WAVE_CHUNK_ID, sizeof(WAVE_CHUNK_ID)-1)) { + goto notwave; + } + + /* read chunk size */ + if (fread(&size, 1, 4, f) != 4) { + ftdm_log(FTDM_LOG_ERROR, "Unable to read wav chunk size from file %s\n", fname); + goto error; + } + + /* check format and sub chunk id */ + if (fread(rbuff, 1, 8, f) != 8) { + ftdm_log(FTDM_LOG_ERROR, "Unable to read wav format and sub chunk id from file %s\n", fname); + goto error; + } + rbuff[8] = 0; + + if (strncasecmp(rbuff, WAVE_FMT, sizeof(WAVE_FMT)-1)) { + goto notwave; + } + + /* At this point we know is a wav file ... */ + + /* validate sub chunk size */ + if (fread(&hs, 1, 4, f) != 4) { + ftdm_log(FTDM_LOG_ERROR, "Unable to read wav sub chunk size from file %s\n", fname); + goto error; + } + + if (hs != 16) { + ftdm_log(FTDM_LOG_ERROR, "Unsupported wav sub chunk size %d from file %s\n", hs, fname); + goto error; + } + + /* validate audio format */ + if (fread(&fmt, 1, 2, f) != 2) { + ftdm_log(FTDM_LOG_ERROR, "Unable to read wav audio format from file %s\n", fname); + goto error; + } + + if (fmt != 1) { + ftdm_log(FTDM_LOG_ERROR, "Unsupported wav audio format %d in file %s, we only support PCM\n", fmt, fname); + goto error; + } + + /* validate channels */ + if (fread(&chans, 1, 2, f) != 2) { + ftdm_log(FTDM_LOG_ERROR, "Unable to read wav channels from file %s\n", fname); + goto error; + } + + if (chans != 1) { + ftdm_log(FTDM_LOG_ERROR, "Unsupported number of channels %d in file %s, we only support 1 (mono)\n", chans, fname); + goto error; + } + + /* validate sampling rate */ + if (fread(&hz, 1, 2, f) != 2) { + ftdm_log(FTDM_LOG_ERROR, "Unable to read wav sampling rate from file %s\n", fname); + goto error; + } + + if (hz != 8000) { + ftdm_log(FTDM_LOG_ERROR, "Invalid input wav sampling rate %dHz, only 8000Hz supported\n", hz); + goto error; + } + + ftdm_log(FTDM_LOG_DEBUG, "Found input file %s. PCM mono wav of %d bytes at %dHz, skipping header ...\n", fname, size, hz); + fseek(f, WAVE_HEADER_LEN, SEEK_SET); + + return 0; + +notwave: + ftdm_log(FTDM_LOG_ERROR, "File %s is not a wav file\n", fname); + return -1; + +error: + return -1; +} + static void *ftdm_analog_em_channel_run(ftdm_thread_t *me, void *obj); /** @@ -82,6 +183,19 @@ static ftdm_status_t ftdm_analog_em_start(ftdm_span_t *span) return ftdm_thread_create_detached(ftdm_analog_em_run, span); } +/** + * \brief Stops EM span thread (monitor) + * \param span Span to monitor + * \return Success or failure + */ +static ftdm_status_t ftdm_analog_em_stop(ftdm_span_t *span) +{ + ftdm_analog_em_data_t *analog_data = span->signal_data; + ftdm_clear_flag(analog_data, FTDM_ANALOG_EM_RUNNING); + ftdm_sleep(100); + return FTDM_SUCCESS; +} + /** * \brief Returns the signalling status on a channel * \param ftdmchan Channel to get status on @@ -120,8 +234,10 @@ static FIO_SPAN_GET_SIG_STATUS_FUNCTION(analog_em_get_span_sig_status) static FIO_SIG_CONFIGURE_FUNCTION(ftdm_analog_em_configure_span) //ftdm_status_t ftdm_analog_em_configure_span(ftdm_span_t *span, char *tonemap, uint32_t digit_timeout, uint32_t max_dialstr, fio_signal_cb_t sig_cb) { - ftdm_analog_em_data_t *analog_data; + ftdm_analog_em_data_t *analog_data = NULL; const char *tonemap = "us"; + const char *ringback_file = ""; + ftdm_bool_t ringback_during_collect = FTDM_FALSE; uint32_t digit_timeout = 2000; uint32_t max_dialstr = 11; uint32_t dial_timeout = 0; @@ -136,9 +252,8 @@ static FIO_SIG_CONFIGURE_FUNCTION(ftdm_analog_em_configure_span) return FTDM_FAIL; } - analog_data = ftdm_malloc(sizeof(*analog_data)); + analog_data = ftdm_calloc(1, sizeof(*analog_data)); assert(analog_data != NULL); - memset(analog_data, 0, sizeof(*analog_data)); while((var = va_arg(ap, char *))) { ftdm_log(FTDM_LOG_DEBUG, "Parsing analog em parameter '%s'\n", var); @@ -147,6 +262,16 @@ static FIO_SIG_CONFIGURE_FUNCTION(ftdm_analog_em_configure_span) break; } tonemap = val; + } else if (!strcasecmp(var, "ringback_during_collect")) { + if (!(val = va_arg(ap, char *))) { + break; + } + ringback_during_collect = ftdm_true(val); + } else if (!strcasecmp(var, "ringback_file")) { + if (!(val = va_arg(ap, char *))) { + break; + } + ringback_file = val; } else if (!strcasecmp(var, "answer_supervision")) { if (!(val = va_arg(ap, char *))) { break; @@ -184,6 +309,7 @@ static FIO_SIG_CONFIGURE_FUNCTION(ftdm_analog_em_configure_span) } span->start = ftdm_analog_em_start; + span->stop = ftdm_analog_em_stop; analog_data->digit_timeout = digit_timeout; analog_data->max_dialstr = max_dialstr; analog_data->dial_timeout = dial_timeout; @@ -195,6 +321,10 @@ static FIO_SIG_CONFIGURE_FUNCTION(ftdm_analog_em_configure_span) span->get_channel_sig_status = analog_em_get_channel_sig_status; span->get_span_sig_status = analog_em_get_span_sig_status; ftdm_span_load_tones(span, tonemap); + if (ringback_during_collect) { + analog_data->ringback_during_collect = FTDM_TRUE; + ftdm_set_string(analog_data->ringback_file, ringback_file); + } return FTDM_SUCCESS; @@ -241,6 +371,7 @@ static void *ftdm_analog_em_channel_run(ftdm_thread_t *me, void *obj) int cas_bits = 0; uint32_t cas_answer = 0; int cas_answer_ms = 500; + FILE *ringback_f = NULL; ftdm_bool_t digits_sent = FTDM_FALSE; ftdm_unused_arg(me); @@ -283,6 +414,18 @@ static void *ftdm_analog_em_channel_run(ftdm_thread_t *me, void *obj) assert(interval != 0); ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "IO Interval: %u\n", interval); + if (analog_data->ringback_during_collect && !ftdm_strlen_zero(analog_data->ringback_file)) { + ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "Using ringback file '%s'\n", analog_data->ringback_file); + ringback_f = fopen(analog_data->ringback_file, "rb"); + if (!ringback_f) { + ftdm_log_chan(ftdmchan, FTDM_LOG_ERROR, "Failed to open ringback file '%s'\n", analog_data->ringback_file); + } else { + if (skip_wave_header(analog_data->ringback_file, ringback_f)) { + ringback_f = NULL; + } + } + } + while (ftdm_running() && ftdm_test_flag(ftdmchan, FTDM_CHANNEL_INTHREAD)) { ftdm_wait_flag_t flags = FTDM_READ; ftdm_size_t dlen = 0; @@ -515,7 +658,6 @@ static void *ftdm_analog_em_channel_run(ftdm_thread_t *me, void *obj) } } - if (last_digit && (!collecting || ((elapsed - last_digit > analog_data->digit_timeout) || strlen(dtmf) > analog_data->max_dialstr))) { ftdm_log(FTDM_LOG_DEBUG, "Number obtained [%s]\n", dtmf); ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_RING); @@ -576,6 +718,14 @@ static void *ftdm_analog_em_channel_run(ftdm_thread_t *me, void *obj) ftdm_channel_write(ftdmchan, frame, sizeof(frame), &rlen); continue; } + + if (analog_data->ringback_during_collect && ringback_f && + (ftdmchan->state == FTDM_CHANNEL_STATE_COLLECT || + ftdmchan->state == FTDM_CHANNEL_STATE_RING || + ftdmchan->state == FTDM_CHANNEL_STATE_RINGING + )) { + indicate = 1; + } if (!indicate) { continue; @@ -585,7 +735,25 @@ static void *ftdm_analog_em_channel_run(ftdm_thread_t *me, void *obj) len *= 2; } - rlen = ftdm_buffer_read_loop(dt_buffer, frame, len); + if (ringback_f) { + uint8_t failed_read = 0; +read_try: + rlen = fread(frame, 1, len, ringback_f); + if (rlen != len) { + if (!feof(ringback_f)) { + ftdm_log(FTDM_LOG_ERROR, "Error reading from ringback file"); + } + if (failed_read) { + continue; + } + /* return cursor to start of wav file */ + fseek(ringback_f, WAVE_HEADER_LEN, SEEK_SET); + failed_read++; + goto read_try; + } + } else { + rlen = ftdm_buffer_read_loop(dt_buffer, frame, len); + } if (ftdmchan->effective_codec != FTDM_CODEC_SLIN) { fio_codec_t codec_func = NULL; @@ -599,7 +767,7 @@ static void *ftdm_analog_em_channel_run(ftdm_thread_t *me, void *obj) if (codec_func) { codec_func(frame, sizeof(frame), &rlen); } else { - snprintf(ftdmchan->last_error, sizeof(ftdmchan->last_error), "codec error!"); + ftdm_log(FTDM_LOG_ERROR, "codec error, no codec function for native codec %d!", ftdmchan->native_codec); goto done; } } @@ -624,6 +792,10 @@ static void *ftdm_analog_em_channel_run(ftdm_thread_t *me, void *obj) ftdm_buffer_destroy(&dt_buffer); } + if (ringback_f) { + fclose(ringback_f); + } + ftdm_clear_flag(closed_chan, FTDM_CHANNEL_INTHREAD); ftdm_log(FTDM_LOG_DEBUG, "ANALOG EM CHANNEL thread ended.\n"); From 626dd2551ae1f869ad0c7dff3c85efd543614cb9 Mon Sep 17 00:00:00 2001 From: Moises Silva Date: Tue, 25 Jun 2013 23:41:30 -0400 Subject: [PATCH 02/63] mod_freetdm: Expose new ringback E&M parameters in the XML config --- libs/freetdm/mod_freetdm/mod_freetdm.c | 9 +++++++++ libs/freetdm/src/ftmod/ftmod_analog_em/ftmod_analog_em.c | 2 +- 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/libs/freetdm/mod_freetdm/mod_freetdm.c b/libs/freetdm/mod_freetdm/mod_freetdm.c index 316f5607c2..f980930f94 100755 --- a/libs/freetdm/mod_freetdm/mod_freetdm.c +++ b/libs/freetdm/mod_freetdm/mod_freetdm.c @@ -3785,7 +3785,10 @@ static switch_status_t load_config(void) char *hold_music = NULL; char *fail_dial_regex = NULL; char str_false[] = "false"; + char str_empty[] = ""; char *answer_supervision = str_false; + char *ringback_during_collect = str_false; + char *ringback_file = str_empty; uint32_t span_id = 0, to = 0, max = 0, dial_timeout_int = 0; ftdm_span_t *span = NULL; analog_option_t analog_options = ANALOG_OPTION_NONE; @@ -3814,6 +3817,10 @@ static switch_status_t load_config(void) max_digits = val; } else if (!strcasecmp(var, "answer-supervision")) { answer_supervision = val; + } else if (!strcasecmp(var, "ringback-during-collect")) { + ringback_during_collect = val; + } else if (!strcasecmp(var, "ringback-file")) { + ringback_file = val; } else if (!strcasecmp(var, "enable-analog-option")) { analog_options = enable_analog_option(val, analog_options); } @@ -3867,6 +3874,8 @@ static switch_status_t load_config(void) if (ftdm_configure_span(span, "analog_em", on_analog_signal, "tonemap", tonegroup, "answer_supervision", answer_supervision, + "ringback_during_collect", ringback_during_collect, + "ringback_file", ringback_file, "digit_timeout", &to, "dial_timeout", &dial_timeout_int, "max_dialstr", &max, diff --git a/libs/freetdm/src/ftmod/ftmod_analog_em/ftmod_analog_em.c b/libs/freetdm/src/ftmod/ftmod_analog_em/ftmod_analog_em.c index 13160ca8e6..c8bb5fddbd 100644 --- a/libs/freetdm/src/ftmod/ftmod_analog_em/ftmod_analog_em.c +++ b/libs/freetdm/src/ftmod/ftmod_analog_em/ftmod_analog_em.c @@ -741,7 +741,7 @@ read_try: rlen = fread(frame, 1, len, ringback_f); if (rlen != len) { if (!feof(ringback_f)) { - ftdm_log(FTDM_LOG_ERROR, "Error reading from ringback file"); + ftdm_log(FTDM_LOG_ERROR, "Error reading from ringback file: %zd != %zd\n", rlen, len); } if (failed_read) { continue; From bd4a5914dc6d4349904124daa553ed9a65030fed Mon Sep 17 00:00:00 2001 From: Moises Silva Date: Wed, 26 Jun 2013 00:10:04 -0400 Subject: [PATCH 03/63] freetdm: Override regular media with ringback in E&M when a ringback file is specified --- libs/freetdm/src/ftmod/ftmod_analog_em/ftmod_analog_em.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/libs/freetdm/src/ftmod/ftmod_analog_em/ftmod_analog_em.c b/libs/freetdm/src/ftmod/ftmod_analog_em/ftmod_analog_em.c index c8bb5fddbd..66a791ebdb 100644 --- a/libs/freetdm/src/ftmod/ftmod_analog_em/ftmod_analog_em.c +++ b/libs/freetdm/src/ftmod/ftmod_analog_em/ftmod_analog_em.c @@ -722,7 +722,9 @@ static void *ftdm_analog_em_channel_run(ftdm_thread_t *me, void *obj) if (analog_data->ringback_during_collect && ringback_f && (ftdmchan->state == FTDM_CHANNEL_STATE_COLLECT || ftdmchan->state == FTDM_CHANNEL_STATE_RING || - ftdmchan->state == FTDM_CHANNEL_STATE_RINGING + ftdmchan->state == FTDM_CHANNEL_STATE_RINGING || + ftdmchan->state == FTDM_CHANNEL_STATE_PROGRESS || + ftdmchan->state == FTDM_CHANNEL_STATE_PROGRESS_MEDIA )) { indicate = 1; } From f9007fb2b62f802322f80f7978fa9541ad0116fd Mon Sep 17 00:00:00 2001 From: Moises Silva Date: Wed, 26 Jun 2013 00:16:11 -0400 Subject: [PATCH 04/63] freetdm: Added E & M logic for routing success and fail regex parameters --- libs/freetdm/mod_freetdm/mod_freetdm.c | 43 ++++++++++++++++++++++++-- 1 file changed, 41 insertions(+), 2 deletions(-) diff --git a/libs/freetdm/mod_freetdm/mod_freetdm.c b/libs/freetdm/mod_freetdm/mod_freetdm.c index f980930f94..9f56d9f454 100755 --- a/libs/freetdm/mod_freetdm/mod_freetdm.c +++ b/libs/freetdm/mod_freetdm/mod_freetdm.c @@ -2241,7 +2241,7 @@ static FIO_SIGNAL_CB_FUNCTION(on_fxo_signal) { switch_core_session_t *session = NULL; switch_channel_t *channel = NULL; - ftdm_status_t status; + ftdm_status_t status = FTDM_SUCCESS; uint32_t spanid; uint32_t chanid; ftdm_caller_data_t *caller_data; @@ -2296,6 +2296,45 @@ static FIO_SIGNAL_CB_FUNCTION(on_fxo_signal) break; case FTDM_SIGEVENT_SIGSTATUS_CHANGED: case FTDM_SIGEVENT_COLLECTED_DIGIT: /* Analog E&M */ + { + int span_id = ftdm_channel_get_span_id(sigmsg->channel); + char *dtmf = sigmsg->ev_data.collected.digits; + char *regex = SPAN_CONFIG[span_id].dial_regex; + char *fail_regex = SPAN_CONFIG[span_id].fail_dial_regex; + ftdm_caller_data_t *caller_data = ftdm_channel_get_caller_data(sigmsg->channel); + + if (zstr(regex)) { + regex = NULL; + } + + if (zstr(fail_regex)) { + fail_regex = NULL; + } + + ftdm_log(FTDM_LOG_DEBUG, "got DTMF sig [%s]\n", dtmf); + switch_set_string(caller_data->collected, dtmf); + + if ((regex || fail_regex) && !zstr(dtmf)) { + switch_regex_t *re = NULL; + int ovector[30]; + int match = 0; + + if (fail_regex) { + match = switch_regex_perform(dtmf, fail_regex, &re, ovector, sizeof(ovector) / sizeof(ovector[0])); + status = match ? FTDM_SUCCESS : FTDM_BREAK; + switch_regex_safe_free(re); + ftdm_log(FTDM_LOG_DEBUG, "DTMF [%s] vs fail regex %s %s\n", dtmf, fail_regex, match ? "matched" : "did not match"); + } + + if (status == FTDM_SUCCESS && regex) { + match = switch_regex_perform(dtmf, regex, &re, ovector, sizeof(ovector) / sizeof(ovector[0])); + status = match ? FTDM_BREAK : FTDM_SUCCESS; + switch_regex_safe_free(re); + ftdm_log(FTDM_LOG_DEBUG, "DTMF [%s] vs dial regex %s %s\n", dtmf, regex, match ? "matched" : "did not match"); + } + ftdm_log(FTDM_LOG_DEBUG, "returning %s to COLLECT event with DTMF %s\n", status == FTDM_SUCCESS ? "success" : "break", dtmf); + } + } break; default: { @@ -2305,7 +2344,7 @@ static FIO_SIGNAL_CB_FUNCTION(on_fxo_signal) break; } - return FTDM_SUCCESS; + return status; } static FIO_SIGNAL_CB_FUNCTION(on_fxs_signal) From 5c6c33fb4fb910e552717000911a93d89b30c443 Mon Sep 17 00:00:00 2001 From: Moises Silva Date: Tue, 13 Aug 2013 11:58:56 -0400 Subject: [PATCH 05/63] mod_oreka: use zstr instead of only checking for null as some caller profile data may be an empty string --- src/mod/applications/mod_oreka/mod_oreka.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/mod/applications/mod_oreka/mod_oreka.c b/src/mod/applications/mod_oreka/mod_oreka.c index f954341b4c..a9c8c927e1 100644 --- a/src/mod/applications/mod_oreka/mod_oreka.c +++ b/src/mod/applications/mod_oreka/mod_oreka.c @@ -274,17 +274,17 @@ static int oreka_send_sip_message(oreka_session_t *oreka, oreka_recording_status caller_id_number = switch_caller_get_field_by_name(caller_profile, "caller_id_number"); caller_id_name = switch_caller_get_field_by_name(caller_profile, "caller_id_name"); - if (!caller_id_name) { + if (zstr(caller_id_name)) { caller_id_name = caller_id_number; } callee_id_number = switch_caller_get_field_by_name(caller_profile, "callee_id_number"); - if (!callee_id_number) { + if (zstr(callee_id_number)) { callee_id_number = switch_caller_get_field_by_name(caller_profile, "destination_number"); } callee_id_name = switch_caller_get_field_by_name(caller_profile, "callee_id_name"); - if (!callee_id_name) { + if (zstr(callee_id_name)) { callee_id_name = callee_id_number; } From 1cd58ddba8a88b174bf4897ab5b784544d92fd0f Mon Sep 17 00:00:00 2001 From: Michael Jerris Date: Tue, 13 Aug 2013 15:40:33 -0400 Subject: [PATCH 06/63] FS-5564: fix gcc extension for unsigned char bitfield type --- libs/srtp/include/srtp_priv.h | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/libs/srtp/include/srtp_priv.h b/libs/srtp/include/srtp_priv.h index 180a51b9e8..8425b351ce 100644 --- a/libs/srtp/include/srtp_priv.h +++ b/libs/srtp/include/srtp_priv.h @@ -83,11 +83,11 @@ typedef struct { #else /* BIG_ENDIAN */ typedef struct { - unsigned char version:2; /* protocol version */ - unsigned char p:1; /* padding flag */ - unsigned char x:1; /* header extension flag */ - unsigned char cc:4; /* CSRC count */ - unsigned char m:1; /* marker bit */ + unsigned version:2; /* protocol version */ + unsigned p:1; /* padding flag */ + unsigned x:1; /* header extension flag */ + unsigned cc:4; /* CSRC count */ + unsigned m:1; /* marker bit */ unsigned pt:7; /* payload type */ unsigned seq:16; /* sequence number */ unsigned ts:32; /* timestamp */ @@ -131,10 +131,10 @@ typedef struct { #else /* BIG_ENDIAN */ typedef struct { - unsigned char version:2; /* protocol version */ - unsigned char p:1; /* padding flag */ - unsigned char rc:5; /* reception report count */ - unsigned char pt:8; /* payload type */ + unsigned version:2; /* protocol version */ + unsigned p:1; /* padding flag */ + unsigned rc:5; /* reception report count */ + unsigned pt:8; /* payload type */ uint16_t len; /* length */ uint32_t ssrc; /* synchronization source */ } srtcp_hdr_t; From 44df6c46b3c106b2ec09bbd4c23c6230a2a17e2c Mon Sep 17 00:00:00 2001 From: Travis Cross Date: Tue, 13 Aug 2013 20:28:47 +0000 Subject: [PATCH 07/63] Add lua script for proxying ZRTP SAS values to legacy phones Ken is creating a bump-in-the-wire box for legacy IP phones and might find this script useful. --- scripts/lua/zrtp_sas_proxy.lua | 103 +++++++++++++++++++++++++++++++++ 1 file changed, 103 insertions(+) create mode 100644 scripts/lua/zrtp_sas_proxy.lua diff --git a/scripts/lua/zrtp_sas_proxy.lua b/scripts/lua/zrtp_sas_proxy.lua new file mode 100644 index 0000000000..503b8d8c72 --- /dev/null +++ b/scripts/lua/zrtp_sas_proxy.lua @@ -0,0 +1,103 @@ +-- zrtp_sas_proxy.lua +-- +-- Copyright (c) 2011-2013 Travis Cross +-- +-- Permission is hereby granted, free of charge, to any person obtaining a copy +-- of this software and associated documentation files (the "Software"), to deal +-- in the Software without restriction, including without limitation the rights +-- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +-- copies of the Software, and to permit persons to whom the Software is +-- furnished to do so, subject to the following conditions: +-- +-- The above copyright notice and this permission notice shall be included in +-- all copies or substantial portions of the Software. +-- +-- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +-- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +-- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +-- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +-- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +-- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +-- THE SOFTWARE. +-- +-- +-- When we're acting as a ZRTP man-in-the-middle, proxy the SAS (Short +-- Authentication String) from one leg of the call to the other. +-- +-- This script should be called asynchonously with luarun. e.g.: +-- +-- +-- +aleg=argv[1] +api=freeswitch.API() + +function log(level,msg) return freeswitch.consoleLog(level,"zrtp_sas: "..msg.."\n") end +function sleep(sec) return freeswitch.msleep(sec*1000) end +function ready() return api:execute("uuid_exists",aleg)=="true" end +function getvar(uuid,var) + local x=api:execute("uuid_getvar",uuid.." "..var) + if x=="_undef_" then return nil end + return x +end +function getvarp(uuid,var) return getvar(uuid,var)=="true" end +function display(uuid,msg) + local cidn=getvar(uuid,"caller_id_name") + return api:execute("uuid_display",uuid.." "..msg.." "..cidn) +end + +function mk_sas(sas1,sas2) + if sas1 and sas2 then return sas1.." "..sas2 + else return sas1 or sas2 or "" end +end + +function get_sas(uuid) + return mk_sas(getvar(uuid,"zrtp_sas1_string_audio"), + getvar(uuid,"zrtp_sas2_string")) +end + +function log_sas(leg,uuid) + return log("notice",leg..": "..uuid.." sas: "..get_sas(uuid)) +end + +function display_sas(to,from) + return display(to," ("..get_sas(from)..")") +end + +function get_bleg(aleg) + local retries=15 bleg=nil + while ready() do + if retries<1 then return nil end + local bleg=getvar(aleg,"signal_bond") + if bleg then return bleg end + log("debug","waiting for bleg uuid...") + sleep(1) + retries=retries-1 + end +end + +function handle_sas(aleg,bleg) + local retries=45 af=false bf=false + while ready() do + if retries<1 then return nil end + if not af and getvarp(aleg,"zrtp_secure_media_confirmed_audio") then + af=true + log_sas("aleg",aleg) + display_sas(bleg,aleg) + end + if not bf and getvarp(bleg,"zrtp_secure_media_confirmed_audio") then + bf=true + log_sas("bleg",bleg) + display_sas(aleg,bleg) + end + if (af and bf) then break + elseif af then log("debug","waiting on bleg zrtp...") + elseif bf then log("debug","waiting on aleg zrtp...") + else log("debug","waiting for zrtp...") end + sleep(1) + retries=retries-1 + end +end + +if not (getvarp(aleg,"zrtp_passthru") or getvarp(aleg,"proxy_media")) then + handle_sas(aleg,get_bleg(aleg)) +end From ef62351c473425e5588f4301eddb477f88b5f5b8 Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Wed, 14 Aug 2013 02:00:31 +0500 Subject: [PATCH 08/63] FS-5693 --resolve --- src/switch_core_media.c | 4 +++- src/switch_rtp.c | 2 +- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/src/switch_core_media.c b/src/switch_core_media.c index e3e42a60f7..d0acc32564 100644 --- a/src/switch_core_media.c +++ b/src/switch_core_media.c @@ -3416,6 +3416,8 @@ SWITCH_DECLARE(switch_status_t) switch_core_media_proxy_remote_addr(switch_core_ if (*rvp) { v_engine->codec_params.remote_sdp_ip = switch_core_session_strdup(session, rip); v_engine->codec_params.remote_sdp_port = (switch_port_t) atoi(rvp); + switch_channel_set_flag(session->channel, CF_VIDEO_POSSIBLE); + switch_channel_set_flag(session->channel, CF_VIDEO); } if (v_engine->codec_params.remote_sdp_ip && v_engine->codec_params.remote_sdp_port) { @@ -6175,7 +6177,7 @@ SWITCH_DECLARE(void) switch_core_media_patch_sdp(switch_core_session_t *session) } a_engine = &smh->engines[SWITCH_MEDIA_TYPE_AUDIO]; - v_engine = &smh->engines[SWITCH_MEDIA_TYPE_AUDIO]; + v_engine = &smh->engines[SWITCH_MEDIA_TYPE_VIDEO]; if (zstr(smh->mparams->local_sdp_str)) { return; diff --git a/src/switch_rtp.c b/src/switch_rtp.c index cfca9f20ae..106f9ec1aa 100644 --- a/src/switch_rtp.c +++ b/src/switch_rtp.c @@ -4604,7 +4604,7 @@ static int rtp_common_read(switch_rtp_t *rtp_session, switch_payload_t *payload_ pt = 0; } - if (rtp_session->flags[SWITCH_RTP_FLAG_VIDEO]) { + if (rtp_session->flags[SWITCH_RTP_FLAG_VIDEO] && !rtp_session->flags[SWITCH_RTP_FLAG_PROXY_MEDIA]) { pt = 100000; } From ae64753112a64cbdca96b03d140a8f6a9f8dddcc Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Wed, 14 Aug 2013 02:08:54 +0500 Subject: [PATCH 09/63] FS-5698 --resolve --- src/mod/endpoints/mod_sofia/sofia_presence.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/mod/endpoints/mod_sofia/sofia_presence.c b/src/mod/endpoints/mod_sofia/sofia_presence.c index 5136eee8fc..197a02df6a 100644 --- a/src/mod/endpoints/mod_sofia/sofia_presence.c +++ b/src/mod/endpoints/mod_sofia/sofia_presence.c @@ -154,6 +154,11 @@ switch_status_t sofia_presence_chat_send(switch_event_t *message_event) goto end; } + if (!from) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Missing From: header.\n"); + goto end; + } + if (!zstr(type)) { ct = type; } From 94b1b6218cda026827dd76f3a026a2890b0e9fed Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Wed, 14 Aug 2013 02:13:49 +0500 Subject: [PATCH 10/63] FS-5453 --resolve --- src/mod/endpoints/mod_loopback/mod_loopback.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/src/mod/endpoints/mod_loopback/mod_loopback.c b/src/mod/endpoints/mod_loopback/mod_loopback.c index 105b96564a..41f5849655 100644 --- a/src/mod/endpoints/mod_loopback/mod_loopback.c +++ b/src/mod/endpoints/mod_loopback/mod_loopback.c @@ -458,10 +458,7 @@ static switch_status_t channel_on_execute(switch_core_session_t *session) if ((find_non_loopback_bridge(tech_pvt->other_session, &other_session, &other_uuid) == SWITCH_STATUS_SUCCESS)) { switch_channel_t *other_channel = switch_core_session_get_channel(other_session); - if (switch_channel_test_flag(other_channel, CF_BRIDGED)) { - /* Wait for real channel to be exchanging media */ - switch_channel_wait_for_state(other_channel, channel, CS_EXCHANGE_MEDIA); - } + switch_channel_wait_for_state_timeout(other_channel, CS_EXCHANGE_MEDIA, 5000); switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(tech_pvt->session), SWITCH_LOG_INFO, "BOWOUT Replacing loopback channel with real channel: %s\n", switch_channel_get_name(other_channel)); From 8859df6789bfa5d94d9b9f6f52178e568cab328a Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Wed, 14 Aug 2013 02:24:53 +0500 Subject: [PATCH 11/63] FS-5683 --resolve --- src/mod/endpoints/mod_sofia/sofia_reg.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/mod/endpoints/mod_sofia/sofia_reg.c b/src/mod/endpoints/mod_sofia/sofia_reg.c index 23f211f53f..3a3e3e1d0a 100644 --- a/src/mod/endpoints/mod_sofia/sofia_reg.c +++ b/src/mod/endpoints/mod_sofia/sofia_reg.c @@ -2891,7 +2891,7 @@ auth_res_t sofia_reg_parse_auth(sofia_profile_t *profile, skip_auth: if (first && (ret == AUTH_OK || ret == AUTH_RENEWED)) { - if (!v_event) { + if (v_event && !*v_event) { switch_event_create_plain(v_event, SWITCH_EVENT_REQUEST_PARAMS); } From 96eba0d6a8e7bbb202e8928c3b18918eeacb4f1c Mon Sep 17 00:00:00 2001 From: Chris Rienzo Date: Wed, 14 Aug 2013 09:41:11 -0400 Subject: [PATCH 12/63] mod_rayo: add support for speech recognizers other than pocketsphinx, fixed some input component bugs, allow simultaneous dtmf and voice input. --- conf/rayo/autoload_configs/rayo.conf.xml | 5 + .../conf/autoload_configs/rayo.conf.xml | 5 + src/mod/event_handlers/mod_rayo/iks_helpers.c | 59 +++ src/mod/event_handlers/mod_rayo/iks_helpers.h | 5 + src/mod/event_handlers/mod_rayo/mod_rayo.c | 36 ++ .../event_handlers/mod_rayo/rayo_components.c | 13 +- .../event_handlers/mod_rayo/rayo_components.h | 8 +- .../event_handlers/mod_rayo/rayo_elements.c | 2 +- .../mod_rayo/rayo_input_component.c | 397 ++++++++++++------ .../mod_rayo/rayo_output_component.c | 5 +- .../mod_rayo/rayo_prompt_component.c | 5 +- .../mod_rayo/rayo_record_component.c | 3 +- .../event_handlers/mod_rayo/test_iks/main.c | 22 + 13 files changed, 408 insertions(+), 157 deletions(-) diff --git a/conf/rayo/autoload_configs/rayo.conf.xml b/conf/rayo/autoload_configs/rayo.conf.xml index 0cb46d7992..248fd47ccf 100644 --- a/conf/rayo/autoload_configs/rayo.conf.xml +++ b/conf/rayo/autoload_configs/rayo.conf.xml @@ -11,6 +11,11 @@ + + + + + diff --git a/src/mod/event_handlers/mod_rayo/conf/autoload_configs/rayo.conf.xml b/src/mod/event_handlers/mod_rayo/conf/autoload_configs/rayo.conf.xml index 0cb46d7992..248fd47ccf 100644 --- a/src/mod/event_handlers/mod_rayo/conf/autoload_configs/rayo.conf.xml +++ b/src/mod/event_handlers/mod_rayo/conf/autoload_configs/rayo.conf.xml @@ -11,6 +11,11 @@ + + + + + diff --git a/src/mod/event_handlers/mod_rayo/iks_helpers.c b/src/mod/event_handlers/mod_rayo/iks_helpers.c index 0b5616a1f3..30d9d215a5 100644 --- a/src/mod/event_handlers/mod_rayo/iks_helpers.c +++ b/src/mod/event_handlers/mod_rayo/iks_helpers.c @@ -216,6 +216,17 @@ double iks_find_decimal_attrib(iks *xml, const char *attrib) return atof(iks_find_attrib_soft(xml, attrib)); } +/** + * Get attribute character value of node + * @param xml the XML node to search + * @param attrib the Attribute name + * @return the attribute value + */ +char iks_find_char_attrib(iks *xml, const char *attrib) +{ + return iks_find_attrib_soft(xml, attrib)[0]; +} + /** * Convert iksemel XML node type to string * @param type the XML node type @@ -392,6 +403,54 @@ int iks_attrib_is_decimal_between_zero_and_one(const char *value) return SWITCH_FALSE; } +/** + * Validate dtmf digit + * @param value + * @return SWITCH_TRUE if 0-9,a,b,c,d,A,B,C,D,*,# + */ +int iks_attrib_is_dtmf_digit(const char *value) +{ + if (value && *value && strlen(value) == 1) { + switch (*value) { + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': + case 'A': + case 'a': + case 'B': + case 'b': + case 'C': + case 'c': + case 'D': + case 'd': + case '*': + case '#': + return SWITCH_TRUE; + } + } + return SWITCH_FALSE; +} + +/** + * @param fn to evaluate attribute + * @param attrib to evaluate + * @return true if not set or is valid + */ +int validate_optional_attrib(iks_attrib_validation_function fn, const char *attrib) +{ + if (!attrib || !*attrib) { + return SWITCH_TRUE; + } + return fn(attrib); +} + #define IKS_SHA256_HEX_DIGEST_LENGTH ((SHA256_DIGEST_LENGTH * 2) + 1) /** diff --git a/src/mod/event_handlers/mod_rayo/iks_helpers.h b/src/mod/event_handlers/mod_rayo/iks_helpers.h index 90a5ca688d..3a7bae02e7 100644 --- a/src/mod/event_handlers/mod_rayo/iks_helpers.h +++ b/src/mod/event_handlers/mod_rayo/iks_helpers.h @@ -63,6 +63,7 @@ extern const char *iks_find_attrib_soft(iks *xml, const char *attrib); extern const char *iks_find_attrib_default(iks *xml, const char *attrib, const char *def); extern int iks_find_bool_attrib(iks *xml, const char *attrib); extern int iks_find_int_attrib(iks *xml, const char *attrib); +extern char iks_find_char_attrib(iks *xml, const char *attrib); extern double iks_find_decimal_attrib(iks *xml, const char *attrib); extern const char *iks_node_type_to_string(int type); extern const char *iks_net_error_to_string(int err); @@ -73,9 +74,12 @@ extern char *iks_server_dialback_key(const char *secret, const char *receiving_s /** A function to validate attribute value */ typedef int (*iks_attrib_validation_function)(const char *); +extern int validate_optional_attrib(iks_attrib_validation_function fn, const char *attrib); + #define ELEMENT_DECL(name) extern int VALIDATE_##name(iks *node); #define ELEMENT(name) int VALIDATE_##name(iks *node) { int result = 1; if (!node) return 0; #define ATTRIB(name, def, rule) result &= iks_attrib_is_##rule(iks_find_attrib_default(node, #name, #def)); +#define OPTIONAL_ATTRIB(name, def, rule) result &= validate_optional_attrib(iks_attrib_is_##rule, iks_find_attrib_default(node, #name, #def)); #define STRING_ATTRIB(name, def, rule) result &= value_matches(iks_find_attrib_default(node, #name, #def), rule); #define ELEMENT_END return result; } @@ -87,6 +91,7 @@ extern int iks_attrib_is_positive(const char *value); extern int iks_attrib_is_positive_or_neg_one(const char *value); extern int iks_attrib_is_any(const char *value); extern int iks_attrib_is_decimal_between_zero_and_one(const char *value); +extern int iks_attrib_is_dtmf_digit(const char *value); #endif diff --git a/src/mod/event_handlers/mod_rayo/mod_rayo.c b/src/mod/event_handlers/mod_rayo/mod_rayo.c index fffffe31eb..69f8b2271b 100644 --- a/src/mod/event_handlers/mod_rayo/mod_rayo.c +++ b/src/mod/event_handlers/mod_rayo/mod_rayo.c @@ -3737,6 +3737,14 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_rayo_load) "" ""); + rayo_add_cmd_alias("prompt_barge_mrcp", "" + "

Please press a digit.

]]>
" + "" + "" + "0123456789]]>" + "" + "
"); + rayo_add_cmd_alias("prompt_no_barge", "" "

Please press a digit.

]]>
" "" @@ -3800,6 +3808,34 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_rayo_load) ""); rayo_add_cmd_alias("unjoin", ""); + rayo_add_cmd_alias("input_voice_yesno_unimrcp", + "" + "" + "yesno]]>"); +rayo_add_cmd_alias("input_voice_yesno_unimrcp_timeout", + "" + "" + "yesno]]>"); + rayo_add_cmd_alias("input_voice_yesno_pocketsphinx", + "" + "" + "yesno]]>"); + rayo_add_cmd_alias("input_voice_yesno_default", + "" + "" + "yesno]]>"); return SWITCH_STATUS_SUCCESS; } diff --git a/src/mod/event_handlers/mod_rayo/rayo_components.c b/src/mod/event_handlers/mod_rayo/rayo_components.c index 54e241d036..d8a8854f52 100644 --- a/src/mod/event_handlers/mod_rayo/rayo_components.c +++ b/src/mod/event_handlers/mod_rayo/rayo_components.c @@ -227,15 +227,10 @@ void rayo_component_api_execute_async(struct rayo_component *component, const ch */ switch_status_t rayo_components_load(switch_loadable_module_interface_t **module_interface, switch_memory_pool_t *pool, const char *config_file) { - rayo_input_component_load(); - rayo_output_component_load(module_interface, pool); - rayo_prompt_component_load(); - rayo_record_component_load(pool, config_file); - - if (rayo_input_component_load() != SWITCH_STATUS_SUCCESS || - rayo_output_component_load(module_interface, pool) != SWITCH_STATUS_SUCCESS || - rayo_prompt_component_load() != SWITCH_STATUS_SUCCESS || - rayo_record_component_load(pool, config_file) != SWITCH_STATUS_SUCCESS) { + if (rayo_input_component_load(module_interface, pool, config_file) != SWITCH_STATUS_SUCCESS || + rayo_output_component_load(module_interface, pool, config_file) != SWITCH_STATUS_SUCCESS || + rayo_prompt_component_load(module_interface, pool, config_file) != SWITCH_STATUS_SUCCESS || + rayo_record_component_load(module_interface, pool, config_file) != SWITCH_STATUS_SUCCESS) { return SWITCH_STATUS_TERM; } return SWITCH_STATUS_SUCCESS; diff --git a/src/mod/event_handlers/mod_rayo/rayo_components.h b/src/mod/event_handlers/mod_rayo/rayo_components.h index 71891ea3d6..6e93dfbc43 100644 --- a/src/mod/event_handlers/mod_rayo/rayo_components.h +++ b/src/mod/event_handlers/mod_rayo/rayo_components.h @@ -54,10 +54,10 @@ #define COMPONENT_COMPLETE_HANGUP "hangup", RAYO_EXT_COMPLETE_NS extern switch_status_t rayo_components_load(switch_loadable_module_interface_t **module_interface, switch_memory_pool_t *pool, const char *config_file); -extern switch_status_t rayo_input_component_load(void); -extern switch_status_t rayo_output_component_load(switch_loadable_module_interface_t **module_interface, switch_memory_pool_t *pool); -extern switch_status_t rayo_prompt_component_load(void); -extern switch_status_t rayo_record_component_load(switch_memory_pool_t *pool, const char *config_file); +extern switch_status_t rayo_input_component_load(switch_loadable_module_interface_t **module_interface, switch_memory_pool_t *pool, const char *config_file); +extern switch_status_t rayo_output_component_load(switch_loadable_module_interface_t **module_interface, switch_memory_pool_t *pool, const char *config_file); +extern switch_status_t rayo_prompt_component_load(switch_loadable_module_interface_t **module_interface, switch_memory_pool_t *pool, const char *config_file); +extern switch_status_t rayo_record_component_load(switch_loadable_module_interface_t **module_interface, switch_memory_pool_t *pool, const char *config_file); extern switch_status_t rayo_components_shutdown(void); extern switch_status_t rayo_input_component_shutdown(void); diff --git a/src/mod/event_handlers/mod_rayo/rayo_elements.c b/src/mod/event_handlers/mod_rayo/rayo_elements.c index 89e31c7d66..34577a9492 100644 --- a/src/mod/event_handlers/mod_rayo/rayo_elements.c +++ b/src/mod/event_handlers/mod_rayo/rayo_elements.c @@ -33,7 +33,7 @@ */ ELEMENT(RAYO_INPUT) STRING_ATTRIB(mode, any, "any,dtmf,voice") - ATTRIB(terminator,, any) + OPTIONAL_ATTRIB(terminator,, dtmf_digit) ATTRIB(recognizer,, any) ATTRIB(language, en-US, any) ATTRIB(initial-timeout, -1, positive_or_neg_one) diff --git a/src/mod/event_handlers/mod_rayo/rayo_input_component.c b/src/mod/event_handlers/mod_rayo/rayo_input_component.c index 9e10d1b7a5..3bf3b6dfb6 100644 --- a/src/mod/event_handlers/mod_rayo/rayo_input_component.c +++ b/src/mod/event_handlers/mod_rayo/rayo_input_component.c @@ -45,6 +45,8 @@ struct input_handler; static struct { /** grammar parser */ struct srgs_parser *parser; + /** default recognizer to use if none specified */ + const char *default_recognizer; } globals; /** @@ -57,8 +59,8 @@ struct input_component { int speech_mode; /** Number of collected digits */ int num_digits; - /** Terminating digits */ - int term_digit_mask; + /** Terminating digit */ + char term_digit; /** The collected digits */ char digits[MAX_DTMF + 1]; /** grammar to match */ @@ -70,7 +72,9 @@ struct input_component { /** maximum silence allowed */ int max_silence; /** minimum speech detection confidence */ - int min_confidence; + double min_confidence; + /** sensitivity to background noise */ + double sensitivity; /** timeout after first digit is received */ int inter_digit_timeout; /** stop flag */ @@ -79,6 +83,10 @@ struct input_component { int start_timers; /** true if event fired for first digit / start of speech */ int barge_event; + /** optional language to use */ + const char *language; + /** optional recognizer to use */ + const char *recognizer; /** global data */ struct input_handler *handler; }; @@ -91,77 +99,24 @@ struct input_component { struct input_handler { /** media bug to monitor frames / control input lifecycle */ switch_media_bug_t *bug; - /** active input component - TODO multiple inputs */ - struct input_component *component; + /** active voice input component */ + struct input_component *voice_component; + /** active dtmf input component */ + struct input_component *dtmf_component; /** synchronizes media bug and dtmf callbacks */ switch_mutex_t *mutex; + /** last recognizer used */ + const char *last_recognizer; }; /** - * @return digit mask + * @param digit1 to match + * @param digit2 to match + * @return true if matching */ -static int get_digit_mask(char digit) +static int digit_test(char digit1, char digit2) { - switch(digit) { - case '0': return 1; - case '1': return 1 << 1; - case '2': return 1 << 2; - case '3': return 1 << 3; - case '4': return 1 << 4; - case '5': return 1 << 5; - case '6': return 1 << 6; - case '7': return 1 << 7; - case '8': return 1 << 8; - case '9': return 1 << 9; - case 'A': - case 'a': return 1 << 10; - case 'B': - case 'b': return 1 << 11; - case 'C': - case 'c': return 1 << 12; - case 'D': - case 'd': return 1 << 13; - case '#': return 1 << 14; - case '*': return 1 << 15; - } - return 0; -} - -/** - * @param digit_mask to check - * @param digit to look for - * @return true if set - */ -static int digit_mask_test(int digit_mask, char digit) -{ - return digit_mask & get_digit_mask(digit); -} - -/** - * @param digit_mask to set digit in - * @param digit to set - * @return the digit mask with the set digit - */ -static int digit_mask_set(int digit_mask, char digit) -{ - return digit_mask | get_digit_mask(digit); -} - -/** - * @param digit_mask to set digits in - * @param digits to add to mask - * @return the digit mask with the set digits - */ -static int digit_mask_set_from_digits(int digit_mask, const char *digits) -{ - if (!zstr(digits)) { - int digits_len = strlen(digits); - int i; - for (i = 0; i < digits_len; i++) { - digit_mask = digit_mask_set(digit_mask, digits[i]); - } - } - return digit_mask; + return digit1 && digit2 && tolower(digit1) == tolower(digit2); } /** @@ -205,15 +160,14 @@ static switch_status_t input_component_on_dtmf(switch_core_session_t *session, c switch_mutex_lock(handler->mutex); - component = handler->component; + component = handler->dtmf_component; /* additional paranoia check */ if (!component) { - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_INFO, "Received DTMF without active input component\n"); switch_mutex_unlock(handler->mutex); return SWITCH_STATUS_SUCCESS; } - is_term_digit = digit_mask_test(component->term_digit_mask, dtmf->digit); + is_term_digit = digit_test(component->term_digit, dtmf->digit); if (!is_term_digit) { component->digits[component->num_digits] = dtmf->digit; @@ -247,7 +201,7 @@ static switch_status_t input_component_on_dtmf(switch_core_session_t *session, c } case SMT_NO_MATCH: { /* notify of no-match and remove input component */ - handler->component = NULL; + handler->dtmf_component = NULL; switch_core_media_bug_remove(session, &handler->bug); switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "NO MATCH = %s\n", component->digits); rayo_component_send_complete(RAYO_COMPONENT(component), INPUT_NOMATCH); @@ -256,7 +210,7 @@ static switch_status_t input_component_on_dtmf(switch_core_session_t *session, c case SMT_MATCH_END: { iks *result = nlsml_create_dtmf_match(component->digits); /* notify of match and remove input component */ - handler->component = NULL; + handler->dtmf_component = NULL; switch_core_media_bug_remove(session, &handler->bug); switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "MATCH = %s\n", component->digits); send_match_event(RAYO_COMPONENT(component), result); @@ -279,7 +233,7 @@ static switch_bool_t input_component_bug_callback(switch_media_bug_t *bug, void struct input_component *component; switch_mutex_lock(handler->mutex); - component = handler->component; + component = handler->dtmf_component; switch(type) { case SWITCH_ABC_TYPE_INIT: { @@ -294,7 +248,7 @@ static switch_bool_t input_component_bug_callback(switch_media_bug_t *bug, void int elapsed_ms = (switch_micro_time_now() - component->last_digit_time) / 1000; if (component->num_digits && component->inter_digit_timeout > 0 && elapsed_ms > component->inter_digit_timeout) { enum srgs_match_type match; - handler->component = NULL; + handler->dtmf_component = NULL; switch_core_media_bug_set_flag(bug, SMBF_PRUNE); /* we got some input, check for match */ @@ -310,7 +264,7 @@ static switch_bool_t input_component_bug_callback(switch_media_bug_t *bug, void rayo_component_send_complete(RAYO_COMPONENT(component), INPUT_NOMATCH); } } else if (!component->num_digits && component->initial_timeout > 0 && elapsed_ms > component->initial_timeout) { - handler->component = NULL; + handler->dtmf_component = NULL; switch_core_media_bug_set_flag(bug, SMBF_PRUNE); switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "initial-timeout\n"); rayo_component_send_complete(RAYO_COMPONENT(component), INPUT_NOINPUT); @@ -323,10 +277,10 @@ static switch_bool_t input_component_bug_callback(switch_media_bug_t *bug, void /* check for hangup */ if (component) { if (component->stop) { - handler->component = NULL; + handler->dtmf_component = NULL; rayo_component_send_complete(RAYO_COMPONENT(component), COMPONENT_COMPLETE_STOP); } else { - handler->component = NULL; + handler->dtmf_component = NULL; rayo_component_send_complete(RAYO_COMPONENT(component), COMPONENT_COMPLETE_HANGUP); } } @@ -396,34 +350,53 @@ static iks *start_call_input(struct input_component *component, switch_core_sess handler = switch_core_session_alloc(session, sizeof(*handler)); switch_mutex_init(&handler->mutex, SWITCH_MUTEX_NESTED, switch_core_session_get_pool(session)); switch_channel_set_private(switch_core_session_get_channel(session), RAYO_INPUT_COMPONENT_PRIVATE_VAR, handler); + handler->last_recognizer = ""; } - handler->component = component; + + /* TODO break up this function by mode... dtmf/voice/fax/etc */ + component->speech_mode = strcmp(iks_find_attrib_soft(input, "mode"), "dtmf"); + if (component->speech_mode && handler->voice_component) { + /* don't allow multi voice input */ + return iks_new_error_detailed(iq, STANZA_ERROR_CONFLICT, "Multiple voice input is not allowed"); + } + if (!component->speech_mode && handler->dtmf_component) { + /* don't allow multi dtmf input */ + return iks_new_error_detailed(iq, STANZA_ERROR_CONFLICT, "Multiple dtmf input is not allowed"); + } + + if (component->speech_mode) { + handler->voice_component = component; + } else { + handler->dtmf_component = component; + } + + component->grammar = NULL; component->num_digits = 0; component->digits[0] = '\0'; component->stop = 0; - component->speech_mode = 0; component->initial_timeout = iks_find_int_attrib(input, "initial-timeout"); component->inter_digit_timeout = iks_find_int_attrib(input, "inter-digit-timeout"); component->max_silence = iks_find_int_attrib(input, "max-silence"); - component->min_confidence = (int)ceil(iks_find_decimal_attrib(input, "min-confidence") * 100.0); + component->min_confidence = iks_find_decimal_attrib(input, "min-confidence"); + component->sensitivity = iks_find_decimal_attrib(input, "sensitivity"); component->barge_event = iks_find_bool_attrib(input, "barge-event"); component->start_timers = iks_find_bool_attrib(input, "start-timers"); - /* TODO this should just be a single digit terminator? */ - component->term_digit_mask = digit_mask_set_from_digits(0, iks_find_attrib_soft(input, "terminator")); - /* TODO recognizer ignored */ - /* TODO language ignored */ + component->term_digit = iks_find_char_attrib(input, "terminator"); + component->recognizer = iks_find_attrib(input, "recognizer"); + component->language = iks_find_attrib(input, "language"); component->handler = handler; - /* parse the grammar */ - if (!(component->grammar = srgs_parse(globals.parser, iks_find_cdata(input, "grammar")))) { - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Failed to parse grammar body\n"); - RAYO_UNLOCK(component); - RAYO_DESTROY(component); - return iks_new_error_detailed(iq, STANZA_ERROR_BAD_REQUEST, "Failed to parse grammar body"); - } - /* is this voice or dtmf srgs grammar? */ - if (!strcasecmp("dtmf", iks_find_attrib_soft(input, "mode"))) { + if (!component->speech_mode) { + + /* parse the grammar */ + if (!(component->grammar = srgs_parse(globals.parser, iks_find_cdata(input, "grammar")))) { + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Failed to parse grammar body\n"); + RAYO_UNLOCK(component); + RAYO_DESTROY(component); + return iks_new_error_detailed(iq, STANZA_ERROR_BAD_REQUEST, "Failed to parse grammar body"); + } + component->last_digit_time = switch_micro_time_now(); /* acknowledge command */ @@ -431,38 +404,124 @@ static iks *start_call_input(struct input_component *component, switch_core_sess /* start dtmf input detection */ if (switch_core_media_bug_add(session, "rayo_input_component", NULL, input_component_bug_callback, handler, 0, SMBF_READ_REPLACE, &handler->bug) != SWITCH_STATUS_SUCCESS) { + handler->dtmf_component = NULL; rayo_component_send_complete(RAYO_COMPONENT(component), COMPONENT_COMPLETE_ERROR); } } else { - char *grammar = NULL; - const char *jsgf_path; - component->speech_mode = 1; - jsgf_path = srgs_grammar_to_jsgf_file(component->grammar, SWITCH_GLOBAL_dirs.grammar_dir, "gram"); - if (!jsgf_path) { + switch_stream_handle_t grammar = { 0 }; + SWITCH_STANDARD_STREAM(grammar); + + if (zstr(component->recognizer)) { + component->recognizer = globals.default_recognizer; + } + + /* if recognition engine is different, we can't handle this request */ + if (!zstr(handler->last_recognizer) && strcmp(component->recognizer, handler->last_recognizer)) { + handler->voice_component = NULL; RAYO_UNLOCK(component); RAYO_DESTROY(component); - return iks_new_error_detailed(iq, STANZA_ERROR_INTERNAL_SERVER_ERROR, "Grammar error"); + return iks_new_error_detailed(iq, STANZA_ERROR_BAD_REQUEST, "Must use the same recognizer for the entire call"); + } + handler->last_recognizer = switch_core_session_strdup(session, component->recognizer); + + if (!strcmp(component->recognizer, "pocketsphinx")) { + const char *jsgf_path; + + /* transform SRGS grammar to JSGF */ + if (!(component->grammar = srgs_parse(globals.parser, iks_find_cdata(input, "grammar")))) { + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Failed to parse grammar body\n"); + handler->voice_component = NULL; + RAYO_UNLOCK(component); + RAYO_DESTROY(component); + return iks_new_error_detailed(iq, STANZA_ERROR_BAD_REQUEST, "Failed to parse grammar body"); + } + jsgf_path = srgs_grammar_to_jsgf_file(component->grammar, SWITCH_GLOBAL_dirs.grammar_dir, "gram"); + if (!jsgf_path) { + handler->voice_component = NULL; + RAYO_UNLOCK(component); + RAYO_DESTROY(component); + return iks_new_error_detailed(iq, STANZA_ERROR_INTERNAL_SERVER_ERROR, "Grammar conversion to JSGF error"); + } + + /* build pocketsphinx grammar string */ + grammar.write_function(&grammar, + "{start-input-timers=%s,no-input-timeout=%d,speech-timeout=%d,confidence-threshold=%d}%s", + component->start_timers ? "true" : "false", + component->initial_timeout, + component->max_silence, + (int)ceil(component->min_confidence * 100.0), + jsgf_path); + } else if (!strncmp(component->recognizer, "unimrcp", strlen("unimrcp"))) { + /* send inline grammar to unimrcp */ + grammar.write_function(&grammar, "{start-input-timers=%s,confidence-threshold=%f,sensitivity-level=%f", + component->start_timers ? "true" : "false", + component->min_confidence, + component->sensitivity); + + if (component->initial_timeout > 0) { + grammar.write_function(&grammar, ",no-input-timeout=%d", + component->initial_timeout); + } + + if (component->max_silence > 0) { + grammar.write_function(&grammar, ",speech-complete-timeout=%d,speech-incomplete-timeout=%d", + component->max_silence, + component->max_silence); + } + + if (!zstr(component->language)) { + grammar.write_function(&grammar, ",speech-language=%s", component->language); + } + + if (!strcmp(iks_find_attrib_soft(input, "mode"), "any")) { + /* set dtmf params */ + if (component->inter_digit_timeout > 0) { + grammar.write_function(&grammar, ",dtmf-interdigit-timeout=%d", component->inter_digit_timeout); + } + if (component->term_digit) { + grammar.write_function(&grammar, ",dtmf-term-char=%c", component->term_digit); + } + } + + grammar.write_function(&grammar, "}inline:%s", iks_find_cdata(input, "grammar")); + } else { + /* passthrough to unknown ASR module */ + grammar.write_function(&grammar, "%s", iks_find_cdata(input, "grammar")); } /* acknowledge command */ rayo_component_send_start(RAYO_COMPONENT(component), iq); - /* TODO configurable speech detection - different engines, grammar passthrough, dtmf handled by recognizer */ - grammar = switch_mprintf("{no-input-timeout=%s,speech-timeout=%s,start-input-timers=%s,confidence-threshold=%d}%s", - component->initial_timeout, component->max_silence, - component->start_timers ? "true" : "false", - component->min_confidence, jsgf_path); /* start speech detection */ switch_channel_set_variable(switch_core_session_get_channel(session), "fire_asr_events", "true"); - if (switch_ivr_detect_speech(session, "pocketsphinx", grammar, "mod_rayo_grammar", "", NULL) != SWITCH_STATUS_SUCCESS) { + if (switch_ivr_detect_speech(session, component->recognizer, grammar.data, "mod_rayo_grammar", "", NULL) != SWITCH_STATUS_SUCCESS) { + handler->voice_component = NULL; rayo_component_send_complete(RAYO_COMPONENT(component), COMPONENT_COMPLETE_ERROR); } - switch_safe_free(grammar); + switch_safe_free(grammar.data); } return NULL; } +/** + * Create input component id for session. + * @param session requesting component + * @param input request + * @return the ID + */ +static char *create_input_component_id(switch_core_session_t *session, iks *input) +{ + const char *mode = "unk"; + if (input) { + mode = iks_find_attrib_soft(input, "mode"); + if (!strcmp(mode, "any")) { + mode = "voice"; + } + } + return switch_core_session_sprintf(session, "%s-input-%s", switch_core_session_get_uuid(session), mode); +} + /** * Start execution of input component */ @@ -470,10 +529,10 @@ static iks *start_call_input_component(struct rayo_actor *call, struct rayo_mess { iks *iq = msg->payload; switch_core_session_t *session = (switch_core_session_t *)session_data; - char *component_id = switch_mprintf("%s-input", switch_core_session_get_uuid(session)); + iks *input = iks_find(iq, "input"); + char *component_id = create_input_component_id(session, input); switch_memory_pool_t *pool = NULL; struct input_component *input_component = NULL; - iks *input = iks_find(iq, "input"); const char *error = NULL; if (!validate_call_input(input, &error)) { @@ -484,7 +543,6 @@ static iks *start_call_input_component(struct rayo_actor *call, struct rayo_mess switch_core_new_memory_pool(&pool); input_component = switch_core_alloc(pool, sizeof(*input_component)); rayo_component_init(RAYO_COMPONENT(input_component), pool, RAT_CALL_COMPONENT, "input", component_id, call, iks_find_attrib(iq, "from")); - switch_safe_free(component_id); /* start input */ return start_call_input(input_component, session, iks_find(iq, "input"), iq, NULL, 0); @@ -530,7 +588,6 @@ static iks *start_timers_call_input_component(struct rayo_actor *component, stru switch_mutex_lock(input_component->handler->mutex); if (input_component->speech_mode) { switch_ivr_detect_speech_start_input_timers(session); - rayo_component_send_complete(RAYO_COMPONENT(component), COMPONENT_COMPLETE_STOP); } else { input_component->last_digit_time = switch_micro_time_now(); input_component->start_timers = 1; @@ -549,53 +606,63 @@ static void on_detected_speech_event(switch_event_t *event) { const char *speech_type = switch_event_get_header(event, "Speech-Type"); char *event_str = NULL; + const char *uuid = switch_event_get_header(event, "Unique-ID"); switch_event_serialize(event, &event_str, SWITCH_FALSE); switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "%s\n", event_str); - if (!speech_type) { + if (!speech_type || !uuid) { return; } + if (!strcasecmp("detected-speech", speech_type)) { - const char *uuid = switch_event_get_header(event, "Unique-ID"); - char *component_id = switch_mprintf("%s-input", uuid); + char *component_id = switch_mprintf("%s-input-voice", uuid); struct rayo_component *component = RAYO_COMPONENT_LOCATE(component_id); + switch_safe_free(component_id); if (component) { const char *result = switch_event_get_body(event); switch_mutex_lock(INPUT_COMPONENT(component)->handler->mutex); - INPUT_COMPONENT(component)->handler->component = NULL; + INPUT_COMPONENT(component)->handler->voice_component = NULL; switch_mutex_unlock(INPUT_COMPONENT(component)->handler->mutex); if (zstr(result)) { rayo_component_send_complete(component, INPUT_NOMATCH); } else { - enum nlsml_match_type match_type = nlsml_parse(result, uuid); - switch (match_type) { - case NMT_NOINPUT: + if (strchr(result, '<')) { + /* got an XML result */ + enum nlsml_match_type match_type = nlsml_parse(result, uuid); + switch (match_type) { + case NMT_NOINPUT: + rayo_component_send_complete(component, INPUT_NOINPUT); + break; + case NMT_MATCH: { + iks *result_xml = nlsml_normalize(result); + send_match_event(RAYO_COMPONENT(component), result_xml); + iks_delete(result_xml); + break; + } + case NMT_BAD_XML: + switch_log_printf(SWITCH_CHANNEL_UUID_LOG(uuid), SWITCH_LOG_WARNING, "Failed to parse NLSML result: %s!\n", result); + rayo_component_send_complete(component, INPUT_NOMATCH); + break; + case NMT_NOMATCH: + rayo_component_send_complete(component, INPUT_NOMATCH); + break; + default: + switch_log_printf(SWITCH_CHANNEL_UUID_LOG(uuid), SWITCH_LOG_CRIT, "Unknown NLSML match type: %i, %s!\n", match_type, result); + rayo_component_send_complete(component, INPUT_NOMATCH); + break; + } + } else if (strstr(result, "002")) { + /* Completion-Cause: 002 no-input-timeout */ rayo_component_send_complete(component, INPUT_NOINPUT); - break; - case NMT_MATCH: { - iks *result_xml = nlsml_normalize(result); - send_match_event(RAYO_COMPONENT(component), result_xml); - iks_delete(result_xml); - break; - } - case NMT_BAD_XML: - switch_log_printf(SWITCH_CHANNEL_UUID_LOG(uuid), SWITCH_LOG_WARNING, "Failed to parse NLSML result: %s!\n", result); + } else { + /* assume no match */ rayo_component_send_complete(component, INPUT_NOMATCH); - break; - case NMT_NOMATCH: - rayo_component_send_complete(component, INPUT_NOMATCH); - break; - default: - switch_log_printf(SWITCH_CHANNEL_UUID_LOG(uuid), SWITCH_LOG_CRIT, "Unknown NLSML match type: %i, %s!\n", match_type, result); - rayo_component_send_complete(component, INPUT_NOMATCH); - break; } } RAYO_UNLOCK(component); } } else if (!strcasecmp("begin-speaking", speech_type)) { - const char *uuid = switch_event_get_header(event, "Unique-ID"); - char *component_id = switch_mprintf("%s-input", uuid); + char *component_id = switch_mprintf("%s-input-voice", uuid); struct rayo_component *component = RAYO_COMPONENT_LOCATE(component_id); switch_safe_free(component_id); if (component && INPUT_COMPONENT(component)->barge_event) { @@ -603,14 +670,13 @@ static void on_detected_speech_event(switch_event_t *event) } RAYO_UNLOCK(component); } else if (!strcasecmp("closed", speech_type)) { - const char *uuid = switch_event_get_header(event, "Unique-ID"); - char *component_id = switch_mprintf("%s-input", uuid); + char *component_id = switch_mprintf("%s-input-voice", uuid); struct rayo_component *component = RAYO_COMPONENT_LOCATE(component_id); switch_safe_free(component_id); if (component) { char *channel_state = switch_event_get_header(event, "Channel-State"); switch_mutex_lock(INPUT_COMPONENT(component)->handler->mutex); - INPUT_COMPONENT(component)->handler->component = NULL; + INPUT_COMPONENT(component)->handler->voice_component = NULL; switch_mutex_unlock(INPUT_COMPONENT(component)->handler->mutex); switch_log_printf(SWITCH_CHANNEL_UUID_LOG(uuid), SWITCH_LOG_DEBUG, "Recognizer closed\n"); if (channel_state && !strcmp("CS_HANGUP", channel_state)) { @@ -625,12 +691,63 @@ static void on_detected_speech_event(switch_event_t *event) switch_safe_free(event_str); } +/** + * Process module XML configuration + * @param pool memory pool to allocate from + * @param config_file to use + * @return SWITCH_STATUS_SUCCESS on successful configuration + */ +static switch_status_t do_config(switch_memory_pool_t *pool, const char *config_file) +{ + switch_xml_t cfg, xml; + + /* set defaults */ + globals.default_recognizer = "pocketsphinx"; + + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Configuring module\n"); + if (!(xml = switch_xml_open_cfg(config_file, &cfg, NULL))) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "open of %s failed\n", config_file); + return SWITCH_STATUS_TERM; + } + + /* get params */ + { + switch_xml_t settings = switch_xml_child(cfg, "input"); + if (settings) { + switch_xml_t param; + for (param = switch_xml_child(settings, "param"); param; param = param->next) { + const char *var = switch_xml_attr_soft(param, "name"); + const char *val = switch_xml_attr_soft(param, "value"); + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "param: %s = %s\n", var, val); + if (!strcasecmp(var, "default-recognizer")) { + if (!zstr(val)) { + globals.default_recognizer = switch_core_strdup(pool, val); + } + } else { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Unsupported param: %s\n", var); + } + } + } + } + + switch_xml_free(xml); + + return SWITCH_STATUS_SUCCESS; +} + /** * Initialize input component + * @param module_interface + * @param pool memory pool to allocate from + * @param config_file to use * @return SWITCH_STATUS_SUCCESS if successful */ -switch_status_t rayo_input_component_load(void) +switch_status_t rayo_input_component_load(switch_loadable_module_interface_t **module_interface, switch_memory_pool_t *pool, const char *config_file) { + if (do_config(pool, config_file) != SWITCH_STATUS_SUCCESS) { + return SWITCH_STATUS_TERM; + } + srgs_init(); nlsml_init(); diff --git a/src/mod/event_handlers/mod_rayo/rayo_output_component.c b/src/mod/event_handlers/mod_rayo/rayo_output_component.c index f92d994a64..e85a12cece 100644 --- a/src/mod/event_handlers/mod_rayo/rayo_output_component.c +++ b/src/mod/event_handlers/mod_rayo/rayo_output_component.c @@ -1092,9 +1092,12 @@ static char *fileman_supported_formats[] = { "fileman", NULL }; /** * Initialize output component + * @param module_interface + * @param pool memory pool to allocate from + * @param config_file to use * @return SWITCH_STATUS_SUCCESS if successful */ -switch_status_t rayo_output_component_load(switch_loadable_module_interface_t **module_interface, switch_memory_pool_t *pool) +switch_status_t rayo_output_component_load(switch_loadable_module_interface_t **module_interface, switch_memory_pool_t *pool, const char *config_file) { switch_api_interface_t *api_interface; switch_file_interface_t *file_interface; diff --git a/src/mod/event_handlers/mod_rayo/rayo_prompt_component.c b/src/mod/event_handlers/mod_rayo/rayo_prompt_component.c index 47dbc46df3..f48e7d02d2 100644 --- a/src/mod/event_handlers/mod_rayo/rayo_prompt_component.c +++ b/src/mod/event_handlers/mod_rayo/rayo_prompt_component.c @@ -620,9 +620,12 @@ static iks *forward_output_component_request(struct rayo_actor *prompt, struct r /** * Initialize prompt component + * @param module_interface + * @param pool memory pool to allocate from + * @param config_file to use * @return SWITCH_STATUS_SUCCESS if successful */ -switch_status_t rayo_prompt_component_load(void) +switch_status_t rayo_prompt_component_load(switch_loadable_module_interface_t **module_interface, switch_memory_pool_t *pool, const char *config_file) { /* Prompt is a convenience component that wraps and */ rayo_actor_command_handler_add(RAT_CALL, "", "set:"RAYO_PROMPT_NS":prompt", start_call_prompt_component); diff --git a/src/mod/event_handlers/mod_rayo/rayo_record_component.c b/src/mod/event_handlers/mod_rayo/rayo_record_component.c index 2db5b30771..601d8cb3aa 100644 --- a/src/mod/event_handlers/mod_rayo/rayo_record_component.c +++ b/src/mod/event_handlers/mod_rayo/rayo_record_component.c @@ -479,11 +479,12 @@ static switch_status_t do_config(switch_memory_pool_t *pool, const char *config_ /** * Initialize record component + * @param module_interface * @param pool memory pool to allocate from * @param config_file to use * @return SWITCH_STATUS_SUCCESS if successful */ -switch_status_t rayo_record_component_load(switch_memory_pool_t *pool, const char *config_file) +switch_status_t rayo_record_component_load(switch_loadable_module_interface_t **module_interface, switch_memory_pool_t *pool, const char *config_file) { if (do_config(pool, config_file) != SWITCH_STATUS_SUCCESS) { return SWITCH_STATUS_TERM; diff --git a/src/mod/event_handlers/mod_rayo/test_iks/main.c b/src/mod/event_handlers/mod_rayo/test_iks/main.c index 699f40267e..09a368dc4b 100644 --- a/src/mod/event_handlers/mod_rayo/test_iks/main.c +++ b/src/mod/event_handlers/mod_rayo/test_iks/main.c @@ -145,6 +145,27 @@ static void test_dialback_key(void) ASSERT_NULL(iks_server_dialback_key("s3cr3tf0rd14lb4ck", "xmpp.example.com", "example.org", NULL)); } +static void test_validate_dtmf(void) +{ + ASSERT_EQUALS(SWITCH_TRUE, iks_attrib_is_dtmf_digit("1")); + ASSERT_EQUALS(SWITCH_TRUE, iks_attrib_is_dtmf_digit("A")); + ASSERT_EQUALS(SWITCH_TRUE, iks_attrib_is_dtmf_digit("a")); + ASSERT_EQUALS(SWITCH_TRUE, iks_attrib_is_dtmf_digit("D")); + ASSERT_EQUALS(SWITCH_TRUE, iks_attrib_is_dtmf_digit("d")); + ASSERT_EQUALS(SWITCH_TRUE, iks_attrib_is_dtmf_digit("*")); + ASSERT_EQUALS(SWITCH_TRUE, iks_attrib_is_dtmf_digit("#")); + ASSERT_EQUALS(SWITCH_FALSE, iks_attrib_is_dtmf_digit("E")); + ASSERT_EQUALS(SWITCH_FALSE, iks_attrib_is_dtmf_digit(NULL)); + ASSERT_EQUALS(SWITCH_FALSE, iks_attrib_is_dtmf_digit("")); + ASSERT_EQUALS(SWITCH_FALSE, iks_attrib_is_dtmf_digit("11")); + ASSERT_EQUALS(SWITCH_TRUE, validate_optional_attrib(iks_attrib_is_dtmf_digit, "A")); + ASSERT_EQUALS(SWITCH_TRUE, validate_optional_attrib(iks_attrib_is_dtmf_digit, "1")); + ASSERT_EQUALS(SWITCH_FALSE, validate_optional_attrib(iks_attrib_is_dtmf_digit, "Z")); + ASSERT_EQUALS(SWITCH_FALSE, validate_optional_attrib(iks_attrib_is_dtmf_digit, "11")); + ASSERT_EQUALS(SWITCH_TRUE, validate_optional_attrib(iks_attrib_is_dtmf_digit, NULL)); + ASSERT_EQUALS(SWITCH_TRUE, validate_optional_attrib(iks_attrib_is_dtmf_digit, "")); +} + /** * main program */ @@ -159,5 +180,6 @@ int main(int argc, char **argv) TEST(test_rayo_test_srgs); TEST(test_iks_helper_value_matches); TEST(test_dialback_key); + TEST(test_validate_dtmf); return 0; } From 451aece80391bf08bc0e8b25fce2e2cb4f88bc41 Mon Sep 17 00:00:00 2001 From: Chris Rienzo Date: Wed, 14 Aug 2013 10:06:18 -0400 Subject: [PATCH 13/63] mod_unimrcp: add example config for Vestec --- conf/vanilla/mrcp_profiles/vestec-mrcp-v1.xml | 26 +++++++++++++++++++ 1 file changed, 26 insertions(+) create mode 100644 conf/vanilla/mrcp_profiles/vestec-mrcp-v1.xml diff --git a/conf/vanilla/mrcp_profiles/vestec-mrcp-v1.xml b/conf/vanilla/mrcp_profiles/vestec-mrcp-v1.xml new file mode 100644 index 0000000000..cbde87ca5a --- /dev/null +++ b/conf/vanilla/mrcp_profiles/vestec-mrcp-v1.xml @@ -0,0 +1,26 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + From cae7d029abe8ebe7a2b79bdfeae8129b83c61e16 Mon Sep 17 00:00:00 2001 From: Ken Rice Date: Wed, 14 Aug 2013 09:05:14 -0500 Subject: [PATCH 14/63] FS-5694 --resolve --- src/mod/applications/mod_voicemail/mod_voicemail.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/mod/applications/mod_voicemail/mod_voicemail.c b/src/mod/applications/mod_voicemail/mod_voicemail.c index 41f7cef5d6..e7d4da79ca 100644 --- a/src/mod/applications/mod_voicemail/mod_voicemail.c +++ b/src/mod/applications/mod_voicemail/mod_voicemail.c @@ -2876,7 +2876,7 @@ static switch_status_t deliver_vm(vm_profile_t *profile, update_mwi(profile, myid, domain_name, myfolder, MWI_REASON_NEW); } - if (send_mail && !zstr(vm_email) && switch_file_exists(file_path, pool) == SWITCH_STATUS_SUCCESS) { + if (send_mail && (!zstr(vm_email) || !zstr(vm_notify_email)) && switch_file_exists(file_path, pool) == SWITCH_STATUS_SUCCESS) { switch_event_t *event; char *from; char *body; From 129a509cfbd1def1c76c2ccacfeb78c696d52a42 Mon Sep 17 00:00:00 2001 From: Ken Rice Date: Wed, 14 Aug 2013 09:48:05 -0500 Subject: [PATCH 15/63] FS-5648 --resolve --- 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 db11faa40e..40c8bc370d 100644 --- a/src/mod/endpoints/mod_sofia/sofia.c +++ b/src/mod/endpoints/mod_sofia/sofia.c @@ -8669,6 +8669,7 @@ void sofia_handle_sip_i_invite(switch_core_session_t *session, nua_t *nua, sofia profile_dup_clean(displayname, tech_pvt->caller_profile->caller_id_name, tech_pvt->caller_profile->pool); profile_dup_clean(from_user, tech_pvt->caller_profile->caller_id_number, tech_pvt->caller_profile->pool); profile_dup_clean(network_ip, tech_pvt->caller_profile->network_addr, tech_pvt->caller_profile->pool); + profile_dup_clean(from_user, tech_pvt->caller_profile->ani, tech_pvt->caller_profile->pool); profile_dup_clean(aniii, tech_pvt->caller_profile->aniii, tech_pvt->caller_profile->pool); profile_dup_clean(context, tech_pvt->caller_profile->context, tech_pvt->caller_profile->pool); profile_dup_clean(destination_number, tech_pvt->caller_profile->destination_number, tech_pvt->caller_profile->pool); From 624189be16a1d3828025d82ae092bbb1da3d489d Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Wed, 14 Aug 2013 21:00:08 +0500 Subject: [PATCH 16/63] FS-5701 --resolve --- src/switch_ivr.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/switch_ivr.c b/src/switch_ivr.c index 232f0a6dd2..1f91ed9625 100644 --- a/src/switch_ivr.c +++ b/src/switch_ivr.c @@ -2907,6 +2907,12 @@ SWITCH_DECLARE(void) switch_ivr_delay_echo(switch_core_session_t *session, uint3 interval = read_impl.microseconds_per_packet / 1000; //samples = switch_samples_per_packet(read_impl.samples_per_second, interval); + if (delay_ms < interval * 2) { + delay_ms = interval * 2; + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_WARNING, "Minimum possible delay for this codec (%d) has been chosen\n", delay_ms); + } + + qlen = delay_ms / (interval) / 2; switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Setting delay to %dms (%d frames)\n", delay_ms, qlen); jb = stfu_n_init(qlen, qlen, read_impl.samples_per_packet, read_impl.samples_per_second, 0); From 9d5f14a15dee6986ec100705181160cdc1c9a2bb Mon Sep 17 00:00:00 2001 From: Moises Silva Date: Wed, 3 Jul 2013 02:07:05 -0400 Subject: [PATCH 17/63] freetdm: Fix longstanding minor bug in ftdm_span_send_signal causing dial-regex in Analog modules to not work The return status of the signal callback was not being passed to the signaling module delivering the signal --- libs/freetdm/src/ftdm_io.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/libs/freetdm/src/ftdm_io.c b/libs/freetdm/src/ftdm_io.c index 9ea22fbbfe..57d5af1b85 100644 --- a/libs/freetdm/src/ftdm_io.c +++ b/libs/freetdm/src/ftdm_io.c @@ -6089,6 +6089,7 @@ static void execute_safety_hangup(void *data) FT_DECLARE(ftdm_status_t) ftdm_span_send_signal(ftdm_span_t *span, ftdm_sigmsg_t *sigmsg) { ftdm_channel_t *fchan = NULL; + ftdm_status_t status = FTDM_SUCCESS; if (sigmsg->channel) { fchan = sigmsg->channel; ftdm_channel_lock(fchan); @@ -6193,7 +6194,7 @@ FT_DECLARE(ftdm_status_t) ftdm_span_send_signal(ftdm_span_t *span, ftdm_sigmsg_t if (ftdm_test_flag(span, FTDM_SPAN_USE_SIGNALS_QUEUE)) { ftdm_span_queue_signal(span, sigmsg); } else { - ftdm_span_trigger_signal(span, sigmsg); + status = ftdm_span_trigger_signal(span, sigmsg); } done: @@ -6202,7 +6203,7 @@ done: ftdm_channel_unlock(fchan); } - return FTDM_SUCCESS; + return status; } static void *ftdm_cpu_monitor_run(ftdm_thread_t *me, void *obj) From 4ae41dd1bd6da60c8c32f4396a9853feaa3ca987 Mon Sep 17 00:00:00 2001 From: Chris Rienzo Date: Wed, 14 Aug 2013 18:00:30 -0400 Subject: [PATCH 18/63] mod_rayo: move alias definition to config file, tweak console command completion to make testing easier --- conf/rayo/autoload_configs/rayo.conf.xml | 207 +++++++ .../conf/autoload_configs/rayo.conf.xml | 207 +++++++ src/mod/event_handlers/mod_rayo/mod_rayo.c | 504 +++++++++--------- src/mod/event_handlers/mod_rayo/mod_rayo.h | 1 + .../event_handlers/mod_rayo/rayo_components.c | 2 +- 5 files changed, 681 insertions(+), 240 deletions(-) diff --git a/conf/rayo/autoload_configs/rayo.conf.xml b/conf/rayo/autoload_configs/rayo.conf.xml index 248fd47ccf..35419319bc 100644 --- a/conf/rayo/autoload_configs/rayo.conf.xml +++ b/conf/rayo/autoload_configs/rayo.conf.xml @@ -47,4 +47,211 @@ + + + ]]> + ]]> + ]]> + ]]> + ]]> + ]]> + ]]> + ]]> + ]]> + ]]> + ]]> + ]]> + ]]> + ]]> + ]]> + ]]> + ]]> + ]]> + ]]> + + + + +

Please press a digit.

]]]]> +
+
+ + + 0123456789]]]]> + + +
+ ]]> + + + + + +

Please press a digit.

]]]]> +
+
+ + + 0123456789]]]]> + + + + ]]> +
+ + + + +

Please press a digit.

]]]]> +
+
+ + + 0123456789]]]]> + + + + ]]> +
+ + + + +

Please press a digit.

]]]]> +
+
+ + + 0123456789]]]]> + + + + ]]> +
+ + + + +

Please press a digit.

]]]]> +
+
+ + + 0123456789]]]]> + + + + ]]> +
+ + + + +

Please press a digit.

]]]]> +
+
+ + + 0123456789]]]]> + + + + ]]> +
+ + + + +

Please press a digit.

]]]]> +
+
+ + + 0123456789]]]]> + + + + ]]> +
+ + + + 0123456789]]]]> + + + ]]> + + + + + yesno + ]]]]> + + + ]]> + + + + + yesno + ]]]]> + + + ]]> + + + + + + yesno + ]]]]> + + + ]]> + + + + + + yesno + ]]]]> + + + ]]> + + + + diff --git a/src/mod/event_handlers/mod_rayo/conf/autoload_configs/rayo.conf.xml b/src/mod/event_handlers/mod_rayo/conf/autoload_configs/rayo.conf.xml index 248fd47ccf..35419319bc 100644 --- a/src/mod/event_handlers/mod_rayo/conf/autoload_configs/rayo.conf.xml +++ b/src/mod/event_handlers/mod_rayo/conf/autoload_configs/rayo.conf.xml @@ -47,4 +47,211 @@ + + + ]]> + ]]> + ]]> + ]]> + ]]> + ]]> + ]]> + ]]> + ]]> + ]]> + ]]> + ]]> + ]]> + ]]> + ]]> + ]]> + ]]> + ]]> + ]]> + + + + +

Please press a digit.

]]]]> +
+
+ + + 0123456789]]]]> + + + + ]]> +
+ + + + +

Please press a digit.

]]]]> +
+
+ + + 0123456789]]]]> + + + + ]]> +
+ + + + +

Please press a digit.

]]]]> +
+
+ + + 0123456789]]]]> + + + + ]]> +
+ + + + +

Please press a digit.

]]]]> +
+
+ + + 0123456789]]]]> + + + + ]]> +
+ + + + +

Please press a digit.

]]]]> +
+
+ + + 0123456789]]]]> + + + + ]]> +
+ + + + +

Please press a digit.

]]]]> +
+
+ + + 0123456789]]]]> + + + + ]]> +
+ + + + +

Please press a digit.

]]]]> +
+
+ + + 0123456789]]]]> + + + + ]]> +
+ + + + 0123456789]]]]> + + + ]]> + + + + + yesno + ]]]]> + + + ]]> + + + + + yesno + ]]]]> + + + ]]> + + + + + + yesno + ]]]]> + + + ]]> + + + + + + yesno + ]]]]> + + + ]]> + + +
+ diff --git a/src/mod/event_handlers/mod_rayo/mod_rayo.c b/src/mod/event_handlers/mod_rayo/mod_rayo.c index 69f8b2271b..be66fe877c 100644 --- a/src/mod/event_handlers/mod_rayo/mod_rayo.c +++ b/src/mod/event_handlers/mod_rayo/mod_rayo.c @@ -239,6 +239,12 @@ static void rayo_console_client_send(struct rayo_actor *client, struct rayo_mess static void on_client_presence(struct rayo_client *rclient, iks *node); +typedef switch_bool_t (* rayo_actor_match_fn)(struct rayo_actor *); + +static switch_bool_t is_call_actor(struct rayo_actor *actor); + + + /** * @param msg to check * @return true if message was sent by admin client (console) @@ -827,7 +833,7 @@ int rayo_actor_seq_next(struct rayo_actor *actor) static struct rayo_call *rayo_call_locate(const char *call_uuid, const char *file, int line) { struct rayo_actor *actor = rayo_actor_locate_by_id(call_uuid, file, line); - if (actor && !strcmp(RAT_CALL, actor->type)) { + if (actor && is_call_actor(actor)) { return RAYO_CALL(actor); } else if (actor) { RAYO_UNLOCK(actor); @@ -3077,6 +3083,21 @@ static void on_xmpp_stream_destroy(struct xmpp_stream *stream) } } +/** + * Add an alias to an API command + * @param alias_name + * @param alias_target + * @param alias_cmd + */ +static void rayo_add_cmd_alias(const char *alias_name, const char *alias_target, const char *alias_cmd) +{ + if (zstr(alias_target)) { + alias_target = "all"; + } + switch_console_set_complete(switch_core_sprintf(globals.pool, "add rayo %s ::rayo::list_%s", alias_name, alias_target)); + switch_core_hash_insert(globals.cmd_aliases, alias_name, alias_cmd); +} + /** * Process module XML configuration * @param pool memory pool to allocate from @@ -3262,6 +3283,22 @@ static switch_status_t do_config(switch_memory_pool_t *pool, const char *config_ } } + /* get aliases */ + { + switch_xml_t aliases = switch_xml_child(cfg, "aliases"); + if (aliases) { + switch_xml_t alias; + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Setting configured aliases\n"); + for (alias = switch_xml_child(aliases, "alias"); alias; alias = alias->next) { + const char *alias_name = switch_xml_attr_soft(alias, "name"); + const char *alias_target = switch_xml_attr_soft(alias, "target"); + if (!zstr(alias_name) && !zstr(alias->txt)) { + rayo_add_cmd_alias(alias_name, alias_target, alias->txt); + } + } + } + } + done: switch_xml_free(xml); @@ -3360,12 +3397,6 @@ static void send_console_command(struct rayo_client *client, const char *to, con iks *command = NULL; iksparser *p = iks_dom_new(&command); - /* check if aliased */ - const char *alias = switch_core_hash_find(globals.cmd_aliases, command_str); - if (!zstr(alias)) { - command_str = alias; - } - if (iks_parse(p, command_str, 0, 1) == IKS_OK && command) { char *str; iks *iq = NULL; @@ -3404,14 +3435,15 @@ static void send_console_command(struct rayo_client *client, const char *to, con /** * Send command to rayo actor */ -static int command_api(const char *cmd, switch_stream_handle_t *stream) +static int command_api(char *cmd, switch_stream_handle_t *stream) { - char *cmd_dup = strdup(cmd); char *argv[2] = { 0 }; - int argc = switch_separate_string(cmd_dup, ' ', argv, sizeof(argv) / sizeof(argv[0])); - - if (argc != 2) { - free(cmd_dup); + if (!zstr(cmd)) { + int argc = switch_separate_string(cmd, ' ', argv, sizeof(argv) / sizeof(argv[0])); + if (argc != 2) { + return 0; + } + } else { return 0; } @@ -3419,7 +3451,22 @@ static int command_api(const char *cmd, switch_stream_handle_t *stream) send_console_command(globals.console, argv[0], argv[1]); stream->write_function(stream, "+OK\n"); - free(cmd_dup); + return 1; +} + +/** + * Send command to rayo actor + */ +static int alias_api(const char *cmd, char *jid, switch_stream_handle_t *stream) +{ + if (zstr(cmd) || zstr(jid)) { + return 0; + } + + /* send command */ + send_console_command(globals.console, jid, cmd); + stream->write_function(stream, "+OK\n"); + return 1; } @@ -3443,14 +3490,15 @@ static void send_console_message(struct rayo_client *client, const char *to, con /** * Send message to rayo actor */ -static int message_api(const char *msg, switch_stream_handle_t *stream) +static int message_api(char *cmd, switch_stream_handle_t *stream) { - char *msg_dup = strdup(msg); char *argv[2] = { 0 }; - int argc = switch_separate_string(msg_dup, ' ', argv, sizeof(argv) / sizeof(argv[0])); - - if (argc != 2) { - free(msg_dup); + if (!zstr(cmd)) { + int argc = switch_separate_string(cmd, ' ', argv, sizeof(argv) / sizeof(argv[0])); + if (argc != 2) { + return 0; + } + } else { return 0; } @@ -3458,7 +3506,6 @@ static int message_api(const char *msg, switch_stream_handle_t *stream) send_console_message(globals.console, argv[0], argv[1]); stream->write_function(stream, "+OK\n"); - free(msg_dup); return 1; } @@ -3484,151 +3531,238 @@ static void send_console_presence(struct rayo_client *client, const char *to, in /** * Send console presence */ -static int presence_api(const char *cmd, switch_stream_handle_t *stream) +static int presence_api(char *cmd, switch_stream_handle_t *stream) { - char *cmd_dup = strdup(cmd); - char *argv[2] = { 0 }; - int argc = switch_separate_string(cmd_dup, ' ', argv, sizeof(argv) / sizeof(argv[0])); int is_online = 0; - - if (argc != 2) { - free(cmd_dup); + char *argv[2] = { 0 }; + if (!zstr(cmd)) { + int argc = switch_separate_string(cmd, ' ', argv, sizeof(argv) / sizeof(argv[0])); + if (argc != 2) { + return 0; + } + } else { return 0; } if (!strcmp("online", argv[1])) { is_online = 1; } else if (strcmp("offline", argv[1])) { - free(cmd_dup); return 0; } /* send presence */ send_console_presence(globals.console, argv[0], is_online); stream->write_function(stream, "+OK\n"); - free(cmd_dup); return 1; } -#define RAYO_API_SYNTAX "status | (cmd ) | (msg ) | (presence )" +#define RAYO_API_SYNTAX "status | ( ) | (cmd ) | (msg ) | (presence )" SWITCH_STANDARD_API(rayo_api) { + const char *alias; + char *cmd_dup = strdup(cmd); + char *argv[2] = { 0 }; int success = 0; - if (!strncmp("status", cmd, 6)) { - success = dump_api(cmd + 6, stream); - } else if (!strncmp("cmd", cmd, 3)) { - success = command_api(cmd + 3, stream); - } else if (!strncmp("msg", cmd, 3)) { - success = message_api(cmd + 3, stream); - } else if (!strncmp("presence", cmd, 8)) { - success = presence_api(cmd + 8, stream); + + switch_separate_string(cmd_dup, ' ', argv, sizeof(argv) / sizeof(argv[0])); + + /* check if a command alias */ + alias = switch_core_hash_find(globals.cmd_aliases, argv[0]); + + if (!zstr(alias)) { + success = alias_api(alias, argv[1], stream); + } else if (!strcmp("cmd", argv[0])) { + success = command_api(argv[1], stream); + } else if (!strcmp("status", argv[0])) { + success = dump_api(argv[1], stream); + } else if (!strcmp("msg", argv[0])) { + success = message_api(argv[1], stream); + } else if (!strcmp("presence", argv[0])) { + success = presence_api(argv[1], stream); } if (!success) { stream->write_function(stream, "-ERR: USAGE %s\n", RAYO_API_SYNTAX); } + free(cmd_dup); + return SWITCH_STATUS_SUCCESS; } +/** + * Console auto-completion for actors given validation function + */ +static switch_status_t list_actors(const char *line, const char *cursor, switch_console_callback_match_t **matches, rayo_actor_match_fn match) +{ + switch_hash_index_t *hi; + void *val; + const void *vvar; + switch_console_callback_match_t *my_matches = NULL; + switch_status_t status = SWITCH_STATUS_FALSE; + struct rayo_actor *actor; + + switch_mutex_lock(globals.actors_mutex); + for (hi = switch_hash_first(NULL, globals.actors); hi; hi = switch_hash_next(hi)) { + switch_hash_this(hi, &vvar, NULL, &val); + + actor = (struct rayo_actor *) val; + if (match(actor)) { + switch_console_push_match(&my_matches, (const char *) vvar); + } + } + switch_mutex_unlock(globals.actors_mutex); + + if (my_matches) { + *matches = my_matches; + status = SWITCH_STATUS_SUCCESS; + } + + return status; +} + +/** + * @return true if internal actor + */ +static switch_bool_t is_internal_actor(struct rayo_actor *actor) +{ + return strcmp(RAT_CLIENT, actor->type) && strcmp(RAT_PEER_SERVER, actor->type); +} + /** * Console auto-completion for all internal actors */ -switch_status_t list_internal(const char *line, const char *cursor, switch_console_callback_match_t **matches) +static switch_status_t list_internal(const char *line, const char *cursor, switch_console_callback_match_t **matches) { - switch_hash_index_t *hi; - void *val; - const void *vvar; - switch_console_callback_match_t *my_matches = NULL; - switch_status_t status = SWITCH_STATUS_FALSE; - struct rayo_actor *actor; + return list_actors(line, cursor, matches, is_internal_actor); +} - switch_mutex_lock(globals.actors_mutex); - for (hi = switch_hash_first(NULL, globals.actors); hi; hi = switch_hash_next(hi)) { - switch_hash_this(hi, &vvar, NULL, &val); - - actor = (struct rayo_actor *) val; - if (strcmp(RAT_CLIENT, actor->type) && strcmp(RAT_PEER_SERVER, actor->type)) { - switch_console_push_match(&my_matches, (const char *) vvar); - } - } - switch_mutex_unlock(globals.actors_mutex); - - if (my_matches) { - *matches = my_matches; - status = SWITCH_STATUS_SUCCESS; - } - - return status; +/** + * @return true if external actor + */ +static switch_bool_t is_external_actor(struct rayo_actor *actor) +{ + return !strcmp(RAT_CLIENT, actor->type) || !strcmp(RAT_PEER_SERVER, actor->type); } /** * Console auto-completion for all external actors */ -switch_status_t list_external(const char *line, const char *cursor, switch_console_callback_match_t **matches) +static switch_status_t list_external(const char *line, const char *cursor, switch_console_callback_match_t **matches) { - switch_hash_index_t *hi; - void *val; - const void *vvar; - switch_console_callback_match_t *my_matches = NULL; - switch_status_t status = SWITCH_STATUS_FALSE; - struct rayo_actor *actor; + return list_actors(line, cursor, matches, is_external_actor); +} - switch_mutex_lock(globals.actors_mutex); - for (hi = switch_hash_first(NULL, globals.actors); hi; hi = switch_hash_next(hi)) { - switch_hash_this(hi, &vvar, NULL, &val); - - actor = (struct rayo_actor *) val; - if (!strcmp(RAT_CLIENT, actor->type) || !strcmp(RAT_PEER_SERVER, actor->type)) { - switch_console_push_match(&my_matches, (const char *) vvar); - } - } - switch_mutex_unlock(globals.actors_mutex); - - if (my_matches) { - *matches = my_matches; - status = SWITCH_STATUS_SUCCESS; - } - - return status; +/** + * @return true + */ +static switch_bool_t is_any_actor(struct rayo_actor *actor) +{ + return SWITCH_TRUE; } /** * Console auto-completion for all actors */ -switch_status_t list_all(const char *line, const char *cursor, switch_console_callback_match_t **matches) +static switch_status_t list_all(const char *line, const char *cursor, switch_console_callback_match_t **matches) { - switch_hash_index_t *hi; - void *val; - const void *vvar; - switch_console_callback_match_t *my_matches = NULL; - switch_status_t status = SWITCH_STATUS_FALSE; - - switch_mutex_lock(globals.actors_mutex); - for (hi = switch_hash_first(NULL, globals.actors); hi; hi = switch_hash_next(hi)) { - switch_hash_this(hi, &vvar, NULL, &val); - switch_console_push_match(&my_matches, (const char *) vvar); - } - switch_mutex_unlock(globals.actors_mutex); - - if (my_matches) { - *matches = my_matches; - status = SWITCH_STATUS_SUCCESS; - } - - return status; + return list_actors(line, cursor, matches, is_any_actor); } /** - * Add an alias to an API command - * @param alias_name - * @param alias_cmd + * @return true if a server */ -static void rayo_add_cmd_alias(const char *alias_name, const char *alias_cmd) +static switch_bool_t is_server_actor(struct rayo_actor *actor) { - char *cmd = switch_core_sprintf(globals.pool, "add rayo cmd ::rayo::list_actors %s", alias_name); - switch_console_set_complete(cmd); - switch_core_hash_insert(globals.cmd_aliases, alias_name, alias_cmd); + return !strcmp(RAT_SERVER, actor->type); +} + +/** + * Console auto-completion for all servers + */ +static switch_status_t list_server(const char *line, const char *cursor, switch_console_callback_match_t **matches) +{ + return list_actors(line, cursor, matches, is_server_actor); +} + +/** + * @return true if a call + */ +static switch_bool_t is_call_actor(struct rayo_actor *actor) +{ + return !strcmp(RAT_CALL, actor->type); +} + +/** + * Console auto-completion for all calls + */ +static switch_status_t list_call(const char *line, const char *cursor, switch_console_callback_match_t **matches) +{ + return list_actors(line, cursor, matches, is_call_actor); +} + +/** + * @return true if a component + */ +switch_bool_t is_component_actor(struct rayo_actor *actor) +{ + return !strncmp(RAT_COMPONENT, actor->type, strlen(RAT_COMPONENT)); +} + +/** + * Console auto-completion for all components + */ +static switch_status_t list_component(const char *line, const char *cursor, switch_console_callback_match_t **matches) +{ + return list_actors(line, cursor, matches, is_component_actor); +} + +/** + * @return true if a record component + */ +static switch_bool_t is_record_actor(struct rayo_actor *actor) +{ + return is_component_actor(actor) && !strcmp(actor->subtype, "record"); +} + +/** + * Console auto-completion for all components + */ +static switch_status_t list_record(const char *line, const char *cursor, switch_console_callback_match_t **matches) +{ + return list_actors(line, cursor, matches, is_record_actor); +} + +/** + * @return true if an output component + */ +static switch_bool_t is_output_actor(struct rayo_actor *actor) +{ + return is_component_actor(actor) && !strcmp(actor->subtype, "output"); +} + +/** + * Console auto-completion for all components + */ +static switch_status_t list_output(const char *line, const char *cursor, switch_console_callback_match_t **matches) +{ + return list_actors(line, cursor, matches, is_output_actor); +} + +/** + * @return true if an input component + */ +static switch_bool_t is_input_actor(struct rayo_actor *actor) +{ + return is_component_actor(actor) && !strcmp(actor->subtype, "input"); +} + +/** + * Console auto-completion for all components + */ +static switch_status_t list_input(const char *line, const char *cursor, switch_console_callback_match_t **matches) +{ + return list_actors(line, cursor, matches, is_input_actor); } /** @@ -3708,134 +3842,20 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_rayo_load) globals.console = rayo_console_client_create(); switch_console_set_complete("add rayo status"); - switch_console_set_complete("add rayo cmd ::rayo::list_internal"); switch_console_set_complete("add rayo msg ::rayo::list_external"); - switch_console_set_complete("add rayo presence ::rayo::list_all online"); - switch_console_set_complete("add rayo presence ::rayo::list_all offline"); + switch_console_set_complete("add rayo cmd ::rayo::list_all"); + switch_console_set_complete("add rayo presence ::rayo::list_server online"); + switch_console_set_complete("add rayo presence ::rayo::list_server offline"); + switch_console_add_complete_func("::rayo::list_all", list_all); switch_console_add_complete_func("::rayo::list_internal", list_internal); switch_console_add_complete_func("::rayo::list_external", list_external); - switch_console_add_complete_func("::rayo::list_all", list_all); + switch_console_add_complete_func("::rayo::list_server", list_server); + switch_console_add_complete_func("::rayo::list_call", list_call); + switch_console_add_complete_func("::rayo::list_component", list_component); + switch_console_add_complete_func("::rayo::list_record", list_record); + switch_console_add_complete_func("::rayo::list_output", list_output); + switch_console_add_complete_func("::rayo::list_input", list_input); - rayo_add_cmd_alias("ping", ""); - rayo_add_cmd_alias("answer", ""); - rayo_add_cmd_alias("hangup", ""); - rayo_add_cmd_alias("stop", ""); - rayo_add_cmd_alias("pause", ""); - rayo_add_cmd_alias("resume", ""); - rayo_add_cmd_alias("speed-up", ""); - rayo_add_cmd_alias("speed-down", ""); - rayo_add_cmd_alias("volume-up", ""); - rayo_add_cmd_alias("volume-down", ""); - rayo_add_cmd_alias("record", ""); - rayo_add_cmd_alias("record_pause", ""); - rayo_add_cmd_alias("record_resume", ""); - rayo_add_cmd_alias("prompt_barge", "" - "

Please press a digit.

]]>
" - "" - "" - "0123456789]]>" - "" - "
"); - - rayo_add_cmd_alias("prompt_barge_mrcp", "" - "

Please press a digit.

]]>
" - "" - "" - "0123456789]]>" - "" - "
"); - - rayo_add_cmd_alias("prompt_no_barge", "" - "

Please press a digit.

]]>
" - "" - "" - "0123456789]]>" - "" - "
"); - - rayo_add_cmd_alias("prompt_long", "" - "" - "" - "" - "0123456789]]>" - "" - ""); - - rayo_add_cmd_alias("prompt_multi_digit", "" - "" - "" - "" - "0123456789]]>" - "" - ""); - - rayo_add_cmd_alias("prompt_terminator", "" - "" - "" - "" - "0123456789]]>" - "" - ""); - - rayo_add_cmd_alias("prompt_input_bad", "" - "" - "" - "" - "0123456789]]>" - "" - ""); - - rayo_add_cmd_alias("prompt_output_bad", "" - "" - "" - "" - "0123456789]]>" - "" - ""); - rayo_add_cmd_alias("input", "" - "" - "0123456789*#]]>" - ""); - rayo_add_cmd_alias("output_bad", - ""); - rayo_add_cmd_alias("join_mixer_duplex", - ""); - rayo_add_cmd_alias("join_mixer_send", - ""); - rayo_add_cmd_alias("join_mixer_recv", - ""); - rayo_add_cmd_alias("unjoin_mixer", - ""); - rayo_add_cmd_alias("unjoin", - ""); - rayo_add_cmd_alias("input_voice_yesno_unimrcp", - "" - "" - "yesno]]>"); -rayo_add_cmd_alias("input_voice_yesno_unimrcp_timeout", - "" - "" - "yesno]]>"); - rayo_add_cmd_alias("input_voice_yesno_pocketsphinx", - "" - "" - "yesno]]>"); - rayo_add_cmd_alias("input_voice_yesno_default", - "" - "" - "yesno]]>"); return SWITCH_STATUS_SUCCESS; } @@ -3844,9 +3864,15 @@ rayo_add_cmd_alias("input_voice_yesno_unimrcp_timeout", */ SWITCH_MODULE_SHUTDOWN_FUNCTION(mod_rayo_shutdown) { + switch_console_del_complete_func("::rayo::list_all"); switch_console_del_complete_func("::rayo::list_internal"); switch_console_del_complete_func("::rayo::list_external"); - switch_console_del_complete_func("::rayo::list_all"); + switch_console_del_complete_func("::rayo::list_server"); + switch_console_del_complete_func("::rayo::list_call"); + switch_console_del_complete_func("::rayo::list_component"); + switch_console_del_complete_func("::rayo::list_record"); + switch_console_del_complete_func("::rayo::list_output"); + switch_console_del_complete_func("::rayo::list_input"); switch_console_set_complete("del rayo"); /* stop XMPP streams */ diff --git a/src/mod/event_handlers/mod_rayo/mod_rayo.h b/src/mod/event_handlers/mod_rayo/mod_rayo.h index f4602cc6b9..260c811a45 100644 --- a/src/mod/event_handlers/mod_rayo/mod_rayo.h +++ b/src/mod/event_handlers/mod_rayo/mod_rayo.h @@ -162,6 +162,7 @@ extern const char *rayo_call_get_dcp_jid(struct rayo_call *call); #define rayo_component_init(component, pool, type, subtype, id, parent, client_jid) _rayo_component_init(component, pool, type, subtype, id, parent, client_jid, __FILE__, __LINE__) extern struct rayo_component *_rayo_component_init(struct rayo_component *component, switch_memory_pool_t *pool, const char *type, const char *subtype, const char *id, struct rayo_actor *parent, const char *client_jid, const char *file, int line); +extern switch_bool_t is_component_actor(struct rayo_actor *); typedef iks *(*rayo_actor_xmpp_handler)(struct rayo_actor *, struct rayo_message *, void *); extern void rayo_actor_command_handler_add(const char *type, const char *subtype, const char *name, rayo_actor_xmpp_handler fn); diff --git a/src/mod/event_handlers/mod_rayo/rayo_components.c b/src/mod/event_handlers/mod_rayo/rayo_components.c index d8a8854f52..b376e97770 100644 --- a/src/mod/event_handlers/mod_rayo/rayo_components.c +++ b/src/mod/event_handlers/mod_rayo/rayo_components.c @@ -40,7 +40,7 @@ struct rayo_component *rayo_component_locate(const char *id, const char *file, int line) { struct rayo_actor *actor = rayo_actor_locate_by_id(id, file, line); - if (actor && !strncmp(RAT_COMPONENT, actor->type, strlen(RAT_COMPONENT))) { + if (actor && is_component_actor(actor)) { return RAYO_COMPONENT(actor); } else if (actor) { RAYO_UNLOCK(actor); From b76c39ade1ef8b511146aa66f8ebafd5d9717425 Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Thu, 15 Aug 2013 21:19:51 +0500 Subject: [PATCH 19/63] FS-5700 --resolve --- src/mod/endpoints/mod_sofia/mod_sofia.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/mod/endpoints/mod_sofia/mod_sofia.c b/src/mod/endpoints/mod_sofia/mod_sofia.c index 2f193c051a..1f1e090a1b 100644 --- a/src/mod/endpoints/mod_sofia/mod_sofia.c +++ b/src/mod/endpoints/mod_sofia/mod_sofia.c @@ -284,11 +284,13 @@ char *generate_pai_str(private_object_t *tech_pvt) pai = switch_core_session_sprintf(tech_pvt->session, "%s: \"%s\" <%s>%s\n" "X-FS-Display-Name: %s\nX-FS-Display-Number: %s\n", header, callee_name, callee_number, - tech_pvt->cid_type == CID_TYPE_RPID ? ";party=calling;privacy=off;screen=no" : "", + tech_pvt->cid_type == CID_TYPE_RPID && !switch_stristr("aastra", ua) ? + ";party=calling;privacy=off;screen=no" : "", callee_name, callee_number); } else { pai = switch_core_session_sprintf(tech_pvt->session, "%s: \"%s\" <%s>%s\n", header, callee_name, callee_number, - tech_pvt->cid_type == CID_TYPE_RPID ? ";party=calling;privacy=off;screen=no" : ""); + tech_pvt->cid_type == CID_TYPE_RPID && !switch_stristr("aastra", ua) ? + ";party=calling;privacy=off;screen=no" : ""); } } From dfc34d5a969f94f5132dc8c5e58e29aec7eea93f Mon Sep 17 00:00:00 2001 From: Steve Underwood Date: Fri, 16 Aug 2013 10:22:23 +0800 Subject: [PATCH 20/63] Some new FAX related variables introduced, to allow access to colour FAXing. This should be treated as experimental right now. --- libs/spandsp/src/t4_tx.c | 2 +- .../applications/mod_spandsp/mod_spandsp.c | 20 ++++++ .../applications/mod_spandsp/mod_spandsp.h | 4 ++ .../mod_spandsp/mod_spandsp_fax.c | 63 +++++++++++++++++-- 4 files changed, 83 insertions(+), 6 deletions(-) diff --git a/libs/spandsp/src/t4_tx.c b/libs/spandsp/src/t4_tx.c index 5c35fdb0b4..f349a136c5 100644 --- a/libs/spandsp/src/t4_tx.c +++ b/libs/spandsp/src/t4_tx.c @@ -1863,7 +1863,7 @@ SPAN_DECLARE(int) t4_tx_set_tx_image_format(t4_tx_state_t *s, s->metadata.image_type = T4_IMAGE_TYPE_BILEVEL; } /* Squashing to a bi-level image is possible */ - span_log(&s->logging, SPAN_LOG_FLOW, "The image may be flattened to %d\n", s->metadata.image_type); + span_log(&s->logging, SPAN_LOG_FLOW, "The image will be flattened to %d\n", s->metadata.image_type); } } diff --git a/src/mod/applications/mod_spandsp/mod_spandsp.c b/src/mod/applications/mod_spandsp/mod_spandsp.c index 51e2505758..b6ff1771de 100644 --- a/src/mod/applications/mod_spandsp/mod_spandsp.c +++ b/src/mod/applications/mod_spandsp/mod_spandsp.c @@ -577,6 +577,26 @@ switch_status_t load_configuration(switch_bool_t reload) spandsp_globals.disable_v17 = 1; else spandsp_globals.disable_v17 = 0; + } else if (!strcmp(name, "enable-colour")) { + if (switch_true(value)) + spandsp_globals.enable_colour_fax = 1; + else + spandsp_globals.enable_colour_fax = 0; + } else if (!strcmp(name, "enable-image-resizing")) { + if (switch_true(value)) + spandsp_globals.enable_image_resizing = 1; + else + spandsp_globals.enable_image_resizing = 0; + } else if (!strcmp(name, "enable-colour-to-bilevel")) { + if (switch_true(value)) + spandsp_globals.enable_colour_to_bilevel = 1; + else + spandsp_globals.enable_colour_to_bilevel = 0; + } else if (!strcmp(name, "enable-grayscale-to-bilevel")) { + if (switch_true(value)) + spandsp_globals.enable_grayscale_to_bilevel = 1; + else + spandsp_globals.enable_grayscale_to_bilevel = 0; } else if (!strcmp(name, "enable-t38")) { if (switch_true(value)) { spandsp_globals.enable_t38= 1; diff --git a/src/mod/applications/mod_spandsp/mod_spandsp.h b/src/mod/applications/mod_spandsp/mod_spandsp.h index 323ff07a45..5f5a038c43 100644 --- a/src/mod/applications/mod_spandsp/mod_spandsp.h +++ b/src/mod/applications/mod_spandsp/mod_spandsp.h @@ -60,6 +60,10 @@ struct spandsp_globals { short int use_ecm; short int verbose; short int disable_v17; + short int enable_colour_fax; + short int enable_image_resizing; + short int enable_colour_to_bilevel; + short int enable_grayscale_to_bilevel; short int enable_t38; short int enable_t38_request; short int enable_t38_insist; diff --git a/src/mod/applications/mod_spandsp/mod_spandsp_fax.c b/src/mod/applications/mod_spandsp/mod_spandsp_fax.c index 21a9cc51dc..993e44c0a5 100644 --- a/src/mod/applications/mod_spandsp/mod_spandsp_fax.c +++ b/src/mod/applications/mod_spandsp/mod_spandsp_fax.c @@ -89,6 +89,10 @@ struct pvt_s { int use_ecm; int disable_v17; + int enable_colour_fax; + int enable_image_resizing; + int enable_colour_to_bilevel; + int enable_grayscale_to_bilevel; int verbose; int caller; @@ -693,6 +697,7 @@ static switch_status_t spanfax_init(pvt_t *pvt, transport_mode_t trans_mode) const char *tz; int fec_entries = DEFAULT_FEC_ENTRIES; int fec_span = DEFAULT_FEC_SPAN; + int compressions; session = (switch_core_session_t *) pvt->session; @@ -872,8 +877,12 @@ static switch_status_t spanfax_init(pvt_t *pvt, transport_mode_t trans_mode) t30_set_phase_b_handler(t30, phase_b_handler, pvt); t30_set_supported_image_sizes(t30, - T4_SUPPORT_LENGTH_US_LETTER | T4_SUPPORT_LENGTH_US_LEGAL | T4_SUPPORT_LENGTH_UNLIMITED - | T4_SUPPORT_WIDTH_215MM | T4_SUPPORT_WIDTH_255MM | T4_SUPPORT_WIDTH_303MM); + T4_SUPPORT_LENGTH_US_LETTER + | T4_SUPPORT_LENGTH_US_LEGAL + | T4_SUPPORT_LENGTH_UNLIMITED + | T4_SUPPORT_WIDTH_215MM + | T4_SUPPORT_WIDTH_255MM + | T4_SUPPORT_WIDTH_303MM); t30_set_supported_bilevel_resolutions(t30, T4_RESOLUTION_R8_STANDARD | T4_RESOLUTION_R8_FINE @@ -883,7 +892,28 @@ static switch_status_t spanfax_init(pvt_t *pvt, transport_mode_t trans_mode) | T4_RESOLUTION_200_200 | T4_RESOLUTION_200_400 | T4_RESOLUTION_400_400); - t30_set_supported_colour_resolutions(t30, 0); + compressions = T4_COMPRESSION_T4_1D + | T4_COMPRESSION_T4_2D + | T4_COMPRESSION_T6 + | T4_COMPRESSION_T85 + | T4_COMPRESSION_T85_L0; + if (pvt->enable_colour_fax) { + t30_set_supported_colour_resolutions(t30, T4_RESOLUTION_100_100 + | T4_RESOLUTION_200_200 + | T4_RESOLUTION_300_300 + | T4_RESOLUTION_400_400); + compressions |= (T4_COMPRESSION_COLOUR | T4_COMPRESSION_T42_T81); + } else { + t30_set_supported_colour_resolutions(t30, 0); + } + if (pvt->enable_image_resizing) + compressions |= T4_COMPRESSION_RESCALING; + if (pvt->enable_colour_to_bilevel) + compressions |= T4_COMPRESSION_COLOUR_TO_BILEVEL; + if (pvt->enable_grayscale_to_bilevel) + compressions |= T4_COMPRESSION_GRAY_TO_BILEVEL; + + t30_set_supported_compressions(t30, compressions); if (pvt->disable_v17) { t30_set_supported_modems(t30, T30_SUPPORT_V29 | T30_SUPPORT_V27TER); @@ -894,11 +924,10 @@ static switch_status_t spanfax_init(pvt_t *pvt, transport_mode_t trans_mode) } if (pvt->use_ecm) { - t30_set_supported_compressions(t30, T4_COMPRESSION_T4_1D | T4_COMPRESSION_T4_2D | T4_COMPRESSION_T6 | T4_COMPRESSION_T85 | T4_COMPRESSION_T85_L0); t30_set_ecm_capability(t30, TRUE); switch_channel_set_variable(channel, "fax_ecm_requested", "1"); } else { - t30_set_supported_compressions(t30, T4_COMPRESSION_T4_1D | T4_COMPRESSION_T4_2D); + t30_set_ecm_capability(t30, FALSE); switch_channel_set_variable(channel, "fax_ecm_requested", "0"); } @@ -1217,6 +1246,30 @@ static pvt_t *pvt_init(switch_core_session_t *session, mod_spandsp_fax_applicati pvt->disable_v17 = spandsp_globals.disable_v17; } + if ((tmp = switch_channel_get_variable(channel, "fax_enable_colour"))) { + pvt->enable_colour_fax = switch_true(tmp); + } else { + pvt->enable_colour_fax = spandsp_globals.enable_colour_fax; + } + + if ((tmp = switch_channel_get_variable(channel, "fax_enable_image_resizing"))) { + pvt->enable_image_resizing = switch_true(tmp); + } else { + pvt->enable_image_resizing = spandsp_globals.enable_image_resizing; + } + + if ((tmp = switch_channel_get_variable(channel, "fax_enable_colour_to_bilevel"))) { + pvt->enable_colour_to_bilevel = switch_true(tmp); + } else { + pvt->enable_colour_to_bilevel = spandsp_globals.enable_colour_to_bilevel; + } + + if ((tmp = switch_channel_get_variable(channel, "fax_enable_grayscale_to_bilevel"))) { + pvt->enable_grayscale_to_bilevel = switch_true(tmp); + } else { + pvt->enable_grayscale_to_bilevel = spandsp_globals.enable_grayscale_to_bilevel; + } + if ((tmp = switch_channel_get_variable(channel, "fax_verbose"))) { pvt->verbose = switch_true(tmp); } else { From 6a2cd0632b7e0ca7228d0d9718af434ca3d19f6c Mon Sep 17 00:00:00 2001 From: Moises Silva Date: Fri, 16 Aug 2013 09:52:14 -0400 Subject: [PATCH 21/63] FS-5528 --resolve --- src/mod/codecs/mod_sangoma_codec/mod_sangoma_codec.c | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/src/mod/codecs/mod_sangoma_codec/mod_sangoma_codec.c b/src/mod/codecs/mod_sangoma_codec/mod_sangoma_codec.c index cd09bf3a26..416eb17b82 100644 --- a/src/mod/codecs/mod_sangoma_codec/mod_sangoma_codec.c +++ b/src/mod/codecs/mod_sangoma_codec/mod_sangoma_codec.c @@ -894,6 +894,7 @@ SWITCH_STANDARD_API(sangoma_function) char *argv[10] = { 0 }; int argc = 0; char *mycmd = NULL; + switch_bool_t locked = SWITCH_FALSE; if (zstr(cmd)) { stream->write_function(stream, "%s", SANGOMA_SYNTAX); @@ -910,6 +911,10 @@ SWITCH_STANDARD_API(sangoma_function) return SWITCH_STATUS_SUCCESS; } + /* Most operations in this API require the global session lock anyways since sessions can disappear at any moment ... */ + switch_mutex_lock(g_sessions_lock); + locked = SWITCH_TRUE; + if (!strcasecmp(argv[0], "settings")) { char addrbuff[50]; int addr; @@ -922,7 +927,6 @@ SWITCH_STANDARD_API(sangoma_function) const void *var; void *val; unsigned totalsess = 0; - switch_mutex_lock(g_sessions_lock); #define STATS_FORMAT "%-10.10s %-10.10s %-10.10s %-10.10s %-10.10s %-10.10s %-10.10s %-10.10s %-10.10s %-10.10s %-15.15s %-15.15s\n" stream->write_function(stream, STATS_FORMAT, "Session", "Codec", "Enc", "Dec", "Enc Tx", "Enc Rx", "Dec Tx", "Dec Rx", "Enc Lost", "Dec Lost", "Enc AvgRxMs", "Dec AvgRxMs"); @@ -967,7 +971,6 @@ SWITCH_STANDARD_API(sangoma_function) decoder_avgrxus_str); totalsess++; } - switch_mutex_unlock(g_sessions_lock); stream->write_function(stream, "Total sessions: %d\n", totalsess); } else if (!strcasecmp(argv[0], "stats")) { struct sangoma_transcoding_session *sess; @@ -983,6 +986,7 @@ SWITCH_STANDARD_API(sangoma_function) stream->write_function(stream, "%s", SANGOMA_SYNTAX); goto done; } + sess = sangoma_find_session(sessid); if (!sess) { stream->write_function(stream, "Failed to find session %lu\n", sessid); @@ -1076,6 +1080,9 @@ SWITCH_STANDARD_API(sangoma_function) } done: + if (locked) { + switch_mutex_unlock(g_sessions_lock); + } switch_safe_free(mycmd); return SWITCH_STATUS_SUCCESS; From d4d2d988a343b756178669092e0f48f8c57b4e97 Mon Sep 17 00:00:00 2001 From: Steve Underwood Date: Fri, 16 Aug 2013 22:21:17 +0800 Subject: [PATCH 22/63] Added missing headers to the spandsp Makefile.am --- libs/spandsp/src/Makefile.am | 3 +++ 1 file changed, 3 insertions(+) diff --git a/libs/spandsp/src/Makefile.am b/libs/spandsp/src/Makefile.am index 812100f9cb..a3b7a48ecd 100644 --- a/libs/spandsp/src/Makefile.am +++ b/libs/spandsp/src/Makefile.am @@ -294,6 +294,9 @@ nobase_include_HEADERS = spandsp/ademco_contactid.h \ spandsp/private/modem_echo.h \ spandsp/private/noise.h \ spandsp/private/oki_adpcm.h \ + spandsp/private/playout.h \ + spandsp/private/plc.h \ + spandsp/private/power_meter.h \ spandsp/private/queue.h \ spandsp/private/schedule.h \ spandsp/private/sig_tone.h \ From 80e2633bb784842abf76ff9f6ed502288421f16b Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Fri, 16 Aug 2013 20:34:29 +0500 Subject: [PATCH 23/63] add mutex in media_engine to prevent double read in video thread --- src/switch_core_media.c | 33 ++++++++++++++++++++++++++------- 1 file changed, 26 insertions(+), 7 deletions(-) diff --git a/src/switch_core_media.c b/src/switch_core_media.c index d0acc32564..b7c57a5abe 100644 --- a/src/switch_core_media.c +++ b/src/switch_core_media.c @@ -156,6 +156,7 @@ typedef struct switch_rtp_engine_s { struct media_helper mh; switch_thread_t *media_thread; + switch_mutex_t *read_mutex; } switch_rtp_engine_t; @@ -1224,6 +1225,15 @@ SWITCH_DECLARE(switch_status_t) switch_core_media_read_frame(switch_core_session switch_assert(engine->rtp_session != NULL); engine->read_frame.datalen = 0; + if (switch_mutex_trylock(engine->read_mutex) != SWITCH_STATUS_SUCCESS) { + /* return CNG for now */ + *frame = &engine->read_frame; + switch_set_flag((*frame), SFF_CNG); + (*frame)->datalen = engine->read_impl.encoded_bytes_per_packet; + memset((*frame)->data, 0, (*frame)->datalen); + return SWITCH_STATUS_SUCCESS; + } + while (smh->media_flags[SCMF_RUNNING] && engine->read_frame.datalen == 0) { engine->read_frame.flags = SFF_NONE; @@ -1239,13 +1249,13 @@ SWITCH_DECLARE(switch_status_t) switch_core_media_read_frame(switch_core_session (*frame)->datalen = engine->read_impl.encoded_bytes_per_packet; memset((*frame)->data, 0, (*frame)->datalen); switch_channel_execute_on(session->channel, "execute_on_media_timeout"); - return SWITCH_STATUS_SUCCESS; + switch_goto_status(SWITCH_STATUS_SUCCESS, end); } switch_channel_hangup(session->channel, SWITCH_CAUSE_MEDIA_TIMEOUT); } - return status; + goto end; } /* Try to read an RTCP frame, if successful raise an event */ @@ -1322,7 +1332,7 @@ SWITCH_DECLARE(switch_status_t) switch_core_media_read_frame(switch_core_session /* Fast PASS! */ if (switch_test_flag((&engine->read_frame), SFF_PROXY_PACKET)) { *frame = &engine->read_frame; - return SWITCH_STATUS_SUCCESS; + switch_goto_status(SWITCH_STATUS_SUCCESS, end); } if (switch_rtp_has_dtmf(engine->rtp_session)) { @@ -1338,7 +1348,7 @@ SWITCH_DECLARE(switch_status_t) switch_core_media_read_frame(switch_core_session if (!switch_test_flag((&engine->read_frame), SFF_CNG)) { if (!engine->read_codec.implementation || !switch_core_codec_ready(&engine->read_codec)) { *frame = NULL; - return SWITCH_STATUS_GENERR; + switch_goto_status(SWITCH_STATUS_GENERR, end); } /* check for timing or codec issues */ @@ -1475,7 +1485,7 @@ SWITCH_DECLARE(switch_status_t) switch_core_media_read_frame(switch_core_session if (switch_rtp_ready(engine->rtp_session)) { if (switch_core_media_set_codec(session, 2, 0) != SWITCH_STATUS_SUCCESS) { *frame = NULL; - return SWITCH_STATUS_GENERR; + switch_goto_status(SWITCH_STATUS_GENERR, end); } if ((val = switch_channel_get_variable(session->channel, "rtp_timeout_sec"))) { @@ -1516,7 +1526,7 @@ SWITCH_DECLARE(switch_status_t) switch_core_media_read_frame(switch_core_session switch_set_flag((*frame), SFF_CNG); (*frame)->datalen = engine->read_impl.encoded_bytes_per_packet; memset((*frame)->data, 0, (*frame)->datalen); - return SWITCH_STATUS_SUCCESS; + switch_goto_status(SWITCH_STATUS_SUCCESS, end); } } @@ -1541,7 +1551,13 @@ SWITCH_DECLARE(switch_status_t) switch_core_media_read_frame(switch_core_session *frame = &engine->read_frame; - return SWITCH_STATUS_SUCCESS; + status = SWITCH_STATUS_SUCCESS; + + end: + + switch_mutex_unlock(engine->read_mutex); + + return status; } //? @@ -4164,6 +4180,8 @@ SWITCH_DECLARE(switch_status_t) switch_core_media_activate_rtp(switch_core_sessi uint8_t inb = switch_channel_direction(session->channel) == SWITCH_CALL_DIRECTION_INBOUND; const char *ssrc; + switch_mutex_init(&a_engine->read_mutex, SWITCH_MUTEX_NESTED, switch_core_session_get_pool(session)); + //switch_core_media_set_rtp_session(session, SWITCH_MEDIA_TYPE_AUDIO, a_engine->rtp_session); if ((ssrc = switch_channel_get_variable(session->channel, "rtp_use_ssrc"))) { @@ -4623,6 +4641,7 @@ SWITCH_DECLARE(switch_status_t) switch_core_media_activate_rtp(switch_core_sessi switch_thread_cond_create(&v_engine->mh.cond, pool); switch_mutex_init(&v_engine->mh.cond_mutex, SWITCH_MUTEX_NESTED, pool); + switch_mutex_init(&v_engine->read_mutex, SWITCH_MUTEX_NESTED, pool); switch_thread_create(&v_engine->media_thread, thd_attr, video_helper_thread, &v_engine->mh, switch_core_session_get_pool(session)); } From d35db852a8bcc4fb10e7a8486046aabd45a7f9b2 Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Fri, 16 Aug 2013 12:17:00 -0400 Subject: [PATCH 24/63] follow up to last commit --- src/include/switch_core.h | 2 ++ .../mod_conference/mod_conference.c | 3 +++ src/switch_core_media.c | 9 ++++++++- src/switch_core_session.c | 19 ++++++++----------- src/switch_core_state_machine.c | 2 ++ src/switch_ivr_bridge.c | 7 ++++--- 6 files changed, 27 insertions(+), 15 deletions(-) diff --git a/src/include/switch_core.h b/src/include/switch_core.h index dfa1d39d7c..880cf9b893 100644 --- a/src/include/switch_core.h +++ b/src/include/switch_core.h @@ -1015,6 +1015,8 @@ SWITCH_DECLARE(switch_app_log_t *) switch_core_session_get_app_log(_In_ switch_c */ SWITCH_DECLARE(switch_status_t) switch_core_session_exec(_In_ switch_core_session_t *session, _In_ const switch_application_interface_t *application_interface, _In_opt_z_ const char *arg); + +SWITCH_DECLARE(void) switch_core_session_video_reset(switch_core_session_t *session); /*! \brief Execute an application on a session \param session the current session diff --git a/src/mod/applications/mod_conference/mod_conference.c b/src/mod/applications/mod_conference/mod_conference.c index 99b992befd..698b2079bd 100644 --- a/src/mod/applications/mod_conference/mod_conference.c +++ b/src/mod/applications/mod_conference/mod_conference.c @@ -7472,6 +7472,8 @@ SWITCH_STANDARD_APP(conference_function) switch_channel_set_app_flag_key("conf_silent", channel, CONF_SILENT_REQ); } + switch_core_session_video_reset(session); + switch_channel_set_flag(channel, CF_CONFERENCE); if (switch_channel_answer(channel) != SWITCH_STATUS_SUCCESS) { @@ -8028,6 +8030,7 @@ SWITCH_STANDARD_APP(conference_function) switch_channel_clear_flag(channel, CF_CONFERENCE); + switch_core_session_video_reset(session); } /* Create a thread for the conference and launch it */ diff --git a/src/switch_core_media.c b/src/switch_core_media.c index b7c57a5abe..b18ec859e8 100644 --- a/src/switch_core_media.c +++ b/src/switch_core_media.c @@ -1225,12 +1225,19 @@ SWITCH_DECLARE(switch_status_t) switch_core_media_read_frame(switch_core_session switch_assert(engine->rtp_session != NULL); engine->read_frame.datalen = 0; + if (!switch_channel_up_nosig(session->channel) || !switch_rtp_ready(engine->rtp_session) || switch_channel_test_flag(session->channel, CF_NOT_READY)) { + return SWITCH_STATUS_FALSE; + } + if (switch_mutex_trylock(engine->read_mutex) != SWITCH_STATUS_SUCCESS) { - /* return CNG for now */ + /* return CNG, another thread is already reading */ *frame = &engine->read_frame; switch_set_flag((*frame), SFF_CNG); (*frame)->datalen = engine->read_impl.encoded_bytes_per_packet; memset((*frame)->data, 0, (*frame)->datalen); + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG1, "%s is already being read for %s\n", + switch_channel_get_name(session->channel), type2str(type)); + switch_yield(10000); return SWITCH_STATUS_SUCCESS; } diff --git a/src/switch_core_session.c b/src/switch_core_session.c index 0768feed15..a67359d677 100644 --- a/src/switch_core_session.c +++ b/src/switch_core_session.c @@ -2521,6 +2521,14 @@ SWITCH_DECLARE(switch_status_t) switch_core_session_execute_application_async(sw return SWITCH_STATUS_FALSE; } +SWITCH_DECLARE(void) switch_core_session_video_reset(switch_core_session_t *session) +{ + if (switch_channel_test_flag(session->channel, CF_VIDEO)) { + switch_channel_set_flag(session->channel, CF_VIDEO_ECHO); + switch_channel_clear_flag(session->channel, CF_VIDEO_PASSIVE); + switch_core_session_refresh_video(session); + } +} SWITCH_DECLARE(switch_status_t) switch_core_session_execute_application_get_flags(switch_core_session_t *session, const char *app, const char *arg, int32_t *flags) @@ -2736,19 +2744,8 @@ SWITCH_DECLARE(switch_status_t) switch_core_session_exec(switch_core_session_t * msg.string_array_arg[1] = expanded; switch_core_session_receive_message(session, &msg); - if (switch_channel_test_flag(channel, CF_VIDEO)) { - switch_channel_set_flag(channel, CF_VIDEO_ECHO); - switch_channel_clear_flag(channel, CF_VIDEO_PASSIVE); - switch_core_session_refresh_video(session); - } - application_interface->application_function(session, expanded); - if (switch_channel_test_flag(channel, CF_VIDEO)) { - switch_channel_set_flag(channel, CF_VIDEO_ECHO); - switch_channel_clear_flag(channel, CF_VIDEO_PASSIVE); - switch_core_session_refresh_video(session); - } if (switch_event_create(&event, SWITCH_EVENT_CHANNEL_EXECUTE_COMPLETE) == SWITCH_STATUS_SUCCESS) { const char *resp = switch_channel_get_variable(session->channel, SWITCH_CURRENT_APPLICATION_RESPONSE_VARIABLE); switch_channel_event_set_data(session->channel, event); diff --git a/src/switch_core_state_machine.c b/src/switch_core_state_machine.c index 56811a1e75..5926e52586 100644 --- a/src/switch_core_state_machine.c +++ b/src/switch_core_state_machine.c @@ -216,6 +216,8 @@ static void switch_core_standard_on_execute(switch_core_session_t *session) top: switch_channel_clear_flag(session->channel, CF_RESET); + + switch_core_session_video_reset(session); if ((extension = switch_channel_get_caller_extension(session->channel)) == 0) { switch_channel_hangup(session->channel, SWITCH_CAUSE_NORMAL_CLEARING); diff --git a/src/switch_ivr_bridge.c b/src/switch_ivr_bridge.c index f9b22f8a4f..e0d005aec9 100644 --- a/src/switch_ivr_bridge.c +++ b/src/switch_ivr_bridge.c @@ -63,7 +63,7 @@ static void *SWITCH_THREAD_FUNC video_bridge_thread(switch_thread_t *thread, voi if (!switch_stristr("loopback", source) && !switch_stristr("loopback", b_source)) { switch_channel_set_flag(channel, CF_VIDEO_PASSIVE); - switch_channel_set_flag(b_channel, CF_VIDEO_PASSIVE); + //switch_channel_set_flag(b_channel, CF_VIDEO_PASSIVE); } switch_core_session_refresh_video(vh->session_a); @@ -94,7 +94,7 @@ static void *SWITCH_THREAD_FUNC video_bridge_thread(switch_thread_t *thread, voi } switch_channel_clear_flag(channel, CF_VIDEO_PASSIVE); - switch_channel_clear_flag(b_channel, CF_VIDEO_PASSIVE); + //switch_channel_clear_flag(b_channel, CF_VIDEO_PASSIVE); switch_core_session_kill_channel(vh->session_b, SWITCH_SIG_BREAK); switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(vh->session_a), SWITCH_LOG_DEBUG, "%s video thread ended.\n", switch_channel_get_name(channel)); @@ -624,7 +624,8 @@ static void *audio_bridge_thread(switch_thread_t *thread, void *obj) if (vid_thread) { switch_status_t st; - if (vh.up) { + if (vh.up == 1) { + vh.up = -1; switch_core_session_kill_channel(session_a, SWITCH_SIG_BREAK); switch_core_session_kill_channel(session_b, SWITCH_SIG_BREAK); } From 6daf13208103b6e9a9412fbb2dfcedc5146c9cfc Mon Sep 17 00:00:00 2001 From: Steve Underwood Date: Sat, 17 Aug 2013 03:42:04 +0800 Subject: [PATCH 25/63] Removed unnecessary fseeks from T.42, and change tried a test with different default T.42 illuminant, to see if the colours suit screens better. --- libs/spandsp/src/t42.c | 16 ++-------------- 1 file changed, 2 insertions(+), 14 deletions(-) diff --git a/libs/spandsp/src/t42.c b/libs/spandsp/src/t42.c index 3e7ea3070b..2fa943cb9c 100644 --- a/libs/spandsp/src/t42.c +++ b/libs/spandsp/src/t42.c @@ -949,6 +949,7 @@ SPAN_DECLARE(int) t42_encode_restart(t42_encode_state_t *s, uint32_t image_width /* ITULAB */ /* Illuminant D50 */ set_lab_illuminant(&s->lab, 96.422f, 100.000f, 82.521f); +set_lab_illuminant(&s->lab, 95.047f, 100.000f, 108.883f); set_lab_gamut(&s->lab, 0, 100, -85, 85, -75, 125, false); } s->compressed_image_size = 0; @@ -965,12 +966,6 @@ SPAN_DECLARE(int) t42_encode_restart(t42_encode_state_t *s, uint32_t image_width span_log(&s->logging, SPAN_LOG_FLOW, "Failed to open_memstream().\n"); return -1; } - if (fseek(s->out, 0, SEEK_SET) != 0) - { - fclose(s->out); - s->out = NULL; - return -1; - } #else if ((s->out = tmpfile()) == NULL) { @@ -1114,14 +1109,6 @@ static int t42_itulab_jpeg_to_srgb(t42_decode_state_t *s) for (i = 0; i < 16; i++) jpeg_save_markers(&s->decompressor, JPEG_APP0 + i, 0xFFFF); - /* Rewind the file */ - if (fseek(s->in, 0, SEEK_SET) != 0) - { - fclose(s->in); - s->in = NULL; - return -1; - } - /* Take the header */ jpeg_read_header(&s->decompressor, false); /* Sanity check and parameter check */ @@ -1328,6 +1315,7 @@ SPAN_DECLARE(int) t42_decode_restart(t42_decode_state_t *s) /* ITULAB */ /* Illuminant D50 */ set_lab_illuminant(&s->lab, 96.422f, 100.000f, 82.521f); +set_lab_illuminant(&s->lab, 95.047f, 100.000f, 108.883f); set_lab_gamut(&s->lab, 0, 100, -85, 85, -75, 125, false); } From c21f65ac5519d26f12c969e26d8d3e009538e6df Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Sat, 17 Aug 2013 02:13:49 +0500 Subject: [PATCH 26/63] FS-5708 --resolve --- 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 a11f908dce..8b5fc8e3c9 100644 --- a/src/switch_utils.c +++ b/src/switch_utils.c @@ -1273,7 +1273,7 @@ static int get_netmask(struct sockaddr_in *me, int *mask) struct sockaddr_in *s = (struct sockaddr_in *) i->ifa_addr; struct sockaddr_in *m = (struct sockaddr_in *) i->ifa_netmask; - if (s && m && s->sin_addr.s_addr == me->sin_addr.s_addr) { + if (s && m && addr->ifa_addr->sa_family == AF_INET && s->sin_addr && s->sin_addr.s_addr == me->sin_addr.s_addr) { *mask = m->sin_addr.s_addr; freeifaddrs(ifaddrs); return 0; From 8e45f23d028f6c3fe375a2dc307b6e66f99e39bb Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Sat, 17 Aug 2013 02:16:28 +0500 Subject: [PATCH 27/63] FS-5709 --resolve --- src/include/switch_console.h | 1 + src/include/switch_utils.h | 15 ++++- .../applications/mod_commands/mod_commands.c | 47 ++++++++++++++++ src/mod/endpoints/mod_sofia/sofia.c | 26 +++++++++ src/switch_console.c | 46 ++++++++++++++++ src/switch_utils.c | 55 +++++++++++++++++++ 6 files changed, 189 insertions(+), 1 deletion(-) diff --git a/src/include/switch_console.h b/src/include/switch_console.h index e6f6cf476e..73410bd248 100644 --- a/src/include/switch_console.h +++ b/src/include/switch_console.h @@ -83,6 +83,7 @@ SWITCH_DECLARE(switch_status_t) switch_console_add_complete_func(const char *nam SWITCH_DECLARE(switch_status_t) switch_console_del_complete_func(const char *name); SWITCH_DECLARE(switch_status_t) switch_console_run_complete_func(const char *func, const char *line, const char *last_word, switch_console_callback_match_t **matches); +SWITCH_DECLARE(void) switch_console_push_match_unique(switch_console_callback_match_t **matches, const char *new_val); SWITCH_DECLARE(void) switch_console_push_match(switch_console_callback_match_t **matches, const char *new_val); SWITCH_DECLARE(void) switch_console_free_matches(switch_console_callback_match_t **matches); SWITCH_DECLARE(unsigned char) switch_console_complete(const char *line, const char *last_word, diff --git a/src/include/switch_utils.h b/src/include/switch_utils.h index 40630d8c9f..f4aa3d7f28 100644 --- a/src/include/switch_utils.h +++ b/src/include/switch_utils.h @@ -467,14 +467,27 @@ SWITCH_DECLARE(switch_status_t) switch_resolve_host(const char *host, char *buf, /*! \brief find local ip of the box - \param buf the buffer to write the ip adress found into + \param buf the buffer to write the ip address found into \param len the length of the buf + \param mask the CIDR found (AF_INET only) \param family the address family to return (AF_INET or AF_INET6) \return SWITCH_STATUS_SUCCESSS for success, otherwise failure */ SWITCH_DECLARE(switch_status_t) switch_find_local_ip(_Out_opt_bytecapcount_(len) char *buf, _In_ int len, _In_opt_ int *mask, _In_ int family); +/*! + \brief find primary ip of the specified interface + \param buf the buffer to write the ip address found into + \param len the length of the buf + \param mask the CIDR found (AF_INET only) + \param ifname interface name to check + \param family the address family to return (AF_INET or AF_INET6) + \return SWITCH_STATUS_SUCCESSS for success, otherwise failure +*/ +SWITCH_DECLARE(switch_status_t) switch_find_interface_ip(_Out_opt_bytecapcount_(len) + char *buf, _In_ int len, _In_opt_ int *mask, _In_ const char *ifname, _In_ int family); + /*! \brief find the char representation of an ip adress \param buf the buffer to write the ip adress found into diff --git a/src/mod/applications/mod_commands/mod_commands.c b/src/mod/applications/mod_commands/mod_commands.c index fc74c3dd65..abc0aace9a 100644 --- a/src/mod/applications/mod_commands/mod_commands.c +++ b/src/mod/applications/mod_commands/mod_commands.c @@ -6028,6 +6028,49 @@ SWITCH_STANDARD_API(file_exists_function) return SWITCH_STATUS_SUCCESS; } +#define INTERFACE_IP_SYNTAX "[auto|ipv4|ipv6] " +SWITCH_STANDARD_API(interface_ip_function) +{ + char *mydata = NULL, *argv[3] = { 0 }; + int argc = 0; + char addr[INET6_ADDRSTRLEN]; + + if (!zstr(cmd)) { + mydata = strdup(cmd); + switch_assert(mydata); + argc = switch_separate_string(mydata, ' ', argv, (sizeof(argv) / sizeof(argv[0]))); + } + + if (argc < 2) { + stream->write_function(stream, "USAGE: interface_ip %s\n", INTERFACE_IP_SYNTAX); + goto end; + } + + if (!strcasecmp(argv[0], "ipv4")) { + if (switch_find_interface_ip(addr, sizeof(addr), NULL, argv[1], AF_INET) == SWITCH_STATUS_SUCCESS) { + stream->write_function(stream, "%s", addr); + } + } + else if (!strcasecmp(argv[0], "ipv6")) { + if (switch_find_interface_ip(addr, sizeof(addr), NULL, argv[1], AF_INET6) == SWITCH_STATUS_SUCCESS) { + stream->write_function(stream, "%s", addr); + } + } + else if (!strcasecmp(argv[0], "auto")) { + if (switch_find_interface_ip(addr, sizeof(addr), NULL, argv[1], AF_UNSPEC) == SWITCH_STATUS_SUCCESS) { + stream->write_function(stream, "%s", addr); + } + } + else { + stream->write_function(stream, "USAGE: interface_ip %s\n", INTERFACE_IP_SYNTAX); + } + +end: + switch_safe_free(mydata); + + return SWITCH_STATUS_SUCCESS; +} + SWITCH_MODULE_LOAD_FUNCTION(mod_commands_load) { switch_api_interface_t *commands_api_interface; @@ -6065,6 +6108,7 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_commands_load) SWITCH_ADD_API(commands_api_interface, "help", "Show help for all the api commands", help_function, ""); SWITCH_ADD_API(commands_api_interface, "host_lookup", "Lookup host", host_lookup_function, ""); SWITCH_ADD_API(commands_api_interface, "hostname", "Return the system hostname", hostname_api_function, ""); + SWITCH_ADD_API(commands_api_interface, "interface_ip", "Return the primary IP of an interface", interface_ip_function, INTERFACE_IP_SYNTAX); SWITCH_ADD_API(commands_api_interface, "switchname", "Return the switch name", switchname_api_function, ""); SWITCH_ADD_API(commands_api_interface, "hupall", "hupall", hupall_api_function, " [ ]"); SWITCH_ADD_API(commands_api_interface, "in_group", "Determine if a user is in a group", in_group_function, "[@] "); @@ -6217,6 +6261,9 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_commands_load) switch_console_set_complete("add fsctl flush_db_handles"); switch_console_set_complete("add fsctl min_idle_cpu"); switch_console_set_complete("add fsctl send_sighup"); + switch_console_set_complete("add interface_ip auto ::console::list_interfaces"); + switch_console_set_complete("add interface_ip ipv4 ::console::list_interfaces"); + switch_console_set_complete("add interface_ip ipv6 ::console::list_interfaces"); switch_console_set_complete("add load ::console::list_available_modules"); switch_console_set_complete("add nat_map reinit"); switch_console_set_complete("add nat_map republish"); diff --git a/src/mod/endpoints/mod_sofia/sofia.c b/src/mod/endpoints/mod_sofia/sofia.c index 40c8bc370d..b399284337 100644 --- a/src/mod/endpoints/mod_sofia/sofia.c +++ b/src/mod/endpoints/mod_sofia/sofia.c @@ -4104,9 +4104,22 @@ switch_status_t config_sofia(sofia_config_t reload, char *profile_name) } } else if (!strcasecmp(var, "rtp-ip")) { char *ip = mod_sofia_globals.guess_ip; + char buf[64]; if (!strcmp(val, "0.0.0.0")) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Invalid IP 0.0.0.0 replaced with %s\n", mod_sofia_globals.guess_ip); + } else if (!strncasecmp(val, "interface:", 10)) { + char *ifname = val+10; + int family = AF_UNSPEC; + if (!strncasecmp(ifname, "auto/", 5)) { ifname += 5; family = AF_UNSPEC; } + if (!strncasecmp(ifname, "ipv4/", 5)) { ifname += 5; family = AF_INET; } + if (!strncasecmp(ifname, "ipv6/", 5)) { ifname += 5; family = AF_INET6; } + if (switch_find_interface_ip(buf, sizeof(buf), NULL, ifname, family) == SWITCH_STATUS_SUCCESS) { + ip = buf; + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Using %s IP for interface %s for rtp-ip\n", ip, val+10); + } else { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Unknown IP for interface %s for rtp-ip\n", val+10); + } } else { ip = strcasecmp(val, "auto") ? val : mod_sofia_globals.guess_ip; } @@ -4117,9 +4130,22 @@ switch_status_t config_sofia(sofia_config_t reload, char *profile_name) } } else if (!strcasecmp(var, "sip-ip")) { char *ip = mod_sofia_globals.guess_ip; + char buf[64]; if (!strcmp(val, "0.0.0.0")) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Invalid IP 0.0.0.0 replaced with %s\n", mod_sofia_globals.guess_ip); + } else if (!strncasecmp(val, "interface:", 10)) { + char *ifname = val+10; + int family = AF_UNSPEC; + if (!strncasecmp(ifname, "auto/", 5)) { ifname += 5; family = AF_UNSPEC; } + if (!strncasecmp(ifname, "ipv4/", 5)) { ifname += 5; family = AF_INET; } + if (!strncasecmp(ifname, "ipv6/", 5)) { ifname += 5; family = AF_INET6; } + if (switch_find_interface_ip(buf, sizeof(buf), NULL, ifname, family) == SWITCH_STATUS_SUCCESS) { + ip = buf; + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Using %s IP for interface %s for sip-ip\n", ip, val+10); + } else { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Unknown IP for interface %s for sip-ip\n", val+10); + } } else { ip = strcasecmp(val, "auto") ? val : mod_sofia_globals.guess_ip; } diff --git a/src/switch_console.c b/src/switch_console.c index b1e2c8e271..b2c003a6c6 100644 --- a/src/switch_console.c +++ b/src/switch_console.c @@ -33,6 +33,7 @@ #include #include #include +#include #define CMD_BUFLEN 1024 #ifdef SWITCH_HAVE_LIBEDIT @@ -619,6 +620,36 @@ SWITCH_DECLARE_NONSTD(switch_status_t) switch_console_list_loaded_modules(const return SWITCH_STATUS_FALSE; } +#ifdef HAVE_GETIFADDRS +#include +#include +SWITCH_DECLARE_NONSTD(switch_status_t) switch_console_list_interfaces(const char *line, const char *cursor, switch_console_callback_match_t **matches) +{ + struct match_helper h = { 0 }; + struct ifaddrs *addrs, *addr; + + getifaddrs(&addrs); + for(addr = addrs; addr; addr = addr->ifa_next) { + if (addr->ifa_flags & IFF_UP) { + switch_console_push_match_unique(&h.my_matches, addr->ifa_name); + } + } + freeifaddrs(addrs); + + if (h.my_matches) { + *matches = h.my_matches; + return SWITCH_STATUS_SUCCESS; + } + + return SWITCH_STATUS_FALSE; +} +#else +SWITCH_DECLARE_NONSTD(switch_status_t) switch_console_list_interfaces(const char *line, const char *cursor, switch_console_callback_match_t **matches) +{ + return SWITCH_STATUS_FALSE; +} +#endif + static int uuid_callback(void *pArg, int argc, char **argv, char **columnNames) { struct match_helper *h = (struct match_helper *) pArg; @@ -1631,6 +1662,7 @@ SWITCH_DECLARE(switch_status_t) switch_console_init(switch_memory_pool_t *pool) switch_core_hash_init(&globals.func_hash, pool); switch_console_add_complete_func("::console::list_available_modules", (switch_console_complete_callback_t) switch_console_list_available_modules); switch_console_add_complete_func("::console::list_loaded_modules", (switch_console_complete_callback_t) switch_console_list_loaded_modules); + switch_console_add_complete_func("::console::list_interfaces", (switch_console_complete_callback_t) switch_console_list_interfaces); switch_console_add_complete_func("::console::list_uuid", (switch_console_complete_callback_t) switch_console_list_uuid); return SWITCH_STATUS_SUCCESS; } @@ -1741,6 +1773,20 @@ SWITCH_DECLARE(void) switch_console_sort_matches(switch_console_callback_match_t } } +SWITCH_DECLARE(void) switch_console_push_match_unique(switch_console_callback_match_t **matches, const char *new_val) +{ + /* Ignore the entry if it is already in the list */ + if (*matches) { + switch_console_callback_match_node_t *node; + + for(node = (*matches)->head; node; node = node->next) { + if (!strcasecmp(node->val, new_val)) return; + } + } + + switch_console_push_match(matches, new_val); +} + SWITCH_DECLARE(void) switch_console_push_match(switch_console_callback_match_t **matches, const char *new_val) { switch_console_callback_match_node_t *match; diff --git a/src/switch_utils.c b/src/switch_utils.c index 8b5fc8e3c9..bc3a9364e3 100644 --- a/src/switch_utils.c +++ b/src/switch_utils.c @@ -1580,6 +1580,61 @@ SWITCH_DECLARE(switch_status_t) switch_find_local_ip(char *buf, int len, int *ma return status; } +#ifdef HAVE_GETIFADDRS +# include +# include +#endif +SWITCH_DECLARE(switch_status_t) switch_find_interface_ip(char *buf, int len, int *mask, const char *ifname, int family) +{ + switch_status_t status = SWITCH_STATUS_FALSE; + +#ifdef HAVE_GETIFADDRS + + struct ifaddrs *addrs, *addr; + + getifaddrs(&addrs); + for(addr = addrs; addr; addr = addr->ifa_next) + { + if (!(addr->ifa_flags & IFF_UP)) continue; // Address is not UP + if (!addr->ifa_addr) continue; // No address set + if (!addr->ifa_netmask) continue; // No netmask set + if (family != AF_UNSPEC && addr->ifa_addr->sa_family != family) continue; // Not the address family we're looking for + if (strcmp(addr->ifa_name, ifname)) continue; // Not the interface we're looking for + + switch(addr->ifa_addr->sa_family) { + case AF_INET: + inet_ntop(AF_INET, &( ((struct sockaddr_in*)(addr->ifa_addr))->sin_addr ), buf, len - 1); + break; + case AF_INET6: + inet_ntop(AF_INET6, &( ((struct sockaddr_in6*)(addr->ifa_addr))->sin6_addr ), buf, len - 1); + break; + default: + continue; + } + + if (mask && addr->ifa_netmask->sa_family == AF_INET) { + *mask = ((struct sockaddr_in*)(addr->ifa_addr))->sin_addr.s_addr; + } + + status = SWITCH_STATUS_SUCCESS; + break; + } + freeifaddrs(addrs); + +#elif defined(__linux__) + + // TODO Not implemented, contributions welcome. + +#elif defined(WIN32) + + // TODO Not implemented, contributions welcome. + +#endif + + return status; +} + + SWITCH_DECLARE(switch_time_t) switch_str_time(const char *in) { switch_time_exp_t tm = { 0 }; From 1facd34bde5986e521abbd28509edd79855c7c6a Mon Sep 17 00:00:00 2001 From: Ken Rice Date: Fri, 16 Aug 2013 17:53:12 -0500 Subject: [PATCH 28/63] Revert "FS-5708 ... problems with build on this one This reverts commit c21f65ac5519d26f12c969e26d8d3e009538e6df. --- 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 bc3a9364e3..1412dd41fe 100644 --- a/src/switch_utils.c +++ b/src/switch_utils.c @@ -1273,7 +1273,7 @@ static int get_netmask(struct sockaddr_in *me, int *mask) struct sockaddr_in *s = (struct sockaddr_in *) i->ifa_addr; struct sockaddr_in *m = (struct sockaddr_in *) i->ifa_netmask; - if (s && m && addr->ifa_addr->sa_family == AF_INET && s->sin_addr && s->sin_addr.s_addr == me->sin_addr.s_addr) { + if (s && m && s->sin_addr.s_addr == me->sin_addr.s_addr) { *mask = m->sin_addr.s_addr; freeifaddrs(ifaddrs); return 0; From 56725ad2f25a0e060c44821bf3bd7591664956e4 Mon Sep 17 00:00:00 2001 From: Steve Underwood Date: Mon, 19 Aug 2013 01:38:02 +0800 Subject: [PATCH 29/63] Tweaks for colour FAXing --- libs/spandsp/src/t4_rx.c | 2 +- src/mod/applications/mod_spandsp/mod_spandsp_fax.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/libs/spandsp/src/t4_rx.c b/libs/spandsp/src/t4_rx.c index 256e8fcdfc..1164814355 100644 --- a/libs/spandsp/src/t4_rx.c +++ b/libs/spandsp/src/t4_rx.c @@ -1020,7 +1020,7 @@ SPAN_DECLARE(void) t4_rx_get_transfer_statistics(t4_rx_state_t *s, t4_stats_t *t break; #endif case T4_COMPRESSION_T42_T81: - t->type = T4_IMAGE_TYPE_GRAY_8BIT; //T4_IMAGE_TYPE_COLOUR_8BIT; + t->type = T4_IMAGE_TYPE_COLOUR_8BIT; //T4_IMAGE_TYPE_GRAY_8BIT; t->width = t42_decode_get_image_width(&s->decoder.t42); t->length = t42_decode_get_image_length(&s->decoder.t42); t->image_type = t->type; diff --git a/src/mod/applications/mod_spandsp/mod_spandsp_fax.c b/src/mod/applications/mod_spandsp/mod_spandsp_fax.c index 993e44c0a5..db9d8c1f2a 100644 --- a/src/mod/applications/mod_spandsp/mod_spandsp_fax.c +++ b/src/mod/applications/mod_spandsp/mod_spandsp_fax.c @@ -442,7 +442,7 @@ static int phase_d_handler(t30_state_t *s, void *user_data, int msg) switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "==== Page %s===========================================================\n", pvt->app_mode == FUNCTION_TX ? "Sent ====": "Received "); switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Page no = %d\n", (pvt->app_mode == FUNCTION_TX) ? t30_stats.pages_tx : t30_stats.pages_rx); - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Image type = %s (%s in the file)\n", t4_image_type_to_str(t30_stats.type), t4_image_type_to_str(t30_stats.image_type)); + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Image type = %s (%s in the file)\n", t4_image_type_to_str(t30_stats.type), t4_image_type_to_str(t30_stats.image_type)); switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Image size = %d x %d pixels (%d x %d pixels in the file)\n", t30_stats.width, t30_stats.length, t30_stats.image_width, t30_stats.image_length); switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Image resolution = %d/m x %d/m (%d/m x %d/m in the file)\n", t30_stats.x_resolution, t30_stats.y_resolution, t30_stats.image_x_resolution, t30_stats.image_y_resolution); switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Compression = %s (%d)\n", t4_compression_to_str(t30_stats.compression), t30_stats.compression); From b346bf56f55ff853f343d29abb3b2a4b1267151f Mon Sep 17 00:00:00 2001 From: Steve Underwood Date: Mon, 19 Aug 2013 02:04:13 +0800 Subject: [PATCH 30/63] Some tweaks to colour FAXing and some alterations to the supervisory tones tables. --- libs/spandsp/spandsp/global-tones.xml | 820 +++++++++++++------------- libs/spandsp/spandsp/tones.dtd | 88 ++- libs/spandsp/spandsp/tsb85.xml | 4 +- 3 files changed, 471 insertions(+), 441 deletions(-) diff --git a/libs/spandsp/spandsp/global-tones.xml b/libs/spandsp/spandsp/global-tones.xml index 466dae5d2f..5b376d1e86 100644 --- a/libs/spandsp/spandsp/global-tones.xml +++ b/libs/spandsp/spandsp/global-tones.xml @@ -5,12 +5,12 @@ - + - + @@ -25,12 +25,12 @@ - + - + @@ -42,12 +42,12 @@ - + - + @@ -82,12 +82,12 @@ - + - + @@ -142,12 +142,12 @@ - + - + @@ -180,12 +180,12 @@ - + - + @@ -230,12 +230,12 @@ - + - + @@ -273,12 +273,12 @@ - + - + @@ -306,14 +306,14 @@ - + - + @@ -377,12 +377,12 @@ - + - + @@ -448,12 +448,12 @@ - + - + @@ -469,14 +469,14 @@ - + - + @@ -533,12 +533,12 @@ - + - + @@ -553,12 +553,12 @@ - + - + @@ -575,12 +575,12 @@ - + - + @@ -601,12 +601,12 @@ - + - + @@ -618,12 +618,12 @@ - + - + @@ -655,14 +655,14 @@ - + - + @@ -689,14 +689,14 @@ - + - + @@ -735,12 +735,12 @@ - + - + @@ -784,12 +784,12 @@ - + - + @@ -841,14 +841,14 @@ - + - + @@ -907,24 +907,24 @@ - + - - + + - - + + - + @@ -995,18 +995,18 @@ - + - - + + - + @@ -1038,12 +1038,12 @@ - + - + @@ -1067,12 +1067,12 @@ - + - + @@ -1096,18 +1096,18 @@ - + - - + + - + @@ -1141,12 +1141,12 @@ - + - + @@ -1173,12 +1173,12 @@ - + - + @@ -1211,14 +1211,14 @@ - + - + @@ -1255,12 +1255,12 @@ - + - + @@ -1310,12 +1310,12 @@ - + - + @@ -1364,12 +1364,12 @@ - + - + @@ -1385,12 +1385,12 @@ - + - + @@ -1409,12 +1409,12 @@ - + - + @@ -1483,24 +1483,24 @@ - + - - + + - - + + - + @@ -1537,20 +1537,20 @@ - + - - + + - + @@ -1604,12 +1604,12 @@ - + - + @@ -1658,12 +1658,12 @@ - + - + @@ -1717,12 +1717,12 @@ - + - + @@ -1733,12 +1733,12 @@ - + - + @@ -1761,12 +1761,12 @@ - + - + @@ -1818,14 +1818,14 @@ - + - + @@ -1860,12 +1860,12 @@ - + - + @@ -1884,12 +1884,12 @@ - + - + @@ -1922,12 +1922,12 @@ - + - + @@ -1939,12 +1939,12 @@ - + - + @@ -1980,12 +1980,12 @@ - + - + @@ -2011,12 +2011,12 @@ - + - + @@ -2050,12 +2050,12 @@ - + - + @@ -2083,22 +2083,22 @@ - + - - + + - + @@ -2146,12 +2146,12 @@ - + - + @@ -2195,12 +2195,12 @@ - + - + @@ -2225,12 +2225,12 @@ - + - + @@ -2260,18 +2260,18 @@ - + - - + + - + @@ -2303,12 +2303,12 @@ - + - + @@ -2323,7 +2323,7 @@ - + @@ -2332,8 +2332,8 @@ - - + + @@ -2342,19 +2342,19 @@ - - + + - - + + - + @@ -2435,12 +2435,12 @@ - + - + @@ -2482,14 +2482,14 @@ - + - + @@ -2531,12 +2531,12 @@ - + - + @@ -2591,12 +2591,12 @@ - + - + @@ -2630,12 +2630,12 @@ - + - + @@ -2652,12 +2652,12 @@ - + - + @@ -2681,12 +2681,12 @@ - + - + @@ -2707,12 +2707,12 @@ - + - + @@ -2727,12 +2727,12 @@ - + - + @@ -2758,14 +2758,14 @@ - + - + @@ -2796,14 +2796,14 @@ - + - + @@ -2839,12 +2839,12 @@ - + - + @@ -2898,12 +2898,12 @@ - + - + @@ -2938,22 +2938,22 @@ - + - - + + - + @@ -2982,12 +2982,12 @@ - + - + @@ -3037,12 +3037,12 @@ - + - + @@ -3096,11 +3096,11 @@ - + - + @@ -3112,14 +3112,14 @@ - + - + @@ -3172,12 +3172,12 @@ - + - + @@ -3249,12 +3249,12 @@ - + - + @@ -3267,12 +3267,12 @@ - + - + @@ -3289,32 +3289,32 @@ - + - - + + - - + + - - + + - + @@ -3381,18 +3381,18 @@ - + - - + + - + @@ -3450,20 +3450,20 @@ - + - - + + - + @@ -3526,7 +3526,7 @@ - + @@ -3537,7 +3537,7 @@ - + @@ -3583,14 +3583,14 @@ - + - + @@ -3628,12 +3628,12 @@ - + - + @@ -3682,18 +3682,18 @@ - + - - + + - + @@ -3742,12 +3742,12 @@ - + - + @@ -3775,12 +3775,12 @@ - + - + @@ -3808,12 +3808,12 @@ - + - + @@ -3825,12 +3825,12 @@ - + - + @@ -3852,12 +3852,12 @@ - + - + @@ -3875,12 +3875,12 @@ - + - + @@ -3924,12 +3924,12 @@ - + - + @@ -3960,12 +3960,12 @@ - + - + @@ -3981,20 +3981,20 @@ - + - - + + - + @@ -4034,14 +4034,14 @@ - + - + @@ -4098,14 +4098,14 @@ - + - + @@ -4139,12 +4139,12 @@ - + - + @@ -4166,14 +4166,14 @@ - + - + @@ -4203,12 +4203,12 @@ - + - + @@ -4232,12 +4232,12 @@ - + - + @@ -4253,12 +4253,12 @@ - + - + @@ -4274,12 +4274,12 @@ - + - + @@ -4303,12 +4303,12 @@ - + - + @@ -4329,12 +4329,12 @@ - + - + @@ -4359,12 +4359,12 @@ - + - + @@ -4419,12 +4419,12 @@ - + - + @@ -4437,12 +4437,12 @@ - + - + @@ -4460,14 +4460,14 @@ - + - + @@ -4517,20 +4517,20 @@ - + - - + + - + @@ -4562,12 +4562,12 @@ - + - + @@ -4595,12 +4595,12 @@ - + - + @@ -4645,12 +4645,12 @@ - + - + @@ -4674,14 +4674,14 @@ - + - + @@ -4752,12 +4752,12 @@ - + - + @@ -4785,12 +4785,12 @@ - + - + @@ -4832,18 +4832,18 @@ - + - - + + - + @@ -4885,14 +4885,14 @@ - + - + @@ -4927,20 +4927,20 @@ - + - - + + - + @@ -4960,12 +4960,12 @@ - + - + @@ -5002,14 +5002,14 @@ - + - + @@ -5074,12 +5074,12 @@ - + - + @@ -5123,18 +5123,18 @@ - + - - + + - + @@ -5167,12 +5167,12 @@ - + - + @@ -5213,18 +5213,18 @@ - + - - + + - + @@ -5281,22 +5281,22 @@ - + - - + + - + @@ -5327,12 +5327,12 @@ - + - + @@ -5356,12 +5356,12 @@ - + - + @@ -5380,12 +5380,12 @@ - + - + @@ -5408,12 +5408,12 @@ - + - + @@ -5438,12 +5438,12 @@ - + - + @@ -5477,12 +5477,12 @@ - + - + @@ -5531,14 +5531,14 @@ - + - + @@ -5576,12 +5576,12 @@ - + - + @@ -5605,12 +5605,12 @@ - + - + @@ -5633,12 +5633,12 @@ - + - + @@ -5650,12 +5650,12 @@ - + - + @@ -5679,12 +5679,12 @@ - + - + @@ -5724,12 +5724,12 @@ - + - + @@ -5745,14 +5745,14 @@ - + - + @@ -5777,12 +5777,12 @@ - + - + @@ -5809,14 +5809,14 @@ - + - + @@ -5874,12 +5874,12 @@ - + - + @@ -5932,12 +5932,12 @@ - + - + @@ -5961,12 +5961,12 @@ - + - + @@ -6005,14 +6005,14 @@ - + - + @@ -6090,12 +6090,12 @@ - + - + @@ -6176,12 +6176,12 @@ - + - + @@ -6214,12 +6214,12 @@ - + - + @@ -6242,14 +6242,14 @@ - + - + @@ -6297,18 +6297,18 @@ - + - - + + - + @@ -6389,12 +6389,12 @@ - + - + @@ -6450,18 +6450,18 @@ - + - - + + - + @@ -6504,12 +6504,12 @@ - + - + @@ -6527,15 +6527,15 @@ - + - - + + - + @@ -6559,12 +6559,12 @@ - + - + @@ -6603,12 +6603,12 @@ - + - + @@ -6619,14 +6619,14 @@ - + - - + + - + @@ -6636,12 +6636,12 @@ - + - + @@ -6672,12 +6672,12 @@ - + - + @@ -6736,12 +6736,12 @@ - + - + @@ -6776,12 +6776,12 @@ - + - + @@ -6829,14 +6829,14 @@ - + - + @@ -6865,14 +6865,14 @@ - + - + @@ -6897,14 +6897,14 @@ - + - + @@ -6957,18 +6957,18 @@ - + - - + + - + @@ -7069,12 +7069,12 @@ - + - + @@ -7126,20 +7126,20 @@ - + - - + + - + @@ -7187,12 +7187,12 @@ - + - + @@ -7216,14 +7216,14 @@ - + - + @@ -7244,18 +7244,18 @@ - + - - + + - + @@ -7280,12 +7280,12 @@ - + - + @@ -7329,14 +7329,14 @@ - + - + diff --git a/libs/spandsp/spandsp/tones.dtd b/libs/spandsp/spandsp/tones.dtd index 023f8d0783..b751d2387d 100644 --- a/libs/spandsp/spandsp/tones.dtd +++ b/libs/spandsp/spandsp/tones.dtd @@ -1,21 +1,64 @@ - - + + - - + + + + + + + + - - - - - - - - - - - - - + + + + - + @@ -6123,7 +6123,7 @@ - + From 84e4b38be33e6b843b52ad95691bc88c663987e9 Mon Sep 17 00:00:00 2001 From: Jeff Lenk Date: Sun, 18 Aug 2013 17:26:13 -0500 Subject: [PATCH 31/63] FS-5690 --resolve with bizarre workaround --- libs/spandsp/src/msvc/spandsp.h | 3 +++ src/switch_console.c | 2 ++ src/switch_scheduler.c | 2 +- 3 files changed, 6 insertions(+), 1 deletion(-) diff --git a/libs/spandsp/src/msvc/spandsp.h b/libs/spandsp/src/msvc/spandsp.h index fbdfac8e49..ec0b629d27 100644 --- a/libs/spandsp/src/msvc/spandsp.h +++ b/libs/spandsp/src/msvc/spandsp.h @@ -48,6 +48,9 @@ #include #include +#if !defined(__cplusplus) +#include +#endif #include #include #include diff --git a/src/switch_console.c b/src/switch_console.c index b2c003a6c6..eea6d5510b 100644 --- a/src/switch_console.c +++ b/src/switch_console.c @@ -33,7 +33,9 @@ #include #include #include +#ifndef _MSC_VER #include +#endif #define CMD_BUFLEN 1024 #ifdef SWITCH_HAVE_LIBEDIT diff --git a/src/switch_scheduler.c b/src/switch_scheduler.c index b71821e298..8e0a7d0963 100644 --- a/src/switch_scheduler.c +++ b/src/switch_scheduler.c @@ -201,7 +201,7 @@ SWITCH_DECLARE(uint32_t) switch_scheduler_add_task(time_t task_runtime, switch_assert(func); if (task_runtime < now) { - container->task.repeat = task_runtime; + container->task.repeat = (uint32_t)task_runtime; task_runtime += now; } From f284746703e39d9d5ee1635f1da769740be2cee2 Mon Sep 17 00:00:00 2001 From: Seven Du Date: Mon, 19 Aug 2013 20:52:34 +0800 Subject: [PATCH 32/63] fix rtp flags --- src/mod/endpoints/mod_sofia/rtp.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/mod/endpoints/mod_sofia/rtp.c b/src/mod/endpoints/mod_sofia/rtp.c index e4fffa6f78..ea4921052e 100644 --- a/src/mod/endpoints/mod_sofia/rtp.c +++ b/src/mod/endpoints/mod_sofia/rtp.c @@ -153,6 +153,7 @@ static switch_call_cause_t channel_outgoing_channel(switch_core_session_t *sessi char name[128]; crtp_private_t *tech_pvt = NULL; switch_caller_profile_t *caller_profile; + switch_rtp_flag_t rtp_flags[SWITCH_RTP_FLAG_INVALID] = {0}; const char *err; @@ -261,7 +262,7 @@ static switch_call_cause_t channel_outgoing_channel(switch_core_session_t *sessi if (!(tech_pvt->rtp_session = switch_rtp_new(local_addr, local_port, remote_addr, remote_port, tech_pvt->agreed_pt, tech_pvt->read_codec.implementation->samples_per_packet, ptime * 1000, - 0, "soft", &err, switch_core_session_get_pool(*new_session)))) { + rtp_flags, "soft", &err, switch_core_session_get_pool(*new_session)))) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Couldn't setup RTP session: [%s]\n", err); goto fail; } From d434bfa86fba13bfe65802a35431893f34e20ea6 Mon Sep 17 00:00:00 2001 From: Steve Underwood Date: Mon, 19 Aug 2013 22:49:03 +0800 Subject: [PATCH 33/63] Better tun the use of open_memstream to safe versions of glibc --- libs/spandsp/src/t30.c | 2 +- libs/spandsp/src/t42.c | 11 ++++++++--- libs/spandsp/src/t4_tx.c | 14 ++++++++++++-- 3 files changed, 21 insertions(+), 6 deletions(-) diff --git a/libs/spandsp/src/t30.c b/libs/spandsp/src/t30.c index 1d3555a97d..d629d79087 100644 --- a/libs/spandsp/src/t30.c +++ b/libs/spandsp/src/t30.c @@ -2589,7 +2589,7 @@ static int start_sending_document(t30_state_t *s) t30_set_status(s, T30_ERR_NORESSUPPORT); break; default: - span_log(&s->logging, SPAN_LOG_WARNING, "Cannot negotiate an image format\n"); + span_log(&s->logging, SPAN_LOG_WARNING, "Cannot negotiate an image mode\n"); t30_set_status(s, T30_ERR_BADTIFF); break; } diff --git a/libs/spandsp/src/t42.c b/libs/spandsp/src/t42.c index 2fa943cb9c..fc90ddba63 100644 --- a/libs/spandsp/src/t42.c +++ b/libs/spandsp/src/t42.c @@ -72,6 +72,11 @@ #include "spandsp/private/t85.h" #include "spandsp/private/t42.h" +/* The open_memstream() and fmemopen() in older versions of glibc seems quirky */ +#if defined(__GLIBC__) && (__GLIBC__ < 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ < 12)) +#undef OPEN_MEMSTREAM +#endif + #define T42_USE_LUTS #include "t42_t43_local.h" @@ -1209,7 +1214,7 @@ SPAN_DECLARE(void) t42_decode_rx_status(t42_decode_state_t *s, int status) { if (t42_itulab_jpeg_to_srgb(s)) span_log(&s->logging, SPAN_LOG_FLOW, "Failed to convert from ITULAB.\n"); - s->end_of_data = 1; + s->end_of_data = true; } break; default: @@ -1229,7 +1234,7 @@ SPAN_DECLARE(int) t42_decode_put(t42_decode_state_t *s, const uint8_t data[], si { if (t42_itulab_jpeg_to_srgb(s)) span_log(&s->logging, SPAN_LOG_FLOW, "Failed to convert from ITULAB.\n"); - s->end_of_data = 1; + s->end_of_data = true; } return T4_DECODE_OK; } @@ -1319,7 +1324,7 @@ set_lab_illuminant(&s->lab, 95.047f, 100.000f, 108.883f); set_lab_gamut(&s->lab, 0, 100, -85, 85, -75, 125, false); } - s->end_of_data = 0; + s->end_of_data = false; s->compressed_image_size = 0; s->error_message[0] = '\0'; diff --git a/libs/spandsp/src/t4_tx.c b/libs/spandsp/src/t4_tx.c index f349a136c5..639ddc93dd 100644 --- a/libs/spandsp/src/t4_tx.c +++ b/libs/spandsp/src/t4_tx.c @@ -1863,7 +1863,7 @@ SPAN_DECLARE(int) t4_tx_set_tx_image_format(t4_tx_state_t *s, s->metadata.image_type = T4_IMAGE_TYPE_BILEVEL; } /* Squashing to a bi-level image is possible */ - span_log(&s->logging, SPAN_LOG_FLOW, "The image will be flattened to %d\n", s->metadata.image_type); + span_log(&s->logging, SPAN_LOG_FLOW, "The image may be flattened to %d\n", s->metadata.image_type); } } @@ -2022,8 +2022,18 @@ SPAN_DECLARE(int) t4_tx_set_tx_image_format(t4_tx_state_t *s, if (s->metadata.image_type != s->tiff.image_type || s->metadata.image_width != s->tiff.image_width) { - if (image_translate_init(&s->translator, s->metadata.image_type, s->metadata.image_width, -1, s->tiff.image_type, s->tiff.image_width, s->tiff.image_length, translate_row_read2, s) == NULL) + if (image_translate_init(&s->translator, + s->metadata.image_type, + s->metadata.image_width, + -1, + s->tiff.image_type, + s->tiff.image_width, + s->tiff.image_length, + translate_row_read2, + s) == NULL) + { return T4_IMAGE_FORMAT_INCOMPATIBLE; + } s->metadata.image_length = image_translate_get_output_length(&s->translator); } From d79d28fb4c7a9c0bafdcb8498f916fe8c056fe76 Mon Sep 17 00:00:00 2001 From: Steve Underwood Date: Mon, 19 Aug 2013 23:00:56 +0800 Subject: [PATCH 34/63] Formatting tweaks --- libs/spandsp/src/msvc/getopt.c | 352 ++++++++++++++++----------------- 1 file changed, 176 insertions(+), 176 deletions(-) diff --git a/libs/spandsp/src/msvc/getopt.c b/libs/spandsp/src/msvc/getopt.c index 2fa9318def..a19bd4b78b 100644 --- a/libs/spandsp/src/msvc/getopt.c +++ b/libs/spandsp/src/msvc/getopt.c @@ -1,177 +1,177 @@ -/***************************************************************************** - * - * MODULE NAME : GETOPT.C - * - * COPYRIGHTS: - * This module contains code made available by IBM - * Corporation on an AS IS basis. Any one receiving the - * module is considered to be licensed under IBM copyrights - * to use the IBM-provided source code in any way he or she - * deems fit, including copying it, compiling it, modifying - * it, and redistributing it, with or without - * modifications. No license under any IBM patents or - * patent applications is to be implied from this copyright - * license. - * - * A user of the module should understand that IBM cannot - * provide technical support for the module and will not be - * responsible for any consequences of use of the program. - * - * Any notices, including this one, are not to be removed - * from the module without the prior written consent of - * IBM. - * - * AUTHOR: Original author: - * G. R. Blair (BOBBLAIR at AUSVM1) - * Internet: bobblair@bobblair.austin.ibm.com - * - * Extensively revised by: - * John Q. Walker II, Ph.D. (JOHHQ at RALVM6) - * Internet: johnq@ralvm6.vnet.ibm.com - * - *****************************************************************************/ - -/****************************************************************************** - * getopt() - * - * The getopt() function is a command line parser. It returns the next - * option character in argv that matches an option character in opstring. - * - * The argv argument points to an array of argc+1 elements containing argc - * pointers to character strings followed by a null pointer. - * - * The opstring argument points to a string of option characters; if an - * option character is followed by a colon, the option is expected to have - * an argument that may or may not be separated from it by white space. - * The external variable optarg is set to point to the start of the option - * argument on return from getopt(). - * - * The getopt() function places in optind the argv index of the next argument - * to be processed. The system initializes the external variable optind to - * 1 before the first call to getopt(). - * - * When all options have been processed (that is, up to the first nonoption - * argument), getopt() returns EOF. The special option "--" may be used to - * delimit the end of the options; EOF will be returned, and "--" will be - * skipped. - * - * The getopt() function returns a question mark (?) when it encounters an - * option character not included in opstring. This error message can be - * disabled by setting opterr to zero. Otherwise, it returns the option - * character that was detected. - * - * If the special option "--" is detected, or all options have been - * processed, EOF is returned. - * - * Options are marked by either a minus sign (-) or a slash (/). - * - * No errors are defined. - *****************************************************************************/ - -#include /* for EOF */ -#include /* for strchr() */ - - -/* static (global) variables that are specified as exported by getopt() */ -char *optarg = NULL; /* pointer to the start of the option argument */ -int optind = 1; /* number of the next argv[] to be evaluated */ -int opterr = 1; /* non-zero if a question mark should be returned - when a non-valid option character is detected */ - -/* handle possible future character set concerns by putting this in a macro */ -#define _next_char(string) (char)(*(string+1)) - -int getopt(int argc, char *argv[], char *opstring) -{ - static char *pIndexPosition = NULL; /* place inside current argv string */ - char *pArgString = NULL; /* where to start from next */ - char *pOptString; /* the string in our program */ - - - if (pIndexPosition != NULL) { - /* we last left off inside an argv string */ - if (*(++pIndexPosition)) { - /* there is more to come in the most recent argv */ - pArgString = pIndexPosition; - } - } - - if (pArgString == NULL) { - /* we didn't leave off in the middle of an argv string */ - if (optind >= argc) { - /* more command-line arguments than the argument count */ - pIndexPosition = NULL; /* not in the middle of anything */ - return EOF; /* used up all command-line arguments */ - } - - /*--------------------------------------------------------------------- - * If the next argv[] is not an option, there can be no more options. - *-------------------------------------------------------------------*/ - pArgString = argv[optind++]; /* set this to the next argument ptr */ - - if (('/' != *pArgString) && /* doesn't start with a slash or a dash? */ - ('-' != *pArgString)) { - --optind; /* point to current arg once we're done */ - optarg = NULL; /* no argument follows the option */ - pIndexPosition = NULL; /* not in the middle of anything */ - return EOF; /* used up all the command-line flags */ - } - - /* check for special end-of-flags markers */ - if ((strcmp(pArgString, "-") == 0) || - (strcmp(pArgString, "--") == 0)) { - optarg = NULL; /* no argument follows the option */ - pIndexPosition = NULL; /* not in the middle of anything */ - return EOF; /* encountered the special flag */ - } - - pArgString++; /* look past the / or - */ - } - - if (':' == *pArgString) { /* is it a colon? */ - /*--------------------------------------------------------------------- - * Rare case: if opterr is non-zero, return a question mark; - * otherwise, just return the colon we're on. - *-------------------------------------------------------------------*/ - return (opterr ? (int)'?' : (int)':'); - } - else if ((pOptString = strchr(opstring, *pArgString)) == 0) { - /*--------------------------------------------------------------------- - * The letter on the command-line wasn't any good. - *-------------------------------------------------------------------*/ - optarg = NULL; /* no argument follows the option */ - pIndexPosition = NULL; /* not in the middle of anything */ - return (opterr ? (int)'?' : (int)*pArgString); - } - else { - /*--------------------------------------------------------------------- - * The letter on the command-line matches one we expect to see - *-------------------------------------------------------------------*/ - if (':' == _next_char(pOptString)) { /* is the next letter a colon? */ - /* It is a colon. Look for an argument string. */ - if ('\0' != _next_char(pArgString)) { /* argument in this argv? */ - optarg = &pArgString[1]; /* Yes, it is */ - } - else { - /*------------------------------------------------------------- - * The argument string must be in the next argv. - * But, what if there is none (bad input from the user)? - * In that case, return the letter, and optarg as NULL. - *-----------------------------------------------------------*/ - if (optind < argc) - optarg = argv[optind++]; - else { - optarg = NULL; - return (opterr ? (int)'?' : (int)*pArgString); - } - } - pIndexPosition = NULL; /* not in the middle of anything */ - } - else { - /* it's not a colon, so just return the letter */ - optarg = NULL; /* no argument follows the option */ - pIndexPosition = pArgString; /* point to the letter we're on */ - } - return (int)*pArgString; /* return the letter that matched */ - } +/***************************************************************************** + * + * MODULE NAME : GETOPT.C + * + * COPYRIGHTS: + * This module contains code made available by IBM + * Corporation on an AS IS basis. Any one receiving the + * module is considered to be licensed under IBM copyrights + * to use the IBM-provided source code in any way he or she + * deems fit, including copying it, compiling it, modifying + * it, and redistributing it, with or without + * modifications. No license under any IBM patents or + * patent applications is to be implied from this copyright + * license. + * + * A user of the module should understand that IBM cannot + * provide technical support for the module and will not be + * responsible for any consequences of use of the program. + * + * Any notices, including this one, are not to be removed + * from the module without the prior written consent of + * IBM. + * + * AUTHOR: Original author: + * G. R. Blair (BOBBLAIR at AUSVM1) + * Internet: bobblair@bobblair.austin.ibm.com + * + * Extensively revised by: + * John Q. Walker II, Ph.D. (JOHHQ at RALVM6) + * Internet: johnq@ralvm6.vnet.ibm.com + * + *****************************************************************************/ + +/****************************************************************************** + * getopt() + * + * The getopt() function is a command line parser. It returns the next + * option character in argv that matches an option character in opstring. + * + * The argv argument points to an array of argc+1 elements containing argc + * pointers to character strings followed by a null pointer. + * + * The opstring argument points to a string of option characters; if an + * option character is followed by a colon, the option is expected to have + * an argument that may or may not be separated from it by white space. + * The external variable optarg is set to point to the start of the option + * argument on return from getopt(). + * + * The getopt() function places in optind the argv index of the next argument + * to be processed. The system initializes the external variable optind to + * 1 before the first call to getopt(). + * + * When all options have been processed (that is, up to the first nonoption + * argument), getopt() returns EOF. The special option "--" may be used to + * delimit the end of the options; EOF will be returned, and "--" will be + * skipped. + * + * The getopt() function returns a question mark (?) when it encounters an + * option character not included in opstring. This error message can be + * disabled by setting opterr to zero. Otherwise, it returns the option + * character that was detected. + * + * If the special option "--" is detected, or all options have been + * processed, EOF is returned. + * + * Options are marked by either a minus sign (-) or a slash (/). + * + * No errors are defined. + *****************************************************************************/ + +#include /* for EOF */ +#include /* for strchr() */ + + +/* static (global) variables that are specified as exported by getopt() */ +char *optarg = NULL; /* pointer to the start of the option argument */ +int optind = 1; /* number of the next argv[] to be evaluated */ +int opterr = 1; /* non-zero if a question mark should be returned + when a non-valid option character is detected */ + +/* handle possible future character set concerns by putting this in a macro */ +#define _next_char(string) (char)(*(string+1)) + +int getopt(int argc, char *argv[], char *opstring) +{ + static char *pIndexPosition = NULL; /* place inside current argv string */ + char *pArgString = NULL; /* where to start from next */ + char *pOptString; /* the string in our program */ + + + if (pIndexPosition != NULL) { + /* we last left off inside an argv string */ + if (*(++pIndexPosition)) { + /* there is more to come in the most recent argv */ + pArgString = pIndexPosition; + } + } + + if (pArgString == NULL) { + /* we didn't leave off in the middle of an argv string */ + if (optind >= argc) { + /* more command-line arguments than the argument count */ + pIndexPosition = NULL; /* not in the middle of anything */ + return EOF; /* used up all command-line arguments */ + } + + /*--------------------------------------------------------------------- + * If the next argv[] is not an option, there can be no more options. + *-------------------------------------------------------------------*/ + pArgString = argv[optind++]; /* set this to the next argument ptr */ + + if (('/' != *pArgString) && /* doesn't start with a slash or a dash? */ + ('-' != *pArgString)) { + --optind; /* point to current arg once we're done */ + optarg = NULL; /* no argument follows the option */ + pIndexPosition = NULL; /* not in the middle of anything */ + return EOF; /* used up all the command-line flags */ + } + + /* check for special end-of-flags markers */ + if ((strcmp(pArgString, "-") == 0) || + (strcmp(pArgString, "--") == 0)) { + optarg = NULL; /* no argument follows the option */ + pIndexPosition = NULL; /* not in the middle of anything */ + return EOF; /* encountered the special flag */ + } + + pArgString++; /* look past the / or - */ + } + + if (':' == *pArgString) { /* is it a colon? */ + /*--------------------------------------------------------------------- + * Rare case: if opterr is non-zero, return a question mark; + * otherwise, just return the colon we're on. + *-------------------------------------------------------------------*/ + return (opterr ? (int)'?' : (int)':'); + } + else if ((pOptString = strchr(opstring, *pArgString)) == 0) { + /*--------------------------------------------------------------------- + * The letter on the command-line wasn't any good. + *-------------------------------------------------------------------*/ + optarg = NULL; /* no argument follows the option */ + pIndexPosition = NULL; /* not in the middle of anything */ + return (opterr ? (int)'?' : (int)*pArgString); + } + else { + /*--------------------------------------------------------------------- + * The letter on the command-line matches one we expect to see + *-------------------------------------------------------------------*/ + if (':' == _next_char(pOptString)) { /* is the next letter a colon? */ + /* It is a colon. Look for an argument string. */ + if ('\0' != _next_char(pArgString)) { /* argument in this argv? */ + optarg = &pArgString[1]; /* Yes, it is */ + } + else { + /*------------------------------------------------------------- + * The argument string must be in the next argv. + * But, what if there is none (bad input from the user)? + * In that case, return the letter, and optarg as NULL. + *-----------------------------------------------------------*/ + if (optind < argc) + optarg = argv[optind++]; + else { + optarg = NULL; + return (opterr ? (int)'?' : (int)*pArgString); + } + } + pIndexPosition = NULL; /* not in the middle of anything */ + } + else { + /* it's not a colon, so just return the letter */ + optarg = NULL; /* no argument follows the option */ + pIndexPosition = pArgString; /* point to the letter we're on */ + } + return (int)*pArgString; /* return the letter that matched */ + } } From 2541bd39aa1e5615ddff2ec729f5940fdf86b371 Mon Sep 17 00:00:00 2001 From: root Date: Tue, 20 Aug 2013 02:35:01 +0800 Subject: [PATCH 35/63] Make spandsp more toelrant of far end's handling of metric/inch in FAX processing --- libs/spandsp/src/t30.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libs/spandsp/src/t30.c b/libs/spandsp/src/t30.c index d629d79087..6074f5f5a1 100644 --- a/libs/spandsp/src/t30.c +++ b/libs/spandsp/src/t30.c @@ -1804,8 +1804,8 @@ static int analyze_rx_dis_dtc(t30_state_t *s, const uint8_t *msg, int len) } else { - if (!test_ctrl_bit(s->far_dis_dtc_frame, T30_DIS_BIT_INCH_RESOLUTION_PREFERRED)) - s->mutual_colour_resolutions &= ~T4_RESOLUTION_200_200; + //if (!test_ctrl_bit(s->far_dis_dtc_frame, T30_DIS_BIT_INCH_RESOLUTION_PREFERRED)) + // s->mutual_colour_resolutions &= ~T4_RESOLUTION_200_200; } if (!test_ctrl_bit(s->far_dis_dtc_frame, T30_DIS_BIT_INCH_RESOLUTION_PREFERRED)) s->mutual_bilevel_resolutions &= ~T4_RESOLUTION_200_100; From 2c6427ccb7cb2eeafc9d87b1a7fb3a32e87c5b6e Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Mon, 19 Aug 2013 23:48:09 +0500 Subject: [PATCH 36/63] FS-5708 --resolve --- 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 1412dd41fe..0eb66f6a1b 100644 --- a/src/switch_utils.c +++ b/src/switch_utils.c @@ -1273,7 +1273,7 @@ static int get_netmask(struct sockaddr_in *me, int *mask) struct sockaddr_in *s = (struct sockaddr_in *) i->ifa_addr; struct sockaddr_in *m = (struct sockaddr_in *) i->ifa_netmask; - if (s && m && s->sin_addr.s_addr == me->sin_addr.s_addr) { + if (s && m && s->sin_family == AF_INET && s->sin_addr.s_addr == me->sin_addr.s_addr) { *mask = m->sin_addr.s_addr; freeifaddrs(ifaddrs); return 0; From facfa16caea77dfb1ae20c6db6f91923319f1df8 Mon Sep 17 00:00:00 2001 From: Steve Underwood Date: Tue, 20 Aug 2013 09:19:15 +0800 Subject: [PATCH 37/63] Described the colour FAX illuminants --- libs/spandsp/src/t42.c | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/libs/spandsp/src/t42.c b/libs/spandsp/src/t42.c index fc90ddba63..6117cd3f19 100644 --- a/libs/spandsp/src/t42.c +++ b/libs/spandsp/src/t42.c @@ -102,23 +102,23 @@ typedef struct static const illuminant_t illuminants[] = { - {"\0D50", "CIE D50/2°", 96.422f, 100.000f, 82.521f}, + {"\0D50", "CIE D50/2°", 96.422f, 100.000f, 82.521f}, /* Horizon Light. ICC profile PCS */ {"", "CIE D50/10°", 96.720f, 100.000f, 81.427f}, - {"", "CIE D55/2°", 95.682f, 100.000f, 92.149f}, + {"", "CIE D55/2°", 95.682f, 100.000f, 92.149f}, /* Mid-morning/mid-afternoon daylight */ {"", "CIE D55/10°", 95.799f, 100.000f, 90.926f}, - {"\0D65", "CIE D65/2°", 95.047f, 100.000f, 108.883f}, + {"\0D65", "CIE D65/2°", 95.047f, 100.000f, 108.883f}, /* Noon daylight, television, sRGB color space */ {"", "CIE D65/10°", 94.811f, 100.000f, 107.304f}, - {"\0D75", "CIE D75/2°", 94.972f, 100.000f, 122.638f}, + {"\0D75", "CIE D75/2°", 94.972f, 100.000f, 122.638f}, /* North sky daylight */ {"", "CIE D75/10°", 94.416f, 100.000f, 120.641f}, - {"\0\0F2", "F02/2°", 99.186f, 100.000f, 67.393f}, + {"\0\0F2", "F02/2°", 99.186f, 100.000f, 67.393f}, /* Cool white fluorescent */ {"", "F02/10°", 103.279f, 100.000f, 69.027f}, - {"\0\0F7", "F07/2°", 95.041f, 100.000f, 108.747f}, + {"\0\0F7", "F07/2°", 95.041f, 100.000f, 108.747f}, /* D65 simulator, daylight simulator */ {"", "F07/10°", 95.792f, 100.000f, 107.686f}, - {"\0F11", "F11/2°", 100.962f, 100.000f, 64.350f}, + {"\0F11", "F11/2°", 100.962f, 100.000f, 64.350f}, /* Philips TL84, Ultralume 40 */ {"", "F11/10°", 103.863f, 100.000f, 65.607f}, - {"\0\0SA", "A/2°", 109.850f, 100.000f, 35.585f}, + {"\0\0SA", "A/2°", 109.850f, 100.000f, 35.585f}, /* Incandescent/tungsten */ {"", "A/10°", 111.144f, 100.000f, 35.200f}, - {"\0\0SC", "C/2°", 98.074f, 100.000f, 118.232f}, + {"\0\0SC", "C/2°", 98.074f, 100.000f, 118.232f}, /* {obsolete} average/north sky daylight */ {"", "C/10°", 97.285f, 100.000f, 116.145f}, {"", "", 0.000f, 0.000f, 0.000f} }; From 7fc4f5996f0c22d54703fa028c7b69064b9e368f Mon Sep 17 00:00:00 2001 From: Nathan Neulinger Date: Tue, 20 Aug 2013 09:24:43 -0500 Subject: [PATCH 38/63] FS-5164 --resolve add support for setting user variables w/ skinny --- src/mod/endpoints/mod_skinny/skinny_server.c | 43 ++++++++++++++++++++ 1 file changed, 43 insertions(+) diff --git a/src/mod/endpoints/mod_skinny/skinny_server.c b/src/mod/endpoints/mod_skinny/skinny_server.c index f3dda49f1b..b24c976729 100644 --- a/src/mod/endpoints/mod_skinny/skinny_server.c +++ b/src/mod/endpoints/mod_skinny/skinny_server.c @@ -438,6 +438,7 @@ switch_status_t skinny_session_send_call_info_all(switch_core_session_t *session struct skinny_session_set_variables_helper { private_t *tech_pvt; switch_channel_t *channel; + listener_t *listener; uint32_t count; }; @@ -463,6 +464,9 @@ int skinny_session_set_variables_callback(void *pArg, int argc, char **argv, cha struct skinny_session_set_variables_helper *helper = pArg; char *tmp; + listener_t *listener; + + switch_xml_t xroot, xdomain, xuser, xvariables, xvariable; helper->count++; switch_channel_set_variable_name_printf(helper->channel, device_name, "skinny_device_name_%d", helper->count); @@ -482,6 +486,44 @@ int skinny_session_set_variables_callback(void *pArg, int argc, char **argv, cha switch_channel_set_variable_name_printf(helper->channel, value, "skinny_line_value_%d", helper->count); switch_channel_set_variable_name_printf(helper->channel, caller_name, "skinny_line_caller_name_%d", helper->count); + listener = helper->listener; + + /* Process through and extract any variables from the user and set in the channel */ + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(helper->tech_pvt->session), SWITCH_LOG_DEBUG, + "searching for user (id=%s) in profile %s in channel var setup\n", + listener->device_name, listener->profile->domain); + + if (switch_xml_locate_user("id", listener->device_name, listener->profile->domain, "", + &xroot, &xdomain, &xuser, NULL, NULL) != SWITCH_STATUS_SUCCESS) { + + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(helper->tech_pvt->session), SWITCH_LOG_WARNING, + "unable to find user (id=%s) in channel var setup\n", listener->device_name); + } + + if ( xuser ) { + char *uid = (char *) switch_xml_attr_soft(xuser, "id"); + + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(helper->tech_pvt->session), SWITCH_LOG_DEBUG, + "found user (id=%s) in channel var setup\n", uid); + + if ((xvariables = switch_xml_child(xuser, "variables"))) { + + for (xvariable = switch_xml_child(xvariables, "variable"); xvariable; xvariable = xvariable->next) { + char *var = (char *) switch_xml_attr_soft(xvariable, "name"); + char *val = (char *) switch_xml_attr_soft(xvariable, "value"); + + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(helper->tech_pvt->session), SWITCH_LOG_DEBUG, + "found variable (%s=%s) for user (%s) in channel var setup\n", listener->device_name, val, var); + + switch_channel_set_variable_name_printf(helper->channel, var, "%s", val); + } + } + } + + if ( xroot ) { + switch_xml_free(xroot); + } + return 0; } @@ -492,6 +534,7 @@ switch_status_t skinny_session_set_variables(switch_core_session_t *session, lis helper.tech_pvt = switch_core_session_get_private(session); helper.channel = switch_core_session_get_channel(session); + helper.listener = listener; helper.count = 0; switch_channel_set_variable(helper.channel, "skinny_profile_name", helper.tech_pvt->profile->name); From 790bf9a94798283955f074abaef84958b3aec55d Mon Sep 17 00:00:00 2001 From: Nathan Neulinger Date: Tue, 20 Aug 2013 13:01:40 -0500 Subject: [PATCH 39/63] FS-5164 - fix segv on ring handling due to listener not being defined --- src/mod/endpoints/mod_skinny/skinny_server.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/mod/endpoints/mod_skinny/skinny_server.c b/src/mod/endpoints/mod_skinny/skinny_server.c index b24c976729..29148f952e 100644 --- a/src/mod/endpoints/mod_skinny/skinny_server.c +++ b/src/mod/endpoints/mod_skinny/skinny_server.c @@ -488,6 +488,12 @@ int skinny_session_set_variables_callback(void *pArg, int argc, char **argv, cha listener = helper->listener; + if ( ! listener ) { + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(helper->tech_pvt->session), SWITCH_LOG_DEBUG, + "no defined listener on channel var setup, will not attempt to set variables\n"); + return(0); + } + /* Process through and extract any variables from the user and set in the channel */ switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(helper->tech_pvt->session), SWITCH_LOG_DEBUG, "searching for user (id=%s) in profile %s in channel var setup\n", From c695f2322b9ecc11ce232d178c065d8b8f3cb98e Mon Sep 17 00:00:00 2001 From: Ben Langfeld Date: Tue, 20 Aug 2013 17:11:27 -0300 Subject: [PATCH 40/63] mod_rayo: Remove compensation for Punchblock Rayo spec incompatibility --- src/mod/event_handlers/mod_rayo/mod_rayo.c | 4 ---- src/mod/event_handlers/mod_rayo/mod_rayo.h | 3 --- src/mod/event_handlers/mod_rayo/rayo_components.c | 4 ---- 3 files changed, 11 deletions(-) diff --git a/src/mod/event_handlers/mod_rayo/mod_rayo.c b/src/mod/event_handlers/mod_rayo/mod_rayo.c index be66fe877c..dc2e4aafce 100644 --- a/src/mod/event_handlers/mod_rayo/mod_rayo.c +++ b/src/mod/event_handlers/mod_rayo/mod_rayo.c @@ -2556,11 +2556,7 @@ static void on_call_originate_event(struct rayo_client *rclient, switch_event_t ref = iks_insert(response, "ref"); iks_insert_attrib(ref, "xmlns", RAYO_NS); -#ifdef RAYO_UUID_IN_REF_URI - iks_insert_attrib(ref, "uri", uuid); -#else iks_insert_attrib_printf(ref, "uri", "xmpp:%s", RAYO_JID(call)); -#endif RAYO_SEND_MESSAGE(call, RAYO_JID(rclient), response); call->dial_id = NULL; } diff --git a/src/mod/event_handlers/mod_rayo/mod_rayo.h b/src/mod/event_handlers/mod_rayo/mod_rayo.h index 260c811a45..dd0adb3192 100644 --- a/src/mod/event_handlers/mod_rayo/mod_rayo.h +++ b/src/mod/event_handlers/mod_rayo/mod_rayo.h @@ -51,9 +51,6 @@ #define RAT_PEER_SERVER "PEER_SERVER" #define RAT_CLIENT "CLIENT" -/* these are support punchblock.. undefine once punchblock is fixed */ -#define RAYO_UUID_IN_REF_URI - struct rayo_actor; struct rayo_call; struct rayo_mixer; diff --git a/src/mod/event_handlers/mod_rayo/rayo_components.c b/src/mod/event_handlers/mod_rayo/rayo_components.c index b376e97770..b5137d9459 100644 --- a/src/mod/event_handlers/mod_rayo/rayo_components.c +++ b/src/mod/event_handlers/mod_rayo/rayo_components.c @@ -58,11 +58,7 @@ void rayo_component_send_start(struct rayo_component *component, iks *iq) iks *response = iks_new_iq_result(iq); iks *ref = iks_insert(response, "ref"); iks_insert_attrib(ref, "xmlns", RAYO_NS); -#ifdef RAYO_UUID_IN_REF_URI - iks_insert_attrib(ref, "uri", component->ref); -#else iks_insert_attrib_printf(ref, "uri", "xmpp:%s", RAYO_JID(component)); -#endif RAYO_SEND_REPLY(component, iks_find_attrib(response, "to"), response); } From d2fb03eda1a281ba89e90543fe8103ed666cd403 Mon Sep 17 00:00:00 2001 From: Chris Rienzo Date: Tue, 20 Aug 2013 17:26:07 -0400 Subject: [PATCH 41/63] mod_rayo: use XMPP URI instead of FS UUID for join/unjoin --- src/mod/event_handlers/mod_rayo/mod_rayo.c | 114 ++++++++++++--------- 1 file changed, 67 insertions(+), 47 deletions(-) diff --git a/src/mod/event_handlers/mod_rayo/mod_rayo.c b/src/mod/event_handlers/mod_rayo/mod_rayo.c index dc2e4aafce..3004601661 100644 --- a/src/mod/event_handlers/mod_rayo/mod_rayo.c +++ b/src/mod/event_handlers/mod_rayo/mod_rayo.c @@ -718,6 +718,9 @@ struct rayo_actor *rayo_actor_locate(const char *jid, const char *file, int line { struct rayo_actor *actor = NULL; switch_mutex_lock(globals.actors_mutex); + if (!strncmp("xmpp:", jid, 5)) { + jid = jid + 5; + } actor = (struct rayo_actor *)switch_core_hash_find(globals.actors, jid); if (actor) { if (!actor->destroy) { @@ -824,13 +827,30 @@ int rayo_actor_seq_next(struct rayo_actor *actor) return seq; } -#define RAYO_CALL_LOCATE(call_uuid) rayo_call_locate(call_uuid, __FILE__, __LINE__) +#define RAYO_CALL_LOCATE(call_uri) rayo_call_locate(call_uri, __FILE__, __LINE__) /** - * Get exclusive access to Rayo call data. Use to access call data outside channel thread. + * Get access to Rayo call data. Use to access call data outside channel thread. + * @param call_uri the Rayo XMPP URI + * @return the call or NULL. + */ +static struct rayo_call *rayo_call_locate(const char *call_uri, const char *file, int line) +{ + struct rayo_actor *actor = rayo_actor_locate(call_uri, file, line); + if (actor && is_call_actor(actor)) { + return RAYO_CALL(actor); + } else if (actor) { + RAYO_UNLOCK(actor); + } + return NULL; +} + +#define RAYO_CALL_LOCATE_BY_ID(call_uuid) rayo_call_locate_by_id(call_uuid, __FILE__, __LINE__) +/** + * Get access to Rayo call data. Use to access call data outside channel thread. * @param call_uuid the FreeSWITCH call UUID * @return the call or NULL. */ -static struct rayo_call *rayo_call_locate(const char *call_uuid, const char *file, int line) +static struct rayo_call *rayo_call_locate_by_id(const char *call_uuid, const char *file, int line) { struct rayo_actor *actor = rayo_actor_locate_by_id(call_uuid, file, line); if (actor && is_call_actor(actor)) { @@ -1692,18 +1712,18 @@ static iks *on_rayo_hangup(struct rayo_actor *call, struct rayo_message *msg, vo * @param call the call that joins * @param session the session * @param node the join request - * @param call_id to join + * @param call_uri to join * @param media mode (direct/bridge) * @return the response */ -static iks *join_call(struct rayo_call *call, switch_core_session_t *session, iks *node, const char *call_id, const char *media) +static iks *join_call(struct rayo_call *call, switch_core_session_t *session, iks *node, const char *call_uri, const char *media) { iks *response = NULL; /* take call out of media path if media = "direct" */ const char *bypass = !strcmp("direct", media) ? "true" : "false"; /* check if joining to rayo call */ - struct rayo_call *b_call = RAYO_CALL_LOCATE(call_id); + struct rayo_call *b_call = RAYO_CALL_LOCATE(call_uri); if (!b_call) { /* not a rayo call */ response = iks_new_error_detailed(node, STANZA_ERROR_SERVICE_UNAVAILABLE, "b-leg is not a rayo call"); @@ -1712,18 +1732,17 @@ static iks *join_call(struct rayo_call *call, switch_core_session_t *session, ik response = iks_new_error_detailed(node, STANZA_ERROR_CONFLICT, "multiple joined calls not supported"); RAYO_UNLOCK(b_call); } else { - RAYO_UNLOCK(b_call); - /* bridge this call to call-uri */ switch_channel_set_variable(switch_core_session_get_channel(session), "bypass_media", bypass); if (switch_false(bypass)) { switch_channel_pre_answer(switch_core_session_get_channel(session)); } - if (switch_ivr_uuid_bridge(rayo_call_get_uuid(call), call_id) == SWITCH_STATUS_SUCCESS) { + if (switch_ivr_uuid_bridge(rayo_call_get_uuid(call), rayo_call_get_uuid(b_call)) == SWITCH_STATUS_SUCCESS) { response = iks_new_iq_result(node); } else { response = iks_new_error_detailed(node, STANZA_ERROR_INTERNAL_SERVER_ERROR, "failed to bridge call"); } + RAYO_UNLOCK(b_call); } return response; } @@ -1797,7 +1816,7 @@ static iks *on_rayo_join(struct rayo_actor *call, struct rayo_message *msg, void iks *join = iks_find(node, "join"); const char *join_id; const char *mixer_name; - const char *call_id; + const char *call_uri; /* validate input attributes */ if (!VALIDATE_RAYO_JOIN(join)) { @@ -1806,22 +1825,22 @@ static iks *on_rayo_join(struct rayo_actor *call, struct rayo_message *msg, void goto done; } mixer_name = iks_find_attrib(join, "mixer-name"); - call_id = iks_find_attrib(join, "call-uri"); + call_uri = iks_find_attrib(join, "call-uri"); if (!zstr(mixer_name)) { join_id = mixer_name; } else { - join_id = call_id; + join_id = call_uri; } /* can't join both mixer and call */ - if (!zstr(mixer_name) && !zstr(call_id)) { + if (!zstr(mixer_name) && !zstr(call_uri)) { response = iks_new_error_detailed(node, STANZA_ERROR_BAD_REQUEST, "mixer-name and call-uri are mutually exclusive"); goto done; } /* need to join *something* */ - if (zstr(mixer_name) && zstr(call_id)) { + if (zstr(mixer_name) && zstr(call_uri)) { response = iks_new_error_detailed(node, STANZA_ERROR_BAD_REQUEST, "mixer-name or call-uri is required"); goto done; } @@ -1838,7 +1857,7 @@ static iks *on_rayo_join(struct rayo_actor *call, struct rayo_message *msg, void response = join_mixer(RAYO_CALL(call), session, node, mixer_name, iks_find_attrib(join, "direction")); } else { /* bridge calls */ - response = join_call(RAYO_CALL(call), session, node, call_id, iks_find_attrib(join, "media")); + response = join_call(RAYO_CALL(call), session, node, call_uri, iks_find_attrib(join, "media")); } done: @@ -1850,21 +1869,22 @@ done: * @param call the call that unjoined * @param session the session * @param node the unjoin request - * @param call_id the b-leg uuid + * @param call_uri the b-leg xmpp URI * @return the response */ -static iks *unjoin_call(struct rayo_call *call, switch_core_session_t *session, iks *node, const char *call_id) +static iks *unjoin_call(struct rayo_call *call, switch_core_session_t *session, iks *node, const char *call_uri) { iks *response = NULL; - const char *bleg = switch_channel_get_variable(switch_core_session_get_channel(session), SWITCH_BRIDGE_UUID_VARIABLE); + const char *bleg_uuid = switch_channel_get_variable(switch_core_session_get_channel(session), SWITCH_BRIDGE_UUID_VARIABLE); + const char *bleg_uri = switch_core_session_sprintf(session, "xmpp:%s@%s", bleg_uuid ? bleg_uuid : "", RAYO_JID(globals.server)); - /* bleg must match call_id */ - if (!zstr(bleg) && !strcmp(bleg, call_id)) { + /* bleg must match call_uri */ + if (!zstr(bleg_uri) && !strcmp(bleg_uri, call_uri)) { /* unbridge call */ response = iks_new_iq_result(node); switch_ivr_park_session(session); } else { - /* not bridged or wrong b-leg UUID */ + /* not bridged or wrong b-leg URI */ response = iks_new_error(node, STANZA_ERROR_SERVICE_UNAVAILABLE); } @@ -1919,16 +1939,16 @@ static iks *on_rayo_unjoin(struct rayo_actor *call, struct rayo_message *msg, vo switch_core_session_t *session = (switch_core_session_t *)session_data; iks *response = NULL; iks *unjoin = iks_find(node, "unjoin"); - const char *call_id = iks_find_attrib(unjoin, "call-uri"); + const char *call_uri = iks_find_attrib(unjoin, "call-uri"); const char *mixer_name = iks_find_attrib(unjoin, "mixer-name"); - if (!zstr(call_id) && !zstr(mixer_name)) { + if (!zstr(call_uri) && !zstr(mixer_name)) { response = iks_new_error(node, STANZA_ERROR_BAD_REQUEST); } else if (!RAYO_CALL(call)->joined) { /* not joined to anything */ response = iks_new_error(node, STANZA_ERROR_SERVICE_UNAVAILABLE); - } else if (!zstr(call_id)) { - response = unjoin_call(RAYO_CALL(call), session, node, call_id); + } else if (!zstr(call_uri)) { + response = unjoin_call(RAYO_CALL(call), session, node, call_uri); } else if (!zstr(mixer_name)) { response = unjoin_mixer(RAYO_CALL(call), session, node, mixer_name); } else { @@ -2043,20 +2063,20 @@ static void *SWITCH_THREAD_FUNC rayo_dial_thread(switch_thread_t *thread, void * if (join) { /* check join args */ - const char *call_id = iks_find_attrib(join, "call-uri"); + const char *call_uri = iks_find_attrib(join, "call-uri"); const char *mixer_name = iks_find_attrib(join, "mixer-name"); - if (!zstr(call_id) && !zstr(mixer_name)) { + if (!zstr(call_uri) && !zstr(mixer_name)) { /* can't join both */ response = iks_new_error(iq, STANZA_ERROR_BAD_REQUEST); goto done; - } else if (zstr(call_id) && zstr(mixer_name)) { + } else if (zstr(call_uri) && zstr(mixer_name)) { /* nobody to join to? */ response = iks_new_error(iq, STANZA_ERROR_BAD_REQUEST); goto done; - } else if (!zstr(call_id)) { + } else if (!zstr(call_uri)) { /* bridge */ - struct rayo_call *b_call = RAYO_CALL_LOCATE(call_id); + struct rayo_call *b_call = RAYO_CALL_LOCATE(call_uri); /* is b-leg available? */ if (!b_call) { response = iks_new_error_detailed(iq, STANZA_ERROR_SERVICE_UNAVAILABLE, "b-leg not found"); @@ -2066,8 +2086,8 @@ static void *SWITCH_THREAD_FUNC rayo_dial_thread(switch_thread_t *thread, void * RAYO_UNLOCK(b_call); goto done; } + stream.write_function(&stream, "%s%s &rayo(bridge %s)", gateway->dial_prefix, dial_to_stripped, rayo_call_get_uuid(b_call)); RAYO_UNLOCK(b_call); - stream.write_function(&stream, "%s%s &rayo(bridge %s)", gateway->dial_prefix, dial_to_stripped, call_id); } else { /* conference */ stream.write_function(&stream, "%s%s &rayo(conference %s@%s)", gateway->dial_prefix, dial_to_stripped, mixer_name, globals.mixer_conf_profile); @@ -2399,7 +2419,7 @@ static void on_mixer_delete_member_event(struct rayo_mixer *mixer, switch_event_ switch_core_hash_delete(mixer->members, uuid); /* flag call as available to join another mixer */ - call = RAYO_CALL_LOCATE(uuid); + call = RAYO_CALL_LOCATE_BY_ID(uuid); if (call) { call->joined = 0; call->joined_id = NULL; @@ -2415,7 +2435,7 @@ static void on_mixer_delete_member_event(struct rayo_mixer *mixer, switch_event_ /* broadcast member unjoined event to subscribers */ delete_member_event = iks_new_presence("unjoined", RAYO_NS, RAYO_JID(mixer), ""); x = iks_find(delete_member_event, "unjoined"); - iks_insert_attrib(x, "call-uri", uuid); + iks_insert_attrib_printf(x, "call-uri", "xmpp:%s@%s", uuid, RAYO_JID(globals.server)); broadcast_mixer_event(mixer, delete_member_event); iks_delete(delete_member_event); @@ -2451,7 +2471,7 @@ static void on_mixer_add_member_event(struct rayo_mixer *mixer, switch_event_t * { iks *add_member_event = NULL, *x; const char *uuid = switch_event_get_header(event, "Unique-ID"); - struct rayo_call *call = RAYO_CALL_LOCATE(uuid); + struct rayo_call *call = RAYO_CALL_LOCATE_BY_ID(uuid); if (!mixer) { /* new mixer */ @@ -2493,7 +2513,7 @@ static void on_mixer_add_member_event(struct rayo_mixer *mixer, switch_event_t * /* broadcast member joined event to subscribers */ add_member_event = iks_new_presence("joined", RAYO_NS, RAYO_JID(mixer), ""); x = iks_find(add_member_event, "joined"); - iks_insert_attrib(x, "call-uri", uuid); + iks_insert_attrib_printf(x, "call-uri", "xmpp:%s@%s", uuid, RAYO_JID(globals.server)); broadcast_mixer_event(mixer, add_member_event); iks_delete(add_member_event); } @@ -2539,7 +2559,7 @@ static void on_call_originate_event(struct rayo_client *rclient, switch_event_t { switch_core_session_t *session = NULL; const char *uuid = switch_event_get_header(event, "Unique-ID"); - struct rayo_call *call = RAYO_CALL_LOCATE(uuid); + struct rayo_call *call = RAYO_CALL_LOCATE_BY_ID(uuid); if (call && (session = switch_core_session_locate(uuid))) { iks *response, *ref; @@ -2569,7 +2589,7 @@ static void on_call_originate_event(struct rayo_client *rclient, switch_event_t */ static void on_call_end_event(switch_event_t *event) { - struct rayo_call *call = RAYO_CALL_LOCATE(switch_event_get_header(event, "Unique-ID")); + struct rayo_call *call = RAYO_CALL_LOCATE_BY_ID(switch_event_get_header(event, "Unique-ID")); if (call) { #if 0 @@ -2593,7 +2613,7 @@ static void on_call_end_event(switch_event_t *event) */ static void on_call_answer_event(struct rayo_client *rclient, switch_event_t *event) { - struct rayo_call *call = RAYO_CALL_LOCATE(switch_event_get_header(event, "Unique-ID")); + struct rayo_call *call = RAYO_CALL_LOCATE_BY_ID(switch_event_get_header(event, "Unique-ID")); if (call) { iks *revent = iks_new_presence("answered", RAYO_NS, switch_event_get_header(event, "variable_rayo_call_jid"), @@ -2612,7 +2632,7 @@ static void on_call_ringing_event(struct rayo_client *rclient, switch_event_t *e { const char *call_direction = switch_event_get_header(event, "Call-Direction"); if (call_direction && !strcmp(call_direction, "outbound")) { - struct rayo_call *call = RAYO_CALL_LOCATE(switch_event_get_header(event, "Unique-ID")); + struct rayo_call *call = RAYO_CALL_LOCATE_BY_ID(switch_event_get_header(event, "Unique-ID")); if (call) { switch_mutex_lock(RAYO_ACTOR(call)->mutex); if (!call->ringing_sent) { @@ -2637,7 +2657,7 @@ static void on_call_bridge_event(struct rayo_client *rclient, switch_event_t *ev { const char *a_uuid = switch_event_get_header(event, "Unique-ID"); const char *b_uuid = switch_event_get_header(event, "Bridge-B-Unique-ID"); - struct rayo_call *call = RAYO_CALL_LOCATE(a_uuid); + struct rayo_call *call = RAYO_CALL_LOCATE_BY_ID(a_uuid); struct rayo_call *b_call; if (call) { @@ -2646,7 +2666,7 @@ static void on_call_bridge_event(struct rayo_client *rclient, switch_event_t *ev switch_event_get_header(event, "variable_rayo_call_jid"), switch_event_get_header(event, "variable_rayo_dcp_jid")); iks *joined = iks_find(revent, "joined"); - iks_insert_attrib(joined, "call-uri", b_uuid); + iks_insert_attrib_printf(joined, "call-uri", "xmpp:%s@%s", b_uuid, RAYO_JID(globals.server)); call->joined = JOINED_CALL; call->joined_id = switch_core_strdup(RAYO_POOL(call), b_uuid); @@ -2654,11 +2674,11 @@ static void on_call_bridge_event(struct rayo_client *rclient, switch_event_t *ev RAYO_SEND_MESSAGE(call, RAYO_JID(rclient), revent); /* send B-leg event */ - b_call = RAYO_CALL_LOCATE(b_uuid); + b_call = RAYO_CALL_LOCATE_BY_ID(b_uuid); if (b_call) { revent = iks_new_presence("joined", RAYO_NS, RAYO_JID(b_call), rayo_call_get_dcp_jid(b_call)); joined = iks_find(revent, "joined"); - iks_insert_attrib(joined, "call-uri", a_uuid); + iks_insert_attrib_printf(joined, "call-uri", "xmpp:%s@%s", a_uuid, RAYO_JID(globals.server)); b_call->joined = JOINED_CALL; b_call->joined_id = switch_core_strdup(RAYO_POOL(b_call), a_uuid); @@ -2679,7 +2699,7 @@ static void on_call_unbridge_event(struct rayo_client *rclient, switch_event_t * { const char *a_uuid = switch_event_get_header(event, "Unique-ID"); const char *b_uuid = switch_event_get_header(event, "Bridge-B-Unique-ID"); - struct rayo_call *call = RAYO_CALL_LOCATE(a_uuid); + struct rayo_call *call = RAYO_CALL_LOCATE_BY_ID(a_uuid); struct rayo_call *b_call; if (call) { @@ -2688,18 +2708,18 @@ static void on_call_unbridge_event(struct rayo_client *rclient, switch_event_t * switch_event_get_header(event, "variable_rayo_call_jid"), switch_event_get_header(event, "variable_rayo_dcp_jid")); iks *joined = iks_find(revent, "unjoined"); - iks_insert_attrib(joined, "call-uri", b_uuid); + iks_insert_attrib_printf(joined, "call-uri", "xmpp:%s@%s", b_uuid, RAYO_JID(globals.server)); RAYO_SEND_MESSAGE(call, RAYO_JID(rclient), revent); call->joined = 0; call->joined_id = NULL; /* send B-leg event */ - b_call = RAYO_CALL_LOCATE(b_uuid); + b_call = RAYO_CALL_LOCATE_BY_ID(b_uuid); if (b_call) { revent = iks_new_presence("unjoined", RAYO_NS, RAYO_JID(b_call), rayo_call_get_dcp_jid(b_call)); joined = iks_find(revent, "unjoined"); - iks_insert_attrib(joined, "call-uri", a_uuid); + iks_insert_attrib_printf(joined, "call-uri", "xmpp:%s@%s", a_uuid, RAYO_JID(globals.server)); RAYO_SEND_MESSAGE(b_call, rayo_call_get_dcp_jid(b_call), revent); b_call->joined = 0; From c09dec0de136eb152a385fc88584f7d04b75921c Mon Sep 17 00:00:00 2001 From: Steve Underwood Date: Wed, 21 Aug 2013 20:08:17 +0800 Subject: [PATCH 42/63] Fixed jaggies in image resizing. Split naming of T.81/T.42 type JPEG from normal JPEG. This is in preparation for allowing the selective output of normal JPEG (like most people want) and the T.81/T.42 type you might want for forwarding as T.37 --- libs/spandsp/src/image_translate.c | 16 +++++------ libs/spandsp/src/spandsp/private/t42.h | 5 +++- libs/spandsp/src/spandsp/t4_rx.h | 6 +++++ libs/spandsp/src/t30.c | 6 ++--- libs/spandsp/src/t42.c | 23 +++++++++------- libs/spandsp/src/t4_rx.c | 37 +++++++++++++++++++++++--- libs/spandsp/src/t4_tx.c | 2 ++ libs/spandsp/tests/fax_tests.c | 2 +- 8 files changed, 71 insertions(+), 26 deletions(-) diff --git a/libs/spandsp/src/image_translate.c b/libs/spandsp/src/image_translate.c index 442d188be5..4c6a5affb8 100644 --- a/libs/spandsp/src/image_translate.c +++ b/libs/spandsp/src/image_translate.c @@ -337,6 +337,7 @@ static int image_resize_row(image_translate_state_t *s, uint8_t buf[]) double int_part; double frac_row; double frac_col; + double width_scaling; #endif uint8_t *row8[2]; uint16_t *row16[2]; @@ -352,17 +353,13 @@ static int image_resize_row(image_translate_state_t *s, uint8_t buf[]) input_width = s->input_width - 1; input_length = s->input_length - 1; - skip = s->raw_output_row*input_length/output_length; + skip = s->raw_output_row*input_length/output_length + 1; if (skip >= s->raw_input_row) { - skip++; while (skip >= s->raw_input_row) { if (s->raw_input_row >= s->input_length) - { - s->raw_output_row = -1; break; - } row_len = get_and_scrunch_row(s, s->raw_pixel_row[0]); if (row_len != s->output_width) { @@ -380,6 +377,7 @@ static int image_resize_row(image_translate_state_t *s, uint8_t buf[]) frac_row = ((s->raw_output_row*256*input_length)/output_length) & 0xFF; #else frac_row = modf((double) s->raw_output_row*input_length/output_length, &int_part); + width_scaling = (double) input_width/output_width; #endif switch (s->output_format) @@ -402,7 +400,7 @@ static int image_resize_row(image_translate_state_t *s, uint8_t buf[]) buf[3*i + j] = saturateu8(c1 + (((c2 - c1)*frac_row) >> 8)); } #else - frac_col = modf((double) i*input_width/output_width, &int_part); + frac_col = modf(width_scaling*i, &int_part); x = 3*int_part; for (j = 0; j < 3; j++) { @@ -431,7 +429,7 @@ static int image_resize_row(image_translate_state_t *s, uint8_t buf[]) buf16[3*i + j] = saturateu16(c1 + (((c2 - c1)*frac_row) >> 8)); } #else - frac_col = modf((double) i*input_width/output_width, &int_part); + frac_col = modf(width_scaling*i, &int_part); x = 3*int_part; for (j = 0; j < 3; j++) { @@ -456,7 +454,7 @@ static int image_resize_row(image_translate_state_t *s, uint8_t buf[]) c2 = row8[1][x] + (((row8[1][x + 1] - row8[1][x])*frac_col) >> 8); buf[i] = saturateu8(c1 + (((c2 - c1)*frac_row) >> 8)); #else - frac_col = modf((double) i*input_width/output_width, &int_part); + frac_col = modf(width_scaling*i, &int_part); x = int_part; c1 = row8[0][x] + (row8[0][x + 1] - row8[0][x])*frac_col; c2 = row8[1][x] + (row8[1][x + 1] - row8[1][x])*frac_col; @@ -478,7 +476,7 @@ static int image_resize_row(image_translate_state_t *s, uint8_t buf[]) c2 = row16[1][x] + (((row16[1][x + 1] - row16[1][x])*frac_col) >> 8); buf[i] = saturateu8(c1 + (((c2 - c1)*frac_row) >> 8)); #else - frac_col = modf((double) i*input_width/output_width, &int_part); + frac_col = modf(width_scaling*i, &int_part); x = int_part; c1 = row16[0][x] + (row16[0][x + 1] - row16[0][x])*frac_col; c2 = row16[1][x] + (row16[1][x + 1] - row16[1][x])*frac_col; diff --git a/libs/spandsp/src/spandsp/private/t42.h b/libs/spandsp/src/spandsp/private/t42.h index 4c1de58ffa..e151afc6fc 100644 --- a/libs/spandsp/src/spandsp/private/t42.h +++ b/libs/spandsp/src/spandsp/private/t42.h @@ -40,10 +40,13 @@ struct lab_params_s float offset_b; int ab_are_signed; - /* Illuminant */ + /* Illuminant, forward and reverse */ float x_n; float y_n; float z_n; + float x_rn; + float y_rn; + float z_rn; }; /* State of a working instance of the T.42 JPEG FAX encoder */ diff --git a/libs/spandsp/src/spandsp/t4_rx.h b/libs/spandsp/src/spandsp/t4_rx.h index 0401d10823..de6698517e 100644 --- a/libs/spandsp/src/spandsp/t4_rx.h +++ b/libs/spandsp/src/spandsp/t4_rx.h @@ -70,6 +70,12 @@ typedef enum T4_COMPRESSION_SYCC_T81 = 0x200, /*! T.88 monochrome JBIG2 compression */ T4_COMPRESSION_T88 = 0x400, + /*! Uncompressed image. This compression cannot be used for FAXes. It is provided for specifying + output formats for received images. */ + T4_COMPRESSION_UNCOMPRESSED = 0x1000, + /*! Conventional JPEG. This compression cannot be used for FAXes. It is provided for specifying + output formats for received images. */ + T4_COMPRESSION_JPEG = 0x2000, /*! Support solour compression without sub-sampling */ T4_COMPRESSION_NO_SUBSAMPLING = 0x800000, /*! Gray-scale support by multi-level codecs */ diff --git a/libs/spandsp/src/t30.c b/libs/spandsp/src/t30.c index 6074f5f5a1..110b5b2e5d 100644 --- a/libs/spandsp/src/t30.c +++ b/libs/spandsp/src/t30.c @@ -6706,9 +6706,9 @@ SPAN_DECLARE(t30_state_t *) t30_init(t30_state_t *s, | T4_SUPPORT_LENGTH_A4 | T4_SUPPORT_LENGTH_B4 | T4_SUPPORT_LENGTH_UNLIMITED; - /* Set the output encoding to something safe. Most things get 1D and 2D - encoding right. Quite a lot get other things wrong. */ - s->supported_output_compressions = T4_COMPRESSION_T4_2D | T4_COMPRESSION_T42_T81; + /* Set the output encoding to something safe. For bi-level images ost things get + 1D and 2D encoding right. Quite a lot get other things wrong. */ + s->supported_output_compressions = T4_COMPRESSION_T4_2D | T4_COMPRESSION_JPEG; s->local_min_scan_time_code = T30_MIN_SCAN_0MS; span_log_init(&s->logging, SPAN_LOG_NONE, NULL); span_log_set_protocol(&s->logging, "T.30"); diff --git a/libs/spandsp/src/t42.c b/libs/spandsp/src/t42.c index 6117cd3f19..1469c389be 100644 --- a/libs/spandsp/src/t42.c +++ b/libs/spandsp/src/t42.c @@ -309,6 +309,9 @@ SPAN_DECLARE(void) set_lab_illuminant(lab_params_t *lab, float new_xn, float new lab->y_n = new_yn; lab->z_n = new_zn; } + lab->x_rn = 1.0f/lab->x_n; + lab->y_rn = 1.0f/lab->y_n; + lab->z_rn = 1.0f/lab->z_n; } /*- End of function --------------------------------------------------------*/ @@ -475,9 +478,9 @@ SPAN_DECLARE(void) srgb_to_lab(lab_params_t *s, uint8_t lab[], const uint8_t srg z = 0.0193f*r + 0.1192f*g + 0.9505f*b; /* Normalise for the illuminant */ - x /= s->x_n; - y /= s->y_n; - z /= s->z_n; + x *= s->x_rn; + y *= s->y_rn; + z *= s->z_rn; /* XYZ to Lab */ xx = (x <= 0.008856f) ? (7.787f*x + 0.1379f) : cbrtf(x); @@ -946,15 +949,16 @@ SPAN_DECLARE(int) t42_encode_restart(t42_encode_state_t *s, uint32_t image_width { /* ITU-YCC */ /* Illuminant D65 */ - set_lab_illuminant(&s->lab, 95.047f, 100.000f, 108.883f); + //set_lab_illuminant(&s->lab, 95.047f, 100.000f, 108.883f); + set_lab_illuminant(&s->lab, 100.0f, 100.0f, 100.0f); set_lab_gamut(&s->lab, 0, 100, -127, 127, -127, 127, false); } else { /* ITULAB */ /* Illuminant D50 */ - set_lab_illuminant(&s->lab, 96.422f, 100.000f, 82.521f); -set_lab_illuminant(&s->lab, 95.047f, 100.000f, 108.883f); + //set_lab_illuminant(&s->lab, 96.422f, 100.000f, 82.521f); + set_lab_illuminant(&s->lab, 100.0f, 100.0f, 100.0f); set_lab_gamut(&s->lab, 0, 100, -85, 85, -75, 125, false); } s->compressed_image_size = 0; @@ -1312,15 +1316,16 @@ SPAN_DECLARE(int) t42_decode_restart(t42_decode_state_t *s) { /* ITU-YCC */ /* Illuminant D65 */ - set_lab_illuminant(&s->lab, 95.047f, 100.000f, 108.883f); + //set_lab_illuminant(&s->lab, 95.047f, 100.000f, 108.883f); + set_lab_illuminant(&s->lab, 100.0f, 100.0f, 100.0f); set_lab_gamut(&s->lab, 0, 100, -127, 127, -127, 127, false); } else { /* ITULAB */ /* Illuminant D50 */ - set_lab_illuminant(&s->lab, 96.422f, 100.000f, 82.521f); -set_lab_illuminant(&s->lab, 95.047f, 100.000f, 108.883f); + //set_lab_illuminant(&s->lab, 96.422f, 100.000f, 82.521f); + set_lab_illuminant(&s->lab, 100.0f, 100.0f, 100.0f); set_lab_gamut(&s->lab, 0, 100, -85, 85, -75, 125, false); } diff --git a/libs/spandsp/src/t4_rx.c b/libs/spandsp/src/t4_rx.c index 1164814355..141a6529e9 100644 --- a/libs/spandsp/src/t4_rx.c +++ b/libs/spandsp/src/t4_rx.c @@ -123,6 +123,11 @@ SPAN_DECLARE(const char *) t4_compression_to_str(int compression) return "T.43"; case T4_COMPRESSION_T45: return "T.45"; + /* Compressions which can only be used in TIFF files */ + case T4_COMPRESSION_UNCOMPRESSED: + return "Uncompressed"; + case T4_COMPRESSION_JPEG: + return "JPEG"; } return "???"; } @@ -238,13 +243,27 @@ static int set_tiff_directory_info(t4_rx_state_t *s) break; #endif #if defined(SPANDSP_SUPPORT_T42) + case T4_COMPRESSION_JPEG: + output_compression = COMPRESSION_JPEG; + bits_per_sample = 8; + if (t->image_type == T4_IMAGE_TYPE_COLOUR_8BIT) + { + samples_per_pixel = 3; + photometric = PHOTOMETRIC_YCBCR; + } + else + { + samples_per_pixel = 1; + photometric = PHOTOMETRIC_MINISBLACK; + } + break; case T4_COMPRESSION_T42_T81: output_compression = COMPRESSION_JPEG; bits_per_sample = 8; if (t->image_type == T4_IMAGE_TYPE_COLOUR_8BIT) { samples_per_pixel = 3; - photometric = PHOTOMETRIC_YCBCR; //PHOTOMETRIC_ITULAB; + photometric = PHOTOMETRIC_ITULAB; } else { @@ -306,12 +325,20 @@ static int set_tiff_directory_info(t4_rx_state_t *s) TIFFSetField(t->tiff_file, TIFFTAG_PLANARCONFIG, PLANARCONFIG_CONTIG); TIFFSetField(t->tiff_file, TIFFTAG_PHOTOMETRIC, photometric); TIFFSetField(t->tiff_file, TIFFTAG_FILLORDER, FILLORDER_LSB2MSB); - if (t->compression == T4_COMPRESSION_T42_T81) + switch (t->compression) { + case T4_COMPRESSION_JPEG: TIFFSetField(t->tiff_file, TIFFTAG_YCBCRSUBSAMPLING, 2, 2); //TIFFSetField(t->tiff_file, TIFFTAG_YCBCRSUBSAMPLING, 1, 1); TIFFSetField(t->tiff_file, TIFFTAG_JPEGQUALITY, 75); TIFFSetField(t->tiff_file, TIFFTAG_JPEGCOLORMODE, JPEGCOLORMODE_RGB); + break; + case T4_COMPRESSION_T42_T81: + TIFFSetField(t->tiff_file, TIFFTAG_YCBCRSUBSAMPLING, 2, 2); + //TIFFSetField(t->tiff_file, TIFFTAG_YCBCRSUBSAMPLING, 1, 1); + TIFFSetField(t->tiff_file, TIFFTAG_JPEGQUALITY, 75); + TIFFSetField(t->tiff_file, TIFFTAG_JPEGCOLORMODE, JPEGCOLORMODE_RGB); + break; } /* TIFFTAG_STRIPBYTECOUNTS and TIFFTAG_STRIPOFFSETS are added automatically */ @@ -815,10 +842,14 @@ static void select_tiff_compression(t4_rx_state_t *s, int output_image_type) } else { - if ((s->supported_tiff_compressions & T4_COMPRESSION_T42_T81)) + if ((s->supported_tiff_compressions & T4_COMPRESSION_JPEG)) + s->tiff.compression = T4_COMPRESSION_JPEG; + else if ((s->supported_tiff_compressions & T4_COMPRESSION_T42_T81)) s->tiff.compression = T4_COMPRESSION_T42_T81; else if ((s->supported_tiff_compressions & T4_COMPRESSION_T43)) s->tiff.compression = T4_COMPRESSION_T43; + else if ((s->supported_tiff_compressions & T4_COMPRESSION_UNCOMPRESSED)) + s->tiff.compression = T4_COMPRESSION_UNCOMPRESSED; } s->tiff.image_type = output_image_type; } diff --git a/libs/spandsp/src/t4_tx.c b/libs/spandsp/src/t4_tx.c index 639ddc93dd..0c17b585f2 100644 --- a/libs/spandsp/src/t4_tx.c +++ b/libs/spandsp/src/t4_tx.c @@ -2009,6 +2009,8 @@ SPAN_DECLARE(int) t4_tx_set_tx_image_format(t4_tx_state_t *s, /* We can't rework a bilevel image that fits none of the patterns */ if (s->tiff.image_type == T4_IMAGE_TYPE_BILEVEL) return T4_IMAGE_FORMAT_NORESSUPPORT; + if (!(supported_compressions & T4_COMPRESSION_RESCALING)) + return T4_IMAGE_FORMAT_NORESSUPPORT; res = T4_IMAGE_FORMAT_OK; /* Any other kind of image might be resizable */ s->metadata.image_width = T4_WIDTH_200_A4; diff --git a/libs/spandsp/tests/fax_tests.c b/libs/spandsp/tests/fax_tests.c index 8e417adf9b..7cbe61fcfa 100644 --- a/libs/spandsp/tests/fax_tests.c +++ b/libs/spandsp/tests/fax_tests.c @@ -926,7 +926,7 @@ int main(int argc, char *argv[]) { t30_set_supported_colour_resolutions(t30_state[i], 0); } - //t30_set_supported_output_compressions(t30_state[i], T4_COMPRESSION_T85); + t30_set_supported_output_compressions(t30_state[i], T4_COMPRESSION_T6 | T4_COMPRESSION_JPEG); t30_set_ecm_capability(t30_state[i], use_ecm); t30_set_supported_compressions(t30_state[i], T4_COMPRESSION_T4_1D From bf2fc31aee2809778822e7e9c0057077e1c78a49 Mon Sep 17 00:00:00 2001 From: Brian West Date: Wed, 21 Aug 2013 11:20:08 -0500 Subject: [PATCH 43/63] FS-5695 --resolve --- scripts/gentls_cert.in | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/scripts/gentls_cert.in b/scripts/gentls_cert.in index 26da60c7f8..49b3940d5d 100644 --- a/scripts/gentls_cert.in +++ b/scripts/gentls_cert.in @@ -7,7 +7,7 @@ export KEY_SIZE=${KEY_SIZE} TMPFILE="/tmp/fs-ca-$$-$(date +%Y%m%d%H%M%S)" -COMMON_NAME="FreesSWITCH CA" +COMMON_NAME="FreeSWITCH CA" ALT_NAME="DNS:test.freeswitch.org" ORG_NAME="FreeSWITCH" OUTFILE="agent.pem" @@ -47,6 +47,7 @@ setup_ca() { default_bits = \$ENV::KEY_SIZE prompt = no distinguished_name = req_dn + x509_extensions = v3_ca [ req_dn ] commonName = %CN% @@ -69,6 +70,12 @@ setup_ca() { subjectAltName=%ALTNAME% nsCertType=client extendedKeyUsage=clientAuth + + [ v3_ca ] + subjectKeyIdentifier=hash + authorityKeyIdentifier=keyid:always,issuer + basicConstraints=CA:TRUE + EOF fi @@ -84,6 +91,7 @@ setup_ca() { -new -x509 -keyout "${CONFDIR}/CA/cakey.pem" \ -config "${TMPFILE}.cfg" -nodes -days ${DAYS} -sha1 >/dev/null || exit 1 cat "${CONFDIR}/CA/cacert.pem" > "${CONFDIR}/cafile.pem" + cp $TMPFILE.cfg /tmp/ssl.cfg rm "${TMPFILE}.cfg" echo "DONE" From 8b7c351fa4f9491d214340e5b17ca8dea78adbda Mon Sep 17 00:00:00 2001 From: Brian West Date: Wed, 21 Aug 2013 11:29:48 -0500 Subject: [PATCH 44/63] FS-5719 --resolve --- scripts/gentls_cert.in | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/scripts/gentls_cert.in b/scripts/gentls_cert.in index 49b3940d5d..f2e4cd5a99 100644 --- a/scripts/gentls_cert.in +++ b/scripts/gentls_cert.in @@ -87,8 +87,9 @@ setup_ca() { "${CONFDIR}/CA/config.tpl" \ > "${TMPFILE}.cfg" || exit 1 + openssl ecparam -name secp160r2 -out CA_CURVE.pem openssl req -out "${CONFDIR}/CA/cacert.pem" \ - -new -x509 -keyout "${CONFDIR}/CA/cakey.pem" \ + -new -x509 -keyout "${CONFDIR}/CA/cakey.pem" -newkey ec:CA_CURVE.pem \ -config "${TMPFILE}.cfg" -nodes -days ${DAYS} -sha1 >/dev/null || exit 1 cat "${CONFDIR}/CA/cacert.pem" > "${CONFDIR}/cafile.pem" cp $TMPFILE.cfg /tmp/ssl.cfg @@ -130,7 +131,7 @@ generate_cert() { > "${TMPFILE}.cfg" || exit 1 openssl req -new -out "${TMPFILE}.req" \ - -newkey rsa:${KEY_SIZE} -keyout "${TMPFILE}.key" \ + -newkey ec:CA_CURVE.pem -keyout "${TMPFILE}.key" \ -config "${TMPFILE}.cfg" -nodes -sha1 >/dev/null || exit 1 openssl x509 -req -CAkey "${CONFDIR}/CA/cakey.pem" -CA "${CONFDIR}/CA/cacert.pem" -CAcreateserial \ @@ -156,7 +157,6 @@ remove_ca() { } OUTFILESET="0" command="$1" -shift while [ $# -gt 0 ]; do case $1 in From f592ce264b771f5d1b2ec814bbc60c6ffa2827e5 Mon Sep 17 00:00:00 2001 From: Brian West Date: Wed, 21 Aug 2013 11:33:13 -0500 Subject: [PATCH 45/63] FS-5718 --resolve --- conf/vanilla/vars.xml | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/conf/vanilla/vars.xml b/conf/vanilla/vars.xml index c3f235bfe3..950e222c3e 100644 --- a/conf/vanilla/vars.xml +++ b/conf/vanilla/vars.xml @@ -14,6 +14,28 @@ --> + + From 395b3b6112d795f97b3a6f321d47acc90ea39967 Mon Sep 17 00:00:00 2001 From: Brian West Date: Wed, 21 Aug 2013 11:47:58 -0500 Subject: [PATCH 46/63] sigh spelling --- conf/vanilla/vars.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/conf/vanilla/vars.xml b/conf/vanilla/vars.xml index 950e222c3e..1abbb240f7 100644 --- a/conf/vanilla/vars.xml +++ b/conf/vanilla/vars.xml @@ -15,7 +15,7 @@