]> git.ipfire.org Git - thirdparty/freeswitch.git/commitdiff
wanpipe commit we've all been waiting for, HW dtmf, ALARMS, proper bounce of PRIs...
authorAnthony Minessale <anthony.minessale@gmail.com>
Wed, 22 Apr 2009 21:22:42 +0000 (21:22 +0000)
committerAnthony Minessale <anthony.minessale@gmail.com>
Wed, 22 Apr 2009 21:22:42 +0000 (21:22 +0000)
git-svn-id: http://svn.openzap.org/svn/openzap/trunk@719 a93c3328-9c30-0410-af19-c9cd2b2d52af

libs/openzap/Makefile.am
libs/openzap/configure.ac
libs/openzap/mod_openzap/mod_openzap.c
libs/openzap/src/ozmod/ozmod_libpri/lpwrap_pri.c
libs/openzap/src/ozmod/ozmod_libpri/ozmod_libpri.c
libs/openzap/src/ozmod/ozmod_ss7_boost/ozmod_ss7_boost.c
libs/openzap/src/ozmod/ozmod_ss7_boost/sigboost.h
libs/openzap/src/ozmod/ozmod_ss7_boost/ss7_boost_client.c
libs/openzap/src/ozmod/ozmod_wanpipe/ozmod_wanpipe.c
libs/openzap/src/ozmod/ozmod_zt/ozmod_zt.c

index 3afec009d7b95b54c892087e987674f85c479c63..a7930917d4a7ffe12fe16e687c1fdb6a1ebe87f1 100644 (file)
@@ -154,10 +154,12 @@ ozmod_skel_la_CFLAGS  = $(AM_CFLAGS) $(MY_CFLAGS)
 ozmod_skel_la_LDFLAGS = -module -avoid-version
 ozmod_skel_la_LIBADD  = $(MYLIB)
 
+if LIBSANGOMA
 ozmod_wanpipe_la_SOURCES = $(SRC)/ozmod/ozmod_wanpipe/ozmod_wanpipe.c
-ozmod_wanpipe_la_CFLAGS  = $(AM_CFLAGS) $(MY_CFLAGS)
-ozmod_wanpipe_la_LDFLAGS = -module -avoid-version
+ozmod_wanpipe_la_CFLAGS  = $(AM_CFLAGS) $(MY_CFLAGS) -D__LINUX__ -I/usr/include/wanpipe
+ozmod_wanpipe_la_LDFLAGS = -module -avoid-version -lsangoma
 ozmod_wanpipe_la_LIBADD  = $(MYLIB)
+endif
 
 ozmod_isdn_la_SOURCES = \
 $(SRC)/isdn/EuroISDNStateNT.c \
index c16ce2b386d3e5916204f67056f97b1075500935..f7a0576809e32a92e985a23b9c2d999b100ab8fe 100644 (file)
@@ -155,6 +155,9 @@ AC_ARG_WITH([libpri],
  [AS_HELP_STRING([--with-libpri], [Install ozmod_libpri])], [enable_libpri="yes"], [enable_libpri="no"])
 AC_SUBST(enable_libpri)
 
+AC_CHECK_LIB([sangoma], [sangoma_span_chan_toif], [have_libsangoma="yes"])
+AM_CONDITIONAL([LIBSANGOMA],[test "${have_libsangoma}" = "yes"])
+
 AM_CONDITIONAL([LIBPRI],[test "${enable_libpri}" = "yes"])
 
 COMP_VENDOR_CFLAGS="$COMP_VENDOR_CFLAGS"
index 74339be232b386fe4c8ef201701d8517fb461697..feca83dc8bbc2c6db8b8ea5dea45f49b77d2d6da 100644 (file)
@@ -475,7 +475,7 @@ static switch_status_t channel_on_hangup(switch_core_session_t *session)
                break;
        default: 
                {
-                       switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Unhandled type for channel %s\n", switch_channel_get_name(channel));
+                       switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Unhandled type for channel %s\n", switch_channel_get_name(channel));
                }
                break;
        }
index 8efdafeca8c5de96154d12c2f04c2fee0cc7a97c..60e6f51d8853105c8f89fa87c771e3cb0bfb14c2 100644 (file)
@@ -115,9 +115,14 @@ static int __pri_lpwrap_read(struct pri *pri, void *buf, int buflen)
        struct lpwrap_pri *spri = (struct lpwrap_pri *) pri_get_userdata(pri);
        zap_size_t len = buflen;
        int res;
+       zap_status_t zst;
 
-       if (zap_channel_read(spri->dchan, buf, &len) != ZAP_SUCCESS) {
-               zap_log(ZAP_LOG_CRIT, "span %d D-READ FAIL! [%s]\n", spri->span->span_id, spri->dchan->last_error);
+       if ((zst = zap_channel_read(spri->dchan, buf, &len)) != ZAP_SUCCESS) {
+               if (zst == ZAP_FAIL) {
+                       zap_log(ZAP_LOG_CRIT, "span %d D-READ FAIL! [%s]\n", spri->span->span_id, spri->dchan->last_error);
+               } else {
+                       zap_log(ZAP_LOG_CRIT, "span %d D-READ TIMEOUT\n", spri->span->span_id);
+               }
                zap_clear_flag(spri, LPWRAP_PRI_READY);
                return -1;
        }
@@ -145,7 +150,7 @@ static int __pri_lpwrap_write(struct pri *pri, void *buf, int buflen)
        if (zap_channel_write(spri->dchan, buf, buflen, &len) != ZAP_SUCCESS) {
                zap_log(ZAP_LOG_CRIT, "span %d D-WRITE FAIL! [%s]\n", spri->span->span_id, spri->dchan->last_error);
                zap_clear_flag(spri, LPWRAP_PRI_READY);
-               return -1;
+               return -1;
        }
 
 #ifdef IODEBUG
@@ -198,9 +203,9 @@ int lpwrap_one_loop(struct lpwrap_pri *spri)
                }
        }
 
-       if (!zap_test_flag(spri, LPWRAP_PRI_READY)) {
-               return -1;
-       }
+       //if (!zap_test_flag(spri, LPWRAP_PRI_READY)) {
+       //return -1;
+       //}
 
        FD_ZERO(&rfds);
        FD_ZERO(&efds);
@@ -246,9 +251,9 @@ int lpwrap_one_loop(struct lpwrap_pri *spri)
                }
        }
 
