diff --git a/conf/lang/en/vm/sounds.xml b/conf/lang/en/vm/sounds.xml
index 976fcde32d..449ad55f2d 100644
--- a/conf/lang/en/vm/sounds.xml
+++ b/conf/lang/en/vm/sounds.xml
@@ -315,7 +315,7 @@
-
+
@@ -331,9 +331,17 @@
+
+
+
+
+
-
+
+
+
+
diff --git a/libs/freetdm/src/ftmod/ftmod_misdn/ftmod_misdn.c b/libs/freetdm/src/ftmod/ftmod_misdn/ftmod_misdn.c
index 9673549f79..06caeef7ae 100644
--- a/libs/freetdm/src/ftmod/ftmod_misdn/ftmod_misdn.c
+++ b/libs/freetdm/src/ftmod/ftmod_misdn/ftmod_misdn.c
@@ -25,6 +25,15 @@
* NOTE: This is intended as a Layer 1 interface only, signaling
* is handled by other modules (e.g. ftmod_libpri or ftmod_isdn).
*/
+/*
+ * TODO:
+ * - Use a fifo and PH_DATA_CNF for b-channel write polling (drop timerfd)
+ *
+ * - Disable L1 idle deactivation on BRI PTMP with IMGL1HOLD ioctl(? optional)
+ *
+ * - Add hfcsusb specific state + flag defines and try to do something useful with
+ * it in misdn_handle_mph_information_ind().
+ */
#include
#include
@@ -91,23 +100,33 @@ typedef enum {
#define MISDN_IS_RAW(x) (x & MISDN_CAPS_RAW)
#define MISDN_IS_HDLC(x) (x & MISDN_CAPS_HDLC)
+#define MISDN_MSG_DATA(x) ((void *)((unsigned char *)(x) + MISDN_HEADER_LEN))
const static struct {
const int id;
const char *name;
} misdn_event_types[] = {
- { PH_DATA_REQ, "PH_DATA_REQ" },
- { PH_DATA_IND, "PH_DATA_IND" },
- { PH_DATA_CNF, "PH_DATA_CNF" },
- { PH_CONTROL_REQ, "PH_CONTROL_REQ" },
- { PH_CONTROL_IND, "PH_CONTROL_IND" },
- { PH_CONTROL_CNF, "PH_CONTROL_CNF" },
- { PH_ACTIVATE_REQ, "PH_ACTIVATE_REQ" },
- { PH_ACTIVATE_IND, "PH_ACTIVATE_IND" },
- { PH_ACTIVATE_CNF, "PH_ACTIVATE_CNF" },
- { PH_DEACTIVATE_REQ, "PH_DEACTIVATE_REQ" },
- { PH_DEACTIVATE_IND, "PH_DEACTIVATE_IND" },
- { PH_DEACTIVATE_CNF, "PH_DEACTIVATE_CNF" },
+#define MISDN_EVENT_TYPE(x) { x, #x }
+ MISDN_EVENT_TYPE(PH_DATA_REQ),
+ MISDN_EVENT_TYPE(PH_DATA_IND),
+ MISDN_EVENT_TYPE(PH_DATA_CNF),
+ MISDN_EVENT_TYPE(PH_DATA_E_IND),
+ MISDN_EVENT_TYPE(PH_CONTROL_REQ),
+ MISDN_EVENT_TYPE(PH_CONTROL_IND),
+ MISDN_EVENT_TYPE(PH_CONTROL_CNF),
+ MISDN_EVENT_TYPE(PH_ACTIVATE_REQ),
+ MISDN_EVENT_TYPE(PH_ACTIVATE_IND),
+ MISDN_EVENT_TYPE(PH_ACTIVATE_CNF),
+ MISDN_EVENT_TYPE(PH_DEACTIVATE_REQ),
+ MISDN_EVENT_TYPE(PH_DEACTIVATE_IND),
+ MISDN_EVENT_TYPE(PH_DEACTIVATE_CNF),
+ MISDN_EVENT_TYPE(MPH_ACTIVATE_REQ),
+ MISDN_EVENT_TYPE(MPH_ACTIVATE_IND),
+ MISDN_EVENT_TYPE(MPH_DEACTIVATE_REQ),
+ MISDN_EVENT_TYPE(MPH_DEACTIVATE_IND),
+ MISDN_EVENT_TYPE(MPH_INFORMATION_REQ),
+ MISDN_EVENT_TYPE(MPH_INFORMATION_IND),
+#undef MISDN_EVENT_TYPE
};
static const char *misdn_event2str(const int event)
@@ -128,6 +147,7 @@ const static struct {
} misdn_control_types[] = {
#define MISDN_CONTROL_TYPE(x) { x, #x }
MISDN_CONTROL_TYPE(DTMF_HFC_COEF),
+#undef MISDN_CONTROL_TYPE
};
#if 0 /* unused for now */
@@ -189,6 +209,7 @@ struct misdn_chan_private {
#define ftdm_span_io_private(x) ((x)->io_data)
static ftdm_status_t misdn_handle_incoming(ftdm_channel_t *ftdmchan, const char *rbuf, const int size);
+static int misdn_handle_mph_information_ind(ftdm_channel_t *chan, const struct mISDNhead *hh, const void *data, const int data_len);
/***********************************************************************************
* mISDN interface functions
@@ -432,8 +453,8 @@ static ftdm_status_t misdn_activate_channel(ftdm_channel_t *chan, int activate)
return FTDM_FAIL;
}
//#ifdef MISDN_DEBUG_EVENTS
- ftdm_log_chan(chan, FTDM_LOG_DEBUG, "mISDN got event '%s' while waiting for %s confirmation\n",
- misdn_event2str(hh->prim), (activate) ? "activation" : "deactivation");
+ ftdm_log_chan(chan, FTDM_LOG_DEBUG, "mISDN got event '%s (%#x)' while waiting for %s confirmation\n",
+ misdn_event2str(hh->prim), hh->prim, (activate) ? "activation" : "deactivation");
//#endif
switch (hh->prim) {
case PH_ACTIVATE_IND: /* success (or not): save last response, */
@@ -451,9 +472,14 @@ static ftdm_status_t misdn_activate_channel(ftdm_channel_t *chan, int activate)
ftdm_log_chan(chan, FTDM_LOG_DEBUG, "mISDN got '%s' echo while waiting for %s confirmation (id: %#x)\n",
misdn_event2str(hh->prim), (activate) ? "activation" : "deactivation", hh->id);
break;
+ case MPH_INFORMATION_IND:
+ ftdm_log_chan(chan, FTDM_LOG_DEBUG, "mISDN ignoring event '%s (%#x)' while waiting for %s confirmation\n",
+ misdn_event2str(hh->prim), hh->prim, (activate) ? "activation" : "deactivation");
+ misdn_handle_mph_information_ind(chan, hh, MISDN_MSG_DATA(buf), retval - MISDN_HEADER_LEN);
+ break;
default: /* other messages, ignore */
- ftdm_log_chan(chan, FTDM_LOG_DEBUG, "mISDN ignoring event '%s' while waiting for %s confirmation\n",
- misdn_event2str(hh->prim), (activate) ? "activation" : "deactivation");
+ ftdm_log_chan(chan, FTDM_LOG_DEBUG, "mISDN ignoring event '%s (%#x)' while waiting for %s confirmation\n",
+ misdn_event2str(hh->prim), hh->prim, (activate) ? "activation" : "deactivation");
break;
}
}
@@ -605,50 +631,88 @@ static int misdn_handle_ph_control_ind(ftdm_channel_t *chan, const struct mISDNh
static int misdn_handle_mph_information_ind(ftdm_channel_t *chan, const struct mISDNhead *hh, const void *data, const int data_len)
{
struct misdn_chan_private *priv = ftdm_chan_io_private(chan);
- int alarm_flags, value;
- if (data_len < sizeof(value)) {
- ftdm_log_chan_msg(chan, FTDM_LOG_ERROR, "mISDN MPH_INFORMATION_IND message is too short\n");
+ /*
+ * mISDN has some inconsistency issues here.
+ *
+ * There are only two drivers that emit MPH_INFORMATION_IND messages,
+ * hfcsusb and hfcmulti. The former sends a set of ph_info and ph_info_ch structures,
+ * while the latter just sends an int containing the current L1_SIGNAL_* event id.
+ *
+ * The flags and state information in the ph_info and ph_info_ch structures
+ * are defined in kernel internal hw-specific headers (mISDNhw.h).
+ *
+ * Use the payload size to guess the type of message.
+ */
+ if (data_len >= sizeof(struct ph_info)) {
+ /* complete port status, hfcsusb sends this */
+ struct ph_info *info = (struct ph_info *)data;
+ struct ph_info_ch *bch_info = NULL;
+
+ if (data_len < (sizeof(*info) + info->dch.num_bch * sizeof(*bch_info))) {
+ ftdm_log_chan_msg(chan, FTDM_LOG_ERROR, "mISDN MPH_INFORMATION_IND message is too short\n");
+ return FTDM_FAIL;
+ }
+ bch_info = &info->bch[0];
+
+ ftdm_log_chan(chan, FTDM_LOG_DEBUG, "mISDN port state:\n\tD-Chan state:\t%hu\n\tD-Chan flags:\t%#x\n\tD-Chan proto:\t%hu\n\tD-Chan active:\t%s\n",
+ info->dch.state, info->dch.ch.Flags, info->dch.ch.protocol, info->dch.ch.Flags & (1 << 6) ? "yes" : "no");
+
+ /* TODO: try to translate this to a usable set of alarm flags */
+
+ } else if (data_len == sizeof(int)) {
+ /* alarm info, sent by hfcmulti */
+ int value = *(int *)data;
+ int alarm_flags = chan->alarm_flags;
+
+ if (data_len < sizeof(value)) {
+ ftdm_log_chan_msg(chan, FTDM_LOG_ERROR, "mISDN MPH_INFORMATION_IND message is too short\n");
+ return FTDM_FAIL;
+ }
+
+ switch (value) {
+ case L1_SIGNAL_LOS_ON:
+ alarm_flags |= FTDM_ALARM_RED;
+ break;
+ case L1_SIGNAL_LOS_OFF:
+ alarm_flags &= ~FTDM_ALARM_RED;
+ break;
+ case L1_SIGNAL_AIS_ON:
+ alarm_flags |= FTDM_ALARM_AIS;
+ break;
+ case L1_SIGNAL_AIS_OFF:
+ alarm_flags &= ~FTDM_ALARM_AIS;
+ break;
+ case L1_SIGNAL_RDI_ON:
+ alarm_flags |= FTDM_ALARM_YELLOW;
+ break;
+ case L1_SIGNAL_RDI_OFF:
+ alarm_flags &= ~FTDM_ALARM_YELLOW;
+ break;
+ case L1_SIGNAL_SLIP_RX:
+ priv->slip_rx_cnt++;
+ break;
+ case L1_SIGNAL_SLIP_TX:
+ priv->slip_tx_cnt++;
+ break;
+ default:
+ ftdm_log_chan(chan, FTDM_LOG_ERROR, "mISDN unknown MPH_INFORMATION_IND signal: %#04x\n",
+ value);
+ return FTDM_FAIL;
+ }
+
+ /* check whether alarm status has changed, update channel flags if it has */
+ if ((value = (alarm_flags ^ chan->alarm_flags))) {
+ ftdm_log_chan(chan, FTDM_LOG_DEBUG, "mISDN alarm flags have changed %#x -> %#x\n",
+ chan->alarm_flags, alarm_flags);
+ chan->alarm_flags ^= value;
+ }
+ } else {
+ ftdm_log_chan(chan, FTDM_LOG_ERROR, "mISDN sent MPH_INFORMATION_IND message with unknown size %d\n",
+ data_len);
return FTDM_FAIL;
}
- value = *(int *)data;
- alarm_flags = chan->alarm_flags;
- switch (value) {
- case L1_SIGNAL_LOS_ON:
- alarm_flags |= FTDM_ALARM_RED;
- break;
- case L1_SIGNAL_LOS_OFF:
- alarm_flags &= ~FTDM_ALARM_RED;
- break;
- case L1_SIGNAL_AIS_ON:
- alarm_flags |= FTDM_ALARM_AIS;
- break;
- case L1_SIGNAL_AIS_OFF:
- alarm_flags &= ~FTDM_ALARM_AIS;
- break;
- case L1_SIGNAL_RDI_ON:
- alarm_flags |= FTDM_ALARM_YELLOW;
- break;
- case L1_SIGNAL_RDI_OFF:
- alarm_flags &= ~FTDM_ALARM_YELLOW;
- break;
- case L1_SIGNAL_SLIP_RX:
- priv->slip_rx_cnt++;
- break;
- case L1_SIGNAL_SLIP_TX:
- priv->slip_tx_cnt++;
- break;
- default:
- ftdm_log_chan(chan, FTDM_LOG_ERROR, "mISDN unknown MPH_INFORMATION_IND message: %d\n",
- value);
- return FTDM_FAIL;
- }
- if ((value = (alarm_flags ^ chan->alarm_flags))) {
- ftdm_log_chan(chan, FTDM_LOG_DEBUG, "mISDN alarm flags have changed %#x -> %#x\n",
- chan->alarm_flags, alarm_flags);
- chan->alarm_flags ^= value;
- }
return FTDM_SUCCESS;
}
diff --git a/src/mod/applications/mod_spandsp/mod_spandsp_fax.c b/src/mod/applications/mod_spandsp/mod_spandsp_fax.c
index f1d56a92c5..7cb0982591 100644
--- a/src/mod/applications/mod_spandsp/mod_spandsp_fax.c
+++ b/src/mod/applications/mod_spandsp/mod_spandsp_fax.c
@@ -341,6 +341,7 @@ static int phase_b_handler(t30_state_t *s, void *user_data, int result)
/* Fire event */
if (switch_event_create_subclass(&event, SWITCH_EVENT_CUSTOM, pvt->app_mode == FUNCTION_TX ? SPANDSP_EVENT_TXFAXNEGOCIATERESULT : SPANDSP_EVENT_RXFAXNEGOCIATERESULT) == SWITCH_STATUS_SUCCESS) {
+ switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "uuid", switch_core_session_get_uuid(session));
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "fax-transfer-rate", fax_transfer_rate);
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "fax-ecm-used", (t30_stats.error_correcting_mode) ? "on" : "off");
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "fax-local-station-id", local_ident);
@@ -437,6 +438,7 @@ static int phase_d_handler(t30_state_t *s, void *user_data, int msg)
switch_channel_execute_on(channel, "execute_on_fax_phase_d");
if (switch_event_create_subclass(&event, SWITCH_EVENT_CUSTOM, pvt->app_mode == FUNCTION_TX ? SPANDSP_EVENT_TXFAXPAGERESULT : SPANDSP_EVENT_RXFAXPAGERESULT) == SWITCH_STATUS_SUCCESS) {
+ switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "uuid", switch_core_session_get_uuid(session));
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "fax-document-transferred-pages", fax_document_transferred_pages);
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "fax-image-resolution", fax_image_resolution);
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "fax-image-size", fax_image_size);
diff --git a/src/mod/applications/mod_voicemail/mod_voicemail.c b/src/mod/applications/mod_voicemail/mod_voicemail.c
index 8461f480bc..df68f28166 100644
--- a/src/mod/applications/mod_voicemail/mod_voicemail.c
+++ b/src/mod/applications/mod_voicemail/mod_voicemail.c
@@ -1544,8 +1544,6 @@ static switch_status_t listen_file(switch_core_session_t *session, vm_profile_t
char cid_buf[1024] = "";
if (switch_channel_ready(channel)) {
- const char *vm_announce_cid = NULL;
-
switch_snprintf(cid_buf, sizeof(cid_buf), "%s|%s", cbt->cid_number, cbt->cid_name);
msg.from = __FILE__;
@@ -1556,10 +1554,8 @@ static switch_status_t listen_file(switch_core_session_t *session, vm_profile_t
cid_buf, switch_channel_get_name(channel));
switch_core_session_receive_message(session, &msg);
- if (!zstr(cbt->cid_number) && (vm_announce_cid = switch_channel_get_variable(channel, "vm_announce_cid"))) {
- switch_ivr_play_file(session, NULL, vm_announce_cid, NULL);
- switch_ivr_sleep(session, 500, SWITCH_TRUE, NULL);
- switch_ivr_say(session, cbt->cid_number, NULL, "name_spelled", "pronounced", NULL, NULL);
+ if (!zstr(cbt->cid_number) && (switch_true(switch_channel_get_variable(channel, "vm_announce_cid")))) {
+ TRY_CODE(switch_ivr_phrase_macro(session, VM_SAY_PHONE_NUMBER_MACRO, cbt->cid_number, NULL, NULL));
}
args.input_callback = cancel_on_dtmf;
diff --git a/src/mod/endpoints/mod_sofia/mod_sofia.h b/src/mod/endpoints/mod_sofia/mod_sofia.h
index 1860c08290..0a2f672df6 100644
--- a/src/mod/endpoints/mod_sofia/mod_sofia.h
+++ b/src/mod/endpoints/mod_sofia/mod_sofia.h
@@ -262,6 +262,7 @@ typedef enum {
PFLAG_SHUTDOWN,
PFLAG_PRESENCE_MAP,
PFLAG_OPTIONS_RESPOND_503_ON_BUSY,
+ PFLAG_PRESENCE_DISABLE_EARLY,
/* No new flags below this line */
PFLAG_MAX
} PFLAGS;
diff --git a/src/mod/endpoints/mod_sofia/sofia.c b/src/mod/endpoints/mod_sofia/sofia.c
index 3dd28d7f60..0668eedf57 100644
--- a/src/mod/endpoints/mod_sofia/sofia.c
+++ b/src/mod/endpoints/mod_sofia/sofia.c
@@ -3035,6 +3035,12 @@ switch_status_t reconfig_sofia(sofia_profile_t *profile)
} else {
sofia_clear_pflag(profile, PFLAG_T38_PASSTHRU);
}
+ } else if (!strcasecmp(var, "presence-disable-early")) {
+ if (switch_true(val)) {
+ sofia_set_pflag(profile, PFLAG_PRESENCE_DISABLE_EARLY);
+ } else {
+ sofia_clear_pflag(profile, PFLAG_PRESENCE_DISABLE_EARLY);
+ }
} else if (!strcasecmp(var, "ignore-183nosdp")) {
if (switch_true(val)) {
sofia_set_pflag(profile, PFLAG_IGNORE_183NOSDP);
@@ -3809,6 +3815,12 @@ switch_status_t config_sofia(int reload, char *profile_name)
} else {
sofia_clear_pflag(profile, PFLAG_T38_PASSTHRU);
}
+ } else if (!strcasecmp(var, "presence-disable-early")) {
+ if (switch_true(val)) {
+ sofia_set_pflag(profile, PFLAG_PRESENCE_DISABLE_EARLY);
+ } else {
+ sofia_clear_pflag(profile, PFLAG_PRESENCE_DISABLE_EARLY);
+ }
} else if (!strcasecmp(var, "ignore-183nosdp")) {
if (switch_true(val)) {
sofia_set_pflag(profile, PFLAG_IGNORE_183NOSDP);
diff --git a/src/mod/endpoints/mod_sofia/sofia_presence.c b/src/mod/endpoints/mod_sofia/sofia_presence.c
index 75c663ef07..683903fc66 100644
--- a/src/mod/endpoints/mod_sofia/sofia_presence.c
+++ b/src/mod/endpoints/mod_sofia/sofia_presence.c
@@ -2499,11 +2499,17 @@ static int sofia_presence_sub_callback(void *pArg, int argc, char **argv, char *
if (!strcasecmp(astate, "answered")) {
astate = "confirmed";
}
-
+
if (!strcasecmp(astate, "hangup")) {
astate = "terminated";
}
+ if (!sofia_test_pflag(profile, PFLAG_PRESENCE_DISABLE_EARLY)) {
+ if (!strcasecmp(astate, "ringing") || !strcasecmp(astate, "early")) {
+ astate = "confirmed";
+ }
+ }
+
if (is_dialog) {
if (!strcasecmp(astate, "ringing")) {
diff --git a/src/mod/timers/mod_posix_timer/mod_posix_timer.c b/src/mod/timers/mod_posix_timer/mod_posix_timer.c
index f5b9a61a1f..425e98c93d 100644
--- a/src/mod/timers/mod_posix_timer/mod_posix_timer.c
+++ b/src/mod/timers/mod_posix_timer/mod_posix_timer.c
@@ -28,8 +28,8 @@
*
*/
#include
-#include
-#include
+#include
+#include
SWITCH_MODULE_LOAD_FUNCTION(mod_posix_timer_load);
SWITCH_MODULE_SHUTDOWN_FUNCTION(mod_posix_timer_shutdown);
@@ -59,7 +59,7 @@ static struct {
/**
* Notified by POSIX timer of a tick
*/
-static void posix_timer_notify(sigval_t data)
+static void posix_timer_notify(union sigval data)
{
interval_timer_t *it = (interval_timer_t *)data.sival_ptr;
switch_mutex_lock(it->mutex);
diff --git a/src/switch_event.c b/src/switch_event.c
index 7e8a8676ba..25bab3185a 100644
--- a/src/switch_event.c
+++ b/src/switch_event.c
@@ -85,6 +85,7 @@ static switch_mutex_t *EVENT_QUEUE_MUTEX = NULL;
static switch_hash_t *CUSTOM_HASH = NULL;
static int THREAD_COUNT = 0;
static int SYSTEM_RUNNING = 0;
+static uint64_t EVENT_SEQUENCE_NR = 0;
#ifdef SWITCH_EVENT_RECYCLE
static switch_queue_t *EVENT_RECYCLE_QUEUE = NULL;
static switch_queue_t *EVENT_HEADER_RECYCLE_QUEUE = NULL;
@@ -1740,6 +1741,10 @@ SWITCH_DECLARE(void) switch_event_prep_for_delivery_detailed(const char *file, c
switch_size_t retsize;
switch_time_t ts = switch_micro_time_now();
+ switch_mutex_lock(EVENT_QUEUE_MUTEX);
+ EVENT_SEQUENCE_NR++;
+ switch_mutex_unlock(EVENT_QUEUE_MUTEX);
+
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Event-Name", switch_event_name(event->event_id));
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Core-UUID", switch_core_get_uuid());
@@ -1757,6 +1762,7 @@ SWITCH_DECLARE(void) switch_event_prep_for_delivery_detailed(const char *file, c
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Event-Calling-File", switch_cut_path(file));
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Event-Calling-Function", func);
switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Event-Calling-Line-Number", "%d", line);
+ switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Event-Sequence", "%" SWITCH_UINT64_T_FMT, (uint64_t) EVENT_SEQUENCE_NR);
}