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       

 
--- ./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", id, domain_name);
+       if (mwi_account == NULL) {
+               switch_event_add_header(event, SWITCH_STACK_BOTTOM, 
"MWI-Message-Account", "%...@%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\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]\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);
_______________________________________________
FreeSWITCH-dev mailing list
FreeSWITCH-dev@lists.freeswitch.org
http://lists.freeswitch.org/mailman/listinfo/freeswitch-dev
UNSUBSCRIBE:http://lists.freeswitch.org/mailman/options/freeswitch-dev
http://www.freeswitch.org

Reply via email to