mirror of
https://github.com/signalwire/freeswitch.git
synced 2025-02-05 18:44:54 +00:00
54c7bbecef
git-svn-id: http://svn.openzap.org/svn/openzap/trunk@718 a93c3328-9c30-0410-af19-c9cd2b2d52af
1111 lines
35 KiB
Diff
1111 lines
35 KiB
Diff
Index: src/ozmod/ozmod_ss7_boost/sigboost.h
|
|
===================================================================
|
|
--- src/ozmod/ozmod_ss7_boost/sigboost.h (revision 717)
|
|
+++ src/ozmod/ozmod_ss7_boost/sigboost.h (working copy)
|
|
@@ -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,16 +50,24 @@
|
|
|
|
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
|
|
|
|
/* Next two defines are used to create the range of values for call_setup_id
|
|
@@ -67,63 +77,73 @@
|
|
#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
|
|
{
|
|
- uint32_t event_id;
|
|
+ uint8_t capability;
|
|
+ uint8_t uil1p;
|
|
+}t_sigboost_bearer;
|
|
+
|
|
+typedef struct
|
|
+{
|
|
+ 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;
|
|
- }
|
|
+ switch (event_id) {
|
|
+ case SIGBOOST_EVENT_CALL_START:
|
|
+ case SIGBOOST_EVENT_DIGIT_IN:
|
|
+ return 1;
|
|
+ default:
|
|
+ return 0;
|
|
+ }
|
|
|
|
- return 0;
|
|
+ return 0;
|
|
}
|
|
|
|
+
|
|
#endif
|
|
Index: src/ozmod/ozmod_ss7_boost/ss7_boost_client.c
|
|
===================================================================
|
|
--- src/ozmod/ozmod_ss7_boost/ss7_boost_client.c (revision 717)
|
|
+++ src/ozmod/ozmod_ss7_boost/ss7_boost_client.c (working copy)
|
|
@@ -73,7 +73,7 @@
|
|
{
|
|
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 @@
|
|
{
|
|
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 @@
|
|
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_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 @@
|
|
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 @@
|
|
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 @@
|
|
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 @@
|
|
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 @@
|
|
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: src/ozmod/ozmod_ss7_boost/ozmod_ss7_boost.c
|
|
===================================================================
|
|
--- src/ozmod/ozmod_ss7_boost/ozmod_ss7_boost.c (revision 717)
|
|
+++ src/ozmod/ozmod_ss7_boost/ozmod_ss7_boost.c (working copy)
|
|
@@ -215,7 +215,11 @@
|
|
|
|
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 @@
|
|
}
|
|
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 @@
|
|
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 @@
|
|
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 @@
|
|
SIGBOOST_EVENT_SYSTEM_RESTART,
|
|
0);
|
|
}
|
|
+#endif
|
|
|
|
if (zap_running()) {
|
|
check_state(span);
|
|
@@ -1094,7 +1101,7 @@
|
|
{
|
|
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: src/ozmod/ozmod_wanpipe/ozmod_wanpipe.c
|
|
===================================================================
|
|
--- src/ozmod/ozmod_wanpipe/ozmod_wanpipe.c (revision 717)
|
|
+++ src/ozmod/ozmod_wanpipe/ozmod_wanpipe.c (working copy)
|
|
@@ -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 @@
|
|
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;
|
|
+#define WP_INVALID_SOCKET -1
|
|
|
|
- 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;
|
|
-}
|
|
-
|
|
/* 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;
|
|
+#ifdef LIBSANGOMA_VERSION
|
|
+ int err;
|
|
+ sangoma_wait_obj_t sangoma_wait_obj;
|
|
|
|
- if (!DeviceIoControl(
|
|
- fd,
|
|
- IoctlApiPoll,
|
|
- (LPVOID)NULL,
|
|
- 0L,
|
|
- (LPVOID)&api_poll,
|
|
- sizeof(API_POLL_STRUCT),
|
|
- (LPDWORD)(&ln),
|
|
- (LPOVERLAPPED)NULL)) {
|
|
- return -1;
|
|
- }
|
|
+ sangoma_init_wait_obj(&sangoma_wait_obj, fd, 1, 1, *flags, SANGOMA_WAIT_OBJ);
|
|
|
|
- *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;
|
|
- }
|
|
-
|
|
- if (api_poll.poll_events_bitmap == 0){
|
|
- return -1;
|
|
+ err=sangoma_socket_waitfor_many(&sangoma_wait_obj,1 , timeout);
|
|
+ if (err > 0) {
|
|
+ *flags=sangoma_wait_obj.flags_out;
|
|
}
|
|
+ return err;
|
|
|
|
- if (api_poll.poll_events_bitmap & POLL_EVENT_TIMEOUT) {
|
|
- return 0;
|
|
- }
|
|
-
|
|
- *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 @@
|
|
|
|
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;
|
|
@@ -379,43 +142,17 @@
|
|
|
|
if (sockfd != WP_INVALID_SOCKET && zap_span_add_channel(span, sockfd, type, &chan) == ZAP_SUCCESS) {
|
|
wanpipe_tdm_api_t tdm_api;
|
|
+ memset(&tdm_api,0,sizeof(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);
|
|
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 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);
|
|
-
|
|
- }
|
|
-
|
|
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);
|
|
+ int err;
|
|
+
|
|
+ /* FIXME: Handle Error Conditino Check for return code */
|
|
+ err= sangoma_tdm_get_hw_coding(chan->sockfd, &tdm_api);
|
|
if (tdm_api.wp_tdm_cmd.hw_tdm_coding) {
|
|
chan->native_codec = chan->effective_codec = ZAP_CODEC_ALAW;
|
|
} else {
|
|
@@ -423,10 +160,24 @@
|
|
}
|
|
}
|
|
|
|
+#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)) {
|
|
@@ -550,18 +301,31 @@
|
|
static ZIO_OPEN_FUNCTION(wanpipe_open)
|
|
{
|
|
|
|
+ int err;
|
|
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);
|
|
+
|
|
+ err=sangoma_tdm_get_hw_dtmf(zchan->sockfd, &tdm_api);
|
|
+ if (err > 0) {
|
|
+ err=sangoma_tdm_enable_dtmf_events(zchan->sockfd, &tdm_api);
|
|
+ if (err == 0) {
|
|
+ //zap_log(ZAP_LOG_DEBUG, "Enabling HW DTMF FEATURE\n");
|
|
+ zap_channel_set_feature(zchan, ZAP_CHANNEL_FEATURE_DTMF_DETECT);
|
|
+ } else {
|
|
+ //zap_log(ZAP_LOG_DEBUG, "NO HW DTMF FEATURE\n");
|
|
+ }
|
|
+ } else {
|
|
+ //zap_log(ZAP_LOG_DEBUG, "NO HW DTMF FEATURE\n");
|
|
+ }
|
|
+
|
|
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 +349,8 @@
|
|
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 +359,8 @@
|
|
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 +369,8 @@
|
|
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 +381,8 @@
|
|
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 +392,26 @@
|
|
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,7 +440,7 @@
|
|
|
|
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;
|
|
|
|
@@ -702,7 +459,7 @@
|
|
|
|
/* 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 +516,29 @@
|
|
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 +556,16 @@
|
|
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,9 +578,12 @@
|
|
if (l) {
|
|
ms = l;
|
|
}
|
|
+#ifdef LIBSANGOMA_VERSION
|
|
+ r = sangoma_socket_waitfor_many(pfds,objects,ms);
|
|
+#else
|
|
+ r = poll(pfds, j, ms);
|
|
+#endif
|
|
|
|
- r = poll(pfds, j, ms);
|
|
-
|
|
if (r == 0) {
|
|
return l ? ZAP_SUCCESS : ZAP_TIMEOUT;
|
|
} else if (r < 0) {
|
|
@@ -828,7 +594,11 @@
|
|
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 +606,43 @@
|
|
}
|
|
|
|
|
|
-
|
|
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 +667,43 @@
|
|
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 +730,9 @@
|
|
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 +758,17 @@
|
|
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;
|
|
default:
|
|
{
|
|
zap_log(ZAP_LOG_WARNING, "Unhandled event %d\n", tdm_api.wp_tdm_cmd.event.wp_tdm_api_event_type);
|
|
@@ -1005,6 +826,7 @@
|
|
#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: configure.ac
|
|
===================================================================
|
|
--- configure.ac (revision 717)
|
|
+++ configure.ac (working copy)
|
|
@@ -155,6 +155,9 @@
|
|
[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: Makefile.am
|
|
===================================================================
|
|
--- Makefile.am (revision 717)
|
|
+++ Makefile.am (working copy)
|
|
@@ -154,10 +154,12 @@
|
|
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 \
|