Merge branch 'master' of ssh://git.freeswitch.org:222/freeswitch

This commit is contained in:
David Yat Sin 2012-02-07 14:28:58 -05:00
commit c5cc318afa
9 changed files with 163 additions and 68 deletions

View File

@ -315,7 +315,7 @@
<macro name="voicemail_say_number">
<input pattern="^(\d+)$">
<match>
<action function="say" data="$1" method="pronounced" type="items"/>
<action function="say" data="$1" method="pronounced" type="items"/>
</match>
</input>
</macro>
@ -331,9 +331,17 @@
</macro>
<macro name="voicemail_say_phone_number">
<input pattern="^000|^$|^[Aa]non|^[Pp]rivate" break_on_match="true">
<match>
<!-- add 'anonymous caller' sound here -->
</match>
</input>
<input pattern="^(.*)$">
<match>
<action function="say" data="$1" method="pronounced" type="name_spelled"/>
<action function="play-file" data="ivr/ivr-this_is_a_call_from.wav"/>
<action function="execute" data="sleep(100)"/>
<action function="say" data="$1" method="pronounced" type="name_spelled"/>
<action function="execute" data="sleep(500)"/>
</match>
</input>
</macro>

View File

@ -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 <errno.h>
#include <stdlib.h>
@ -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;
}

View File

@ -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);

View File

@ -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;

View File

@ -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;

View File

@ -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);

View File

@ -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")) {

View File

@ -28,8 +28,8 @@
*
*/
#include <switch.h>
#include <sys/signal.h>
#include <sys/time.h>
#include <time.h>
#include <signal.h>
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);

View File

@ -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);
}