-       if (zap_test_flag(spri, LPWRAP_PRI_READY)) {
-               return sel;
-       }
+
+       return sel;
+
 
        if ((handler = spri->eventmap[LPWRAP_PRI_EVENT_IO_FAIL] ? spri->eventmap[LPWRAP_PRI_EVENT_IO_FAIL] : spri->eventmap[0] ? spri->eventmap[0] : NULL)) {
                handler(spri, LPWRAP_PRI_EVENT_IO_FAIL, NULL);
index 101a09ca85190ffd808c58a375760caaf842d0ec..7053d3177de65311fb216d548e055b41254c9e12 100644 (file)
@@ -691,16 +691,103 @@ static int on_ring(lpwrap_pri_t *spri, lpwrap_pri_event_t event_type, pri_event
        return ret;
 }
 
+
+static __inline__ zap_status_t process_event(zap_span_t *span, zap_event_t *event)
+{
+       zap_sigmsg_t sig;
+       zap_libpri_data_t *isdn_data = span->signal_data;
+
+       memset(&sig, 0, sizeof(sig));
+       sig.chan_id = event->channel->chan_id;
+       sig.span_id = event->channel->span_id;
+       sig.channel = event->channel;
+
+       zap_log(ZAP_LOG_DEBUG, "EVENT [%s][%d][%d:%d] STATE [%s]\n", 
+                       zap_oob_event2str(event->enum_id), event->enum_id, event->channel->span_id, event->channel->chan_id, zap_channel_state2str(event->channel->state));
+
+       switch(event->enum_id) {
+       case ZAP_OOB_ALARM_TRAP:
+               {
+                       sig.event_id = ZAP_OOB_ALARM_TRAP;
+                       if (event->channel->state != ZAP_CHANNEL_STATE_DOWN) {
+                               if (event->channel->type == ZAP_CHAN_TYPE_B) {
+                                       zap_set_state_locked(event->channel, ZAP_CHANNEL_STATE_RESTART);
+                               }
+                       }
+                       
+
+                       zap_set_flag(event->channel, ZAP_CHANNEL_SUSPENDED);
+
+                       
+                       zap_channel_get_alarms(event->channel);
+                       isdn_data->sig_cb(&sig);
+                       zap_log(ZAP_LOG_WARNING, "channel %d:%d (%d:%d) has alarms! [%s]\n", 
+                                       event->channel->span_id, event->channel->chan_id, 
+                                       event->channel->physical_span_id, event->channel->physical_chan_id, 
+                                       event->channel->last_error);
+               }
+               break;
+       case ZAP_OOB_ALARM_CLEAR:
+               {
+                       
+                       zap_log(ZAP_LOG_WARNING, "channel %d:%d (%d:%d) alarms Cleared!\n", event->channel->span_id, event->channel->chan_id,
+                                       event->channel->physical_span_id, event->channel->physical_chan_id);
+
+                       sig.event_id = ZAP_OOB_ALARM_CLEAR;
+                       zap_clear_flag(event->channel, ZAP_CHANNEL_SUSPENDED);
+                       zap_channel_get_alarms(event->channel);
+                       isdn_data->sig_cb(&sig);
+               }
+               break;
+       }
+
+       return ZAP_SUCCESS;
+}
+
+
+
+static __inline__ void check_events(zap_span_t *span)
+{
+       zap_status_t status;
+
+       status = zap_span_poll_event(span, 5);
+
+       switch(status) {
+       case ZAP_SUCCESS:
+               {
+                       zap_event_t *event;
+                       while (zap_span_next_event(span, &event) == ZAP_SUCCESS) {
+                               if (event->enum_id == ZAP_OOB_NOOP) {
+                                       continue;
+                               }
+                               if (process_event(span, event) != ZAP_SUCCESS) {
+                                       break;
+                               }
+                       }
+               }
+               break;
+       case ZAP_FAIL:
+               {
+                       zap_log(ZAP_LOG_DEBUG, "Event Failure! %d\n", zap_running());
+               }
+               break;
+       default:
+               break;
+       }
+}
+
 static int check_flags(lpwrap_pri_t *spri)
 {
        zap_span_t *span = spri->private_info;
 
-       check_state(span);
-
        if (!zap_running() || zap_test_flag(span, ZAP_SPAN_STOP_THREAD)) {
                return -1;
        }
 
+       check_state(span);
+       check_events(span);
+
+
        return 0;
 }
 
@@ -769,27 +856,29 @@ static void *zap_libpri_run(zap_thread_t *me, void *obj)
 {
        zap_span_t *span = (zap_span_t *) obj;
        zap_libpri_data_t *isdn_data = span->signal_data;
-       int x, i;
+       int i, x = 0;
        int down = 0;
+       int got_d = 0;
        
        zap_set_flag(span, ZAP_SPAN_IN_THREAD);
        
        while(zap_running() && !zap_test_flag(span, ZAP_SPAN_STOP_THREAD)) {
-               x = 0;
-
-               for(i = 1; i <= span->chan_count; i++) {
-                       if (span->channels[i]->type == ZAP_CHAN_TYPE_DQ921) {
-                               if (zap_channel_open(span->span_id, i, &isdn_data->dchan) == ZAP_SUCCESS) {
-                                       zap_log(ZAP_LOG_DEBUG, "opening d-channel #%d %d:%d\n", x, isdn_data->dchan->span_id, isdn_data->dchan->chan_id);
-                                       isdn_data->dchan->state = ZAP_CHANNEL_STATE_UP;
-                                       x++;
-                                       break;
+               if (!got_d) {
+                       for(i = 1; i <= span->chan_count; i++) {
+                               if (span->channels[i]->type == ZAP_CHAN_TYPE_DQ921) {
+                                       if (zap_channel_open(span->span_id, i, &isdn_data->dchan) == ZAP_SUCCESS) {
+                                               zap_log(ZAP_LOG_DEBUG, "opening d-channel #%d %d:%d\n", x, isdn_data->dchan->span_id, isdn_data->dchan->chan_id);
+                                               isdn_data->dchan->state = ZAP_CHANNEL_STATE_UP;
+                                               got_d = 1;
+                                               x++;
+                                               break;
+                                       }
                                }
                        }
                }
-
                
-               if (!x || lpwrap_init_pri(&isdn_data->spri,
+               
+               if (lpwrap_init_pri(&isdn_data->spri,
                                                                  span,  // span
                                                                  isdn_data->dchan, // dchan
                                                                  isdn_data->pswitch,
@@ -820,9 +909,8 @@ static void *zap_libpri_run(zap_thread_t *me, void *obj)
 
                        isdn_data->spri.on_loop = check_flags;
                        isdn_data->spri.private_info = span;
-                       
                        lpwrap_run_pri(&isdn_data->spri);
-                       zap_channel_close(&isdn_data->dchan);
+                       
                }
                
                if (!zap_running() || zap_test_flag(span, ZAP_SPAN_STOP_THREAD)) {
@@ -830,9 +918,15 @@ static void *zap_libpri_run(zap_thread_t *me, void *obj)
                }
 
                zap_log(ZAP_LOG_CRIT, "PRI down on span %d\n", isdn_data->spri.span->span_id);
-               zap_set_state_all(span, ZAP_CHANNEL_STATE_RESTART);
-               check_state(span);
+
+               if (!down) {
+                       zap_set_state_all(span, ZAP_CHANNEL_STATE_RESTART);
+                       check_state(span);
+               }
+
                check_state(span);
+               check_events(span);
+
                down++;
                zap_sleep(5000);
        }
index 656b09a9a5d52c91ba7564a0dbffc69a1f7ee852..f5daec4afce7265f90881aec51fb332c06d10680 100644 (file)
@@ -215,7 +215,11 @@ static ZIO_CHANNEL_REQUEST_FUNCTION(ss7_boost_channel_request)
 
        ss7bc_call_init(&event, caller_data->cid_num.digits, caller_data->ani.digits, r);
        zap_set_string(event.calling_name, caller_data->cid_name);
-       zap_set_string(event.redirection_string, caller_data->rdnis.digits);
+       zap_set_string(event.isup_in_rdnis, caller_data->rdnis.digits);
+    if (strlen(caller_data->rdnis.digits)) {
+        event.isup_in_rdnis_size = strlen(caller_data->rdnis.digits)+1;
+    }
+    
        event.calling_number_screening_ind = caller_data->screen;
        event.calling_number_presentation = caller_data->pres;
 
@@ -483,7 +487,7 @@ static void handle_call_start(zap_span_t *span, ss7bc_connection_t *mcon, ss7bc_
        }
        zap_set_string(zchan->caller_data.ani.digits, (char *)event->calling_number_digits);
        zap_set_string(zchan->caller_data.dnis.digits, (char *)event->called_number_digits);
-       zap_set_string(zchan->caller_data.rdnis.digits, (char *)event->redirection_string);
+       zap_set_string(zchan->caller_data.rdnis.digits, (char *)event->isup_in_rdnis);
        zchan->caller_data.screen = event->calling_number_screening_ind;
        zchan->caller_data.pres = event->calling_number_presentation;
        zap_set_state_locked(zchan, ZAP_CHANNEL_STATE_RING);
@@ -851,7 +855,7 @@ static void *zap_ss7_boost_run(zap_thread_t *me, void *obj)
     zap_span_t *span = (zap_span_t *) obj;
     zap_ss7_boost_data_t *ss7_boost_data = span->signal_data;
        ss7bc_connection_t *mcon, *pcon;
-       uint32_t ms = 10, too_long = 20000;
+       uint32_t ms = 10; //, too_long = 20000;
                
 
        ss7_boost_data->pcon = ss7_boost_data->mcon;
@@ -942,6 +946,8 @@ static void *zap_ss7_boost_run(zap_thread_t *me, void *obj)
                        pcon->hb_elapsed = 0;
                }
 
+
+#if 0
                if (pcon->hb_elapsed >= too_long) {
                        zap_log(ZAP_LOG_CRIT, "Lost Heartbeat!\n");
                        zap_set_flag_locked(span, ZAP_SPAN_SUSPENDED);
@@ -953,6 +959,7 @@ static void *zap_ss7_boost_run(zap_thread_t *me, void *obj)
                                                                SIGBOOST_EVENT_SYSTEM_RESTART,
                                                                0);
                }
+#endif
 
                if (zap_running()) {
                        check_state(span);
@@ -1094,7 +1101,7 @@ static ZIO_SIG_CONFIGURE_FUNCTION(zap_ss7_boost_configure_span)
 {
        zap_ss7_boost_data_t *ss7_boost_data = NULL;
        const char *local_ip = "127.0.0.65", *remote_ip = "127.0.0.66";
-       int local_port = 5300, remote_port = 5300;
+       int local_port = 53000, remote_port = 53000;
        char *var, *val;
        int *intval;
 
index a5a147cd11ea05a7a56cd7f12cb4937e4ad6cb0d..f705dfd09fa45aa5a3c19968e3fe5cd8f8d9771f 100644 (file)
@@ -1,5 +1,5 @@
 /****************************************************************************
- * sigboost.h     $Revision: 1.5 $
+ * sigboost.h     $Revision: 1.13 $
  *
  * Definitions for the sigboost interface.
  *
@@ -14,6 +14,8 @@
 #ifndef _SIGBOOST_H_
 #define _SIGBOOST_H_
 
+#define SIGBOOST_VERSION 100
+
 #include <stdint.h>
 #include <sys/time.h>
 
@@ -48,14 +50,22 @@ enum        e_sigboost_release_cause_values
 
 enum   e_sigboost_call_setup_ack_nack_cause_values
 {
-       SIGBOOST_CALL_SETUP_NACK_ALL_CKTS_BUSY          = 117, /* unused Q.850 value */
-       SIGBOOST_CALL_SETUP_NACK_TEST_CKT_BUSY          = 118, /* unused Q.850 value */
-       SIGBOOST_CALL_SETUP_NACK_INVALID_NUMBER         = 28,
-       /* probable elimination */
-       //SIGBOOST_CALL_SETUP_RESERVED                  = 0x00,
-       //SIGBOOST_CALL_SETUP_CIRCUIT_RESET             = 0x10,
-       //SIGBOOST_CALL_SETUP_NACK_CKT_START_TIMEOUT    = 0x11,
-       //SIGBOOST_CALL_SETUP_NACK_AUTO_CALL_GAP        = 0x17,
+       //SIGBOOST_CALL_SETUP_NACK_ALL_CKTS_BUSY                = 34,  /* Q.850 value - don't use */
+       SIGBOOST_CALL_SETUP_NACK_ALL_CKTS_BUSY          = 117,  /* non Q.850 value indicates local all ckt busy 
+                                                                  causing sangoma_mgd to perform automatic call 
+                                                                  gapping*/
+       SIGBOOST_CALL_SETUP_NACK_TEST_CKT_BUSY          = 17,  /* Q.850 value */
+       SIGBOOST_CALL_SETUP_NACK_INVALID_NUMBER         = 28,  /* Q.850 value */
+       SIGBOOST_CALL_SETUP_CSUPID_DBL_USE              = 200, /* unused Q.850 value */
+};
+
+
+enum   e_sigboost_huntgroup_values
+{
+       SIGBOOST_HUNTGRP_SEQ_ASC        = 0x00, /* sequential with lowest available first */
+       SIGBOOST_HUNTGRP_SEQ_DESC       = 0x01, /* sequential with highest available first */
+       SIGBOOST_HUNTGRP_RR_ASC         = 0x02, /* round-robin with lowest available first */
+       SIGBOOST_HUNTGRP_RR_DESC        = 0x03, /* round-robin with highest available first */
 };
 
 #define MAX_DIALED_DIGITS      31
@@ -67,63 +77,73 @@ enum        e_sigboost_call_setup_ack_nack_cause_values
 #define CORE_MAX_CHAN_PER_SPAN         30
 #define MAX_PENDING_CALLS      CORE_MAX_SPANS * CORE_MAX_CHAN_PER_SPAN
 /* 0..(MAX_PENDING_CALLS-1) is range of call_setup_id below */
-#define SIZE_RDNIS             128
+#define SIZE_RDNIS     900
+
 
 #pragma pack(1)
+
+typedef struct
+{
+       uint8_t                 capability;
+       uint8_t                 uil1p;
+}t_sigboost_bearer;
+
 typedef struct
 {
-       uint32_t        event_id;
+       uint16_t                version;
+       uint32_t                event_id;
        /* delete sequence numbers - SCTP does not need them */
-       uint32_t        fseqno;
-       uint32_t        bseqno;
-       uint16_t        call_setup_id;
-       uint32_t        trunk_group;
-       uint8_t         span;
-       uint8_t         chan;
-       struct timeval  tv;
-       uint8_t         called_number_digits_count;
-       char            called_number_digits [MAX_DIALED_DIGITS + 1]; /* it's a null terminated string */
-       uint8_t         calling_number_digits_count; /* it's an array */
-       char            calling_number_digits [MAX_DIALED_DIGITS + 1]; /* it's a null terminated string */
+       uint32_t                fseqno;
+       uint32_t                bseqno;
+       uint16_t                call_setup_id;
+       uint32_t                trunk_group;
+       uint8_t                 span;
+       uint8_t                 chan;
+       struct timeval          tv;
+       uint8_t                 called_number_digits_count;
+       char                    called_number_digits [MAX_DIALED_DIGITS + 1]; /* it's a null terminated string */
+       uint8_t                 calling_number_digits_count; /* it's an array */
+       char                    calling_number_digits [MAX_DIALED_DIGITS + 1]; /* it's a null terminated string */
        /* ref. Q.931 Table 4-11 and Q.951 Section 3 */
-       uint8_t         calling_number_screening_ind;
-       uint8_t         calling_number_presentation;
-       char            calling_name[MAX_DIALED_DIGITS + 1];
-       uint16_t        redirection_string_size;
-       char            redirection_string [SIZE_RDNIS]; /* it's a null terminated string */
-       /* redir string format: 
-        * http://www.ss7box.com/wiki/tiki-index.php?page=Call+Redirection
-        * */
+       uint8_t                 calling_number_screening_ind;
+       uint8_t                 calling_number_presentation;
+       char                    calling_name[MAX_DIALED_DIGITS + 1];
+       t_sigboost_bearer       bearer;
+       uint8_t                 hunt_group;
+       uint16_t                isup_in_rdnis_size;
+       char                    isup_in_rdnis [SIZE_RDNIS]; /* it's a null terminated string */
 } t_sigboost_callstart;
 
-#define MIN_SIZE_CALLSTART_MSG  (sizeof(t_sigboost_callstart) - SIZE_RDNIS)
+#define MIN_SIZE_CALLSTART_MSG  sizeof(t_sigboost_callstart) - SIZE_RDNIS
 
 typedef struct
 {
-       uint32_t        event_id;
+       uint16_t                version;
+       uint32_t                event_id;
        /* delete sequence numbers - SCTP does not need them */
-       uint32_t        fseqno;
-       uint32_t        bseqno;
-       uint16_t        call_setup_id;
-       uint32_t        trunk_group;
-       uint8_t         span;
-       uint8_t         chan;
-       struct timeval  tv;
-       uint8_t         release_cause;
+       uint32_t                fseqno;
+       uint32_t                bseqno;
+       uint16_t                call_setup_id;
+       uint32_t                trunk_group;
+       uint8_t                 span;
+       uint8_t                 chan;
+       struct timeval          tv;
+       uint8_t                 release_cause;
 } t_sigboost_short;
 #pragma pack()
 
 static inline int boost_full_event(int event_id)
 {
-       switch (event_id) {
-       case SIGBOOST_EVENT_CALL_START:
-       case SIGBOOST_EVENT_DIGIT_IN:
-               return 1;
-       default:
-               return 0;
-       }
-
-       return 0;
+        switch (event_id) {
+        case SIGBOOST_EVENT_CALL_START:
+        case SIGBOOST_EVENT_DIGIT_IN:
+                return 1;
+        default:
+                return 0;
+        }
+
+        return 0;
 }
 
+
 #endif
index 20986b30f19564a9e9203bbeddb8301d6747a308..37ad3d02b9aeef9877a1f439502da8b712af7dba 100644 (file)
@@ -73,7 +73,7 @@ static void ss7bc_print_event_call(ss7bc_connection_t *mcon, ss7bc_event_t *even
 {
        if (event->event_id == SIGBOOST_EVENT_HEARTBEAT)
                return;
-       zap_log(file, func, line, ZAP_LOG_LEVEL_DEBUG, "%s EVENT: %s:(%X) [w%dg%d] CSid=%i Seq=%i Cn=[%s] Cd=[%s] Ci=[%s]\n", 
+       zap_log(file, func, line, ZAP_LOG_LEVEL_WARNING, "%s EVENT: %s:(%X) [w%dg%d] CSid=%i Seq=%i Cn=[%s] Cd=[%s] Ci=[%s]\n", 
                    dir ? "TX":"RX", 
                        ss7bc_event_id_name(event->event_id), 
                        event->event_id, 
@@ -91,7 +91,7 @@ static void ss7bc_print_event_short(ss7bc_connection_t *mcon, ss7bc_short_event_
 {
        if (event->event_id == SIGBOOST_EVENT_HEARTBEAT)
                return;
-       zap_log(file, func, line, ZAP_LOG_LEVEL_DEBUG, "%s EVENT (%s): %s:(%X) [w%dg%d] Rc=%i CSid=%i Seq=%i \n", 
+       zap_log(file, func, line, ZAP_LOG_LEVEL_WARNING, "%s EVENT (%s): %s:(%X) [w%dg%d] Rc=%i CSid=%i Seq=%i \n", 
                           dir ? "TX":"RX", 
                           priority ? "P":"N",  
                            ss7bc_event_id_name(event->event_id), 
@@ -261,6 +261,10 @@ ss7bc_event_t *__ss7bc_connection_read(ss7bc_connection_t *mcon, int iteration,
        bytes = recvfrom(mcon->socket, &mcon->event, sizeof(mcon->event), MSG_DONTWAIT, 
                                         (struct sockaddr *) &mcon->local_addr, &fromlen);
 
+    if (mcon->event.version != SIGBOOST_VERSION) {
+               zap_log(ZAP_LOG_CRIT, "Invalid Boost Version %i  Expecting %i\n",mcon->event.version, SIGBOOST_VERSION);
+    }   
+
        /* Must check for < 0 cannot rely on bytes > MIN_SIZE_... compiler issue */
        if (bytes < 0) {
                msg_ok=0;
@@ -293,7 +297,7 @@ ss7bc_event_t *__ss7bc_connection_read(ss7bc_connection_t *mcon, int iteration,
                        ss7bc_print_event_short(mcon, (ss7bc_short_event_t*)&mcon->event, 0, 0, file, func, line);
                }
 
-#if 1
+#if 0
 /* NC: NOT USED ANY MORE */
                if (mcon->rxseq_reset) {
                        //if (mcon->event.event_id == SIGBOOST_EVENT_SYSTEM_RESTART_ACK) {
@@ -310,15 +314,17 @@ ss7bc_event_t *__ss7bc_connection_read(ss7bc_connection_t *mcon, int iteration,
                mcon->txwindow = mcon->txseq - mcon->event.bseqno;
                mcon->rxseq++;
 
+#if 0
                if (mcon->rxseq != mcon->event.fseqno) {
                        zap_log(ZAP_LOG_CRIT, "Invalid Sequence Number Expect=%i Rx=%i\n", mcon->rxseq, mcon->event.fseqno);
                        return NULL;
                }
+#endif
 
                return &mcon->event;
        } else {
                if (iteration == 0) {
-                       zap_log(ZAP_LOG_CRIT, "Invalid Event length from boost rxlen=%i evsz=%i\n", bytes, sizeof(mcon->event));
+                       zap_log(ZAP_LOG_CRIT, "NC -  Invalid Event length from boost rxlen=%i evsz=%i\n", bytes, sizeof(mcon->event));
                        return NULL;
                }
        }
@@ -332,6 +338,10 @@ ss7bc_event_t *__ss7bc_connection_readp(ss7bc_connection_t *mcon, int iteration,
        int bytes = 0;
 
        bytes = recvfrom(mcon->socket, &mcon->event, sizeof(mcon->event), MSG_DONTWAIT, (struct sockaddr *) &mcon->local_addr, &fromlen);
+    
+    if (mcon->event.version != SIGBOOST_VERSION) {
+               zap_log(ZAP_LOG_CRIT, "Invalid Boost Version %i  Expecting %i\n",mcon->event.version, SIGBOOST_VERSION);
+    }   
 
        if (bytes == sizeof(ss7bc_short_event_t)) {
 
@@ -356,7 +366,7 @@ ss7bc_event_t *__ss7bc_connection_readp(ss7bc_connection_t *mcon, int iteration,
 int __ss7bc_connection_write(ss7bc_connection_t *mcon, ss7bc_event_t *event, const char *file, const char *func, int line)
 {
        int err;
-       int event_size=sizeof(ss7bc_event_t);
+       int event_size=MIN_SIZE_CALLSTART_MSG+event->isup_in_rdnis_size;
  
        if (!event || mcon->socket < 0 || !mcon->mutex) {
                zap_log(file, func, line, ZAP_LOG_LEVEL_CRIT, "Critical Error: No Event Device\n");
@@ -395,6 +405,7 @@ int __ss7bc_connection_write(ss7bc_connection_t *mcon, ss7bc_event_t *event, con
                event->fseqno = mcon->txseq++;
        }
        event->bseqno = mcon->rxseq;
+    event->version = SIGBOOST_VERSION; 
        err = sendto(mcon->socket, event, event_size, 0, (struct sockaddr *) &mcon->remote_addr, sizeof(mcon->remote_addr));
 
        zap_mutex_unlock(mcon->mutex);
@@ -432,6 +443,7 @@ int __ss7bc_connection_writep(ss7bc_connection_t *mcon, ss7bc_event_t *event, co
        gettimeofday(&event->tv, NULL);
        
        zap_mutex_lock(mcon->mutex);
+    event->version = SIGBOOST_VERSION; 
        err = sendto(mcon->socket, event, event_size, 0, (struct sockaddr *) &mcon->remote_addr, sizeof(mcon->remote_addr));
        zap_mutex_unlock(mcon->mutex);
 
index 4efdf6dc76f65ccdc751728059c673f40cf42eeb..e29f7f3ad44ce160c7a8aa117501a15522845757 100644 (file)
@@ -38,7 +38,7 @@
 #include "openzap.h"
 #include <poll.h>
 #include <sys/socket.h>
-#include "wanpipe_tdm_api_iface.h"
+#include "libsangoma.h"
 
 typedef enum {
        WP_RINGING = (1 << 0)
@@ -57,196 +57,28 @@ static struct {
 ZIO_SPAN_POLL_EVENT_FUNCTION(wanpipe_poll_event);
 ZIO_SPAN_NEXT_EVENT_FUNCTION(wanpipe_next_event);
 
-#define WP_INVALID_SOCKET -1
-/* on windows right now, there is no way to specify if we want to read events here or not, we allways get them here */
-/* we need some what to select if we are reading regular tdm msgs or events */
-/* need to either have 2 functions, 1 for events, 1 for regural read, or a flag on this function to choose */
-/* 2 functions preferred.  Need implementation for the event function for both nix and windows that is threadsafe */
-static __inline__ int tdmv_api_readmsg_tdm(sng_fd_t fd, void *hdrbuf, int hdrlen, void *databuf, int datalen)
-{
-       /* What do we need to do here to avoid having to do all */
-       /* the memcpy's on windows and still maintain api compat with nix */
-       uint32_t rx_len=0;
-#if defined(__WINDOWS__)
-       static RX_DATA_STRUCT   rx_data;
-       api_header_t                    *pri;
-       wp_tdm_api_rx_hdr_t             *tdm_api_rx_hdr;
-       wp_tdm_api_rx_hdr_t             *user_buf = (wp_tdm_api_rx_hdr_t*)hdrbuf;
-       DWORD ln;
-
-       if (hdrlen != sizeof(wp_tdm_api_rx_hdr_t)){
-               return -1;
-       }
-
-       if (!DeviceIoControl(
-                                                fd,
-                                                IoctlReadCommand,
-                                                (LPVOID)NULL,
-                                                0L,
-                                                (LPVOID)&rx_data,
-                                                sizeof(RX_DATA_STRUCT),
-                                                (LPDWORD)(&ln),
-                                                (LPOVERLAPPED)NULL
-                                                )){
-               return -1;
-       }
-
-       pri = &rx_data.api_header;
-       tdm_api_rx_hdr = (wp_tdm_api_rx_hdr_t*)rx_data.data;
-
-       user_buf->wp_tdm_api_event_type = pri->operation_status;
-
-       switch(pri->operation_status)
-               {
-               case SANG_STATUS_RX_DATA_AVAILABLE:
-                       if (pri->data_length > datalen){
-                               break;
-                       }
-                       memcpy(databuf, rx_data.data, pri->data_length);
-                       rx_len = pri->data_length;
-                       break;
-
-               default:
-                       break;
-               }
-
-#else
-       struct msghdr msg;
-       struct iovec iov[2];
-
-       memset(&msg,0,sizeof(struct msghdr));
-
-       iov[0].iov_len=hdrlen;
-       iov[0].iov_base=hdrbuf;
-
-       iov[1].iov_len=datalen;
-       iov[1].iov_base=databuf;
-
-       msg.msg_iovlen=2;
-       msg.msg_iov=iov;
-
-       rx_len = read(fd,&msg,datalen+hdrlen);
-
-       if (rx_len <= sizeof(wp_tdm_api_rx_hdr_t)){
-               return -EINVAL;
-       }
-
-       rx_len-=sizeof(wp_tdm_api_rx_hdr_t);
-#endif
-    return rx_len;
-}                    
-
-static __inline__ int tdmv_api_writemsg_tdm(sng_fd_t fd, void *hdrbuf, int hdrlen, void *databuf, unsigned short datalen)
-{
-       /* What do we need to do here to avoid having to do all */
-       /* the memcpy's on windows and still maintain api compat with nix */
-       int bsent = 0;
-#if defined(__WINDOWS__)
-       static TX_DATA_STRUCT   local_tx_data;
-       api_header_t                    *pri;
-       DWORD ln;
-
-       /* Are these really not needed or used???  What about for nix?? */
-       (void)hdrbuf;
-       (void)hdrlen;
-
-       pri = &local_tx_data.api_header;
-
-       pri->data_length = datalen;
-       memcpy(local_tx_data.data, databuf, pri->data_length);
-
-       if (!DeviceIoControl(
-                                                fd,
-                                                IoctlWriteCommand,
-                                                (LPVOID)&local_tx_data,
-                                                (ULONG)sizeof(TX_DATA_STRUCT),
-                                                (LPVOID)&local_tx_data,
-                                                sizeof(TX_DATA_STRUCT),
-                                                (LPDWORD)(&ln),
-                                                (LPOVERLAPPED)NULL
-                                                )){
-               return -1;
-       }
-
-       if (local_tx_data.api_header.operation_status == SANG_STATUS_SUCCESS) {
-               bsent = datalen;
-       }
-#else
-       struct msghdr msg;
-       struct iovec iov[2];
-
-       memset(&msg,0,sizeof(struct msghdr));
-
-       iov[0].iov_len = hdrlen;
-       iov[0].iov_base = hdrbuf;
-
-       iov[1].iov_len = datalen;
-       iov[1].iov_base = databuf;
-
-       msg.msg_iovlen = 2;
-       msg.msg_iov = iov;
-
-       bsent = write(fd, &msg, datalen + hdrlen);
-       if (bsent > 0){
-               bsent -= sizeof(wp_tdm_api_tx_hdr_t);
-       }
-#endif
-       return bsent;
-}
+#define WP_INVALID_SOCKET -1 
 
 /* a cross platform way to poll on an actual pollset (span and/or list of spans) will probably also be needed for analog */
 /* so we can have one analong handler thread that will deal with all the idle analog channels for events */
 /* the alternative would be for the driver to provide one socket for all of the oob events for all analog channels */
 static __inline__ int tdmv_api_wait_socket(sng_fd_t fd, int timeout, int *flags)
 {
-#if defined(__WINDOWS__)
-       DWORD ln;
-       API_POLL_STRUCT api_poll;
-
-       memset(&api_poll, 0x00, sizeof(API_POLL_STRUCT));
        
-       api_poll.user_flags_bitmap = *flags;
-       api_poll.timeout = timeout;
-
-       if (!DeviceIoControl(
-                                                fd,
-                                                IoctlApiPoll,
-                                                (LPVOID)NULL,
-                                                0L,
-                                                (LPVOID)&api_poll,
-                                                sizeof(API_POLL_STRUCT),
-                                                (LPDWORD)(&ln),
-                                                (LPOVERLAPPED)NULL)) {
-               return -1;
-       }
-
-       *flags = 0;
-
-       switch(api_poll.operation_status)
-               {
-               case SANG_STATUS_RX_DATA_AVAILABLE:
-                       break;
-
-               case SANG_STATUS_RX_DATA_TIMEOUT:
-                       return 0;
-
-               default:
-                       return -1;
-               }
+#ifdef LIBSANGOMA_VERSION
+       int err;
+       sangoma_wait_obj_t sangoma_wait_obj;
 
-       if (api_poll.poll_events_bitmap == 0){
-               return -1;
-       }
+       sangoma_init_wait_obj(&sangoma_wait_obj, fd, 1, 1, *flags, SANGOMA_WAIT_OBJ);
 
-       if (api_poll.poll_events_bitmap & POLL_EVENT_TIMEOUT) {
-               return 0;
+       err=sangoma_socket_waitfor_many(&sangoma_wait_obj,1 , timeout);
+       if (err > 0) {
+               *flags=sangoma_wait_obj.flags_out;
        }
+       return err;
 
-       *flags = api_poll.poll_events_bitmap;
-
-       return 1;
 #else
-    struct pollfd pfds[1];
+       struct pollfd pfds[1];
     int res;
 
     memset(&pfds[0], 0, sizeof(pfds[0]));
@@ -265,87 +97,18 @@ static __inline__ int tdmv_api_wait_socket(sng_fd_t fd, int timeout, int *flags)
 
     return res;
 #endif
+       
 }
 
-#define FNAME_LEN 128
 static __inline__ sng_fd_t tdmv_api_open_span_chan(int span, int chan) 
 {
-       char fname[FNAME_LEN];
-       sng_fd_t fd = WP_INVALID_SOCKET;
-#if defined(__WINDOWS__)
-       DWORD                   ln;
-       wan_udp_hdr_t   wan_udp;
-
-       /* NOTE: under Windows Interfaces are zero based but 'chan' is 1 based. */
-       /*              Subtract 1 from 'chan'. */
-       _snprintf(fname , FNAME_LEN, "\\\\.\\WANPIPE%d_IF%d", span, chan - 1);
-
-       fd = CreateFile(        fname, 
-                                               GENERIC_READ | GENERIC_WRITE, 
-                                               FILE_SHARE_READ | FILE_SHARE_WRITE,
-                                               (LPSECURITY_ATTRIBUTES)NULL, 
-                                               OPEN_EXISTING,
-                                               FILE_FLAG_NO_BUFFERING | FILE_FLAG_WRITE_THROUGH,
-                                               (HANDLE)NULL
-                                               );
-
-       /* make sure that we are the only ones who have this chan open */
-       /* is this a threadsafe way to make sure that we are ok and will */
-       /* never return a valid handle to more than one thread for the same channel? */
-
-       wan_udp.wan_udphdr_command = GET_OPEN_HANDLES_COUNTER; 
-       wan_udp.wan_udphdr_data_len = 0;
-
-       DeviceIoControl(
-                                       fd,
-                                       IoctlManagementCommand,
-                                       (LPVOID)&wan_udp,
-                                       sizeof(wan_udp_hdr_t),
-                                       (LPVOID)&wan_udp,
-                                       sizeof(wan_udp_hdr_t),
-                                       (LPDWORD)(&ln),
-                                       (LPOVERLAPPED)NULL
-                                       );
-
-       if ((wan_udp.wan_udphdr_return_code) || (*(int*)&wan_udp.wan_udphdr_data[0] != 1)){
-               /* somone already has this channel, or somthing else is not right. */
-               tdmv_api_close_socket(&fd);
-       }
-
-#else
-       /* Does this fail if another thread already has this chan open? */
-       /* if not, we need to add some code to make sure it does */
-       snprintf(fname, FNAME_LEN, "/dev/wptdm_s%dc%d",span,chan);
-
-       fd = open(fname, O_RDWR);
-
-       if (fd < 0) {
-               fd = WP_INVALID_SOCKET;
-       }
-
-#endif
-       return fd;  
+       return sangoma_open_tdmapi_span_chan(span, chan);
 }            
 
 
 
 static zap_io_interface_t wanpipe_interface;
 
-static zap_status_t wp_tdm_cmd_exec(zap_channel_t *zchan, wanpipe_tdm_api_t *tdm_api)
-{
-       int err;
-
-       /* I'm told the 2nd arg is ignored but i send it as the cmd anyway for good measure */
-       err = ioctl(zchan->sockfd, tdm_api->wp_tdm_cmd.cmd, &tdm_api->wp_tdm_cmd);
-
-       if (err) {
-               snprintf(zchan->last_error, sizeof(zchan->last_error), "%s", strerror(errno));
-               return ZAP_FAIL;
-       }
-
-       return ZAP_SUCCESS;
-}
-
 static unsigned char wanpipe_swap_bits(unsigned char cas_bits)
 {
        unsigned char swapped_bits = 0x0;
@@ -374,59 +137,60 @@ static unsigned wp_open_range(zap_span_t *span, unsigned spanno, unsigned start,
        for(x = start; x < end; x++) {
                zap_channel_t *chan;
                zap_socket_t sockfd = WP_INVALID_SOCKET;
-               
+               const char *dtmf = "none";
+
                sockfd = tdmv_api_open_span_chan(spanno, x);
                
                if (sockfd != WP_INVALID_SOCKET && zap_span_add_channel(span, sockfd, type, &chan) == ZAP_SUCCESS) {
                        wanpipe_tdm_api_t tdm_api;
-                       zap_log(ZAP_LOG_INFO, "configuring device s%dc%d as OpenZAP device %d:%d fd:%d\n", spanno, x, chan->span_id, chan->chan_id, sockfd);
+                       memset(&tdm_api,0,sizeof(tdm_api));
+                       
                        chan->physical_span_id = spanno;
                        chan->physical_chan_id = x;
                        chan->rate = 8000;
 
-                       if (type == ZAP_CHAN_TYPE_FXS || type == ZAP_CHAN_TYPE_FXO) {
+                       if (type == ZAP_CHAN_TYPE_FXS || type == ZAP_CHAN_TYPE_FXO || type == ZAP_CHAN_TYPE_B) {
+                               int err;
                                
+                               dtmf = "software";
 
-#if 1
-                               if (type == ZAP_CHAN_TYPE_FXO) {
-                                       tdm_api.wp_tdm_cmd.cmd = SIOC_WP_TDM_SET_EVENT;
-                                       tdm_api.wp_tdm_cmd.event.wp_tdm_api_event_type = WP_TDMAPI_EVENT_TXSIG_ONHOOK;
-                                       tdm_api.wp_tdm_cmd.event.wp_tdm_api_event_mode = WP_TDMAPI_EVENT_ENABLE;
-                                       wp_tdm_cmd_exec(chan, &tdm_api);
-                               }
-#endif
-
-                               tdm_api.wp_tdm_cmd.cmd = SIOC_WP_TDM_SET_EVENT;
-                               tdm_api.wp_tdm_cmd.event.wp_tdm_api_event_type = WP_TDMAPI_EVENT_RING_DETECT;
-                               tdm_api.wp_tdm_cmd.event.wp_tdm_api_event_mode = WP_TDMAPI_EVENT_ENABLE;
-                               wp_tdm_cmd_exec(chan, &tdm_api);
-#if 1
-                               tdm_api.wp_tdm_cmd.cmd = SIOC_WP_TDM_SET_EVENT;
-                               tdm_api.wp_tdm_cmd.event.wp_tdm_api_event_type = WP_TDMAPI_EVENT_RING_TRIP_DETECT;
-                               tdm_api.wp_tdm_cmd.event.wp_tdm_api_event_mode = WP_TDMAPI_EVENT_ENABLE;
-                               wp_tdm_cmd_exec(chan, &tdm_api);
-#endif
-                               tdm_api.wp_tdm_cmd.cmd = SIOC_WP_TDM_SET_EVENT;
-                               tdm_api.wp_tdm_cmd.event.wp_tdm_api_event_type = WP_TDMAPI_EVENT_RXHOOK;
-                               tdm_api.wp_tdm_cmd.event.wp_tdm_api_event_mode = WP_TDMAPI_EVENT_ENABLE;
-                               wp_tdm_cmd_exec(chan, &tdm_api);
-
-                       }
+                               /* FIXME: Handle Error Conditino Check for return code */
+                               err= sangoma_tdm_get_hw_coding(chan->sockfd, &tdm_api);
 
-                       if (type == ZAP_CHAN_TYPE_FXS || type == ZAP_CHAN_TYPE_FXO || type == ZAP_CHAN_TYPE_B) {
-                               tdm_api.wp_tdm_cmd.cmd = SIOC_WP_TDM_GET_HW_CODING;
-                               wp_tdm_cmd_exec(chan, &tdm_api);
                                if (tdm_api.wp_tdm_cmd.hw_tdm_coding) {
                                        chan->native_codec = chan->effective_codec = ZAP_CODEC_ALAW;
                                } else {
                                        chan->native_codec = chan->effective_codec = ZAP_CODEC_ULAW;
                                }
+
+                               err = sangoma_tdm_get_hw_dtmf(chan->sockfd, &tdm_api);
+                               if (err > 0) {
+                                       err = sangoma_tdm_enable_dtmf_events(chan->sockfd, &tdm_api);
+                                       if (err == 0) {
+                                               zap_channel_set_feature(chan, ZAP_CHANNEL_FEATURE_DTMF_DETECT);
+                                               dtmf = "hardware";
+                                       }
+                               }
                        }
 
+#if 0
+            if (type == ZAP_CHAN_TYPE_FXS || type == ZAP_CHAN_TYPE_FXO) {
+                /* Enable FLASH/Wink Events */
+                int err=sangoma_set_rm_rxflashtime(chan->sockfd, &tdm_api, wp_globals.flash_ms);
+                if (err == 0) {
+                               zap_log(ZAP_LOG_ERROR, "flash enabled s%dc%d\n", spanno, x);
+                } else {
+                               zap_log(ZAP_LOG_ERROR, "flash disabled s%dc%d\n", spanno, x);
+                }
+            }
+#endif
+
                        if (type == ZAP_CHAN_TYPE_CAS) {
-                               tdm_api.wp_tdm_cmd.cmd = SIOC_WP_TDM_WRITE_RBS_BITS;
-                               tdm_api.wp_tdm_cmd.rbs_tx_bits = wanpipe_swap_bits(cas_bits);
-                               wp_tdm_cmd_exec(chan, &tdm_api);
+#ifdef LIBSANGOMA_VERSION
+                               sangoma_tdm_write_rbs(chan->sockfd,&tdm_api,chan->physical_chan_id,wanpipe_swap_bits(cas_bits));
+#else
+                               sangoma_tdm_write_rbs(chan->sockfd,&tdm_api,wanpipe_swap_bits(cas_bits));
+#endif
                        }
                        
                        if (!zap_strlen_zero(name)) {
@@ -439,6 +203,9 @@ static unsigned wp_open_range(zap_span_t *span, unsigned spanno, unsigned start,
                } else {
                        zap_log(ZAP_LOG_ERROR, "failure configuring device s%dc%d\n", spanno, x);
                }
+
+               zap_log(ZAP_LOG_INFO, "configuring device s%dc%d as OpenZAP device %d:%d fd:%d DTMF: %s\n", 
+                               spanno, x, chan->span_id, chan->chan_id, sockfd, dtmf);
        }
        
        return configured;
@@ -552,16 +319,15 @@ static ZIO_OPEN_FUNCTION(wanpipe_open)
 
        wanpipe_tdm_api_t tdm_api;
 
+       memset(&tdm_api,0,sizeof(tdm_api));
+
        if (zchan->type == ZAP_CHAN_TYPE_DQ921 || zchan->type == ZAP_CHAN_TYPE_DQ931) {
                zchan->native_codec = zchan->effective_codec = ZAP_CODEC_NONE;
        } else {
                zchan->effective_codec = zchan->native_codec;
-               tdm_api.wp_tdm_cmd.cmd = SIOC_WP_TDM_SET_CODEC;
-               tdm_api.wp_tdm_cmd.tdm_codec = 0;
-               wp_tdm_cmd_exec(zchan, &tdm_api);               
-               tdm_api.wp_tdm_cmd.cmd = SIOC_WP_TDM_SET_USR_PERIOD;
-               tdm_api.wp_tdm_cmd.usr_period = wp_globals.codec_ms;
-               wp_tdm_cmd_exec(zchan, &tdm_api);
+               
+               sangoma_tdm_set_usr_period(zchan->sockfd, &tdm_api, wp_globals.codec_ms);
+
                zap_channel_set_feature(zchan, ZAP_CHANNEL_FEATURE_INTERVAL);
                zchan->effective_interval = zchan->native_interval = wp_globals.codec_ms;
                zchan->packet_len = zchan->native_interval * 8;
@@ -585,10 +351,8 @@ static ZIO_COMMAND_FUNCTION(wanpipe_command)
        switch(command) {
        case ZAP_COMMAND_OFFHOOK:
                {
-                       tdm_api.wp_tdm_cmd.cmd = SIOC_WP_TDM_SET_EVENT;
-                       tdm_api.wp_tdm_cmd.event.wp_tdm_api_event_type = WP_TDMAPI_EVENT_TXSIG_OFFHOOK;
-                       tdm_api.wp_tdm_cmd.event.wp_tdm_api_event_mode = WP_TDMAPI_EVENT_ENABLE;
-                       if ((err = wp_tdm_cmd_exec(zchan, &tdm_api))) {
+                       err=sangoma_tdm_txsig_offhook(zchan->sockfd,&tdm_api);
+                       if (err) {
                                snprintf(zchan->last_error, sizeof(zchan->last_error), "OFFHOOK Failed");
                                return ZAP_FAIL;
                        }
@@ -597,10 +361,8 @@ static ZIO_COMMAND_FUNCTION(wanpipe_command)
                break;
        case ZAP_COMMAND_ONHOOK:
                {
-                       tdm_api.wp_tdm_cmd.cmd = SIOC_WP_TDM_SET_EVENT;
-                       tdm_api.wp_tdm_cmd.event.wp_tdm_api_event_type = WP_TDMAPI_EVENT_TXSIG_ONHOOK;
-                       tdm_api.wp_tdm_cmd.event.wp_tdm_api_event_mode = WP_TDMAPI_EVENT_ENABLE;
-                       if ((err = wp_tdm_cmd_exec(zchan, &tdm_api))) {
+                       err=sangoma_tdm_txsig_onhook(zchan->sockfd,&tdm_api);
+                       if (err) {
                                snprintf(zchan->last_error, sizeof(zchan->last_error), "ONHOOK Failed");
                                return ZAP_FAIL;
                        }
@@ -609,9 +371,8 @@ static ZIO_COMMAND_FUNCTION(wanpipe_command)
                break;
        case ZAP_COMMAND_GENERATE_RING_ON:
                {
-                       tdm_api.wp_tdm_cmd.cmd = SIOC_WP_TDM_SET_EVENT;
-                       tdm_api.wp_tdm_cmd.event.wp_tdm_api_event_type = WP_TDMAPI_EVENT_TXSIG_START;
-                       if ((err = wp_tdm_cmd_exec(zchan, &tdm_api))) {
+                       err=sangoma_tdm_txsig_start(zchan->sockfd,&tdm_api);
+                       if (err) {
                                snprintf(zchan->last_error, sizeof(zchan->last_error), "Ring Failed");
                                return ZAP_FAIL;
                        }
@@ -622,9 +383,8 @@ static ZIO_COMMAND_FUNCTION(wanpipe_command)
                break;
        case ZAP_COMMAND_GENERATE_RING_OFF:
                {
-                       tdm_api.wp_tdm_cmd.cmd = SIOC_WP_TDM_SET_EVENT;
-                       tdm_api.wp_tdm_cmd.event.wp_tdm_api_event_type = WP_TDMAPI_EVENT_TXSIG_OFFHOOK;
-                       if ((err = wp_tdm_cmd_exec(zchan, &tdm_api))) {
+                       err=sangoma_tdm_txsig_offhook(zchan->sockfd,&tdm_api);
+                       if (err) {
                                snprintf(zchan->last_error, sizeof(zchan->last_error), "Ring-off Failed");
                                return ZAP_FAIL;
                        }
@@ -634,27 +394,26 @@ static ZIO_COMMAND_FUNCTION(wanpipe_command)
                break;
        case ZAP_COMMAND_GET_INTERVAL:
                {
-                       tdm_api.wp_tdm_cmd.cmd = SIOC_WP_TDM_GET_USR_PERIOD;
-                       
-                       if (!(err = wp_tdm_cmd_exec(zchan, &tdm_api))) {
-                               ZAP_COMMAND_OBJ_INT = tdm_api.wp_tdm_cmd.usr_period;
+                       err=sangoma_tdm_get_usr_period(zchan->sockfd, &tdm_api);
+                       if (err > 0 ) {
+                               ZAP_COMMAND_OBJ_INT = err;
+                               err=0;
                        }
-
                }
                break;
        case ZAP_COMMAND_SET_INTERVAL: 
                {
-                       tdm_api.wp_tdm_cmd.cmd = SIOC_WP_TDM_SET_USR_PERIOD;
-                       tdm_api.wp_tdm_cmd.usr_period = ZAP_COMMAND_OBJ_INT;
-                       err = wp_tdm_cmd_exec(zchan, &tdm_api);
+                       err=sangoma_tdm_set_usr_period(zchan->sockfd, &tdm_api, ZAP_COMMAND_OBJ_INT);
                        zchan->packet_len = zchan->native_interval * (zchan->effective_codec == ZAP_CODEC_SLIN ? 16 : 8);
                }
                break;
        case ZAP_COMMAND_SET_CAS_BITS:
                {
-                       tdm_api.wp_tdm_cmd.cmd = SIOC_WP_TDM_WRITE_RBS_BITS;
-                       tdm_api.wp_tdm_cmd.rbs_tx_bits = wanpipe_swap_bits(ZAP_COMMAND_OBJ_INT);
-                       err = wp_tdm_cmd_exec(zchan, &tdm_api);
+#ifdef LIBSANGOMA_VERSION
+                       err=sangoma_tdm_write_rbs(zchan->sockfd,&tdm_api,zchan->physical_chan_id,wanpipe_swap_bits(ZAP_COMMAND_OBJ_INT));
+#else
+                       err=sangoma_tdm_write_rbs(zchan->sockfd,&tdm_api,wanpipe_swap_bits(ZAP_COMMAND_OBJ_INT));
+#endif
                }
                break;
        case ZAP_COMMAND_GET_CAS_BITS:
@@ -683,14 +442,18 @@ static ZIO_READ_FUNCTION(wanpipe_read)
 
        memset(&hdrframe, 0, sizeof(hdrframe));
 
-       rx_len = tdmv_api_readmsg_tdm(zchan->sockfd, &hdrframe, (int)sizeof(hdrframe), data, (int)*datalen);
-       
+       rx_len = sangoma_readmsg_tdm(zchan->sockfd, &hdrframe, (int)sizeof(hdrframe), data, (int)*datalen,0);
        *datalen = rx_len;
 
-       if (rx_len <= 0) {
+       if (rx_len == 0 || rx_len == -17) {
+               return ZAP_TIMEOUT;
+       }
+
+       if (rx_len < 0) {
                snprintf(zchan->last_error, sizeof(zchan->last_error), "%s", strerror(errno));
                return ZAP_FAIL;
-       }
+       } 
+
 
        return ZAP_SUCCESS;
 }
@@ -702,7 +465,7 @@ static ZIO_WRITE_FUNCTION(wanpipe_write)
 
        /* Do we even need the headerframe here? on windows, we don't even pass it to the driver */
        memset(&hdrframe, 0, sizeof(hdrframe));
-       bsent = tdmv_api_writemsg_tdm(zchan->sockfd, &hdrframe, (int)sizeof(hdrframe), data, (unsigned short)(*datalen));
+       bsent = sangoma_writemsg_tdm(zchan->sockfd, &hdrframe, (int)sizeof(hdrframe), data, (unsigned short)(*datalen),0);
 
        /* should we be checking if bsent == *datalen here? */
        if (bsent > 0) {
@@ -759,19 +522,29 @@ static ZIO_WAIT_FUNCTION(wanpipe_wait)
        return ZAP_SUCCESS;
 }
 
-#ifndef WIN32
 ZIO_SPAN_POLL_EVENT_FUNCTION(wanpipe_poll_event)
 {
+#ifdef LIBSANGOMA_VERSION
+       sangoma_wait_obj_t pfds[ZAP_MAX_CHANNELS_SPAN];
+#else
        struct pollfd pfds[ZAP_MAX_CHANNELS_SPAN];
+#endif
+
        uint32_t i, j = 0, k = 0, l = 0;
+       int objects=0;
        int r;
        
        for(i = 1; i <= span->chan_count; i++) {
                zap_channel_t *zchan = span->channels[i];
+
+#ifdef LIBSANGOMA_VERSION
+               sangoma_init_wait_obj(&pfds[j], zchan->sockfd , 1, 1, POLLPRI, SANGOMA_WAIT_OBJ);
+#else
                memset(&pfds[j], 0, sizeof(pfds[j]));
                pfds[j].fd = span->channels[i]->sockfd;
                pfds[j].events = POLLPRI;
-
+#endif
+               objects++;
                /* The driver probably should be able to do this wink/flash/ringing by itself this is sort of a hack to make it work! */
 
                if (zap_test_flag(zchan, ZAP_CHANNEL_WINK) || zap_test_flag(zchan, ZAP_CHANNEL_FLASH)) {
@@ -789,20 +562,16 @@ ZIO_SPAN_POLL_EVENT_FUNCTION(wanpipe_poll_event)
                        int err;
                        memset(&tdm_api, 0, sizeof(tdm_api));
                        if (zap_test_pflag(zchan, WP_RINGING)) {
-                               tdm_api.wp_tdm_cmd.cmd = SIOC_WP_TDM_SET_EVENT;
-                               tdm_api.wp_tdm_cmd.event.wp_tdm_api_event_type = WP_TDMAPI_EVENT_TXSIG_OFFHOOK;
-                               tdm_api.wp_tdm_cmd.event.wp_tdm_api_event_mode = WP_TDMAPI_EVENT_DISABLE;
-                               if ((err = wp_tdm_cmd_exec(zchan, &tdm_api))) {
+                               err=sangoma_tdm_txsig_offhook(zchan->sockfd,&tdm_api);
+                               if (err) {
                                        snprintf(zchan->last_error, sizeof(zchan->last_error), "Ring-off Failed");
                                        return ZAP_FAIL;
                                }
                                zap_clear_pflag_locked(zchan, WP_RINGING);
                                zchan->ring_time = zap_current_time_in_ms() + wp_globals.ring_off_ms;
                        } else {
-                               tdm_api.wp_tdm_cmd.cmd = SIOC_WP_TDM_SET_EVENT;
-                               tdm_api.wp_tdm_cmd.event.wp_tdm_api_event_type = WP_TDMAPI_EVENT_TXSIG_START;
-                               tdm_api.wp_tdm_cmd.event.wp_tdm_api_event_mode = WP_TDMAPI_EVENT_ENABLE;
-                               if ((err = wp_tdm_cmd_exec(zchan, &tdm_api))) {
+                               err=sangoma_tdm_txsig_start(zchan->sockfd,&tdm_api);
+                               if (err) {
                                        snprintf(zchan->last_error, sizeof(zchan->last_error), "Ring Failed");
                                        return ZAP_FAIL;
                                }
@@ -815,8 +584,11 @@ ZIO_SPAN_POLL_EVENT_FUNCTION(wanpipe_poll_event)
        if (l) {
                ms = l;
        }
-       
-    r = poll(pfds, j, ms);
+#ifdef LIBSANGOMA_VERSION
+       r = sangoma_socket_waitfor_many(pfds,objects,ms);
+#else
+       r = poll(pfds, j, ms);
+#endif
        
        if (r == 0) {
                return l ? ZAP_SUCCESS : ZAP_TIMEOUT;
@@ -828,7 +600,11 @@ ZIO_SPAN_POLL_EVENT_FUNCTION(wanpipe_poll_event)
        for(i = 1; i <= span->chan_count; i++) {
                zap_channel_t *zchan = span->channels[i];
 
+#ifdef LIBSANGOMA_VERSION
+               if (pfds[i-1].flags_out & POLLPRI) {
+#else
                if (pfds[i-1].revents & POLLPRI) {
+#endif
                        zap_set_flag(zchan, ZAP_CHANNEL_EVENT);
                        zchan->last_event_time = zap_current_time_in_ms();
                        k++;
@@ -836,15 +612,43 @@ ZIO_SPAN_POLL_EVENT_FUNCTION(wanpipe_poll_event)
        }
        
 
-
        return k ? ZAP_SUCCESS : ZAP_FAIL;
 }
 
+
+static ZIO_GET_ALARMS_FUNCTION(wanpipe_get_alarms)
+{
+       wanpipe_tdm_api_t tdm_api;
+       unsigned int alarms = 0;
+       int err;
+
+       memset(&tdm_api,0,sizeof(tdm_api));
+
+#ifdef LIBSANGOMA_VERSION
+       if ((err = sangoma_tdm_get_fe_alarms(zchan->sockfd, &tdm_api, &alarms))) {
+        snprintf(zchan->last_error, sizeof(zchan->last_error), "ioctl failed (%s)", strerror(errno));
+        snprintf(zchan->span->last_error, sizeof(zchan->span->last_error), "ioctl failed (%s)", strerror(errno));
+        return ZAP_FAIL;               
+       }
+#else
+       if ((err = sangoma_tdm_get_fe_alarms(zchan->sockfd, &tdm_api)) < 0){
+        snprintf(zchan->last_error, sizeof(zchan->last_error), "ioctl failed (%s)", strerror(errno));
+        snprintf(zchan->span->last_error, sizeof(zchan->span->last_error), "ioctl failed (%s)", strerror(errno));
+        return ZAP_FAIL;               
+       }
+       alarms = tdm_api.wp_tdm_cmd.fe_alarms;
 #endif
 
+       
+    zchan->alarm_flags = alarms ? ZAP_ALARM_RED : ZAP_ALARM_NONE;
+
+    return ZAP_SUCCESS;
+}
+
+
 ZIO_SPAN_NEXT_EVENT_FUNCTION(wanpipe_next_event)
 {
-       uint32_t i;
+       uint32_t i,err;
        zap_oob_event_t event_id;
        
        for(i = 1; i <= span->chan_count; i++) {
@@ -869,29 +673,43 @@ ZIO_SPAN_NEXT_EVENT_FUNCTION(wanpipe_next_event)
                                        event_id = ZAP_OOB_ONHOOK;
 
                                        if (span->channels[i]->type == ZAP_CHAN_TYPE_FXO) {
+                                               zap_channel_t *zchan = span->channels[i];
                                                wanpipe_tdm_api_t tdm_api;
                                                memset(&tdm_api, 0, sizeof(tdm_api));
-                                               tdm_api.wp_tdm_cmd.cmd = SIOC_WP_TDM_SET_EVENT;
-                                               tdm_api.wp_tdm_cmd.event.wp_tdm_api_event_type = WP_TDMAPI_EVENT_TXSIG_ONHOOK;
-                                               tdm_api.wp_tdm_cmd.event.wp_tdm_api_event_mode = WP_TDMAPI_EVENT_ENABLE;
-                                               wp_tdm_cmd_exec(span->channels[i], &tdm_api);
+
+                                               sangoma_tdm_txsig_onhook(zchan->sockfd,&tdm_api);
                                        }
                                        goto event;
                                }
                        }
-               }
+               } 
                if (zap_test_flag(span->channels[i], ZAP_CHANNEL_EVENT)) {
                        wanpipe_tdm_api_t tdm_api;
+                       zap_channel_t *zchan = span->channels[i];
                        memset(&tdm_api, 0, sizeof(tdm_api));
                        zap_clear_flag(span->channels[i], ZAP_CHANNEL_EVENT);
 
-                       tdm_api.wp_tdm_cmd.cmd = SIOC_WP_TDM_READ_EVENT;
-                       if (wp_tdm_cmd_exec(span->channels[i], &tdm_api) != ZAP_SUCCESS) {
+                       err=sangoma_tdm_read_event(zchan->sockfd,&tdm_api);
+                       if (err != ZAP_SUCCESS) {
                                snprintf(span->last_error, sizeof(span->last_error), "%s", strerror(errno));
                                return ZAP_FAIL;
                        }
                        
                        switch(tdm_api.wp_tdm_cmd.event.wp_tdm_api_event_type) {
+
+                       case WP_TDMAPI_EVENT_LINK_STATUS:
+                               {
+                                       switch(tdm_api.wp_tdm_cmd.event.wp_tdm_api_event_link_status) {
+                                       case WP_TDMAPI_EVENT_LINK_STATUS_CONNECTED:
+                                               event_id = ZAP_OOB_ALARM_CLEAR;
+                                               break;
+                                       default:
+                                               event_id = ZAP_OOB_ALARM_TRAP;
+                                               break;
+                                       };
+                               }
+                               break;
+
                        case WP_TDMAPI_EVENT_RXHOOK:
                                {
                                        if (span->channels[i]->type == ZAP_CHAN_TYPE_FXS) {
@@ -918,11 +736,9 @@ ZIO_SPAN_NEXT_EVENT_FUNCTION(wanpipe_next_event)
                                                continue;
                                        } else {
                                                int err;
-                                               
-                                               tdm_api.wp_tdm_cmd.cmd = SIOC_WP_TDM_SET_EVENT;
-                                               tdm_api.wp_tdm_cmd.event.wp_tdm_api_event_type = WP_TDMAPI_EVENT_TXSIG_ONHOOK;
-                                               tdm_api.wp_tdm_cmd.event.wp_tdm_api_event_mode = WP_TDMAPI_EVENT_ENABLE;
-                                               if ((err = wp_tdm_cmd_exec(span->channels[i], &tdm_api))) {
+                                               zap_channel_t *zchan = span->channels[i];
+                                               err=sangoma_tdm_txsig_onhook(zchan->sockfd,&tdm_api);
+                                               if (err) {
                                                        snprintf(span->channels[i]->last_error, sizeof(span->channels[i]->last_error), "ONHOOK Failed");
                                                        return ZAP_FAIL;
                                                }
@@ -948,6 +764,20 @@ ZIO_SPAN_NEXT_EVENT_FUNCTION(wanpipe_next_event)
                                        span->channels[i]->cas_bits = wanpipe_swap_bits(tdm_api.wp_tdm_cmd.event.wp_tdm_api_event_rbs_bits);
                                }
                                break;
+            case WP_TDMAPI_EVENT_DTMF:
+                {
+                    char tmp_dtmf[2] = { tdm_api.wp_tdm_cmd.event.wp_tdm_api_event_dtmf_digit, 0 };
+                                       event_id = ZAP_OOB_NOOP;
+
+                                       //zap_log(ZAP_LOG_DEBUG, "%d:%d queue hardware dtmf %s\n", zchan->span_id, zchan->chan_id, tmp_dtmf);
+                    if (tdm_api.wp_tdm_cmd.event.wp_tdm_api_event_dtmf_type == WAN_EC_TONE_STOP) {
+                        zap_channel_queue_dtmf(zchan, tmp_dtmf);
+                    } 
+                }
+                break;
+                       case WP_TDMAPI_EVENT_ALARM:
+                               event_id = ZAP_OOB_NOOP;
+                               break;
                        default:
                                {
                                        zap_log(ZAP_LOG_WARNING, "Unhandled event %d\n", tdm_api.wp_tdm_cmd.event.wp_tdm_api_event_type);
@@ -1005,6 +835,7 @@ static ZIO_IO_LOAD_FUNCTION(wanpipe_init)
 #endif
        wanpipe_interface.next_event = wanpipe_next_event;
        wanpipe_interface.channel_destroy = wanpipe_channel_destroy;
+       wanpipe_interface.get_alarms = wanpipe_get_alarms;
        *zio = &wanpipe_interface;
 
        return ZAP_SUCCESS;
index 096b655ceb21749dd31dc7a91f0e8e1beac235b9..c3f80e0f6e2809a389f99d6c6e684c69c3b3a5e7 100644 (file)
@@ -868,6 +868,9 @@ static ZIO_READ_FUNCTION(zt_read)
                if ((r = read(zchan->sockfd, data, *datalen)) > 0) {
                        break;
                }
+               if (r == 0) {
+                       errs--;
+               }
        }
 
        if (r > 0) {
@@ -878,7 +881,7 @@ static ZIO_READ_FUNCTION(zt_read)
                return ZAP_SUCCESS;
        }
 
-       return ZAP_FAIL;
+       return r == 0 ? ZAP_TIMEOUT : ZAP_FAIL;
 }
 
 static ZIO_WRITE_FUNCTION(zt_write)