[Freeswitch-dev] Openzap and CLIP
François Legal
devel at thom.fr.eu.org
Wed Feb 24 01:27:31 PST 2010
Oh, you're right. I always forget to attach files ;-)
François
On
Wed, 24 Feb 2010 04:13:38 -0500, Michael Jerris wrote: where?
On Feb
24, 2010, at 3:53 AM, François Legal wrote:
Hello,
Here comes the
patch.
The patch fixes the CID for France (and probably other european
countries except maybe england where a specific TAS has to be used), both
for incoming calls and call waiting cases.
If anybody can try this patch
with US hardware to verify the compatibility.
I added a new parameter in
openzap.conf (modem-type defaulting to FSK_BELL202) so that modulation can
be specified in config.
The patch also adds the MWI functionnality on FXS
ports (that meant to also patch mod_voicemail), by using the MWI-Account
parameter in directory set to something like "openzap/x/y".
Please
comment on this, if any modification need to be made.
François
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://lists.freeswitch.org/pipermail/freeswitch-dev/attachments/20100224/8d15a7dd/attachment-0001.html
-------------- next part --------------
--- ./libs/openzap/src/.svn/text-base/zap_io.c.svn-base 2010-02-11 11:03:16.000000000 +0100
+++ ./libs/openzap/src/zap_io.c 2010-02-23 17:02:28.371058955 +0100
@@ -645,12 +645,13 @@
}
if (zchan->token_count > 1) {
- zap_fsk_modulator_init(&fsk_trans, FSK_BELL202, zchan->rate, fsk_data, db_level, 80, 5, 0, zchan_fsk_write_sample, zchan);
+ /*zap_fsk_modulator_init(&fsk_trans, FSK_V23_FORWARD_MODE2, zchan->rate, fsk_data, db_level, 80, 5, 0, zchan_fsk_write_sample, zchan);*/
+ zap_fsk_modulator_init(&fsk_trans, zchan->span->modem_type, zchan->rate, fsk_data, db_level, 80, 5, 0, zchan_fsk_write_sample, zchan);
zap_fsk_modulator_send_all((&fsk_trans));
} else {
- zap_fsk_modulator_init(&fsk_trans, FSK_BELL202, zchan->rate, fsk_data, db_level, 180, 5, 300, zchan_fsk_write_sample, zchan);
+ /*zap_fsk_modulator_init(&fsk_trans, FSK_V23_FORWARD_MODE2, zchan->rate, fsk_data, db_level, 180, 5, 300, zchan_fsk_write_sample, zchan);*/
+ zap_fsk_modulator_init(&fsk_trans, zchan->span->modem_type, zchan->rate, fsk_data, db_level, 180, 5, 300, zchan_fsk_write_sample, zchan);
zap_fsk_modulator_send_all((&fsk_trans));
- zchan->buffer_delay = 3500 / zchan->effective_interval;
}
return ZAP_SUCCESS;
@@ -868,6 +869,7 @@
case ZAP_CHANNEL_STATE_PROGRESS:
case ZAP_CHANNEL_STATE_GET_CALLERID:
case ZAP_CHANNEL_STATE_GENRING:
+ case ZAP_CHANNEL_STATE_MWI:
ok = 1;
break;
default:
@@ -1582,6 +1584,16 @@
zap_mutex_unlock(zchan->pre_buffer_mutex);
}
break;
+
+ case ZAP_COMMAND_SET_MWI:
+ {
+ zchan->pre_buffer_size = ZAP_COMMAND_OBJ_INT;
+
+ status = zap_channel_set_state(zchan, ZAP_CHANNEL_STATE_MWI, 1);
+
+ GOTO_STATUS(done, status);
+ }
+ break;
default:
break;
}
@@ -1925,6 +1937,13 @@
}
}
+ if (zchan->fds[1] > -1) {
+ if ((write(zchan->fds[1], auxbuf, dlen)) != dlen) {
+ snprintf(zchan->last_error, sizeof(zchan->last_error), "file write error!");
+ return ZAP_FAIL;
+ }
+ }
+
return zchan->zio->write(zchan, auxbuf, &dlen);
}
@@ -2047,6 +2066,7 @@
if (zap_fsk_demod_feed(&zchan->fsk, sln, slen) != ZAP_SUCCESS) {
zap_size_t type, mlen;
char str[128], *sp;
+ char firstcaller[128] = { '*', '\0'};
while(zap_fsk_data_parse(&zchan->fsk, &type, &sp, &mlen) == ZAP_SUCCESS) {
*(str+mlen) = '\0';
@@ -2091,9 +2111,29 @@
zap_set_string(zchan->caller_data.cid_date, str);
}
break;
+ case MDMF_FIRST_PHONE_NUM:
+ {
+ if (mlen > sizeof(firstcaller) - 2) {
+ mlen = sizeof(firstcaller) - 2;
+ }
+ zap_set_string(&firstcaller[1], str);
+ }
+ break;
}
}
zap_channel_command(zchan, ZAP_COMMAND_DISABLE_CALLERID_DETECT, NULL);
+ if (! zap_strlen_zero(&firstcaller[1])) {
+ if ((strncmp("private", zchan->caller_data.ani.digits, sizeof ("private") - 1) == 0) ||
+ (strncmp("unknown", zchan->caller_data.ani.digits, sizeof ("unknown") - 1) == 0)) {
+ zap_set_string(zchan->caller_data.ani.digits, firstcaller);
+ zap_set_string(zchan->caller_data.cid_name, "FWD ");
+ zap_copy_string((char *) (zchan->caller_data.cid_name + 4), & firstcaller[1], strlen(& firstcaller[1]));
+ } else if ((strncmp("private", zchan->caller_data.cid_name, sizeof ("private") - 1) == 0) ||
+ (strncmp("unknown", zchan->caller_data.cid_name, sizeof ("unknown") - 1) == 0)) {
+ zap_set_string(zchan->caller_data.cid_name, "FWD ");
+ zap_copy_string((char *) (zchan->caller_data.cid_name + 4), & firstcaller[1], strlen(& firstcaller[1]));
+ }
+ }
}
}
@@ -2410,6 +2450,9 @@
continue;
}
+ /* Set default modem type for span */
+ span->modem_type = FSK_BELL202;
+
zap_log(ZAP_LOG_DEBUG, "span %d [%s]=[%s]\n", span->span_id, var, val);
if (!strcasecmp(var, "trunk_type")) {
@@ -2490,6 +2533,14 @@
} else if (!strcasecmp(var, "dtmf_hangup")) {
span->dtmf_hangup = strdup(val);
span->dtmf_hangup_len = strlen(val);
+ } else if (!strcasecmp(var, "modem-type")) {
+ if (!strcasecmp(val, "FSK_V23_FORWARD_MODE1")) {
+ span->modem_type = FSK_V23_FORWARD_MODE1;
+ } else if (!strcasecmp(val, "FSK_V23_FORWARD_MODE2")) {
+ span->modem_type = FSK_V23_FORWARD_MODE2;
+ } else if (!strcasecmp(val, "FSK_V23_BACKWARD")) {
+ span->modem_type = FSK_V23_BACKWARD;
+ }
} else {
zap_log(ZAP_LOG_ERROR, "unknown span variable '%s'\n", var);
}
--- ./libs/openzap/src/ozmod/ozmod_analog/.svn/text-base/ozmod_analog.c.svn-base 2010-02-11 11:03:15.000000000 +0100
+++ ./libs/openzap/src/ozmod/ozmod_analog/ozmod_analog.c 2010-02-24 09:27:29.079058352 +0100
@@ -256,6 +256,52 @@
}
/**
+ * \brief Sends message wainting indicator on an analog channel (FSK coded)
+ * \param zchan Channel to send caller id on
+ * \param state indicator value as follows : if bit 0x80 is set, light on indicator - bits 0x7F : amount of messages waiting
+ */
+static void send_mwi(zap_channel_t *zchan, int state)
+{
+ zap_fsk_data_state_t fsk_data;
+ uint8_t databuf[1024] = "";
+ char time_str[9];
+ struct tm tm;
+ time_t now;
+ char indicator;
+ char amount_messages;
+
+ time(&now);
+#ifdef WIN32
+ _tzset();
+ _localtime64_s(&tm, &now);
+#else
+ localtime_r(&now, &tm);
+#endif
+ strftime(time_str, sizeof(time_str), "%m%d%H%M", &tm);
+
+ zap_fsk_data_init(&fsk_data, databuf, sizeof(databuf));
+ zap_fsk_data_add_mdmf(&fsk_data, MDMF_DATETIME, (uint8_t *) time_str, 8);
+
+ if (state & 0x80) {
+ indicator = 0xFF;
+ amount_messages = state & 0x7F;
+ } else {
+ indicator = 0;
+ amount_messages = state;
+ }
+
+ zap_fsk_data_add_mdmf(&fsk_data, MDMF_MWI, (uint8_t *) & indicator, (uint8_t) sizeof (indicator));
+
+ zap_fsk_data_add_mdmf(&fsk_data, MDMF_AMOUNT_MESSAGES, (uint8_t *) & amount_messages, (uint8_t) sizeof (amount_messages));
+
+ fsk_data.buf[0] = ZAP_CID_TYPE_MWI;
+
+ zap_fsk_data_add_checksum(&fsk_data);
+
+ zap_channel_send_fsk_data(zchan, &fsk_data, -14);
+}
+
+/**
* \brief Main thread function for analog channel (outgoing call)
* \param me Current thread
* \param obj Channel to run in this thread
@@ -275,6 +321,7 @@
uint32_t state_counter = 0, elapsed = 0, collecting = 0, interval = 0, last_digit = 0, indicate = 0, dial_timeout = 30000;
zap_sigmsg_t sig;
zap_status_t status;
+ int time = 0;
zap_log(ZAP_LOG_DEBUG, "ANALOG CHANNEL thread starting.\n");
@@ -346,7 +393,15 @@
break;
case ZAP_CHANNEL_STATE_GENRING:
{
- if (state_counter > 60000) {
+ if (state_counter == 260) {
+ zap_channel_command(zchan, ZAP_COMMAND_GENERATE_RING_OFF, NULL);
+ } else if (state_counter == 900) {
+ send_caller_id(zchan);
+ } else if (state_counter > 900 && !zap_buffer_inuse(zchan->fsk_buffer) && time == 0) {
+ time = state_counter + 400;
+ } else if (state_counter == time) {
+ zap_channel_command(zchan, ZAP_COMMAND_GENERATE_RING_ON, NULL);
+ } else if (state_counter > 60000) {
zap_set_state_locked(zchan, ZAP_CHANNEL_STATE_DOWN);
} else if (!zchan->fsk_buffer || !zap_buffer_inuse(zchan->fsk_buffer)) {
zap_sleep(interval);
@@ -354,6 +409,18 @@
}
}
break;
+ case ZAP_CHANNEL_STATE_MWI:
+ {
+ if (state_counter == 400) {
+ zap_channel_command(zchan, ZAP_COMMAND_GENERATE_RING_OFF, NULL);
+ } else if (state_counter == 1100) {
+ send_mwi(zchan, zchan->pre_buffer_size);
+ } else if (state_counter > 1200 && !zap_buffer_inuse(zchan->fsk_buffer)) {
+ zap_set_state_locked(zchan, ZAP_CHANNEL_STATE_DOWN);
+ continue;
+ }
+ }
+ break;
case ZAP_CHANNEL_STATE_DIALTONE:
{
if (!zap_test_flag(zchan, ZAP_CHANNEL_HOLD) && state_counter > 10000) {
@@ -397,7 +464,15 @@
{
int done = 0;
- if (zchan->detected_tones[ZAP_TONEMAP_CALLWAITING_ACK] == 1) {
+ if (state_counter == 760) {
+ ts.user_data = zchan->fsk_buffer;
+ teletone_run(&ts, zchan->span->tone_map[ZAP_TONEMAP_CALLWAITING_CAS]);
+ ts.user_data = dt_buffer;
+ } else if (state_counter == 1100) {
+ send_caller_id(zchan);
+ } else
+
+ /*if (zchan->detected_tones[ZAP_TONEMAP_CALLWAITING_ACK] == 1) {
send_caller_id(zchan);
zchan->detected_tones[ZAP_TONEMAP_CALLWAITING_ACK]++;
} else if (state_counter > 600 && !zchan->detected_tones[ZAP_TONEMAP_CALLWAITING_ACK]) {
@@ -405,7 +480,8 @@
zchan->detected_tones[ZAP_TONEMAP_CALLWAITING_ACK]++;
} else if (state_counter > 1000 && !zchan->detected_tones[ZAP_TONEMAP_CALLWAITING_ACK]) {
done = 1;
- } else if (state_counter > 10000) {
+ } else*/ if (state_counter > 10000) {
+ /*
if (zchan->fsk_buffer) {
zap_buffer_zero(zchan->fsk_buffer);
} else {
@@ -414,7 +490,7 @@
ts.user_data = zchan->fsk_buffer;
teletone_run(&ts, zchan->span->tone_map[ZAP_TONEMAP_CALLWAITING_SAS]);
- ts.user_data = dt_buffer;
+ ts.user_data = dt_buffer;*/
done = 1;
}
@@ -533,7 +609,7 @@
ts.user_data = zchan->fsk_buffer;
teletone_run(&ts, zchan->span->tone_map[ZAP_TONEMAP_CALLWAITING_SAS]);
- teletone_run(&ts, zchan->span->tone_map[ZAP_TONEMAP_CALLWAITING_CAS]);
+ /*teletone_run(&ts, zchan->span->tone_map[ZAP_TONEMAP_CALLWAITING_CAS]);*/
ts.user_data = dt_buffer;
}
break;
@@ -541,8 +617,8 @@
{
zap_sigmsg_t sig;
- send_caller_id(zchan);
zap_channel_command(zchan, ZAP_COMMAND_GENERATE_RING_ON, NULL);
+ time = 0;
memset(&sig, 0, sizeof(sig));
sig.chan_id = zchan->chan_id;
@@ -553,6 +629,17 @@
}
break;
+ case ZAP_CHANNEL_STATE_MWI:
+ {
+ if (zchan->fsk_buffer) {
+ zap_buffer_zero(zchan->fsk_buffer);
+ } else {
+ zap_buffer_create(&zchan->fsk_buffer, 128, 128, 0);
+ }
+
+ zap_channel_command(zchan, ZAP_COMMAND_GENERATE_RING_ON, NULL);
+ }
+ break;
case ZAP_CHANNEL_STATE_GET_CALLERID:
{
memset(&zchan->caller_data, 0, sizeof(zchan->caller_data));
@@ -671,6 +758,8 @@
zap_log(ZAP_LOG_ERROR, "No Digits to send!\n");
zap_set_state_locked(zchan, ZAP_CHANNEL_STATE_BUSY);
} else {
+ /* I seem to have some trouble when dialing as soon as dialtone is detected */
+ usleep (400000);
if (zap_channel_command(zchan, ZAP_COMMAND_SEND_DTMF, zchan->caller_data.ani.digits) != ZAP_SUCCESS) {
zap_log(ZAP_LOG_ERROR, "Send Digits Failed [%s]\n", zchan->last_error);
zap_set_state_locked(zchan, ZAP_CHANNEL_STATE_BUSY);
--- ./libs/openzap/src/include/.svn/text-base/openzap.h.svn-base 2010-02-11 11:03:16.000000000 +0100
+++ ./libs/openzap/src/include/openzap.h 2010-02-23 17:00:23.540058087 +0100
@@ -585,6 +585,7 @@
int suggest_chan_id;
zap_state_map_t *state_map;
struct zap_span *next;
+ fsk_modem_types_t modem_type;
};
@@ -636,6 +637,7 @@
OZ_DECLARE(int) zap_fsk_demod_init(zap_fsk_data_state_t *state, int rate, uint8_t *buf, size_t bufsize);
OZ_DECLARE(zap_status_t) zap_fsk_data_init(zap_fsk_data_state_t *state, uint8_t *data, uint32_t datalen);
OZ_DECLARE(zap_status_t) zap_fsk_data_add_mdmf(zap_fsk_data_state_t *state, zap_mdmf_type_t type, const uint8_t *data, uint32_t datalen);
+OZ_DECLARE(zap_status_t) zap_fsk_data_add_mwi(zap_fsk_data_state_t *state, zap_mdmf_type_t type, const uint8_t *data, uint32_t datalen);
OZ_DECLARE(zap_status_t) zap_fsk_data_add_checksum(zap_fsk_data_state_t *state);
OZ_DECLARE(zap_status_t) zap_fsk_data_add_sdmf(zap_fsk_data_state_t *state, const char *date, char *number);
OZ_DECLARE(zap_status_t) zap_channel_outgoing_call(zap_channel_t *zchan);
--- ./src/include/.svn/text-base/zap_types.h.svn-base 2010-02-11 11:03:16.000000000 +0100
+++ ./src/include/zap_types.h 2010-02-17 14:34:58.427058956 +0100
@@ -81,7 +81,8 @@
typedef enum {
ZAP_CID_TYPE_SDMF = 0x04,
- ZAP_CID_TYPE_MDMF = 0x80
+ ZAP_CID_TYPE_MDMF = 0x80,
+ ZAP_CID_TYPE_MWI = 0x82
} zap_cid_type_t;
typedef enum {
@@ -92,9 +93,16 @@
MDMF_PHONE_NAME = 7,
MDMF_NO_NAME = 8,
MDMF_ALT_ROUTE = 9,
- MDMF_INVALID = 10
+ MDMF_MWI = 11,
+ MDMF_MESSAGE_ID = 13,
+ MDMF_LAST_VM_FROM = 14,
+ MDMF_CALL_TYPE = 17,
+ MDMF_FIRST_PHONE_NUM = 18,
+ MDMF_AMOUNT_MESSAGES = 19,
+ MDMF_FWD_TYPE = 21,
+ MDMF_INVALID = 22
} zap_mdmf_type_t;
-#define MDMF_STRINGS "X", "DATETIME", "PHONE_NUM", "DDN", "NO_NUM", "X", "X", "PHONE_NAME", "NO_NAME", "ALT_ROUTE", "INVALID"
+#define MDMF_STRINGS "X", "DATETIME", "PHONE_NUM", "DDN", "NO_NUM", "X", "X", "PHONE_NAME", "NO_NAME", "ALT_ROUTE", "X", "MWI", "X", "MESSAGE_ID", "LAST_VM_FROM", "X", "X", "CALL_TYPE", "FIRST_PHONE_NUM", "AMOUNT_OF_MESSAGES", "X", "FWD_TYPE", "INVALID"
ZAP_STR2ENUM_P(zap_str2zap_mdmf_type, zap_mdmf_type2str, zap_mdmf_type_t)
#define ZAP_TONEMAP_LEN 128
@@ -284,7 +292,8 @@
ZAP_COMMAND_FLUSH_RX_BUFFERS,
ZAP_COMMAND_FLUSH_BUFFERS,
ZAP_COMMAND_SET_PRE_BUFFER_SIZE,
- ZAP_COMMAND_COUNT
+ ZAP_COMMAND_COUNT,
+ ZAP_COMMAND_SET_MWI
} zap_command_t;
typedef enum {
@@ -316,7 +325,8 @@
ZAP_CHANNEL_FEATURE_CODECS = (1 << 2),
ZAP_CHANNEL_FEATURE_INTERVAL = (1 << 3),
ZAP_CHANNEL_FEATURE_CALLERID = (1 << 4),
- ZAP_CHANNEL_FEATURE_PROGRESS = (1 << 5)
+ ZAP_CHANNEL_FEATURE_PROGRESS = (1 << 5),
+ ZAP_CHANNEL_FEATURE_FAX_DETECT = (1 << 6)
} zap_channel_feature_t;
typedef enum {
@@ -341,11 +351,12 @@
ZAP_CHANNEL_STATE_CANCEL,
ZAP_CHANNEL_STATE_HANGUP,
ZAP_CHANNEL_STATE_HANGUP_COMPLETE,
+ ZAP_CHANNEL_STATE_MWI,
ZAP_CHANNEL_STATE_INVALID
} zap_channel_state_t;
#define CHANNEL_STATE_STRINGS "DOWN", "HOLD", "SUSPENDED", "DIALTONE", "COLLECT", \
"RING", "BUSY", "ATTN", "GENRING", "DIALING", "GET_CALLERID", "CALLWAITING", \
- "RESTART", "PROGRESS", "PROGRESS_MEDIA", "UP", "IDLE", "TERMINATING", "CANCEL", "HANGUP", "HANGUP_COMPLETE", "INVALID"
+ "RESTART", "PROGRESS", "PROGRESS_MEDIA", "UP", "IDLE", "TERMINATING", "CANCEL", "HANGUP", "HANGUP_COMPLETE", "MWI", "INVALID"
ZAP_STR2ENUM_P(zap_str2zap_channel_state, zap_channel_state2str, zap_channel_state_t)
typedef enum {
--- ./libs/openzap/mod_openzap/.svn/text-base/mod_openzap.c.svn-base 2010-02-11 11:03:16.000000000 +0100
+++ ./libs/openzap/mod_openzap/mod_openzap.c 2010-02-23 19:02:31.071059153 +0100
@@ -1901,6 +1901,95 @@
}
+static switch_status_t zap_send_mwi (int span_no, int chan_no, int messages)
+{
+ zap_span_t *span;
+ zap_channel_t *chan = NULL;
+
+ if ((span = SPAN_CONFIG[span_no].span) == NULL) {
+ zap_log(ZAP_LOG_ERROR, "invalid span %d\n", span_no);
+ return (ZAP_FAIL);
+ }
+
+ if (chan_no > span->chan_count || span->channels[chan_no] == NULL) {
+ zap_log(ZAP_LOG_ERROR, "invalid channel %d:%d\n", span_no, chan_no);
+ return (ZAP_FAIL);
+ }
+
+ while (span->channels[chan_no]->state != ZAP_CHANNEL_STATE_DOWN) {
+ sleep (2);
+ }
+
+ sleep (2);
+
+ zap_channel_open(span_no, chan_no, &chan);
+ zap_channel_outgoing_call(chan);
+ zap_channel_command(chan, ZAP_COMMAND_SET_MWI, &messages);
+ zap_channel_init(chan);
+
+ return (ZAP_SUCCESS);
+}
+
+static void mod_openzap_mwi_handler(switch_event_t *event)
+{
+ char *account, *amount;
+ char *seek_ptr, *end_ptr;
+ int span_no = 0;
+ int chan_no = 0;
+ int amount_new = 0;
+ int amount_saved = 0;
+
+ switch_assert(event);
+
+ if (event->event_id == SWITCH_EVENT_MESSAGE_WAITING) {
+
+ if (!(account = switch_event_get_header(event, "mwi-message-account"))) {
+ zap_log(ZAP_LOG_ERROR, "Missing required Header 'MWI-Message-Account'\n");
+ return;
+ }
+
+ if (strncmp ("openzap/", account, sizeof("openzap/") - 1)) {
+ zap_log(ZAP_LOG_DEBUG, "The MWI-Account is not for openzap notification : %s\n", account);
+ return;
+ }
+
+ if ((seek_ptr = strchr(account, '/')) == NULL) {
+ span_no = chan_no = 0;
+ } else if ((end_ptr = strchr (++seek_ptr, '/')) == NULL) {
+ span_no = atoi(seek_ptr);
+ chan_no = 0;
+ } else {
+ span_no = atoi(seek_ptr);
+ chan_no = atoi(++end_ptr);
+ }
+
+ if (!(amount = switch_event_get_header(event, "mwi-voice-message"))) {
+ zap_log(ZAP_LOG_ERROR, "Missing required Header 'mwi-voice-message'\n");
+ return;
+ }
+
+ if ((seek_ptr = strchr(amount, '/')) == NULL) {
+ amount_new = atoi(amount);
+ } else {
+ amount_new = atoi(amount);
+ amount_saved = atoi(++seek_ptr);
+ }
+
+ if (amount_new > 0) {
+ amount_new |= 0x80;
+ } else {
+ amount_new += amount_saved;
+ }
+
+ zap_log(ZAP_LOG_DEBUG, "Sending MWI on [%d:%d] : 0x%X\n", span_no, chan_no, amount_new);
+ zap_send_mwi(span_no, chan_no, amount_new);
+
+ } else {
+ zap_log(ZAP_LOG_ERROR, "Unexpected event %d for this handler\n", event->event_id);
+ }
+
+}
+
static uint32_t enable_analog_option(const char *str, uint32_t current_options)
{
if (!strcasecmp(str, "3-way")) {
@@ -2720,7 +2809,8 @@
);
}
-#define OZ_SYNTAX "list || dump <span_id> [<chan_id>] || q931_pcap <span_id> on|off [pcapfilename without suffix]"
+#define OZ_SYNTAX "list || dump <span_id> [<chan_id>] || q931_pcap <span_id> on|off [pcapfilename without suffix]" \
+ " || trace <span_id> <chan_id> in|out [filename] || mwi <span_id> <chan_id> <mwi data>"
SWITCH_STANDARD_API(oz_function)
{
char *mycmd = NULL, *argv[10] = { 0 };
@@ -2909,6 +2999,79 @@
goto end;
}
+ } else if (!strcasecmp(argv[0], "trace")) {
+ int32_t span_id = 0;
+ int32_t chan_id = 0;
+ zap_span_t *span;
+ zap_channel_t *chan;
+ const char *pcapfn = NULL;
+ char *tmp_path = NULL;
+ zap_command_t command;
+
+ if (argc < 3) {
+ stream->write_function(stream, "-ERR Usage: oz trace <span_id> <chan_id> in|out <filename>\n");
+ goto end;
+ }
+ span_id = atoi(argv[1]);
+ if (!(span_id && (span = SPAN_CONFIG[span_id].span))) {
+ stream->write_function(stream, "-ERR invalid span\n");
+ goto end;
+ }
+
+ chan_id = atoi(argv[2]);
+ if (!(chan_id && (chan = span->channels[chan_id]))) {
+ stream->write_function(stream, "-ERR invalid channel\n");
+ goto end;
+ }
+
+ if (strcasecmp(argv[3], "in")) {
+ command = ZAP_COMMAND_TRACE_INPUT;
+ } else {
+ if (strcasecmp(argv[3], "out")) {
+ command = ZAP_COMMAND_TRACE_OUTPUT;
+ } else {
+ stream->write_function(stream, "-ERR invalid recording direction\n");
+ goto end;
+ }
+ }
+
+ /*Look for a given file name or use default file name*/
+ if (argc > 4) {
+ if(argv[4]){
+ pcapfn=argv[4];
+ }
+ }
+ else {
+ tmp_path=switch_mprintf("%s%szap-%1d-%1d-%s.dmp", SWITCH_GLOBAL_dirs.log_dir, SWITCH_PATH_SEPARATOR, span_id, chan_id, argv[3]);
+ }
+ if (zap_channel_command(chan, command, tmp_path) != ZAP_SUCCESS) {
+ zap_log(ZAP_LOG_ERROR, "Error couldn't enable trace!\n");
+ goto end;
+ } else {
+ stream->write_function(stream, "+OK\n");
+ }
+
+ } else if (!strcasecmp(argv[0], "mwi")) {
+ int32_t span_id = 0;
+ int32_t chan_id = 0;
+ int32_t indicator = 0;
+
+ if (argc < 4) {
+ stream->write_function(stream, "-ERR Usage: oz mwi <span_id> <chan_id> <0|1>\n");
+ goto end;
+ }
+ span_id = atoi(argv[1]);
+ chan_id = atoi(argv[2]);
+ indicator = atoi(argv[3]);
+
+ zap_log(ZAP_LOG_DEBUG, "Sending MWI on [%d:%d] : 0x%X\n", span_id, chan_id, indicator);
+
+ if (zap_send_mwi(span_id, chan_id, indicator) == ZAP_SUCCESS) {
+ stream->write_function(stream, "+OK\n");
+ } else {
+ stream->write_function(stream, "-ERR\n");
+ }
+
} else {
char *rply = zap_api_execute(cmd, NULL);
@@ -2978,6 +3141,10 @@
openzap_endpoint_interface->io_routines = &openzap_io_routines;
openzap_endpoint_interface->state_handler = &openzap_state_handlers;
+ if (switch_event_bind(openzap_endpoint_interface->interface_name, SWITCH_EVENT_MESSAGE_WAITING, SWITCH_EVENT_SUBCLASS_ANY, mod_openzap_mwi_handler, NULL) != SWITCH_STATUS_SUCCESS) {
+ zap_log(ZAP_LOG_ERROR, "Error binding MWI to OpenZAP\n");
+ }
+
SWITCH_ADD_API(commands_api_interface, "oz", "OpenZAP commands", oz_function, OZ_SYNTAX);
SWITCH_ADD_APP(app_interface, "disable_ec", "Disable Echo Canceller", "Disable Echo Canceller", disable_ec_function, "", SAF_NONE);
@@ -2988,6 +3155,8 @@
SWITCH_MODULE_SHUTDOWN_FUNCTION(mod_openzap_shutdown)
{
+ switch_event_unbind_callback(mod_openzap_mwi_handler);
+
zap_global_destroy();
// this breaks pika but they are MIA so *shrug*
--- .src/mod/applications/mod_voicemail/.svn/text-base/mod_voicemail.c.svn-base 2010-02-11 11:00:12.000000000 +0100
+++ .src/mod/applications/mod_voicemail/mod_voicemail.c 2010-02-19 09:49:06.344058424 +0100
@@ -1653,7 +1661,7 @@
}
-static void update_mwi(vm_profile_t *profile, const char *id, const char *domain_name, const char *myfolder)
+static void update_mwi(vm_profile_t *profile, const char *id, const char *domain_name, const char *myfolder, const char *mwi_account)
{
const char *yn = "no";
int total_new_messages = 0;
@@ -1673,13 +1681,16 @@
yn = "yes";
}
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "MWI-Messages-Waiting", yn);
- switch_event_add_header(event, SWITCH_STACK_BOTTOM, "MWI-Message-Account", "%s@%s", id, domain_name);
+ if (mwi_account == NULL) {
+ switch_event_add_header(event, SWITCH_STACK_BOTTOM, "MWI-Message-Account", "%s@%s", id, domain_name);
+ } else {
+ switch_event_add_header(event, SWITCH_STACK_BOTTOM, "MWI-Message-Account", "%s", mwi_account);
+ }
switch_event_add_header(event, SWITCH_STACK_BOTTOM, "MWI-Voice-Message", "%d/%d (%d/%d)", total_new_messages, total_saved_messages,
total_new_urgent_messages, total_saved_urgent_messages);
switch_event_fire(&event);
}
-
#define FREE_DOMAIN_ROOT() if (x_domain_root) switch_xml_free(x_domain_root); x_user = x_domain = x_domain_root = NULL
@@ -1703,6 +1714,7 @@
int total_saved_urgent_messages = 0;
int heard_auto_saved = 0, heard_auto_new = 0;
char *vm_email = NULL, *email_addr = NULL;
+ char *mwi_account = NULL;
char *convert_cmd = profile->convert_cmd;
char *convert_ext = profile->convert_ext;
char *vm_storage_dir = NULL;
@@ -1872,7 +1884,7 @@
vm_execute_sql(profile, sql, profile->mutex);
vm_check_state = VM_CHECK_FOLDER_SUMMARY;
- update_mwi(profile, myid, domain_name, myfolder);
+ update_mwi(profile, myid, domain_name, myfolder, mwi_account);
}
break;
case VM_CHECK_CONFIG:
@@ -2145,6 +2157,8 @@
} else if (!strcasecmp(var, "timezone")) {
switch_channel_set_variable(channel, var, val);
+ } else if (!strcasecmp(var, "MWI-Account")) {
+ mwi_account = switch_core_session_strdup(session, val);
}
}
@@ -2279,6 +2293,7 @@
char *vm_notify_email = NULL;
char *email_addr = NULL;
char *vm_timezone = NULL;
+ char *mwi_account = NULL;
int send_mail = 0;
int send_main = 0;
int send_notify = 0;
@@ -2351,10 +2366,12 @@
convert_ext = switch_core_strdup(pool, val);
} else if (!strcasecmp(var, "timezone")) {
vm_timezone = switch_core_strdup(pool, val);
+ } else if (!strcasecmp(var, "MWI-Account")) {
+ mwi_account = switch_core_strdup(pool, val);
}
/*switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Send mail is %d, var is %s\n", send_mail, var); */
}
-
+
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Deliver VM to %s@%s\n", myid, domain_name);
if (!zstr(vm_storage_dir)) {
@@ -2415,7 +2432,7 @@
vm_execute_sql(profile, usql, profile->mutex);
switch_safe_free(usql);
- update_mwi(profile, myid, domain_name, myfolder);
+ update_mwi(profile, myid, domain_name, myfolder, mwi_account);
}
if (send_mail && !zstr(vm_email) && switch_file_exists(file_path, pool) == SWITCH_STATUS_SUCCESS) {
@@ -3569,6 +3586,8 @@
char *sql;
struct holder holder;
char *ref = NULL;
+ char *mwi_account = NULL;
+ switch_xml_t x_domain = NULL, x_domain_root = NULL, x_user = NULL, x_params, x_param;
if (stream->param_event) {
ref = switch_event_get_header(stream->param_event, "http-referer");
@@ -3586,7 +3605,22 @@
vm_execute_sql(profile, sql, profile->mutex);
free(sql);
- update_mwi(profile, user, domain, myfolder);
+ if (switch_xml_locate_user("id", user, domain, NULL, &x_domain_root, &x_domain, &x_user, NULL, NULL) != SWITCH_STATUS_SUCCESS) {
+ stream->write_function(stream, "Can't find user [%s@%s]\n", user, domain);
+ } else {
+ if ((x_params = switch_xml_child(x_user, "params"))) {
+ for (x_param = switch_xml_child(x_params, "param"); x_param; x_param = x_param->next) {
+ const char *var = switch_xml_attr_soft(x_param, "name");
+ const char *val = switch_xml_attr_soft(x_param, "value");
+
+ if (!strcasecmp(var, "MWI-Account")) {
+ mwi_account = switch_core_strdup(profile->pool, val);
+ }
+ }
+ }
+ }
+
+ update_mwi(profile, user, domain, myfolder, mwi_account);
if (ref) {
stream->write_function(stream, "Content-type: text/html\n\n<h2>Message Deleted</h2>\n" "<META http-equiv=\"refresh\" content=\"1;URL=%s\">", ref);
More information about the FreeSWITCH-dev
mailing list