git-svn-id: http://svn.freeswitch.org/svn/freeswitch/trunk@4902 d0543943-73ff-0310-b7d9-9358b9ac24b2
This commit is contained in:
Anthony Minessale 2007-04-09 19:27:59 +00:00
parent 7e979e7649
commit 350ed66d5d
6 changed files with 1660 additions and 560 deletions

View File

@ -3,20 +3,23 @@ LIBPRI_HOST=http://ftp.digium.com/pub/libpri
LIBPRI=libpri-1.2.4 LIBPRI=libpri-1.2.4
LIBPRI_FILE=$(LIBPRI).tar.gz LIBPRI_FILE=$(LIBPRI).tar.gz
LIBPRI_DIR=$(BASE)/libs/$(LIBPRI) LIBPRI_DIR=$(BASE)/libs/$(LIBPRI)
WANPIPE=wanpipe-3.1.0.p13 WANPIPE=wanpipe-3.1.0.p15
WANPIPE_HOST=ftp://ftp.sangoma.com/linux/custom/3.1 WANPIPE_HOST=ftp://ftp.sangoma.com/linux/custom/3.1
WANPIPE_FILE=$(WANPIPE).tgz WANPIPE_FILE=$(WANPIPE).tgz
WANPIPE_DIR=$(BASE)/libs/$(WANPIPE) WANPIPE_DIR=$(BASE)/libs/$(WANPIPE)
WANPIPE_INCLUDE=$(WANPIPE_DIR)/patches/kdrivers/include WANPIPE_INCLUDE=$(WANPIPE_DIR)/patches/kdrivers/include
WANPIPE_KO=$(WANPIPE_DIR)/patches/kdrivers/src/net/wanpipe.ko WANPIPE_KO=$(WANPIPE_DIR)/patches/kdrivers/src/net/wanpipe.ko
WANPIPE_INSTALLED_KO=$(shell echo "/lib/modules/`uname -r`/kernel/drivers/net/wan/wanpipe.ko") WANPIPE_INSTALLED_KO=$(shell echo "/lib/modules/`uname -r`/kernel/drivers/net/wan/wanpipe.ko")
LIBSANGOMA_DIR=$(WANPIPE_DIR)/api/libsangoma LIBSANGOMA_DIR=./libsangoma
LOCAL_CFLAGS =-w -I$(WANPIPE_INCLUDE) -I$(LIBSANGOMA_DIR) -I/usr/local/include -I$(LIBPRI_DIR) -I/usr/src/linux/include -I. -I/usr/include LOCAL_CFLAGS =-w -I$(WANPIPE_INCLUDE) -I$(LIBSANGOMA_DIR) -I/usr/local/include -I$(LIBPRI_DIR) -I/usr/src/linux/include -I. -I/usr/include
LOCAL_CFLAGS +=-D__LINUX__ -D_REENTRANT -D_GNU_SOURCE -DAFT_A104 -DWANPIPE_TDM_API -I$(switch_srcdir)/libs/libteletone/src -D_GNUC_ -DWANPIPE_TDM_API LOCAL_CFLAGS +=-D__LINUX__ -D_REENTRANT -D_GNU_SOURCE -DAFT_A104 -DWANPIPE_TDM_API -I$(switch_srcdir)/libs/libteletone/src -D_GNUC_ -DWANPIPE_TDM_API
LOCAL_OBJS = ss7boost_client.o $(LIBPRI_DIR)/copy_string.o $(LIBPRI_DIR)/pri.o $(LIBPRI_DIR)/q921.o $(LIBPRI_DIR)/prisched.o $(LIBPRI_DIR)/q931.o $(LIBPRI_DIR)/pri_facility.o $(LIBSANGOMA_DIR)/libsangoma.o $(LIBSANGOMA_DIR)/sangoma_pri.o LOCAL_OBJS = ss7boost_client.o $(LIBPRI_DIR)/copy_string.o $(LIBPRI_DIR)/pri.o $(LIBPRI_DIR)/q921.o $(LIBPRI_DIR)/prisched.o $(LIBPRI_DIR)/q931.o $(LIBPRI_DIR)/pri_facility.o $(LIBSANGOMA_DIR)/libsangoma.o $(LIBSANGOMA_DIR)/sangoma_pri.o
include $(BASE)/build/modmake.rules include $(BASE)/build/modmake.rules
testapp: testapp.c $(LIBSANGOMA_DIR)/libsangoma.o
$(CC) -I$(WANPIPE_DIR)/api/lib $(CFLAGS) $(LOCAL_CFLAGS) lib_api.c testapp.c $(LIBSANGOMA_DIR)/libsangoma.o -o testapp
$(LIBPRI_DIR): $(LIBPRI_DIR):
$(GETLIB) $(LIBPRI_HOST) $(LIBPRI_FILE) $(GETLIB) $(LIBPRI_HOST) $(LIBPRI_FILE)

View File

@ -0,0 +1,537 @@
/*****************************************************************************
* lib_api.c Common API library
*
* Author(s): Nenad Corbic <ncorbic@sangoma.com>
*
* Copyright: (c) 2003 Sangoma Technologies Inc.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version
* 2 of the License, or (at your option) any later version.
* ============================================================================
*/
#include <stdlib.h>
#include <stdio.h>
#include <ctype.h>
#include <unistd.h>
#include <sys/time.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <linux/if_wanpipe.h>
#include <string.h>
#include <errno.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#include <sys/types.h>
#include <signal.h>
#include <linux/if.h>
#include <linux/wanpipe_defines.h>
#include <linux/wanpipe_cfg.h>
#include <linux/wanpipe.h>
#include "lib_api.h"
#define SINGLE_CHANNEL 0x2
#define RANGE_CHANNEL 0x1
char read_enable=0;
char write_enable=0;
char primary_enable=0;
int tx_cnt=1;
int rx_cnt=0;
int tx_size=10;
int tx_delay=0;
int tx_data=-1;
int tx_ss7_type=0;
int rx_ss7_timer=0;
unsigned char card_name[WAN_IFNAME_SZ];
unsigned char if_name[WAN_IFNAME_SZ];
unsigned char sw_if_name[WAN_IFNAME_SZ];
unsigned char sw_card_name[WAN_IFNAME_SZ];
unsigned char tx_file[WAN_IFNAME_SZ];
unsigned char rx_file[WAN_IFNAME_SZ];
unsigned char daddr[TX_ADDR_STR_SZ];
unsigned char saddr[TX_ADDR_STR_SZ];
unsigned char udata[TX_ADDR_STR_SZ];
int files_used=0;
int verbose=0;
int tx_connections;
int ds_prot=0;
int ds_prot_opt=0;
int ds_max_mult_cnt=0;
unsigned int ds_active_ch=0;
int ds_7bit_hdlc=0;
int direction=-1;
int tx_channels=1;
int cause=0;
int diagn=0;
int card_cnt=0;
int i_cnt=0;
unsigned long parse_active_channel(char* val);
int init_args(int argc, char *argv[])
{
int i;
int c_cnt=0;
sprintf(daddr,"111");
sprintf(saddr,"222");
sprintf(udata,"C9");
for (i = 0; i < argc; i++){
if (!strcmp(argv[i],"-i")){
if (i+1 > argc-1){
printf("ERROR: Invalid Interface Name!\n");
return WAN_FALSE;
}
strncpy(if_name, argv[i+1],WAN_IFNAME_SZ);
i_cnt=1;
}else if (!strcmp(argv[i],"-si")){
if (i+1 > argc-1){
printf("ERROR: Invalid Switch Interface Name!\n");
return WAN_FALSE;
}
strncpy(sw_if_name, argv[i+1], WAN_IFNAME_SZ);
}else if (!strcmp(argv[i],"-c")){
if (i+1 > argc-1){
printf("ERROR: Invalid Card Name!\n");
return WAN_FALSE;
}
strncpy(card_name, argv[i+1], WAN_IFNAME_SZ);
card_cnt=1;
}else if (!strcmp(argv[i],"-sc")){
if (i+1 > argc-1){
printf("ERROR: Invalid Switch Card Name!\n");
return WAN_FALSE;
}
strncpy(sw_card_name, argv[i+1], WAN_IFNAME_SZ);
}else if (!strcmp(argv[i],"-r")){
read_enable=1;
c_cnt=1;
}else if (!strcmp(argv[i],"-w")){
write_enable=1;
c_cnt=1;
}else if (!strcmp(argv[i],"-pri")){
primary_enable=1;
}else if (!strcmp(argv[i],"-txcnt")){
if (i+1 > argc-1){
printf("ERROR: Invalid tx cnt!\n");
return WAN_FALSE;
}
if(isdigit(argv[i+1][0])){
tx_cnt = atoi(argv[i+1]);
}else{
printf("ERROR: Invalid tx cnt!\n");
return WAN_FALSE;
}
}else if (!strcmp(argv[i],"-rxcnt")){
if (i+1 > argc-1){
printf("ERROR: Invalid rx cnt!\n");
return WAN_FALSE;
}
if(isdigit(argv[i+1][0])){
rx_cnt = atoi(argv[i+1]);
}else{
printf("ERROR: Invalid rx cnt!\n");
return WAN_FALSE;
}
}else if (!strcmp(argv[i],"-txsize")){
if (i+1 > argc-1){
printf("ERROR: Invalid tx size!\n");
return WAN_FALSE;
}
if(isdigit(argv[i+1][0])){
tx_size = atoi(argv[i+1]);
}else{
printf("ERROR: Invalid tx size, must be a digit!\n");
return WAN_FALSE;
}
}else if (!strcmp(argv[i],"-txdelay")){
if (i+1 > argc-1){
printf("ERROR: Invalid tx delay!\n");
return WAN_FALSE;
}
if(isdigit(argv[i+1][0])){
tx_delay = atoi(argv[i+1]);
}else{
printf("ERROR: Invalid tx delay, must be a digit!\n");
return WAN_FALSE;
}
}else if (!strcmp(argv[i],"-txdata")){
if (i+1 > argc-1){
printf("ERROR: Invalid tx data!\n");
return WAN_FALSE;
}
if(isdigit(argv[i+1][0])){
tx_data = atoi(argv[i+1]);
}else{
printf("ERROR: Invalid tx data, must be a digit!\n");
return WAN_FALSE;
}
}else if (!strcmp(argv[i],"-tx_ss7_type")){
if (i+1 > argc-1){
printf("ERROR: Invalid tx ss7 type!\n");
return WAN_FALSE;
}
if(isdigit(argv[i+1][0])){
tx_ss7_type = atoi(argv[i+1]);
}else{
printf("ERROR: Invalid tx ss7 type, must be a digit!\n");
return WAN_FALSE;
}
}else if (!strcmp(argv[i],"-rx_ss7_timer")){
if (i+1 > argc-1){
printf("ERROR: Invalid rx ss7 timer!\n");
return WAN_FALSE;
}
if(isdigit(argv[i+1][0])){
rx_ss7_timer = atoi(argv[i+1]);
}else{
printf("ERROR: Invalid tx ss7 type, must be a digit!\n");
return WAN_FALSE;
}
}else if (!strcmp(argv[i],"-txfile")){
if (i+1 > argc-1){
printf("ERROR: Invalid Tx File Name!\n");
return WAN_FALSE;
}
strncpy(tx_file, argv[i+1],WAN_IFNAME_SZ);
files_used |= TX_FILE_USED;
}else if (!strcmp(argv[i],"-rxfile")){
if (i+1 > argc-1){
printf("ERROR: Invalid Rx File Name!\n");
return WAN_FALSE;
}
strncpy(rx_file, argv[i+1],WAN_IFNAME_SZ);
files_used |= RX_FILE_USED;
}else if (!strcmp(argv[i],"-daddr")){
if (i+1 > argc-1){
printf("ERROR: Invalid daddr str!\n");
return WAN_FALSE;
}
strncpy(daddr, argv[i+1],TX_ADDR_STR_SZ);
}else if (!strcmp(argv[i],"-saddr")){
if (i+1 > argc-1){
printf("ERROR: Invalid saddr str!\n");
return WAN_FALSE;
}
strncpy(saddr, argv[i+1],TX_ADDR_STR_SZ);
}else if (!strcmp(argv[i],"-udata")){
if (i+1 > argc-1){
printf("ERROR: Invalid udata str!\n");
return WAN_FALSE;
}
strncpy(udata, argv[i+1],TX_ADDR_STR_SZ);
}else if (!strcmp(argv[i],"-verbose")){
verbose=1;
}else if (!strcmp(argv[i],"-prot")){
if (i+1 > argc-1){
printf("ERROR: Invalid prot!\n");
return WAN_FALSE;
}
if(isdigit(argv[i+1][0])){
ds_prot = atoi(argv[i+1]);
}else{
printf("ERROR: Invalid prot, must be a digit!\n");
return WAN_FALSE;
}
}else if (!strcmp(argv[i],"-prot_opt")){
if (i+1 > argc-1){
printf("ERROR: Invalid prot_opt!\n");
return WAN_FALSE;
}
if(isdigit(argv[i+1][0])){
ds_prot_opt = atoi(argv[i+1]);
}else{
printf("ERROR: Invalid prot_opt, must be a digit!\n");
return WAN_FALSE;
}
}else if (!strcmp(argv[i],"-max_mult_cnt")){
if (i+1 > argc-1){
printf("ERROR: Invalid max_mult_cnt!\n");
return WAN_FALSE;
}
if(isdigit(argv[i+1][0])){
ds_max_mult_cnt = atoi(argv[i+1]);
}else{
printf("ERROR: Invalid max_mult_cnt, must be a digit!\n");
return WAN_FALSE;
}
}else if (!strcmp(argv[i],"-active_ch")){
if (i+1 > argc-1){
printf("ERROR: Invalid active ch!\n");
return WAN_FALSE;
}
ds_active_ch = parse_active_channel(argv[i+1]);
}else if (!strcmp(argv[i],"-txchan")){
if (i+1 > argc-1){
printf("ERROR: Invalid channels!\n");
return WAN_FALSE;
}
if(isdigit(argv[i+1][0])){
tx_channels = atoi(argv[i+1]);
}else{
printf("ERROR: Invalid channels, must be a digit!\n");
return WAN_FALSE;
}
}else if (!strcmp(argv[i],"-diagn")){
if (i+1 > argc-1){
printf("ERROR: Invalid diagn!\n");
return WAN_FALSE;
}
if(isdigit(argv[i+1][0])){
diagn = atoi(argv[i+1]);
}else{
printf("ERROR: Invalid diagn, must be a digit!\n");
return WAN_FALSE;
}
}else if (!strcmp(argv[i],"-cause")){
if (i+1 > argc-1){
printf("ERROR: Invalid cause!\n");
return WAN_FALSE;
}
if(isdigit(argv[i+1][0])){
cause = atoi(argv[i+1]);
}else{
printf("ERROR: Invalid cause, must be a digit!\n");
return WAN_FALSE;
}
}else if (!strcmp(argv[i],"-7bit_hdlc")){
if (i+1 > argc-1){
printf("ERROR: Invalid 7bit hdlc value!\n");
return WAN_FALSE;
}
if(isdigit(argv[i+1][0])){
ds_7bit_hdlc = atoi(argv[i+1]);
}else{
printf("ERROR: Invalid 7bit hdlc, must be a digit!\n");
return WAN_FALSE;
}
}else if (!strcmp(argv[i],"-dir")){
if (i+1 > argc-1){
printf("ERROR: Invalid direction value!\n");
return WAN_FALSE;
}
if(isdigit(argv[i+1][0])){
direction = atoi(argv[i+1]);
}else{
printf("ERROR: Invalid direction, must be a digit!\n");
return WAN_FALSE;
}
}
}
if (!i_cnt){
printf("ERROR: No Interface Name!\n");
return WAN_FALSE;
}
if (!card_cnt){
printf("ERROR: No Card name!\n");
return WAN_FALSE;
}
if (!c_cnt){
printf("ERROR: No Read or Write Command!\n");
return WAN_FALSE;
}
return WAN_TRUE;
}
static unsigned char api_usage[]="\n"
"\n"
"<options>:\n"
" -i <ifname> #interface name\n"
" -c <card name> #card name\n"
" -r #read enable\n"
" -w #write eable\n"
"\n"
"<extra options>\n"
" -txcnt <digit> #number of tx packets (Dflt: 1)\n"
" -txsize <digit> #tx packet size (Dflt: 10)\n"
" -txdelay <digit> #delay in sec after each tx packet (Dflt: 0)\n"
" -txdata <digit> #data to tx <1-255>\n"
"\n"
" -txfile <file> #Use file to tx instead\n"
" -rxfile <file> #Save all rx data to a file\n"
" \n"
"\n"
" -tx_ss7_type <digit> # 1=FISU 2=LSSU (repeating)\n"
" -rx_ss7_timer <digit> #Force receive timeout value \n"
"\n"
" -rxcnt <digit> #number of rx packets before exit\n"
" #this number overwrites the txcnt\n"
" #Thus, app will only exit after it\n"
" #receives the rxcnt number of packets.\n"
" \n"
" -verbose #Enable verbose mode\n"
"\n"
"<datascope options>\n"
"\n"
" -prot <digit> #Protocol Bit map: \n"
" #1=FISU, 2=LSSU, 4=MSU, 8=RAW HDLC\n"
" \n"
" -prot_opt <digit> #Protocol bit map\n"
" #0=None, 1=Delta, 2=Max Multiple\n"
"\n"
" -active_ch <digit> #Active channel\n"
" #ALL = all channels \n"
" #1 24 = 1 to 24 \n"
" #1.24 = 1 and 24 \n"
" #1-4.7-15 = 1 to 4 and 7 to 15\n"
" \n"
" -max_mult_cnt <digit> #If Prot_opt == 2 \n"
" #max_mult_cnt is the number of \n"
" #consecutive duplicate frames \n"
" #received before pass up the stack.\n"
" \n"
" -7bit_hdlc <digit> #Enable 7 Bit Hdlc Engine\n"
" #1=Enable 0=Disable\n"
" \n"
" -dir <digit> #Direction 0: Rx 1: Tx none: All\n"
"\n"
"<x25 protocol options>\n"
"\n"
" -txchan <digit> #Number of channels (dflt=1)\n"
" -cause <digit> #disconnect cause (dflt=0)\n"
" -diagn <digit> #disconnect diagnostic (dflt=0)\n"
"\n";
void usage(unsigned char *api_name)
{
printf ("\n\nAPI %s USAGE:\n\n%s <options> <extra options>\n\n%s\n",
api_name,api_name,api_usage);
}
/*============================================================================
* TE1
*/
unsigned long get_active_channels(int channel_flag, int start_channel, int stop_channel)
{
int i = 0;
unsigned long tmp = 0, mask = 0;
if ((channel_flag & (SINGLE_CHANNEL | RANGE_CHANNEL)) == 0)
return tmp;
if (channel_flag & RANGE_CHANNEL) { /* Range of channels */
for(i = start_channel; i <= stop_channel; i++) {
mask = 1 << (i - 1);
tmp |=mask;
}
} else { /* Single channel */
mask = 1 << (stop_channel - 1);
tmp |= mask;
}
return tmp;
}
unsigned long parse_active_channel(char* val)
{
int channel_flag = 0;
char* ptr = val;
int channel = 0, start_channel = 0;
unsigned long tmp = 0;
if (strcmp(val,"ALL") == 0)
return ENABLE_ALL_CHANNELS;
while(*ptr != '\0') {
if (isdigit(*ptr)) {
channel = strtoul(ptr, &ptr, 10);
channel_flag |= SINGLE_CHANNEL;
} else {
if (*ptr == '-') {
channel_flag |= RANGE_CHANNEL;
start_channel = channel;
} else {
tmp |= get_active_channels(channel_flag, start_channel, channel);
channel_flag = 0;
}
ptr++;
}
}
if (channel_flag){
tmp |= get_active_channels(channel_flag, start_channel, channel);
}
return tmp;
}
void u_delay(int usec)
{
struct timeval tv;
tv.tv_usec = usec;
tv.tv_sec=0;
select(0,NULL,NULL, NULL, &tv);
}

View File

@ -34,17 +34,17 @@ wan_udp_hdr_t wan_udp;
#include "win_api_common.h" #include "win_api_common.h"
static wan_cmd_api_t api_cmd; static wan_cmd_api_t api_cmd;
static api_tx_hdr_t *tx_hdr = (api_tx_hdr_t *) api_cmd.data; static api_tx_hdr_t *tx_hdr = (api_tx_hdr_t *)api_cmd.data;
/* keeps the LAST (and single) event received */ /* keeps the LAST (and single) event received */
static wp_tdm_api_rx_hdr_t last_tdm_api_event_buffer; static wp_tdm_api_rx_hdr_t last_tdm_api_event_buffer;
#endif /* WIN32 */ #endif /* WIN32 */
void sangoma_socket_close(sng_fd_t * sp) void sangoma_socket_close(sng_fd_t *sp)
{ {
#if defined(WIN32) #if defined(WIN32)
if (*sp != INVALID_HANDLE_VALUE) { if( *sp != INVALID_HANDLE_VALUE){
CloseHandle(*sp); CloseHandle(*sp);
*sp = INVALID_HANDLE_VALUE; *sp = INVALID_HANDLE_VALUE;
} }
@ -65,22 +65,25 @@ int sangoma_socket_waitfor(sng_fd_t fd, int timeout, int flags)
api_poll.user_flags_bitmap = flags; api_poll.user_flags_bitmap = flags;
if (DoApiPollCommand(fd, &api_poll)) { if(DoApiPollCommand(fd, &api_poll)){
//failed //failed
return 0; return 0;
} }
switch (api_poll.operation_status) { switch(api_poll.operation_status)
{
case SANG_STATUS_RX_DATA_AVAILABLE: case SANG_STATUS_RX_DATA_AVAILABLE:
break; break;
default: default:
prn(1, "Error: sangoma_socket_waitfor(): Unknown Operation Status: %d\n", api_poll.operation_status); prn(1, "Error: sangoma_socket_waitfor(): Unknown Operation Status: %d\n",
api_poll.operation_status);
return 0; return 0;
} //switch() }//switch()
if (api_poll.poll_events_bitmap == 0) { if(api_poll.poll_events_bitmap == 0){
prn(1, "Error: invalid Poll Events bitmap: 0x%X\n", api_poll.poll_events_bitmap); prn(1, "Error: invalid Poll Events bitmap: 0x%X\n",
api_poll.poll_events_bitmap);
} }
return api_poll.poll_events_bitmap; return api_poll.poll_events_bitmap;
#else #else
@ -94,7 +97,7 @@ int sangoma_socket_waitfor(sng_fd_t fd, int timeout, int flags)
if (res > 0) { if (res > 0) {
if ((pfds[0].revents & POLLERR)) { if ((pfds[0].revents & POLLERR)) {
res = -1; res = -1;
} else if ((pfds[0].revents)) { } else if((pfds[0].revents)) {
res = 1; res = 1;
} }
} }
@ -106,13 +109,13 @@ int sangoma_socket_waitfor(sng_fd_t fd, int timeout, int flags)
int sangoma_span_chan_toif(int span, int chan, char *interface_name) int sangoma_span_chan_toif(int span, int chan, char *interface_name)
{ {
sprintf(interface_name, "s%ic%i", span, chan); sprintf(interface_name,"s%ic%i",span,chan);
return 0; return 0;
} }
int sangoma_interface_toi(char *interface_name, int *span, int *chan) int sangoma_interface_toi(char *interface_name, int *span, int *chan)
{ {
char *p = NULL, *sp = NULL, *ch = NULL; char *p=NULL, *sp = NULL, *ch = NULL;
int ret = 0; int ret = 0;
char data[FNAME_LEN]; char data[FNAME_LEN];
@ -128,7 +131,7 @@ int sangoma_interface_toi(char *interface_name, int *span, int *chan)
} }
} }
if (ch && sp) { if(ch && sp) {
*span = atoi(sp); *span = atoi(sp);
*chan = atoi(ch); *chan = atoi(ch);
ret = 1; ret = 1;
@ -159,7 +162,7 @@ int sangoma_span_chan_fromif(char *interface_name, int *span, int *chan)
} }
} }
if (ch && sp) { if(ch && sp) {
*span = atoi(sp); *span = atoi(sp);
*chan = atoi(ch); *chan = atoi(ch);
ret = 1; ret = 1;
@ -179,18 +182,22 @@ sng_fd_t sangoma_open_tdmapi_span_chan(int span, int chan)
//NOTE: under Windows Interfaces are zero based but 'chan' is 1 based. //NOTE: under Windows Interfaces are zero based but 'chan' is 1 based.
// Subtract 1 from 'chan'. // Subtract 1 from 'chan'.
_snprintf(fname, FNAME_LEN, "\\\\.\\WANPIPE%d_IF%d", span, chan - 1); _snprintf(fname , FNAME_LEN, "\\\\.\\WANPIPE%d_IF%d", span, chan - 1);
//prn(verbose, "Opening device: %s...\n", fname); //prn(verbose, "Opening device: %s...\n", fname);
return CreateFile(fname, return CreateFile( fname,
GENERIC_READ | GENERIC_WRITE, GENERIC_READ | GENERIC_WRITE,
FILE_SHARE_READ | FILE_SHARE_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE,
(LPSECURITY_ATTRIBUTES) NULL, OPEN_EXISTING, FILE_FLAG_NO_BUFFERING | FILE_FLAG_WRITE_THROUGH, (HANDLE) NULL); (LPSECURITY_ATTRIBUTES)NULL,
OPEN_EXISTING,
FILE_FLAG_NO_BUFFERING | FILE_FLAG_WRITE_THROUGH,
(HANDLE)NULL
);
#else #else
int fd = -1; int fd=-1;
sprintf(fname, "/dev/wptdm_s%dc%d", span, chan); sprintf(fname,"/dev/wptdm_s%dc%d",span,chan);
fd = open(fname, O_RDWR); fd = open(fname, O_RDWR);
@ -200,53 +207,56 @@ sng_fd_t sangoma_open_tdmapi_span_chan(int span, int chan)
sng_fd_t sangoma_create_socket_by_name(char *device, char *card) sng_fd_t sangoma_create_socket_by_name(char *device, char *card)
{ {
int span, chan; int span,chan;
sangoma_interface_toi(device, &span, &chan); sangoma_interface_toi(device,&span,&chan);
return sangoma_open_tdmapi_span_chan(span, chan); return sangoma_open_tdmapi_span_chan(span,chan);
} }
sng_fd_t sangoma_open_tdmapi_span(int span) sng_fd_t sangoma_open_tdmapi_span(int span)
{ {
int i = 0; int i=0;
#if defined(WIN32) #if defined(WIN32)
sng_fd_t fd = INVALID_HANDLE_VALUE; sng_fd_t fd = INVALID_HANDLE_VALUE;
for (i = 1; i < 32; i++) { for(i = 1; i < 32; i++){
if ((fd = sangoma_open_tdmapi_span_chan(span, i)) == INVALID_HANDLE_VALUE) { if((fd = sangoma_open_tdmapi_span_chan(span, i)) == INVALID_HANDLE_VALUE){
//prn(verbose, "Span: %d, chan: %d: is not running, consider 'busy'\n", //prn(verbose, "Span: %d, chan: %d: is not running, consider 'busy'\n",
// span, i); // span, i);
continue; continue;
} }
//get the open handle counter //get the open handle counter
wan_udp.wan_udphdr_command = GET_OPEN_HANDLES_COUNTER; wan_udp.wan_udphdr_command = GET_OPEN_HANDLES_COUNTER;
wan_udp.wan_udphdr_data_len = 0; wan_udp.wan_udphdr_data_len = 0;
DoManagementCommand(fd, &wan_udp); DoManagementCommand(fd, &wan_udp);
if (wan_udp.wan_udphdr_return_code) { if(wan_udp.wan_udphdr_return_code){
prn(1, "Error: command GET_OPEN_HANDLES_COUNTER failed! Span: %d, chan: %d\n", span, i); prn(1, "Error: command GET_OPEN_HANDLES_COUNTER failed! Span: %d, chan: %d\n",
span, i);
//don't forget to close!! otherwize counter will stay incremented. //don't forget to close!! otherwize counter will stay incremented.
sangoma_socket_close(&fd); sangoma_socket_close(&fd);
continue; continue;
} }
//prn(verbose, "open handles counter: %d\n", *(int*)&wan_udp.wan_udphdr_data[0]); //prn(verbose, "open handles counter: %d\n", *(int*)&wan_udp.wan_udphdr_data[0]);
if (*(int *) &wan_udp.wan_udphdr_data[0] == 1) { if(*(int*)&wan_udp.wan_udphdr_data[0] == 1){
//this is the only process using this chan/span, so it is 'free' //this is the only process using this chan/span, so it is 'free'
//prn(verbose, "Found 'free' Span: %d, chan: %d\n",span, i); //prn(verbose, "Found 'free' Span: %d, chan: %d\n",span, i);
break; break;
} }
//don't forget to close!! otherwize counter will stay incremented. //don't forget to close!! otherwize counter will stay incremented.
sangoma_socket_close(&fd); sangoma_socket_close(&fd);
} //for() }//for()
#else #else
unsigned char fname[FNAME_LEN]; unsigned char fname[FNAME_LEN];
int fd = 0; int fd=0;
for (i = 1; i < 32; i++) { for (i=1;i<32;i++){
sprintf(fname, "/dev/wptdm_s%dc%d", span, i); sprintf(fname,"/dev/wptdm_s%dc%d",span,i);
fd = open(fname, O_RDWR); fd = open(fname, O_RDWR);
if (fd < 0) { if (fd < 0){
continue; continue;
} }
break; break;
@ -257,38 +267,40 @@ sng_fd_t sangoma_open_tdmapi_span(int span)
int sangoma_readmsg_tdm(sng_fd_t fd, void *hdrbuf, int hdrlen, void *databuf, int datalen, int flag) int sangoma_readmsg_tdm(sng_fd_t fd, void *hdrbuf, int hdrlen, void *databuf, int datalen, int flag)
{ {
int rx_len = 0; int rx_len=0;
#if defined(WIN32) #if defined(WIN32)
static RX_DATA_STRUCT rx_data; static RX_DATA_STRUCT rx_data;
api_header_t *pri; api_header_t *pri;
wp_tdm_api_rx_hdr_t *tdm_api_rx_hdr; 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; wp_tdm_api_rx_hdr_t *user_buf = (wp_tdm_api_rx_hdr_t*)hdrbuf;
if (hdrlen != sizeof(wp_tdm_api_rx_hdr_t)) { if(hdrlen != sizeof(wp_tdm_api_rx_hdr_t)){
//error //error
prn(1, "Error: sangoma_readmsg_tdm(): invalid size of user's 'header buffer'.\ prn(1, "Error: sangoma_readmsg_tdm(): invalid size of user's 'header buffer'.\
Should be 'sizeof(wp_tdm_api_rx_hdr_t)'.\n"); Should be 'sizeof(wp_tdm_api_rx_hdr_t)'.\n");
return -1; return -1;
} }
if (DoReadCommand(fd, &rx_data)) { if(DoReadCommand(fd, &rx_data) ){
//error //error
prn(1, "Error: DoReadCommand() failed! Check messages log.\n"); prn(1, "Error: DoReadCommand() failed! Check messages log.\n");
return -1; return -1;
} }
//use our special buffer at rxdata to hold received data //use our special buffer at rxdata to hold received data
pri = &rx_data.api_header; pri = &rx_data.api_header;
tdm_api_rx_hdr = (wp_tdm_api_rx_hdr_t *) rx_data.data; tdm_api_rx_hdr = (wp_tdm_api_rx_hdr_t*)rx_data.data;
user_buf->wp_tdm_api_event_type = pri->operation_status; user_buf->wp_tdm_api_event_type = pri->operation_status;
switch (pri->operation_status) { switch(pri->operation_status)
{
case SANG_STATUS_RX_DATA_AVAILABLE: case SANG_STATUS_RX_DATA_AVAILABLE:
//prn(verbose, "SANG_STATUS_RX_DATA_AVAILABLE\n"); //prn(verbose, "SANG_STATUS_RX_DATA_AVAILABLE\n");
if (pri->data_length > datalen) { if(pri->data_length > datalen){
rx_len = 0; rx_len=0;
break; break;
} }
memcpy(databuf, rx_data.data, pri->data_length); memcpy(databuf, rx_data.data, pri->data_length);
@ -303,11 +315,12 @@ Should be 'sizeof(wp_tdm_api_rx_hdr_t)'.\n");
rx_len = pri->data_length; rx_len = pri->data_length;
//make copy for use with sangoma_tdm_read_event() - indirect access. //make copy for use with sangoma_tdm_read_event() - indirect access.
memcpy(&last_tdm_api_event_buffer, tdm_api_rx_hdr, sizeof(wp_tdm_api_rx_hdr_t)); memcpy( &last_tdm_api_event_buffer, tdm_api_rx_hdr, sizeof(wp_tdm_api_rx_hdr_t));
break; break;
default: default:
switch (pri->operation_status) { switch(pri->operation_status)
{
case SANG_STATUS_RX_DATA_TIMEOUT: case SANG_STATUS_RX_DATA_TIMEOUT:
//no data in READ_CMD_TIMEOUT, try again. //no data in READ_CMD_TIMEOUT, try again.
prn(1, "Error: Timeout on read.\n"); prn(1, "Error: Timeout on read.\n");
@ -331,32 +344,32 @@ Should be 'sizeof(wp_tdm_api_rx_hdr_t)'.\n");
default: default:
prn(1, "Rx:Unknown Operation Status: %d\n", pri->operation_status); prn(1, "Rx:Unknown Operation Status: %d\n", pri->operation_status);
break; break;
} //switch() }//switch()
return 0; return 0;
} //switch() }//switch()
#else #else
struct msghdr msg; struct msghdr msg;
struct iovec iov[2]; struct iovec iov[2];
memset(&msg, 0, sizeof(struct msghdr)); memset(&msg,0,sizeof(struct msghdr));
iov[0].iov_len = hdrlen; iov[0].iov_len=hdrlen;
iov[0].iov_base = hdrbuf; iov[0].iov_base=hdrbuf;
iov[1].iov_len = datalen; iov[1].iov_len=datalen;
iov[1].iov_base = databuf; iov[1].iov_base=databuf;
msg.msg_iovlen = 2; msg.msg_iovlen=2;
msg.msg_iov = iov; msg.msg_iov=iov;
rx_len = read(fd, &msg, datalen + hdrlen); rx_len = read(fd,&msg,datalen+hdrlen);
if (rx_len <= sizeof(wp_tdm_api_rx_hdr_t)) { if (rx_len <= sizeof(wp_tdm_api_rx_hdr_t)){
return -EINVAL; return -EINVAL;
} }
rx_len -= sizeof(wp_tdm_api_rx_hdr_t); rx_len-=sizeof(wp_tdm_api_rx_hdr_t);
#endif #endif
return rx_len; return rx_len;
} }
@ -375,15 +388,16 @@ int sangoma_writemsg_tdm(sng_fd_t fd, void *hdrbuf, int hdrlen, void *databuf, u
memcpy(local_tx_data.data, databuf, pri->data_length); memcpy(local_tx_data.data, databuf, pri->data_length);
//queue data for transmission //queue data for transmission
if (DoWriteCommand(fd, &local_tx_data)) { if( DoWriteCommand(fd, &local_tx_data)){
//error //error
prn(1, "Error: DoWriteCommand() failed!! Check messages log.\n"); prn(1, "Error: DoWriteCommand() failed!! Check messages log.\n");
return -1; return -1;
} }
bsent = 0; bsent=0;
//check that frame was transmitted //check that frame was transmitted
switch (local_tx_data.api_header.operation_status) { switch(local_tx_data.api_header.operation_status)
{
case SANG_STATUS_SUCCESS: case SANG_STATUS_SUCCESS:
bsent = datalen; bsent = datalen;
break; break;
@ -416,27 +430,28 @@ int sangoma_writemsg_tdm(sng_fd_t fd, void *hdrbuf, int hdrlen, void *databuf, u
break; break;
default: default:
prn(1, "Unknown return code (0x%X) on transmission!\n", local_tx_data.api_header.operation_status); prn(1, "Unknown return code (0x%X) on transmission!\n",
local_tx_data.api_header.operation_status);
break; break;
} //switch() }//switch()
#else #else
struct msghdr msg; struct msghdr msg;
struct iovec iov[2]; struct iovec iov[2];
memset(&msg, 0, sizeof(struct msghdr)); memset(&msg,0,sizeof(struct msghdr));
iov[0].iov_len = hdrlen; iov[0].iov_len=hdrlen;
iov[0].iov_base = hdrbuf; iov[0].iov_base=hdrbuf;
iov[1].iov_len = datalen; iov[1].iov_len=datalen;
iov[1].iov_base = databuf; iov[1].iov_base=databuf;
msg.msg_iovlen = 2; msg.msg_iovlen=2;
msg.msg_iov = iov; msg.msg_iov=iov;
bsent = write(fd, &msg, datalen + hdrlen); bsent = write(fd,&msg,datalen+hdrlen);
if (bsent > 0) { if (bsent > 0){
bsent -= sizeof(wp_tdm_api_tx_hdr_t); bsent-=sizeof(wp_tdm_api_tx_hdr_t);
} }
#endif #endif
return bsent; return bsent;
@ -449,17 +464,17 @@ int sangoma_writemsg_tdm(sng_fd_t fd, void *hdrbuf, int hdrlen, void *databuf, u
* Execute TDM command * Execute TDM command
* *
*/ */
static int sangoma_tdm_cmd_exec(sng_fd_t fd, wanpipe_tdm_api_t * tdm_api) static int sangoma_tdm_cmd_exec(sng_fd_t fd, wanpipe_tdm_api_t *tdm_api)
{ {
int err; int err;
#if defined(WIN32) #if defined(WIN32)
err = tdmv_api_ioctl(fd, &tdm_api->wp_tdm_cmd); err = tdmv_api_ioctl(fd, &tdm_api->wp_tdm_cmd);
#else #else
err = ioctl(fd, SIOC_WANPIPE_TDM_API, &tdm_api->wp_tdm_cmd); err = ioctl(fd,SIOC_WANPIPE_TDM_API,&tdm_api->wp_tdm_cmd);
if (err < 0) { if (err < 0){
char tmp[50]; char tmp[50];
sprintf(tmp, "TDM API: CMD: %i\n", tdm_api->wp_tdm_cmd.cmd); sprintf(tmp,"TDM API: CMD: %i\n",tdm_api->wp_tdm_cmd.cmd);
perror(tmp); perror(tmp);
return -1; return -1;
} }
@ -471,33 +486,38 @@ static int sangoma_tdm_cmd_exec(sng_fd_t fd, wanpipe_tdm_api_t * tdm_api)
* Get Full TDM API configuration per channel * Get Full TDM API configuration per channel
* *
*/ */
int sangoma_get_full_cfg(sng_fd_t fd, wanpipe_tdm_api_t * tdm_api) int sangoma_get_full_cfg(sng_fd_t fd, wanpipe_tdm_api_t *tdm_api)
{ {
int err; int err;
tdm_api->wp_tdm_cmd.cmd = SIOC_WP_TDM_GET_FULL_CFG; tdm_api->wp_tdm_cmd.cmd = SIOC_WP_TDM_GET_FULL_CFG;
err = sangoma_tdm_cmd_exec(fd, tdm_api); err=sangoma_tdm_cmd_exec(fd,tdm_api);
if (err) { if (err){
return err; return err;
} }
printf("TDM API CFG:\n"); printf("TDM API CFG:\n");
printf("\thw_tdm_coding:\t%d\n", tdm_api->wp_tdm_cmd.hw_tdm_coding); printf("\thw_tdm_coding:\t%d\n",tdm_api->wp_tdm_cmd.hw_tdm_coding);
printf("\tusr_mtu_mru:\t%d\n", tdm_api->wp_tdm_cmd.hw_mtu_mru); printf("\tusr_mtu_mru:\t%d\n",tdm_api->wp_tdm_cmd.hw_mtu_mru);
printf("\tusr_period:\t%d\n", tdm_api->wp_tdm_cmd.usr_period); printf("\tusr_period:\t%d\n",tdm_api->wp_tdm_cmd.usr_period);
printf("\ttdm_codec:\t%d\n", tdm_api->wp_tdm_cmd.tdm_codec); printf("\ttdm_codec:\t%d\n",tdm_api->wp_tdm_cmd.tdm_codec);
printf("\tpower_level:\t%d\n", tdm_api->wp_tdm_cmd.power_level); printf("\tpower_level:\t%d\n",tdm_api->wp_tdm_cmd.power_level);
printf("\trx_disable:\t%d\n", tdm_api->wp_tdm_cmd.rx_disable); printf("\trx_disable:\t%d\n",tdm_api->wp_tdm_cmd.rx_disable);
printf("\ttx_disable:\t%d\n", tdm_api->wp_tdm_cmd.tx_disable); printf("\ttx_disable:\t%d\n",tdm_api->wp_tdm_cmd.tx_disable);
printf("\tusr_mtu_mru:\t%d\n", tdm_api->wp_tdm_cmd.usr_mtu_mru); printf("\tusr_mtu_mru:\t%d\n",tdm_api->wp_tdm_cmd.usr_mtu_mru);
printf("\tidle flag:\t0x%02X\n", tdm_api->wp_tdm_cmd.idle_flag); printf("\tidle flag:\t0x%02X\n",tdm_api->wp_tdm_cmd.idle_flag);
printf("\tfe alarms:\t0x%02X\n", tdm_api->wp_tdm_cmd.fe_alarms); printf("\tfe alarms:\t0x%02X\n",tdm_api->wp_tdm_cmd.fe_alarms);
printf("\trx pkt\t%d\ttx pkt\t%d\n", tdm_api->wp_tdm_cmd.stats.rx_packets, tdm_api->wp_tdm_cmd.stats.tx_packets); printf("\trx pkt\t%d\ttx pkt\t%d\n",tdm_api->wp_tdm_cmd.stats.rx_packets,
printf("\trx err\t%d\ttx err\t%d\n", tdm_api->wp_tdm_cmd.stats.rx_errors, tdm_api->wp_tdm_cmd.stats.tx_errors); tdm_api->wp_tdm_cmd.stats.tx_packets);
printf("\trx err\t%d\ttx err\t%d\n",
tdm_api->wp_tdm_cmd.stats.rx_errors,
tdm_api->wp_tdm_cmd.stats.tx_errors);
#ifndef __WINDOWS__ #ifndef __WINDOWS__
printf("\trx ovr\t%d\ttx idl\t%d\n", tdm_api->wp_tdm_cmd.stats.rx_fifo_errors, tdm_api->wp_tdm_cmd.stats.tx_carrier_errors); printf("\trx ovr\t%d\ttx idl\t%d\n",
tdm_api->wp_tdm_cmd.stats.rx_fifo_errors,
tdm_api->wp_tdm_cmd.stats.tx_carrier_errors);
#endif #endif
return 0; return 0;
@ -515,14 +535,14 @@ int sangoma_get_full_cfg(sng_fd_t fd, wanpipe_tdm_api_t * tdm_api)
* } * }
* *
*/ */
int sangoma_tdm_set_codec(sng_fd_t fd, wanpipe_tdm_api_t * tdm_api, int codec) int sangoma_tdm_set_codec(sng_fd_t fd, wanpipe_tdm_api_t *tdm_api, int codec)
{ {
int err; int err;
tdm_api->wp_tdm_cmd.cmd = SIOC_WP_TDM_SET_CODEC; tdm_api->wp_tdm_cmd.cmd = SIOC_WP_TDM_SET_CODEC;
tdm_api->wp_tdm_cmd.tdm_codec = codec; tdm_api->wp_tdm_cmd.tdm_codec = codec;
err = sangoma_tdm_cmd_exec(fd, tdm_api); err=sangoma_tdm_cmd_exec(fd,tdm_api);
return err; return err;
} }
@ -539,14 +559,14 @@ int sangoma_tdm_set_codec(sng_fd_t fd, wanpipe_tdm_api_t * tdm_api, int codec)
* } * }
* *
*/ */
int sangoma_tdm_get_codec(sng_fd_t fd, wanpipe_tdm_api_t * tdm_api) int sangoma_tdm_get_codec(sng_fd_t fd, wanpipe_tdm_api_t *tdm_api)
{ {
int err; int err;
tdm_api->wp_tdm_cmd.cmd = SIOC_WP_TDM_GET_CODEC; tdm_api->wp_tdm_cmd.cmd = SIOC_WP_TDM_GET_CODEC;
err = sangoma_tdm_cmd_exec(fd, tdm_api); err=sangoma_tdm_cmd_exec(fd,tdm_api);
if (err) { if (err){
return err; return err;
} }
@ -561,14 +581,14 @@ int sangoma_tdm_get_codec(sng_fd_t fd, wanpipe_tdm_api_t * tdm_api)
* 10,20,30,40,50 ms * 10,20,30,40,50 ms
* *
*/ */
int sangoma_tdm_set_usr_period(sng_fd_t fd, wanpipe_tdm_api_t * tdm_api, int period) int sangoma_tdm_set_usr_period(sng_fd_t fd, wanpipe_tdm_api_t *tdm_api, int period)
{ {
int err; int err;
tdm_api->wp_tdm_cmd.cmd = SIOC_WP_TDM_SET_USR_PERIOD; tdm_api->wp_tdm_cmd.cmd = SIOC_WP_TDM_SET_USR_PERIOD;
tdm_api->wp_tdm_cmd.usr_period = period; tdm_api->wp_tdm_cmd.usr_period = period;
err = sangoma_tdm_cmd_exec(fd, tdm_api); err=sangoma_tdm_cmd_exec(fd,tdm_api);
return err; return err;
} }
@ -580,14 +600,14 @@ int sangoma_tdm_set_usr_period(sng_fd_t fd, wanpipe_tdm_api_t * tdm_api, int per
* 10,20,30,40,50 ms * 10,20,30,40,50 ms
* *
*/ */
int sangoma_tdm_get_usr_period(sng_fd_t fd, wanpipe_tdm_api_t * tdm_api) int sangoma_tdm_get_usr_period(sng_fd_t fd, wanpipe_tdm_api_t *tdm_api)
{ {
int err; int err;
tdm_api->wp_tdm_cmd.cmd = SIOC_WP_TDM_GET_USR_PERIOD; tdm_api->wp_tdm_cmd.cmd = SIOC_WP_TDM_GET_USR_PERIOD;
err = sangoma_tdm_cmd_exec(fd, tdm_api); err=sangoma_tdm_cmd_exec(fd,tdm_api);
if (err) { if (err){
return err; return err;
} }
@ -600,12 +620,12 @@ int sangoma_tdm_get_usr_period(sng_fd_t fd, wanpipe_tdm_api_t * tdm_api)
* Coding Format will be ULAW/ALAW based on T1/E1 * Coding Format will be ULAW/ALAW based on T1/E1
*/ */
int sangoma_tdm_get_hw_coding(int fd, wanpipe_tdm_api_t * tdm_api) int sangoma_tdm_get_hw_coding(int fd, wanpipe_tdm_api_t *tdm_api)
{ {
int err; int err;
tdm_api->wp_tdm_cmd.cmd = SIOC_WP_TDM_GET_HW_CODING; tdm_api->wp_tdm_cmd.cmd = SIOC_WP_TDM_GET_HW_CODING;
err = sangoma_tdm_cmd_exec(fd, tdm_api); err=sangoma_tdm_cmd_exec(fd,tdm_api);
if (err) { if (err){
return err; return err;
} }
return tdm_api->wp_tdm_cmd.hw_tdm_coding; return tdm_api->wp_tdm_cmd.hw_tdm_coding;
@ -618,14 +638,14 @@ int sangoma_tdm_get_hw_coding(int fd, wanpipe_tdm_api_t * tdm_api)
* The USER MTU/MRU values will change each time a PERIOD * The USER MTU/MRU values will change each time a PERIOD
* or CODEC is adjusted. * or CODEC is adjusted.
*/ */
int sangoma_tdm_get_usr_mtu_mru(sng_fd_t fd, wanpipe_tdm_api_t * tdm_api) int sangoma_tdm_get_usr_mtu_mru(sng_fd_t fd, wanpipe_tdm_api_t *tdm_api)
{ {
int err; int err;
tdm_api->wp_tdm_cmd.cmd = SIOC_WP_TDM_GET_USR_MTU_MRU; tdm_api->wp_tdm_cmd.cmd = SIOC_WP_TDM_GET_USR_MTU_MRU;
err = sangoma_tdm_cmd_exec(fd, tdm_api); err=sangoma_tdm_cmd_exec(fd,tdm_api);
if (err) { if (err){
return err; return err;
} }
@ -638,14 +658,14 @@ int sangoma_tdm_get_usr_mtu_mru(sng_fd_t fd, wanpipe_tdm_api_t * tdm_api)
* This option is not implemented yet * This option is not implemented yet
* *
*/ */
int sangoma_tdm_set_power_level(sng_fd_t fd, wanpipe_tdm_api_t * tdm_api, int power) int sangoma_tdm_set_power_level(sng_fd_t fd, wanpipe_tdm_api_t *tdm_api, int power)
{ {
int err; int err;
tdm_api->wp_tdm_cmd.cmd = SIOC_WP_TDM_SET_POWER_LEVEL; tdm_api->wp_tdm_cmd.cmd = SIOC_WP_TDM_SET_POWER_LEVEL;
tdm_api->wp_tdm_cmd.power_level = power; tdm_api->wp_tdm_cmd.power_level = power;
err = sangoma_tdm_cmd_exec(fd, tdm_api); err=sangoma_tdm_cmd_exec(fd,tdm_api);
return err; return err;
} }
@ -656,43 +676,42 @@ int sangoma_tdm_set_power_level(sng_fd_t fd, wanpipe_tdm_api_t * tdm_api, int po
* This option is not implemented yet * This option is not implemented yet
* *
*/ */
int sangoma_tdm_get_power_level(sng_fd_t fd, wanpipe_tdm_api_t * tdm_api) int sangoma_tdm_get_power_level(sng_fd_t fd, wanpipe_tdm_api_t *tdm_api)
{ {
int err; int err;
tdm_api->wp_tdm_cmd.cmd = SIOC_WP_TDM_GET_POWER_LEVEL; tdm_api->wp_tdm_cmd.cmd = SIOC_WP_TDM_GET_POWER_LEVEL;
err = sangoma_tdm_cmd_exec(fd, tdm_api); err=sangoma_tdm_cmd_exec(fd,tdm_api);
if (err) { if (err){
return err; return err;
} }
return tdm_api->wp_tdm_cmd.power_level; return tdm_api->wp_tdm_cmd.power_level;
} }
int sangoma_tdm_flush_bufs(sng_fd_t fd, wanpipe_tdm_api_t * tdm_api) int sangoma_tdm_flush_bufs(sng_fd_t fd, wanpipe_tdm_api_t *tdm_api)
{ {
#if 0 #if 0
tdm_api->wp_tdm_cmd.cmd = SIOC_WP_TDM_FLUSH_BUFFERS; tdm_api->wp_tdm_cmd.cmd = SIOC_WP_TDM_FLUSH_BUFFERS;
err = sangoma_tdm_cmd_exec(fd, tdm_api); err=sangoma_tdm_cmd_exec(fd,tdm_api);
if (err) { if (err){
return err; return err;
} }
#endif #endif
return 0; return 0;
} }
int sangoma_tdm_enable_rbs_events(sng_fd_t fd, wanpipe_tdm_api_t * tdm_api, int poll_in_sec) int sangoma_tdm_enable_rbs_events(sng_fd_t fd, wanpipe_tdm_api_t *tdm_api, int poll_in_sec) {
{
int err; int err;
tdm_api->wp_tdm_cmd.cmd = SIOC_WP_TDM_ENABLE_RBS_EVENTS; tdm_api->wp_tdm_cmd.cmd = SIOC_WP_TDM_ENABLE_RBS_EVENTS;
tdm_api->wp_tdm_cmd.rbs_poll = poll_in_sec; tdm_api->wp_tdm_cmd.rbs_poll=poll_in_sec;
err = sangoma_tdm_cmd_exec(fd, tdm_api); err=sangoma_tdm_cmd_exec(fd,tdm_api);
if (err) { if (err){
return err; return err;
} }
@ -700,36 +719,35 @@ int sangoma_tdm_enable_rbs_events(sng_fd_t fd, wanpipe_tdm_api_t * tdm_api, int
} }
int sangoma_tdm_disable_rbs_events(sng_fd_t fd, wanpipe_tdm_api_t * tdm_api) int sangoma_tdm_disable_rbs_events(sng_fd_t fd, wanpipe_tdm_api_t *tdm_api) {
{
int err; int err;
tdm_api->wp_tdm_cmd.cmd = SIOC_WP_TDM_DISABLE_RBS_EVENTS; tdm_api->wp_tdm_cmd.cmd = SIOC_WP_TDM_DISABLE_RBS_EVENTS;
err = sangoma_tdm_cmd_exec(fd, tdm_api); err=sangoma_tdm_cmd_exec(fd,tdm_api);
if (err) { if (err){
return err; return err;
} }
return 0; return 0;
} }
int sangoma_tdm_write_rbs(sng_fd_t fd, wanpipe_tdm_api_t * tdm_api, unsigned char rbs) int sangoma_tdm_write_rbs(sng_fd_t fd, wanpipe_tdm_api_t *tdm_api, unsigned char rbs)
{ {
int err; int err;
tdm_api->wp_tdm_cmd.cmd = SIOC_WP_TDM_WRITE_RBS_BITS; tdm_api->wp_tdm_cmd.cmd = SIOC_WP_TDM_WRITE_RBS_BITS;
tdm_api->wp_tdm_cmd.rbs_tx_bits = rbs; tdm_api->wp_tdm_cmd.rbs_tx_bits=rbs;
err = sangoma_tdm_cmd_exec(fd, tdm_api); err=sangoma_tdm_cmd_exec(fd,tdm_api);
if (err) { if (err){
return err; return err;
} }
return 0; return 0;
} }
int sangoma_tdm_read_event(sng_fd_t fd, wanpipe_tdm_api_t * tdm_api) int sangoma_tdm_read_event(sng_fd_t fd, wanpipe_tdm_api_t *tdm_api)
{ {
wp_tdm_api_rx_hdr_t *rx_event; wp_tdm_api_rx_hdr_t *rx_event;
@ -740,140 +758,146 @@ int sangoma_tdm_read_event(sng_fd_t fd, wanpipe_tdm_api_t * tdm_api)
tdm_api->wp_tdm_cmd.cmd = SIOC_WP_TDM_READ_EVENT; tdm_api->wp_tdm_cmd.cmd = SIOC_WP_TDM_READ_EVENT;
err = sangoma_tdm_cmd_exec(fd, tdm_api); err=sangoma_tdm_cmd_exec(fd,tdm_api);
if (err) { if (err){
return err; return err;
} }
rx_event = &tdm_api->wp_tdm_cmd.event; rx_event = &tdm_api->wp_tdm_cmd.event;
#endif #endif
switch (rx_event->wp_tdm_api_event_type) { switch (rx_event->wp_tdm_api_event_type){
case WP_TDM_EVENT_RBS: case WP_TDM_EVENT_RBS:
printf("%d: GOT RBS EVENT %p\n", (int) fd, tdm_api->wp_tdm_event.wp_rbs_event); printf("%d: GOT RBS EVENT %p\n",(int)fd,tdm_api->wp_tdm_event.wp_rbs_event);
if (tdm_api->wp_tdm_event.wp_rbs_event) { if (tdm_api->wp_tdm_event.wp_rbs_event) {
tdm_api->wp_tdm_event.wp_rbs_event(fd, rx_event->wp_tdm_api_event_rbs_rx_bits); tdm_api->wp_tdm_event.wp_rbs_event(fd,rx_event->wp_tdm_api_event_rbs_rx_bits);
} }
break; break;
case WP_TDM_EVENT_DTMF: case WP_TDM_EVENT_DTMF:
printf("%d: GOT DTMF EVENT\n", (int) fd); printf("%d: GOT DTMF EVENT\n",(int)fd);
if (tdm_api->wp_tdm_event.wp_dtmf_event) { if (tdm_api->wp_tdm_event.wp_dtmf_event) {
tdm_api->wp_tdm_event.wp_dtmf_event(fd, tdm_api->wp_tdm_event.wp_dtmf_event(fd,
rx_event->wp_tdm_api_event_dtmf_digit, rx_event->wp_tdm_api_event_dtmf_digit,
rx_event->wp_tdm_api_event_dtmf_type, rx_event->wp_tdm_api_event_dtmf_port); rx_event->wp_tdm_api_event_dtmf_type,
rx_event->wp_tdm_api_event_dtmf_port);
} }
break; break;
case WP_TDM_EVENT_RXHOOK: case WP_TDM_EVENT_RXHOOK:
printf("%d: GOT RXHOOK EVENT\n", (int) fd); printf("%d: GOT RXHOOK EVENT\n",(int)fd);
if (tdm_api->wp_tdm_event.wp_rxhook_event) { if (tdm_api->wp_tdm_event.wp_rxhook_event) {
tdm_api->wp_tdm_event.wp_rxhook_event(fd, rx_event->wp_tdm_api_event_rxhook_state); tdm_api->wp_tdm_event.wp_rxhook_event(fd,
rx_event->wp_tdm_api_event_rxhook_state);
} }
break; break;
case WP_TDM_EVENT_RING_DETECT: case WP_TDM_EVENT_RING_DETECT:
printf("%d: GOT RXRING EVENT\n", (int) fd); printf("%d: GOT RXRING EVENT\n",(int)fd);
if (tdm_api->wp_tdm_event.wp_rxring_event) { if (tdm_api->wp_tdm_event.wp_rxring_event) {
tdm_api->wp_tdm_event.wp_rxring_event(fd, rx_event->wp_tdm_api_event_ring_state); tdm_api->wp_tdm_event.wp_rxring_event(fd,
rx_event->wp_tdm_api_event_ring_state);
} }
break; break;
case WP_TDM_EVENT_RING_TRIP: case WP_TDM_EVENT_RING_TRIP:
printf("%d: GOT RING TRIP EVENT\n", (int) fd); printf("%d: GOT RING TRIP EVENT\n",(int)fd);
if (tdm_api->wp_tdm_event.wp_ringtrip_event) { if (tdm_api->wp_tdm_event.wp_ringtrip_event) {
tdm_api->wp_tdm_event.wp_ringtrip_event(fd, rx_event->wp_tdm_api_event_ring_state); tdm_api->wp_tdm_event.wp_ringtrip_event(fd,
rx_event->wp_tdm_api_event_ring_state);
} }
break; break;
case WP_TDM_EVENT_FE_ALARM: case WP_TDM_EVENT_FE_ALARM:
printf("%d: GOT FE ALARMS EVENT %i\n", (int) fd, rx_event->wp_tdm_api_event_fe_alarm); printf("%d: GOT FE ALARMS EVENT %i\n",(int)fd,
rx_event->wp_tdm_api_event_fe_alarm);
if (tdm_api->wp_tdm_event.wp_fe_alarm_event) { if (tdm_api->wp_tdm_event.wp_fe_alarm_event) {
tdm_api->wp_tdm_event.wp_fe_alarm_event(fd, rx_event->wp_tdm_api_event_fe_alarm); tdm_api->wp_tdm_event.wp_fe_alarm_event(fd,
rx_event->wp_tdm_api_event_fe_alarm);
} }
default: default:
printf("%d: Unknown TDM event!", (int) fd); printf("%d: Unknown TDM event!", (int)fd);
break; break;
} }
return 0; return 0;
} }
int sangoma_tdm_enable_dtmf_events(sng_fd_t fd, wanpipe_tdm_api_t * tdm_api) int sangoma_tdm_enable_dtmf_events(sng_fd_t fd, wanpipe_tdm_api_t *tdm_api)
{ {
int err; int err;
tdm_api->wp_tdm_cmd.cmd = SIOC_WP_TDM_ENABLE_DTMF_EVENTS; tdm_api->wp_tdm_cmd.cmd = SIOC_WP_TDM_ENABLE_DTMF_EVENTS;
err = sangoma_tdm_cmd_exec(fd, tdm_api); err=sangoma_tdm_cmd_exec(fd,tdm_api);
if (err) { if (err){
return err; return err;
} }
return 0; return 0;
} }
int sangoma_tdm_disable_dtmf_events(sng_fd_t fd, wanpipe_tdm_api_t * tdm_api) int sangoma_tdm_disable_dtmf_events(sng_fd_t fd, wanpipe_tdm_api_t *tdm_api)
{ {
int err; int err;
tdm_api->wp_tdm_cmd.cmd = SIOC_WP_TDM_DISABLE_DTMF_EVENTS; tdm_api->wp_tdm_cmd.cmd = SIOC_WP_TDM_DISABLE_DTMF_EVENTS;
err = sangoma_tdm_cmd_exec(fd, tdm_api); err=sangoma_tdm_cmd_exec(fd,tdm_api);
if (err) { if (err){
return err; return err;
} }
return 0; return 0;
} }
int sangoma_tdm_enable_rm_dtmf_events(sng_fd_t fd, wanpipe_tdm_api_t * tdm_api) int sangoma_tdm_enable_rm_dtmf_events(sng_fd_t fd, wanpipe_tdm_api_t *tdm_api)
{ {
int err; int err;
tdm_api->wp_tdm_cmd.cmd = SIOC_WP_TDM_ENABLE_RM_DTMF_EVENTS; tdm_api->wp_tdm_cmd.cmd = SIOC_WP_TDM_ENABLE_RM_DTMF_EVENTS;
err = sangoma_tdm_cmd_exec(fd, tdm_api); err=sangoma_tdm_cmd_exec(fd,tdm_api);
if (err) { if (err){
return err; return err;
} }
return 0; return 0;
} }
int sangoma_tdm_disable_rm_dtmf_events(sng_fd_t fd, wanpipe_tdm_api_t * tdm_api) int sangoma_tdm_disable_rm_dtmf_events(sng_fd_t fd, wanpipe_tdm_api_t *tdm_api)
{ {
int err; int err;
tdm_api->wp_tdm_cmd.cmd = SIOC_WP_TDM_DISABLE_RM_DTMF_EVENTS; tdm_api->wp_tdm_cmd.cmd = SIOC_WP_TDM_DISABLE_RM_DTMF_EVENTS;
err = sangoma_tdm_cmd_exec(fd, tdm_api); err=sangoma_tdm_cmd_exec(fd,tdm_api);
if (err) { if (err){
return err; return err;
} }
return 0; return 0;
} }
int sangoma_tdm_enable_rxhook_events(sng_fd_t fd, wanpipe_tdm_api_t * tdm_api) int sangoma_tdm_enable_rxhook_events(sng_fd_t fd, wanpipe_tdm_api_t *tdm_api)
{ {
int err; int err;
tdm_api->wp_tdm_cmd.cmd = SIOC_WP_TDM_ENABLE_RXHOOK_EVENTS; tdm_api->wp_tdm_cmd.cmd = SIOC_WP_TDM_ENABLE_RXHOOK_EVENTS;
err = sangoma_tdm_cmd_exec(fd, tdm_api); err=sangoma_tdm_cmd_exec(fd,tdm_api);
if (err) { if (err){
return err; return err;
} }
return 0; return 0;
} }
int sangoma_tdm_disable_rxhook_events(sng_fd_t fd, wanpipe_tdm_api_t * tdm_api) int sangoma_tdm_disable_rxhook_events(sng_fd_t fd, wanpipe_tdm_api_t *tdm_api)
{ {
int err; int err;
tdm_api->wp_tdm_cmd.cmd = SIOC_WP_TDM_DISABLE_RXHOOK_EVENTS; tdm_api->wp_tdm_cmd.cmd = SIOC_WP_TDM_DISABLE_RXHOOK_EVENTS;
err = sangoma_tdm_cmd_exec(fd, tdm_api); err=sangoma_tdm_cmd_exec(fd,tdm_api);
if (err) { if (err){
return err; return err;
} }
@ -884,14 +908,14 @@ int sangoma_tdm_disable_rxhook_events(sng_fd_t fd, wanpipe_tdm_api_t * tdm_api)
* GET Front End Alarms * GET Front End Alarms
* *
*/ */
int sangoma_tdm_get_fe_alarms(sng_fd_t fd, wanpipe_tdm_api_t * tdm_api) int sangoma_tdm_get_fe_alarms(sng_fd_t fd, wanpipe_tdm_api_t *tdm_api)
{ {
int err; int err;
tdm_api->wp_tdm_cmd.cmd = SIOC_WP_TDM_GET_FE_ALARMS; tdm_api->wp_tdm_cmd.cmd = SIOC_WP_TDM_GET_FE_ALARMS;
err = sangoma_tdm_cmd_exec(fd, tdm_api); err=sangoma_tdm_cmd_exec(fd,tdm_api);
if (err) { if (err){
return err; return err;
} }

View File

@ -34,7 +34,7 @@ typedef unsigned __int32 u_int32_t;
#ifdef WANPIPE_TDM_API #ifdef WANPIPE_TDM_API
#include <wanpipe_tdm_api.h> //for TDMV API #include <wanpipe_tdm_api.h> //for TDMV API
#endif #endif
#include <sang_status_defines.h> //return codes #include <sang_status_defines.h>//return codes
#include <sang_api.h> //for IOCTL codes #include <sang_api.h> //for IOCTL codes
#include <sdla_te1_pmc.h> //RBS definitions #include <sdla_te1_pmc.h> //RBS definitions
#include <sdla_te1.h> //TE1 macros #include <sdla_te1.h> //TE1 macros
@ -105,63 +105,65 @@ sng_fd_t sangoma_open_tdmapi_span(int span);
* writemsg_tdm: tx header + data from separate buffers * writemsg_tdm: tx header + data from separate buffers
* readmsg_tdm: rx header + data to separate buffers * readmsg_tdm: rx header + data to separate buffers
*/ */
int sangoma_writemsg_tdm(sng_fd_t fd, void *hdrbuf, int hdrlen, void *databuf, unsigned short datalen, int flag); int sangoma_writemsg_tdm(sng_fd_t fd, void *hdrbuf, int hdrlen,
int sangoma_readmsg_tdm(sng_fd_t fd, void *hdrbuf, int hdrlen, void *databuf, int datalen, int flag); void *databuf, unsigned short datalen, int flag);
int sangoma_readmsg_tdm(sng_fd_t fd, void *hdrbuf, int hdrlen,
void *databuf, int datalen, int flag);
#define sangoma_readmsg_socket sangoma_readmsg_tdm #define sangoma_readmsg_socket sangoma_readmsg_tdm
#define sangoma_sendmsg_socket sangoma_writemsg_tdm #define sangoma_sendmsg_socket sangoma_writemsg_tdm
#ifdef WANPIPE_TDM_API #ifdef WANPIPE_TDM_API
void sangoma_socket_close(sng_fd_t * sp); void sangoma_socket_close(sng_fd_t *sp);
int sangoma_socket_waitfor(sng_fd_t fd, int timeout, int flags); int sangoma_socket_waitfor(sng_fd_t fd, int timeout, int flags);
/* Get Full TDM API configuration per chan */ /* Get Full TDM API configuration per chan */
int sangoma_get_full_cfg(sng_fd_t fd, wanpipe_tdm_api_t * tdm_api); int sangoma_get_full_cfg(sng_fd_t fd, wanpipe_tdm_api_t *tdm_api);
/* Get/Set TDM Codec per chan */ /* Get/Set TDM Codec per chan */
int sangoma_tdm_set_codec(sng_fd_t fd, wanpipe_tdm_api_t * tdm_api, int codec); int sangoma_tdm_set_codec(sng_fd_t fd, wanpipe_tdm_api_t *tdm_api, int codec);
int sangoma_tdm_get_codec(sng_fd_t fd, wanpipe_tdm_api_t * tdm_api); int sangoma_tdm_get_codec(sng_fd_t fd, wanpipe_tdm_api_t *tdm_api);
/* Get/Set USR Tx/Rx Period in milliseconds */ /* Get/Set USR Tx/Rx Period in milliseconds */
int sangoma_tdm_set_usr_period(sng_fd_t fd, wanpipe_tdm_api_t * tdm_api, int period); int sangoma_tdm_set_usr_period(sng_fd_t fd, wanpipe_tdm_api_t *tdm_api, int period);
int sangoma_tdm_get_usr_period(sng_fd_t fd, wanpipe_tdm_api_t * tdm_api); int sangoma_tdm_get_usr_period(sng_fd_t fd, wanpipe_tdm_api_t *tdm_api);
/* Get user MTU/MRU values in bytes */ /* Get user MTU/MRU values in bytes */
int sangoma_tdm_get_usr_mtu_mru(sng_fd_t fd, wanpipe_tdm_api_t * tdm_api); int sangoma_tdm_get_usr_mtu_mru(sng_fd_t fd, wanpipe_tdm_api_t *tdm_api);
/* Not supported yet */ /* Not supported yet */
int sangoma_tdm_set_power_level(sng_fd_t fd, wanpipe_tdm_api_t * tdm_api, int power); int sangoma_tdm_set_power_level(sng_fd_t fd, wanpipe_tdm_api_t *tdm_api, int power);
int sangoma_tdm_get_power_level(sng_fd_t fd, wanpipe_tdm_api_t * tdm_api); int sangoma_tdm_get_power_level(sng_fd_t fd, wanpipe_tdm_api_t *tdm_api);
/* Flush buffers from current channel */ /* Flush buffers from current channel */
int sangoma_tdm_flush_bufs(sng_fd_t fd, wanpipe_tdm_api_t * tdm_api); int sangoma_tdm_flush_bufs(sng_fd_t fd, wanpipe_tdm_api_t *tdm_api);
int sangoma_tdm_enable_rbs_events(sng_fd_t fd, wanpipe_tdm_api_t * tdm_api, int poll_in_sec); int sangoma_tdm_enable_rbs_events(sng_fd_t fd, wanpipe_tdm_api_t *tdm_api, int poll_in_sec);
int sangoma_tdm_disable_rbs_events(sng_fd_t fd, wanpipe_tdm_api_t * tdm_api); int sangoma_tdm_disable_rbs_events(sng_fd_t fd, wanpipe_tdm_api_t *tdm_api);
int sangoma_tdm_write_rbs(sng_fd_t fd, wanpipe_tdm_api_t * tdm_api, unsigned char rbs); int sangoma_tdm_write_rbs(sng_fd_t fd, wanpipe_tdm_api_t *tdm_api, unsigned char rbs);
int sangoma_tdm_read_event(sng_fd_t fd, wanpipe_tdm_api_t * tdm_api); int sangoma_tdm_read_event(sng_fd_t fd, wanpipe_tdm_api_t *tdm_api);
/* DTMF Detection on Octasic chip */ /* DTMF Detection on Octasic chip */
int sangoma_tdm_enable_dtmf_events(sng_fd_t fd, wanpipe_tdm_api_t * tdm_api); int sangoma_tdm_enable_dtmf_events(sng_fd_t fd, wanpipe_tdm_api_t *tdm_api);
int sangoma_tdm_disable_dtmf_events(sng_fd_t fd, wanpipe_tdm_api_t * tdm_api); int sangoma_tdm_disable_dtmf_events(sng_fd_t fd, wanpipe_tdm_api_t *tdm_api);
/* DTMF Detection on A200 (SLIC) chip */ /* DTMF Detection on A200 (SLIC) chip */
int sangoma_tdm_enable_rm_dtmf_events(sng_fd_t fd, wanpipe_tdm_api_t * tdm_api); int sangoma_tdm_enable_rm_dtmf_events(sng_fd_t fd, wanpipe_tdm_api_t *tdm_api);
int sangoma_tdm_disable_rm_dtmf_events(sng_fd_t fd, wanpipe_tdm_api_t * tdm_api); int sangoma_tdm_disable_rm_dtmf_events(sng_fd_t fd, wanpipe_tdm_api_t *tdm_api);
/* On/Off hook events on A200 (Analog) card */ /* On/Off hook events on A200 (Analog) card */
int sangoma_tdm_enable_rxhook_events(sng_fd_t fd, wanpipe_tdm_api_t * tdm_api); int sangoma_tdm_enable_rxhook_events(sng_fd_t fd, wanpipe_tdm_api_t *tdm_api);
int sangoma_tdm_disable_rxhook_events(sng_fd_t fd, wanpipe_tdm_api_t * tdm_api); int sangoma_tdm_disable_rxhook_events(sng_fd_t fd, wanpipe_tdm_api_t *tdm_api);
int sangoma_tdm_get_fe_alarms(sng_fd_t fd, wanpipe_tdm_api_t * tdm_api); int sangoma_tdm_get_fe_alarms(sng_fd_t fd, wanpipe_tdm_api_t *tdm_api);
#ifndef LIBSANGOMA_GET_HWCODING #ifndef LIBSANGOMA_GET_HWCODING
#define LIBSANGOMA_GET_HWCODING 1 #define LIBSANGOMA_GET_HWCODING 1
#endif #endif
int sangoma_tdm_get_hw_coding(int fd, wanpipe_tdm_api_t * tdm_api); int sangoma_tdm_get_hw_coding(int fd, wanpipe_tdm_api_t *tdm_api);
#endif /* WANPIPE_TDM_API */ #endif /* WANPIPE_TDM_API */

View File

@ -80,8 +80,8 @@ struct channel_map {
char map[SANGOMA_MAX_CHAN_PER_SPAN][SWITCH_UUID_FORMATTED_LENGTH + 1]; char map[SANGOMA_MAX_CHAN_PER_SPAN][SWITCH_UUID_FORMATTED_LENGTH + 1];
}; };
unsigned int txseq = 0; unsigned int txseq=0;
unsigned int rxseq = 0; unsigned int rxseq=0;
#define SETUP_LEN CORE_MAX_CHAN_PER_SPAN*CORE_MAX_SPANS+1 #define SETUP_LEN CORE_MAX_CHAN_PER_SPAN*CORE_MAX_SPANS+1
@ -99,7 +99,7 @@ struct ss7boost_handle {
typedef struct ss7boost_handle ss7boost_handle_t; typedef struct ss7boost_handle ss7boost_handle_t;
static int isup_exec_command(ss7boost_handle_t * ss7boost_handle, int span, int chan, int id, int cmd, int cause); static int isup_exec_command(ss7boost_handle_t *ss7boost_handle, int span, int chan, int id, int cmd, int cause);
static struct { static struct {
int debug; int debug;
@ -210,7 +210,7 @@ typedef struct private_object private_object_t;
static int local_sangoma_tdm_read_event(sng_fd_t fd, wp_tdm_api_rx_hdr_t * rx_event) static int local_sangoma_tdm_read_event(sng_fd_t fd, wp_tdm_api_rx_hdr_t *rx_event)
{ {
wanpipe_tdm_api_t tdm_api[1]; wanpipe_tdm_api_t tdm_api[1];
@ -231,17 +231,17 @@ static int local_sangoma_tdm_read_event(sng_fd_t fd, wp_tdm_api_rx_hdr_t * rx_ev
return 0; return 0;
} }
static int analog_set_state(analog_channel_t * alc, analog_state_t state) static int analog_set_state(analog_channel_t *alc, analog_state_t state)
{ {
alc->state = state; alc->state = state;
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Changing State to %d\n", state); switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Changing State to %d\n", state);
} }
static void analog_check_state(analog_channel_t * alc) static void analog_check_state(analog_channel_t *alc)
{ {
wanpipe_tdm_api_t tdm_api; wanpipe_tdm_api_t tdm_api;
switch (alc->state) { switch(alc->state) {
case ANALOG_STATE_DOWN: case ANALOG_STATE_DOWN:
sangoma_tdm_enable_rxhook_events(alc->sock->fd, &tdm_api); sangoma_tdm_enable_rxhook_events(alc->sock->fd, &tdm_api);
analog_set_state(alc, ANALOG_STATE_ONHOOK); analog_set_state(alc, ANALOG_STATE_ONHOOK);
@ -251,7 +251,7 @@ static void analog_check_state(analog_channel_t * alc)
} }
} }
static void analog_parse_event(analog_channel_t * alc) static void analog_parse_event(analog_channel_t *alc)
{ {
wp_tdm_api_rx_hdr_t rx_event; wp_tdm_api_rx_hdr_t rx_event;
int err = local_sangoma_tdm_read_event(alc->sock->fd, &rx_event); int err = local_sangoma_tdm_read_event(alc->sock->fd, &rx_event);
@ -269,15 +269,15 @@ static void analog_parse_event(analog_channel_t * alc)
} }
static void *SWITCH_THREAD_FUNC fxs_thread_run(switch_thread_t * thread, void *obj) static void *SWITCH_THREAD_FUNC fxs_thread_run(switch_thread_t *thread, void *obj)
{ {
for (;;) { for(;;) {
int i = 0, sel_on = -1; int i = 0, sel_on = -1;
fd_set oob; fd_set oob;
FD_ZERO(&oob); FD_ZERO(&oob);
for (i = 0; i < globals.fxs_index; i++) { for(i = 0; i < globals.fxs_index; i++) {
int fd; int fd;
assert(FXS_ANALOG_CHANNELS[i]); assert(FXS_ANALOG_CHANNELS[i]);
assert(FXS_ANALOG_CHANNELS[i]->sock); assert(FXS_ANALOG_CHANNELS[i]->sock);
@ -295,7 +295,7 @@ static void *SWITCH_THREAD_FUNC fxs_thread_run(switch_thread_t * thread, void *o
if (sel_on > -1) { if (sel_on > -1) {
if (select(++sel_on, NULL, NULL, &oob, NULL)) { if (select(++sel_on, NULL, NULL, &oob, NULL)) {
for (i = 0; i < globals.fxs_index; i++) { for(i = 0; i < globals.fxs_index; i++) {
int fd = FXS_ANALOG_CHANNELS[i]->sock->fd; int fd = FXS_ANALOG_CHANNELS[i]->sock->fd;
if (FD_ISSET(fd, &oob)) { if (FD_ISSET(fd, &oob)) {
analog_parse_event(FXS_ANALOG_CHANNELS[i]); analog_parse_event(FXS_ANALOG_CHANNELS[i]);
@ -307,7 +307,7 @@ static void *SWITCH_THREAD_FUNC fxs_thread_run(switch_thread_t * thread, void *o
} }
static int wp_close(private_object_t * tech_pvt) static int wp_close(private_object_t *tech_pvt)
{ {
int ret = 0; int ret = 0;
@ -321,7 +321,7 @@ static int wp_close(private_object_t * tech_pvt)
return ret; return ret;
} }
static wpsock_t *wp_open(private_object_t * tech_pvt, int span, int chan) static wpsock_t *wp_open(private_object_t *tech_pvt, int span, int chan)
{ {
sng_fd_t fd; sng_fd_t fd;
wpsock_t *sock; wpsock_t *sock;
@ -460,25 +460,26 @@ static switch_status_t wanpipe_on_init(switch_core_session_t *session);
static switch_status_t wanpipe_on_hangup(switch_core_session_t *session); static switch_status_t wanpipe_on_hangup(switch_core_session_t *session);
static switch_status_t wanpipe_on_loopback(switch_core_session_t *session); static switch_status_t wanpipe_on_loopback(switch_core_session_t *session);
static switch_status_t wanpipe_on_transmit(switch_core_session_t *session); static switch_status_t wanpipe_on_transmit(switch_core_session_t *session);
static switch_call_cause_t wanpipe_outgoing_channel(switch_core_session_t *session, static switch_call_cause_t wanpipe_outgoing_channel(switch_core_session_t *session, switch_caller_profile_t *outbound_profile,
switch_caller_profile_t *outbound_profile,
switch_core_session_t **new_session, switch_memory_pool_t **pool); switch_core_session_t **new_session, switch_memory_pool_t **pool);
static switch_status_t wanpipe_read_frame(switch_core_session_t *session, switch_frame_t **frame, int timeout, switch_io_flag_t flags, int stream_id); static switch_status_t wanpipe_read_frame(switch_core_session_t *session, switch_frame_t **frame, int timeout,
static switch_status_t wanpipe_write_frame(switch_core_session_t *session, switch_frame_t *frame, int timeout, switch_io_flag_t flags, int stream_id); switch_io_flag_t flags, int stream_id);
static int on_info(struct sangoma_pri *spri, sangoma_pri_event_t event_type, pri_event * pevent); static switch_status_t wanpipe_write_frame(switch_core_session_t *session, switch_frame_t *frame, int timeout,
static int on_hangup(struct sangoma_pri *spri, sangoma_pri_event_t event_type, pri_event * pevent); switch_io_flag_t flags, int stream_id);
static int on_ring(struct sangoma_pri *spri, sangoma_pri_event_t event_type, pri_event * pevent); static int on_info(struct sangoma_pri *spri, sangoma_pri_event_t event_type, pri_event *pevent);
static int on_hangup(struct sangoma_pri *spri, sangoma_pri_event_t event_type, pri_event *pevent);
static int on_ring(struct sangoma_pri *spri, sangoma_pri_event_t event_type, pri_event *pevent);
static int check_flags(struct sangoma_pri *spri); static int check_flags(struct sangoma_pri *spri);
static int on_restart(struct sangoma_pri *spri, sangoma_pri_event_t event_type, pri_event * pevent); static int on_restart(struct sangoma_pri *spri, sangoma_pri_event_t event_type, pri_event *pevent);
static int on_anything(struct sangoma_pri *spri, sangoma_pri_event_t event_type, pri_event * pevent); static int on_anything(struct sangoma_pri *spri, sangoma_pri_event_t event_type, pri_event *pevent);
static void *SWITCH_THREAD_FUNC pri_thread_run(switch_thread_t * thread, void *obj); static void *SWITCH_THREAD_FUNC pri_thread_run(switch_thread_t *thread, void *obj);
static switch_status_t config_wanpipe(int reload); static switch_status_t config_wanpipe(int reload);
static switch_status_t wanpipe_codec_init(private_object_t * tech_pvt) static switch_status_t wanpipe_codec_init(private_object_t *tech_pvt)
{ {
int err = 0; int err = 0;
wanpipe_tdm_api_t tdm_api = { {0} }; wanpipe_tdm_api_t tdm_api = {{0}};
unsigned int rate = 8000; unsigned int rate = 8000;
switch_channel_t *channel = NULL; switch_channel_t *channel = NULL;
@ -496,16 +497,16 @@ static switch_status_t wanpipe_codec_init(private_object_t * tech_pvt)
tech_pvt->frame_size = sangoma_tdm_get_usr_mtu_mru(tech_pvt->wpsock->fd, &tdm_api); tech_pvt->frame_size = sangoma_tdm_get_usr_mtu_mru(tech_pvt->wpsock->fd, &tdm_api);
if (switch_core_codec_init if (switch_core_codec_init
(&tech_pvt->read_codec, "L16", NULL, rate, globals.samples_per_frame / 8, 1, (&tech_pvt->read_codec, "L16", NULL, rate, globals.samples_per_frame / 8, 1, SWITCH_CODEC_FLAG_ENCODE | SWITCH_CODEC_FLAG_DECODE, NULL,
SWITCH_CODEC_FLAG_ENCODE | SWITCH_CODEC_FLAG_DECODE, NULL, switch_core_session_get_pool(tech_pvt->session)) != SWITCH_STATUS_SUCCESS) { switch_core_session_get_pool(tech_pvt->session)) != SWITCH_STATUS_SUCCESS) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "%s Cannot set read codec\n", switch_channel_get_name(channel)); switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "%s Cannot set read codec\n", switch_channel_get_name(channel));
switch_channel_hangup(channel, SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER); switch_channel_hangup(channel, SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER);
return SWITCH_STATUS_FALSE; return SWITCH_STATUS_FALSE;
} }
if (switch_core_codec_init if (switch_core_codec_init
(&tech_pvt->write_codec, "L16", NULL, rate, globals.samples_per_frame / 8, 1, (&tech_pvt->write_codec, "L16", NULL, rate, globals.samples_per_frame / 8, 1, SWITCH_CODEC_FLAG_ENCODE | SWITCH_CODEC_FLAG_DECODE, NULL,
SWITCH_CODEC_FLAG_ENCODE | SWITCH_CODEC_FLAG_DECODE, NULL, switch_core_session_get_pool(tech_pvt->session)) != SWITCH_STATUS_SUCCESS) { switch_core_session_get_pool(tech_pvt->session)) != SWITCH_STATUS_SUCCESS) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "%s Cannot set read codec\n", switch_channel_get_name(channel)); switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "%s Cannot set read codec\n", switch_channel_get_name(channel));
switch_channel_hangup(channel, SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER); switch_channel_hangup(channel, SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER);
return SWITCH_STATUS_FALSE; return SWITCH_STATUS_FALSE;
@ -533,7 +534,7 @@ static switch_status_t wanpipe_codec_init(private_object_t * tech_pvt)
tech_pvt->tone_session.duration = globals.dtmf_on * (tech_pvt->tone_session.rate / 1000); tech_pvt->tone_session.duration = globals.dtmf_on * (tech_pvt->tone_session.rate / 1000);
tech_pvt->tone_session.wait = globals.dtmf_off * (tech_pvt->tone_session.rate / 1000); tech_pvt->tone_session.wait = globals.dtmf_off * (tech_pvt->tone_session.rate / 1000);
teletone_dtmf_detect_init(&tech_pvt->dtmf_detect, rate); teletone_dtmf_detect_init (&tech_pvt->dtmf_detect, rate);
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Audio init %s\n", switch_channel_get_name(channel)); switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Audio init %s\n", switch_channel_get_name(channel));
switch_set_flag(tech_pvt, TFLAG_CODEC); switch_set_flag(tech_pvt, TFLAG_CODEC);
@ -577,11 +578,11 @@ static switch_status_t wanpipe_on_init(switch_core_session_t *session)
switch_mutex_unlock(tech_pvt->ss7boost_handle->mutex); switch_mutex_unlock(tech_pvt->ss7boost_handle->mutex);
switch_copy_string(tech_pvt->ss7boost_handle->setup_array[tech_pvt->setup_index], switch_copy_string(tech_pvt->ss7boost_handle->setup_array[tech_pvt->setup_index],
switch_core_session_get_uuid(session), sizeof(tech_pvt->ss7boost_handle->setup_array[tech_pvt->setup_index])); switch_core_session_get_uuid(session),
sizeof(tech_pvt->ss7boost_handle->setup_array[tech_pvt->setup_index]));
ss7boost_client_call_init(&event, tech_pvt->caller_profile->caller_id_number, tech_pvt->caller_profile->destination_number, ss7boost_client_call_init(&event, tech_pvt->caller_profile->caller_id_number, tech_pvt->caller_profile->destination_number, tech_pvt->setup_index);
tech_pvt->setup_index);
if (ss7boost_client_connection_write(&tech_pvt->ss7boost_handle->mcon, &event) <= 0) { if (ss7boost_client_connection_write(&tech_pvt->ss7boost_handle->mcon, &event) <= 0) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Critical System Error: Failed to tx on ISUP socket [%s]\n", strerror(errno)); switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Critical System Error: Failed to tx on ISUP socket [%s]\n", strerror(errno));
@ -655,7 +656,11 @@ static switch_status_t wanpipe_on_hangup(switch_core_session_t *session)
switch_mutex_unlock(tech_pvt->ss7boost_handle->mutex); switch_mutex_unlock(tech_pvt->ss7boost_handle->mutex);
if (!switch_test_flag(tech_pvt, TFLAG_BYE)) { if (!switch_test_flag(tech_pvt, TFLAG_BYE)) {
isup_exec_command(tech_pvt->ss7boost_handle, isup_exec_command(tech_pvt->ss7boost_handle,
tech_pvt->boost_span_number, tech_pvt->boost_chan_number, -1, SIGBOOST_EVENT_CALL_STOPPED, SIGBOOST_RELEASE_CAUSE_NORMAL); tech_pvt->boost_span_number,
tech_pvt->boost_chan_number,
-1,
SIGBOOST_EVENT_CALL_STOPPED,
SIGBOOST_RELEASE_CAUSE_NORMAL);
} }
} else if (tech_pvt->spri) { } else if (tech_pvt->spri) {
chanmap = tech_pvt->spri->private_info; chanmap = tech_pvt->spri->private_info;
@ -720,7 +725,12 @@ static switch_status_t wanpipe_answer_channel(switch_core_session_t *session)
pri_answer(tech_pvt->spri->pri, tech_pvt->call, 0, 1); pri_answer(tech_pvt->spri->pri, tech_pvt->call, 0, 1);
} }
} else if (tech_pvt->ss7boost_handle) { } else if (tech_pvt->ss7boost_handle) {
isup_exec_command(tech_pvt->ss7boost_handle, tech_pvt->boost_span_number, tech_pvt->boost_chan_number, -1, SIGBOOST_EVENT_CALL_ANSWERED, 0); isup_exec_command(tech_pvt->ss7boost_handle,
tech_pvt->boost_span_number,
tech_pvt->boost_chan_number,
-1,
SIGBOOST_EVENT_CALL_ANSWERED,
0);
} }
return SWITCH_STATUS_SUCCESS; return SWITCH_STATUS_SUCCESS;
@ -728,7 +738,8 @@ static switch_status_t wanpipe_answer_channel(switch_core_session_t *session)
static switch_status_t wanpipe_read_frame(switch_core_session_t *session, switch_frame_t **frame, int timeout, switch_io_flag_t flags, int stream_id) static switch_status_t wanpipe_read_frame(switch_core_session_t *session, switch_frame_t **frame, int timeout,
switch_io_flag_t flags, int stream_id)
{ {
private_object_t *tech_pvt; private_object_t *tech_pvt;
switch_channel_t *channel = NULL; switch_channel_t *channel = NULL;
@ -761,7 +772,8 @@ static switch_status_t wanpipe_read_frame(switch_core_session_t *session, switch
} }
if ((bread = sangoma_readmsg_socket(tech_pvt->wpsock->fd, if ((bread = sangoma_readmsg_socket(tech_pvt->wpsock->fd,
&tech_pvt->hdrframe, sizeof(tech_pvt->hdrframe), bp, sizeof(tech_pvt->databuf) - bytes, 0)) < 0) { &tech_pvt->hdrframe,
sizeof(tech_pvt->hdrframe), bp, sizeof(tech_pvt->databuf) - bytes, 0)) < 0) {
if (errno == EBUSY) { if (errno == EBUSY) {
continue; continue;
} else { } else {
@ -780,10 +792,10 @@ static switch_status_t wanpipe_read_frame(switch_core_session_t *session, switch
tech_pvt->read_frame.datalen = bytes; tech_pvt->read_frame.datalen = bytes;
tech_pvt->read_frame.samples = bytes / 2; tech_pvt->read_frame.samples = bytes / 2;
teletone_dtmf_detect(&tech_pvt->dtmf_detect, tech_pvt->read_frame.data, tech_pvt->read_frame.samples); teletone_dtmf_detect (&tech_pvt->dtmf_detect, tech_pvt->read_frame.data, tech_pvt->read_frame.samples);
teletone_dtmf_get(&tech_pvt->dtmf_detect, digit_str, sizeof(digit_str)); teletone_dtmf_get(&tech_pvt->dtmf_detect, digit_str, sizeof(digit_str));
if (digit_str[0]) { if(digit_str[0]) {
switch_channel_queue_dtmf(channel, digit_str); switch_channel_queue_dtmf(channel, digit_str);
if (globals.debug) { if (globals.debug) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "DTMF DETECTED: [%s]\n", digit_str); switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "DTMF DETECTED: [%s]\n", digit_str);
@ -797,6 +809,7 @@ static switch_status_t wanpipe_read_frame(switch_core_session_t *session, switch
memset(tech_pvt->read_frame.data, 0, tech_pvt->read_frame.datalen); memset(tech_pvt->read_frame.data, 0, tech_pvt->read_frame.datalen);
tech_pvt->skip_read_frames--; tech_pvt->skip_read_frames--;
} }
#ifdef DOTRACE #ifdef DOTRACE
write(tech_pvt->fd2, tech_pvt->read_frame.data, (int) tech_pvt->read_frame.datalen); write(tech_pvt->fd2, tech_pvt->read_frame.data, (int) tech_pvt->read_frame.datalen);
#endif #endif
@ -805,7 +818,8 @@ static switch_status_t wanpipe_read_frame(switch_core_session_t *session, switch
return SWITCH_STATUS_SUCCESS; return SWITCH_STATUS_SUCCESS;
} }
static switch_status_t wanpipe_write_frame(switch_core_session_t *session, switch_frame_t *frame, int timeout, switch_io_flag_t flags, int stream_id) static switch_status_t wanpipe_write_frame(switch_core_session_t *session, switch_frame_t *frame, int timeout,
switch_io_flag_t flags, int stream_id)
{ {
private_object_t *tech_pvt; private_object_t *tech_pvt;
uint32_t dtmf_blen; uint32_t dtmf_blen;
@ -827,13 +841,14 @@ static switch_status_t wanpipe_write_frame(switch_core_session_t *session, switc
uint8_t *data = frame->data; uint8_t *data = frame->data;
memcpy(data + len, tech_pvt->auxbuf + len, frame->datalen - len); memcpy(data + len, tech_pvt->auxbuf + len, frame->datalen - len);
} }
data = tech_pvt->auxbuf; data= tech_pvt->auxbuf;
} }
if (tech_pvt->skip_write_frames) { if (tech_pvt->skip_write_frames) {
tech_pvt->skip_write_frames--; tech_pvt->skip_write_frames--;
return SWITCH_STATUS_SUCCESS; return SWITCH_STATUS_SUCCESS;
} }
#ifdef DOTRACE #ifdef DOTRACE
write(tech_pvt->fd, data, frame->datalen); write(tech_pvt->fd, data, frame->datalen);
#endif #endif
@ -871,7 +886,7 @@ static switch_status_t wanpipe_send_dtmf(switch_core_session_t *session, char *d
} }
} }
for (cur = digits; *cur; cur++) { for (cur = digits; *cur; cur++) {
if ((wrote = teletone_mux_tones(&tech_pvt->tone_session, &tech_pvt->tone_session.TONES[(int) *cur]))) { if ((wrote = teletone_mux_tones(&tech_pvt->tone_session, &tech_pvt->tone_session.TONES[(int)*cur]))) {
switch_buffer_write(tech_pvt->dtmf_buffer, tech_pvt->tone_session.buffer, wrote * 2); switch_buffer_write(tech_pvt->dtmf_buffer, tech_pvt->tone_session.buffer, wrote * 2);
} }
} }
@ -930,7 +945,7 @@ static switch_status_t wanpipe_kill_channel(switch_core_session_t *session, int
tech_pvt = switch_core_session_get_private(session); tech_pvt = switch_core_session_get_private(session);
assert(tech_pvt != NULL); assert(tech_pvt != NULL);
switch (sig) { switch(sig) {
case SWITCH_SIG_KILL: case SWITCH_SIG_KILL:
switch_clear_flag_locked(tech_pvt, TFLAG_MEDIA); switch_clear_flag_locked(tech_pvt, TFLAG_MEDIA);
break; break;
@ -953,8 +968,8 @@ static const switch_io_routines_t wanpipe_io_routines = {
/*.kill_channel */ wanpipe_kill_channel, /*.kill_channel */ wanpipe_kill_channel,
/*.waitfor_read */ NULL, /*.waitfor_read */ NULL,
/*.waitfor_read */ NULL, /*.waitfor_read */ NULL,
/*.send_dtmf */ wanpipe_send_dtmf, /*.send_dtmf*/ wanpipe_send_dtmf,
/*.receive_message */ wanpipe_receive_message /*.receive_message*/ wanpipe_receive_message
}; };
static const switch_state_handler_table_t wanpipe_state_handlers = { static const switch_state_handler_table_t wanpipe_state_handlers = {
@ -984,8 +999,7 @@ static const switch_loadable_module_interface_t wanpipe_module_interface = {
}; };
static switch_call_cause_t wanpipe_outgoing_channel(switch_core_session_t *session, static switch_call_cause_t wanpipe_outgoing_channel(switch_core_session_t *session, switch_caller_profile_t *outbound_profile,
switch_caller_profile_t *outbound_profile,
switch_core_session_t **new_session, switch_memory_pool_t **pool) switch_core_session_t **new_session, switch_memory_pool_t **pool)
{ {
char *bchan = NULL; char *bchan = NULL;
@ -1148,16 +1162,16 @@ static switch_call_cause_t wanpipe_outgoing_channel(switch_core_session_t *sessi
chanmap = spri->private_info; chanmap = spri->private_info;
if (autochan > 0) { if (autochan > 0) {
for (callno = 1; callno < SANGOMA_MAX_CHAN_PER_SPAN; callno++) { for(callno = 1; callno < SANGOMA_MAX_CHAN_PER_SPAN; callno++) {
if ((SPANS[span]->bchans & (1 << callno)) && !*chanmap->map[callno]) { if ((SPANS[span]->bchans & (1 << callno)) && ! *chanmap->map[callno]) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Choosing channel s%dc%d\n", span, callno); switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Choosing channel s%dc%d\n", span, callno);
goto done; goto done;
} }
} }
callno = 0; callno = 0;
} else if (autochan < 0) { } else if (autochan < 0) {
for (callno = SANGOMA_MAX_CHAN_PER_SPAN; callno > 0; callno--) { for(callno = SANGOMA_MAX_CHAN_PER_SPAN; callno > 0; callno--) {
if ((SPANS[span]->bchans & (1 << callno)) && !*chanmap->map[callno]) { if ((SPANS[span]->bchans & (1 << callno)) && ! *chanmap->map[callno]) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Choosing channel s%dc%d\n", span, callno); switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Choosing channel s%dc%d\n", span, callno);
goto done; goto done;
} }
@ -1195,12 +1209,17 @@ static switch_call_cause_t wanpipe_outgoing_channel(switch_core_session_t *sessi
pri_sr_set_bearer(sr, 0, SPANS[span]->l1); pri_sr_set_bearer(sr, 0, SPANS[span]->l1);
pri_sr_set_called(sr, caller_profile->destination_number, SPANS[span]->dp, 1); pri_sr_set_called(sr, caller_profile->destination_number, SPANS[span]->dp, 1);
pri_sr_set_caller(sr, pri_sr_set_caller(sr,
caller_profile->caller_id_number, caller_profile->caller_id_name, SPANS[span]->dp, caller_profile->caller_id_number,
caller_profile->caller_id_name,
SPANS[span]->dp,
PRES_ALLOWED_USER_NUMBER_PASSED_SCREEN); PRES_ALLOWED_USER_NUMBER_PASSED_SCREEN);
pri_sr_set_redirecting(sr, caller_profile->caller_id_number, SPANS[span]->dp, PRES_ALLOWED_USER_NUMBER_PASSED_SCREEN, pri_sr_set_redirecting(sr,
caller_profile->caller_id_number,
SPANS[span]->dp,
PRES_ALLOWED_USER_NUMBER_PASSED_SCREEN,
PRI_REDIR_UNCONDITIONAL); PRI_REDIR_UNCONDITIONAL);
if (pri_setup(spri->pri, tech_pvt->call, sr)) { if (pri_setup(spri->pri, tech_pvt->call , sr)) {
switch_core_session_destroy(new_session); switch_core_session_destroy(new_session);
pri_sr_free(sr); pri_sr_free(sr);
cause = SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER; cause = SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER;
@ -1215,7 +1234,9 @@ static switch_call_cause_t wanpipe_outgoing_channel(switch_core_session_t *sessi
goto error; goto error;
} }
pri_sr_free(sr); pri_sr_free(sr);
switch_copy_string(chanmap->map[callno], switch_core_session_get_uuid(*new_session), sizeof(chanmap->map[callno])); switch_copy_string(chanmap->map[callno],
switch_core_session_get_uuid(*new_session),
sizeof(chanmap->map[callno]));
tech_pvt->spri = spri; tech_pvt->spri = spri;
} }
} else if (is_boost) { } else if (is_boost) {
@ -1224,8 +1245,8 @@ static switch_call_cause_t wanpipe_outgoing_channel(switch_core_session_t *sessi
if ((p = strchr(caller_profile->destination_number, '/'))) { if ((p = strchr(caller_profile->destination_number, '/'))) {
char *grp = caller_profile->destination_number; char *grp = caller_profile->destination_number;
*p = '\0'; *p = '\0';
caller_profile->destination_number = p + 1; caller_profile->destination_number = p+1;
tech_pvt->boost_trunk_group = atoi(grp + 1) - 1; tech_pvt->boost_trunk_group = atoi(grp+1) - 1;
if (tech_pvt->boost_trunk_group < 0) { if (tech_pvt->boost_trunk_group < 0) {
tech_pvt->boost_trunk_group = 0; tech_pvt->boost_trunk_group = 0;
} }
@ -1310,7 +1331,7 @@ SWITCH_MOD_DECLARE(switch_status_t) switch_module_load(const switch_loadable_mod
/*event Handlers */ /*event Handlers */
static int on_info(struct sangoma_pri *spri, sangoma_pri_event_t event_type, pri_event * pevent) static int on_info(struct sangoma_pri *spri, sangoma_pri_event_t event_type, pri_event *pevent)
{ {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "number is: %s\n", pevent->ring.callednum); switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "number is: %s\n", pevent->ring.callednum);
if (strlen(pevent->ring.callednum) > 3) { if (strlen(pevent->ring.callednum) > 3) {
@ -1320,7 +1341,7 @@ static int on_info(struct sangoma_pri *spri, sangoma_pri_event_t event_type, pri
return 0; return 0;
} }
static int on_hangup(struct sangoma_pri *spri, sangoma_pri_event_t event_type, pri_event * pevent) static int on_hangup(struct sangoma_pri *spri, sangoma_pri_event_t event_type, pri_event *pevent)
{ {
struct channel_map *chanmap; struct channel_map *chanmap;
switch_core_session_t *session; switch_core_session_t *session;
@ -1355,7 +1376,7 @@ static int on_hangup(struct sangoma_pri *spri, sangoma_pri_event_t event_type, p
return 0; return 0;
} }
static int on_answer(struct sangoma_pri *spri, sangoma_pri_event_t event_type, pri_event * pevent) static int on_answer(struct sangoma_pri *spri, sangoma_pri_event_t event_type, pri_event *pevent)
{ {
switch_core_session_t *session; switch_core_session_t *session;
switch_channel_t *channel; switch_channel_t *channel;
@ -1378,7 +1399,7 @@ static int on_answer(struct sangoma_pri *spri, sangoma_pri_event_t event_type, p
} }
static int on_proceed(struct sangoma_pri *spri, sangoma_pri_event_t event_type, pri_event * pevent) static int on_proceed(struct sangoma_pri *spri, sangoma_pri_event_t event_type, pri_event *pevent)
{ {
switch_core_session_t *session; switch_core_session_t *session;
switch_channel_t *channel; switch_channel_t *channel;
@ -1407,15 +1428,15 @@ static int on_proceed(struct sangoma_pri *spri, sangoma_pri_event_t event_type,
switch_core_session_rwunlock(session); switch_core_session_rwunlock(session);
} else { } else {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "-- Proceeding on channel s%dc%d but it's not in use?\n",
"-- Proceeding on channel s%dc%d but it's not in use?\n", spri->span, pevent->proceeding.channel); spri->span, pevent->proceeding.channel);
} }
return 0; return 0;
} }
static int on_ringing(struct sangoma_pri *spri, sangoma_pri_event_t event_type, pri_event * pevent) static int on_ringing(struct sangoma_pri *spri, sangoma_pri_event_t event_type, pri_event *pevent)
{ {
switch_core_session_t *session; switch_core_session_t *session;
switch_channel_t *channel; switch_channel_t *channel;
@ -1434,16 +1455,14 @@ static int on_ringing(struct sangoma_pri *spri, sangoma_pri_event_t event_type,
switch_core_session_rwunlock(session); switch_core_session_rwunlock(session);
} else { } else {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "-- Ringing on channel s%dc%d %s but it's not in use?\n", spri->span, pevent->ringing.channel, chanmap->map[pevent->ringing.channel]);
"-- Ringing on channel s%dc%d %s but it's not in use?\n", spri->span, pevent->ringing.channel,
chanmap->map[pevent->ringing.channel]);
} }
return 0; return 0;
} }
static int on_ring(struct sangoma_pri *spri, sangoma_pri_event_t event_type, pri_event * pevent) static int on_ring(struct sangoma_pri *spri, sangoma_pri_event_t event_type, pri_event *pevent)
{ {
char name[128]; char name[128];
switch_core_session_t *session; switch_core_session_t *session;
@ -1455,14 +1474,15 @@ static int on_ring(struct sangoma_pri *spri, sangoma_pri_event_t event_type, pri
chanmap = spri->private_info; chanmap = spri->private_info;
if (switch_core_session_locate(chanmap->map[pevent->ring.channel])) { if (switch_core_session_locate(chanmap->map[pevent->ring.channel])) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "--Duplicate Ring on channel s%dc%d (ignored)\n", spri->span, pevent->ring.channel); switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "--Duplicate Ring on channel s%dc%d (ignored)\n",
spri->span, pevent->ring.channel);
switch_core_session_rwunlock(session); switch_core_session_rwunlock(session);
ret = 0; ret = 0;
goto done; goto done;
} }
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "-- Ring on channel s%dc%d (from %s to %s)\n", spri->span, switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "-- Ring on channel s%dc%d (from %s to %s)\n", spri->span, pevent->ring.channel,
pevent->ring.channel, pevent->ring.callingnum, pevent->ring.callednum); pevent->ring.callingnum, pevent->ring.callednum);
pri_proceeding(spri->pri, pevent->ring.call, pevent->ring.channel, 0); pri_proceeding(spri->pri, pevent->ring.call, pevent->ring.channel, 0);
@ -1494,14 +1514,21 @@ static int on_ring(struct sangoma_pri *spri, sangoma_pri_event_t event_type, pri
} }
if ((tech_pvt->caller_profile = switch_caller_profile_new(switch_core_session_get_pool(session), if ((tech_pvt->caller_profile = switch_caller_profile_new(switch_core_session_get_pool(session),
NULL, globals.dialplan, "FreeSWITCH", pevent->ring.callingnum, NULL,
globals.dialplan,
"FreeSWITCH",
pevent->ring.callingnum,
#ifdef WIN32 #ifdef WIN32
NULL, NULL,
#else #else
pevent->ring.callingani, pevent->ring.callingani,
#endif #endif
switch_strlen_zero(ani2str) ? NULL : ani2str, switch_strlen_zero(ani2str) ? NULL : ani2str,
NULL, NULL, (char *) modname, NULL, pevent->ring.callednum))) { NULL,
NULL,
(char *)modname,
NULL,
pevent->ring.callednum))) {
switch_channel_set_caller_profile(channel, tech_pvt->caller_profile); switch_channel_set_caller_profile(channel, tech_pvt->caller_profile);
} }
@ -1540,7 +1567,7 @@ static int check_flags(struct sangoma_pri *spri)
return 0; return 0;
} }
static int on_restart(struct sangoma_pri *spri, sangoma_pri_event_t event_type, pri_event * pevent) static int on_restart(struct sangoma_pri *spri, sangoma_pri_event_t event_type, pri_event *pevent)
{ {
switch_core_session_t *session; switch_core_session_t *session;
struct channel_map *chanmap; struct channel_map *chanmap;
@ -1568,7 +1595,7 @@ static int on_restart(struct sangoma_pri *spri, sangoma_pri_event_t event_type,
return 0; return 0;
} }
static int on_dchan_up(struct sangoma_pri *spri, sangoma_pri_event_t event_type, pri_event * pevent) static int on_dchan_up(struct sangoma_pri *spri, sangoma_pri_event_t event_type, pri_event *pevent)
{ {
if (!switch_test_flag(spri, SANGOMA_PRI_READY)) { if (!switch_test_flag(spri, SANGOMA_PRI_READY)) {
@ -1579,7 +1606,7 @@ static int on_dchan_up(struct sangoma_pri *spri, sangoma_pri_event_t event_type,
return 0; return 0;
} }
static int on_dchan_down(struct sangoma_pri *spri, sangoma_pri_event_t event_type, pri_event * pevent) static int on_dchan_down(struct sangoma_pri *spri, sangoma_pri_event_t event_type, pri_event *pevent)
{ {
if (switch_test_flag(spri, SANGOMA_PRI_READY)) { if (switch_test_flag(spri, SANGOMA_PRI_READY)) {
@ -1590,15 +1617,16 @@ static int on_dchan_down(struct sangoma_pri *spri, sangoma_pri_event_t event_typ
return 0; return 0;
} }
static int on_anything(struct sangoma_pri *spri, sangoma_pri_event_t event_type, pri_event * pevent) static int on_anything(struct sangoma_pri *spri, sangoma_pri_event_t event_type, pri_event *pevent)
{ {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Caught Event span %d %u (%s)\n", spri->span, event_type, sangoma_pri_event_str(event_type)); switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Caught Event span %d %u (%s)\n", spri->span, event_type,
sangoma_pri_event_str(event_type));
return 0; return 0;
} }
static void *SWITCH_THREAD_FUNC pri_thread_run(switch_thread_t * thread, void *obj) static void *SWITCH_THREAD_FUNC pri_thread_run(switch_thread_t *thread, void *obj)
{ {
struct sangoma_pri *spri = obj; struct sangoma_pri *spri = obj;
struct channel_map chanmap; struct channel_map chanmap;
@ -1646,7 +1674,7 @@ static void pri_thread_launch(struct sangoma_pri *spri)
} }
static int isup_exec_command(ss7boost_handle_t * ss7boost_handle, int span, int chan, int id, int cmd, int cause) static int isup_exec_command(ss7boost_handle_t *ss7boost_handle, int span, int chan, int id, int cmd, int cause)
{ {
ss7boost_client_event_t oevent; ss7boost_client_event_t oevent;
int r = 0; int r = 0;
@ -1659,7 +1687,7 @@ static int isup_exec_command(ss7boost_handle_t * ss7boost_handle, int span, int
oevent.call_setup_id = id; oevent.call_setup_id = id;
} }
if (ss7boost_client_connection_write(&ss7boost_handle->mcon, &oevent) <= 0) { if (ss7boost_client_connection_write(&ss7boost_handle->mcon, &oevent) <= 0){
r = -1; r = -1;
} }
@ -1680,12 +1708,12 @@ static int waitfor_socket(int fd, int timeout, int flags)
res = poll(pfds, 1, timeout); res = poll(pfds, 1, timeout);
if (res > 0) { if (res > 0) {
if (pfds[0].revents & POLLIN) { if(pfds[0].revents & POLLIN) {
res = 1; res = 1;
} else if ((pfds[0].revents & POLLERR)) { } else if ((pfds[0].revents & POLLERR)) {
res = -1; res = -1;
} else { } else {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "System Error: Poll Event Error no event!\n"); switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR,"System Error: Poll Event Error no event!\n");
res = -1; res = -1;
} }
} }
@ -1708,7 +1736,7 @@ static void validate_number(unsigned char *s)
} }
static void handle_call_stop(ss7boost_handle_t * ss7boost_handle, ss7boost_client_event_t * event) static void handle_call_stop(ss7boost_handle_t *ss7boost_handle, ss7boost_client_event_t *event)
{ {
char *uuid = ss7boost_handle->span_chanmap[event->span].map[event->chan]; char *uuid = ss7boost_handle->span_chanmap[event->span].map[event->chan];
@ -1732,19 +1760,29 @@ static void handle_call_stop(ss7boost_handle_t * ss7boost_handle, ss7boost_clien
} }
isup_exec_command(ss7boost_handle, event->span, event->chan, -1, SIGBOOST_EVENT_CALL_STOPPED_ACK, 0); isup_exec_command(ss7boost_handle,
event->span,
event->chan,
-1,
SIGBOOST_EVENT_CALL_STOPPED_ACK,
0);
} }
static void handle_call_start(ss7boost_handle_t * ss7boost_handle, ss7boost_client_event_t * event) static void handle_call_start(ss7boost_handle_t *ss7boost_handle, ss7boost_client_event_t *event)
{ {
switch_core_session_t *session = NULL; switch_core_session_t *session = NULL;
switch_channel_t *channel = NULL; switch_channel_t *channel = NULL;
char name[128]; char name[128];
if (*ss7boost_handle->span_chanmap[event->span].map[event->chan]) { if (*ss7boost_handle->span_chanmap[event->span].map[event->chan]) {
isup_exec_command(ss7boost_handle, event->span, event->chan, -1, SIGBOOST_EVENT_CALL_START_NACK, SIGBOOST_RELEASE_CAUSE_BUSY); isup_exec_command(ss7boost_handle,
event->span,
event->chan,
-1,
SIGBOOST_EVENT_CALL_START_NACK,
SIGBOOST_RELEASE_CAUSE_BUSY);
return; return;
} }
@ -1758,7 +1796,7 @@ static void handle_call_start(ss7boost_handle_t * ss7boost_handle, ss7boost_clie
switch_mutex_init(&tech_pvt->flag_mutex, SWITCH_MUTEX_NESTED, switch_core_session_get_pool(session)); switch_mutex_init(&tech_pvt->flag_mutex, SWITCH_MUTEX_NESTED, switch_core_session_get_pool(session));
channel = switch_core_session_get_channel(session); channel = switch_core_session_get_channel(session);
switch_core_session_set_private(session, tech_pvt); switch_core_session_set_private(session, tech_pvt);
sprintf(name, "wanpipe/ss7boost/s%dc%d", event->span + 1, event->chan + 1); sprintf(name, "wanpipe/ss7boost/s%dc%d", event->span+1, event->chan+1);
switch_channel_set_name(channel, name); switch_channel_set_name(channel, name);
tech_pvt->session = session; tech_pvt->session = session;
} else { } else {
@ -1768,13 +1806,21 @@ static void handle_call_start(ss7boost_handle_t * ss7boost_handle, ss7boost_clie
if ((tech_pvt->caller_profile = switch_caller_profile_new(switch_core_session_get_pool(session), if ((tech_pvt->caller_profile = switch_caller_profile_new(switch_core_session_get_pool(session),
NULL, globals.dialplan, "FreeSWITCH(boost)", (char *) event->calling_number_digits, NULL,
globals.dialplan,
"FreeSWITCH(boost)",
(char *)event->calling_number_digits,
#ifdef WIN32 #ifdef WIN32
NULL, NULL,
#else #else
(char *) event->calling_number_digits, (char *)event->calling_number_digits,
#endif #endif
NULL, NULL, NULL, (char *) modname, NULL, (char *) event->called_number_digits))) { NULL,
NULL,
NULL,
(char *)modname,
NULL,
(char *)event->called_number_digits))) {
switch_channel_set_caller_profile(channel, tech_pvt->caller_profile); switch_channel_set_caller_profile(channel, tech_pvt->caller_profile);
} }
@ -1787,16 +1833,21 @@ static void handle_call_start(ss7boost_handle_t * ss7boost_handle, ss7boost_clie
tech_pvt->boost_chan_number = event->chan; tech_pvt->boost_chan_number = event->chan;
tech_pvt->boost_pres = event->calling_number_presentation; tech_pvt->boost_pres = event->calling_number_presentation;
if (!wp_open(tech_pvt, event->span + 1, event->chan + 1)) { if (!wp_open(tech_pvt, event->span+1, event->chan+1)) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Can't open channel %d:%d\n", event->span + 1, event->chan + 1); switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Can't open channel %d:%d\n", event->span+1, event->chan+1);
goto fail; goto fail;
} }
switch_copy_string(ss7boost_handle->span_chanmap[event->span].map[event->chan], switch_copy_string(ss7boost_handle->span_chanmap[event->span].map[event->chan], switch_core_session_get_uuid(session),
switch_core_session_get_uuid(session), sizeof(ss7boost_handle->span_chanmap[event->span].map[event->chan])); sizeof(ss7boost_handle->span_chanmap[event->span].map[event->chan]));
switch_channel_set_state(channel, CS_INIT); switch_channel_set_state(channel, CS_INIT);
isup_exec_command(ss7boost_handle, event->span, event->chan, -1, SIGBOOST_EVENT_CALL_START_ACK, 0); isup_exec_command(ss7boost_handle,
event->span,
event->chan,
-1,
SIGBOOST_EVENT_CALL_START_ACK,
0);
switch_core_session_thread_launch(session); switch_core_session_thread_launch(session);
return; return;
} else { } else {
@ -1809,21 +1860,31 @@ static void handle_call_start(ss7boost_handle_t * ss7boost_handle, ss7boost_clie
switch_core_session_destroy(&session); switch_core_session_destroy(&session);
} }
isup_exec_command(ss7boost_handle, event->span, event->chan, -1, SIGBOOST_EVENT_CALL_STOPPED, SIGBOOST_RELEASE_CAUSE_BUSY); isup_exec_command(ss7boost_handle,
event->span,
event->chan,
-1,
SIGBOOST_EVENT_CALL_STOPPED,
SIGBOOST_RELEASE_CAUSE_BUSY);
} }
static void handle_heartbeat(ss7boost_handle_t * ss7boost_handle, ss7boost_client_event_t * event) static void handle_heartbeat(ss7boost_handle_t *ss7boost_handle, ss7boost_client_event_t *event)
{ {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Heartbeat!\n"); switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Heartbeat!\n");
isup_exec_command(ss7boost_handle, event->span, event->chan, -1, SIGBOOST_EVENT_HEARTBEAT, 0); isup_exec_command(ss7boost_handle,
event->span,
event->chan,
-1,
SIGBOOST_EVENT_HEARTBEAT,
0);
} }
static void handle_call_start_ack(ss7boost_handle_t * ss7boost_handle, ss7boost_client_event_t * event) static void handle_call_start_ack(ss7boost_handle_t *ss7boost_handle, ss7boost_client_event_t *event)
{ {
char *uuid = ss7boost_handle->setup_array[event->call_setup_id]; char *uuid = ss7boost_handle->setup_array[event->call_setup_id];
@ -1844,15 +1905,15 @@ static void handle_call_start_ack(ss7boost_handle_t * ss7boost_handle, ss7boost_
tech_pvt->boost_span_number = event->span; tech_pvt->boost_span_number = event->span;
tech_pvt->boost_chan_number = event->chan; tech_pvt->boost_chan_number = event->chan;
switch_copy_string(ss7boost_handle->span_chanmap[event->span].map[event->chan], switch_copy_string(ss7boost_handle->span_chanmap[event->span].map[event->chan], switch_core_session_get_uuid(session),
switch_core_session_get_uuid(session), sizeof(ss7boost_handle->span_chanmap[event->span].map[event->chan])); sizeof(ss7boost_handle->span_chanmap[event->span].map[event->chan]));
if (!tech_pvt->wpsock) { if (!tech_pvt->wpsock) {
if (!wp_open(tech_pvt, tech_pvt->boost_span_number + 1, tech_pvt->boost_chan_number + 1)) { if (!wp_open(tech_pvt, tech_pvt->boost_span_number+1, tech_pvt->boost_chan_number+1)) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Can't open fd for s%dc%d! [%s]\n", switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Can't open fd for s%dc%d! [%s]\n",
tech_pvt->boost_span_number + 1, tech_pvt->boost_chan_number + 1, strerror(errno)); tech_pvt->boost_span_number+1, tech_pvt->boost_chan_number+1, strerror(errno));
switch_channel_hangup(channel, SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER); switch_channel_hangup(channel, SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER);
return; return;
} }
@ -1870,12 +1931,12 @@ static void handle_call_start_ack(ss7boost_handle_t * ss7boost_handle, ss7boost_
} }
} }
static void handle_call_start_nack_ack(ss7boost_handle_t * ss7boost_handle, ss7boost_client_event_t * event) static void handle_call_start_nack_ack(ss7boost_handle_t *ss7boost_handle, ss7boost_client_event_t *event)
{ {
// WTF IS THIS! ? // WTF IS THIS! ?
} }
static void handle_call_answer(ss7boost_handle_t * ss7boost_handle, ss7boost_client_event_t * event) static void handle_call_answer(ss7boost_handle_t *ss7boost_handle, ss7boost_client_event_t *event)
{ {
char *uuid = ss7boost_handle->span_chanmap[event->span].map[event->chan]; char *uuid = ss7boost_handle->span_chanmap[event->span].map[event->chan];
@ -1893,9 +1954,9 @@ static void handle_call_answer(ss7boost_handle_t * ss7boost_handle, ss7boost_cli
assert(tech_pvt != NULL); assert(tech_pvt != NULL);
if (!tech_pvt->wpsock) { if (!tech_pvt->wpsock) {
if (!wp_open(tech_pvt, tech_pvt->boost_span_number + 1, tech_pvt->boost_chan_number + 1)) { if (!wp_open(tech_pvt, tech_pvt->boost_span_number+1, tech_pvt->boost_chan_number+1)) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Can't open fd for s%dc%d! [%s]\n", switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Can't open fd for s%dc%d! [%s]\n",
tech_pvt->boost_span_number + 1, tech_pvt->boost_chan_number + 1, strerror(errno)); tech_pvt->boost_span_number+1, tech_pvt->boost_chan_number+1, strerror(errno));
switch_channel_hangup(channel, SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER); switch_channel_hangup(channel, SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER);
return; return;
} }
@ -1917,13 +1978,13 @@ static void handle_call_answer(ss7boost_handle_t * ss7boost_handle, ss7boost_cli
} }
} }
static void handle_call_stop_ack(ss7boost_handle_t * ss7boost_handle, ss7boost_client_event_t * event) static void handle_call_stop_ack(ss7boost_handle_t *ss7boost_handle, ss7boost_client_event_t *event)
{ {
// TODO anything here? // TODO anything here?
} }
static void handle_call_start_nack(ss7boost_handle_t * ss7boost_handle, ss7boost_client_event_t * event) static void handle_call_start_nack(ss7boost_handle_t *ss7boost_handle, ss7boost_client_event_t *event)
{ {
char *uuid = ss7boost_handle->setup_array[event->call_setup_id]; char *uuid = ss7boost_handle->setup_array[event->call_setup_id];
@ -1946,7 +2007,12 @@ static void handle_call_start_nack(ss7boost_handle_t * ss7boost_handle, ss7boost
switch_channel_hangup(channel, event->release_cause); switch_channel_hangup(channel, event->release_cause);
isup_exec_command(ss7boost_handle, event->span, event->chan, event->call_setup_id, SIGBOOST_EVENT_CALL_START_NACK_ACK, 0); isup_exec_command(ss7boost_handle,
event->span,
event->chan,
event->call_setup_id,
SIGBOOST_EVENT_CALL_START_NACK_ACK,
0);
switch_core_session_rwunlock(session); switch_core_session_rwunlock(session);
} else { } else {
@ -1956,14 +2022,14 @@ static void handle_call_start_nack(ss7boost_handle_t * ss7boost_handle, ss7boost
} }
} }
static int parse_ss7_event(ss7boost_handle_t * ss7boost_handle, ss7boost_client_event_t * event) static int parse_ss7_event(ss7boost_handle_t *ss7boost_handle, ss7boost_client_event_t *event)
{ {
int ret = 0; int ret = 0;
switch_mutex_lock(ss7boost_handle->mutex); switch_mutex_lock(ss7boost_handle->mutex);
validate_number((unsigned char *) event->called_number_digits); validate_number((unsigned char*)event->called_number_digits);
validate_number((unsigned char *) event->calling_number_digits); validate_number((unsigned char*)event->calling_number_digits);
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG,
"\nRX EVENT\n" "\nRX EVENT\n"
@ -1982,15 +2048,20 @@ static int parse_ss7_event(ss7boost_handle_t * ss7boost_handle, ss7boost_client_
"\n", "\n",
ss7boost_client_event_id_name(event->event_id), ss7boost_client_event_id_name(event->event_id),
event->event_id, event->event_id,
event->span + 1, event->span+1,
event->chan + 1, event->chan+1,
(event->called_number_digits_count ? (char *) event->called_number_digits : "N/A"), (event->called_number_digits_count ? (char *) event->called_number_digits : "N/A"),
(event->calling_number_digits_count ? (char *) event->calling_number_digits : "N/A"), (event->calling_number_digits_count ? (char *) event->calling_number_digits : "N/A"),
switch_channel_cause2str(event->release_cause), event->span + 1, event->chan + 1, event->event_id, event->call_setup_id, switch_channel_cause2str(event->release_cause),
event->seqno); event->span+1,
event->chan+1,
event->event_id,
event->call_setup_id,
event->seqno
);
switch (event->event_id) { switch(event->event_id) {
case SIGBOOST_EVENT_CALL_START: case SIGBOOST_EVENT_CALL_START:
handle_call_start(ss7boost_handle, event); handle_call_start(ss7boost_handle, event);
@ -2025,7 +2096,7 @@ static int parse_ss7_event(ss7boost_handle_t * ss7boost_handle, ss7boost_client_
return ret; return ret;
} }
static void *SWITCH_THREAD_FUNC boost_thread_run(switch_thread_t * thread, void *obj) static void *SWITCH_THREAD_FUNC boost_thread_run(switch_thread_t *thread, void *obj)
{ {
ss7boost_handle_t *ss7boost_handle = (ss7boost_handle_t *) obj; ss7boost_handle_t *ss7boost_handle = (ss7boost_handle_t *) obj;
ss7boost_client_event_t *event; ss7boost_client_event_t *event;
@ -2033,12 +2104,19 @@ static void *SWITCH_THREAD_FUNC boost_thread_run(switch_thread_t * thread, void
if (ss7boost_client_connection_open(&ss7boost_handle->mcon, if (ss7boost_client_connection_open(&ss7boost_handle->mcon,
ss7boost_handle->local_ip, ss7boost_handle->local_ip,
ss7boost_handle->local_port, ss7boost_handle->local_port,
ss7boost_handle->remote_ip, ss7boost_handle->remote_port, module_pool) != SWITCH_STATUS_SUCCESS) { ss7boost_handle->remote_ip,
ss7boost_handle->remote_port,
module_pool) != SWITCH_STATUS_SUCCESS) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "FATAL ERROR CREATING CLIENT CONNECTION\n"); switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "FATAL ERROR CREATING CLIENT CONNECTION\n");
return NULL; return NULL;
} }
isup_exec_command(ss7boost_handle, 0, 0, -1, SIGBOOST_EVENT_SYSTEM_RESTART, 0); isup_exec_command(ss7boost_handle,
0,
0,
-1,
SIGBOOST_EVENT_SYSTEM_RESTART,
0);
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Monitor Thread Started\n"); switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Monitor Thread Started\n");
@ -2049,14 +2127,15 @@ static void *SWITCH_THREAD_FUNC boost_thread_run(switch_thread_t * thread, void
globals.ss7boost_handle = ss7boost_handle; globals.ss7boost_handle = ss7boost_handle;
for (;;) { for(;;) {
if (ss7boost_client_connection_read(&ss7boost_handle->mcon, &event) == SWITCH_STATUS_SUCCESS) { if (ss7boost_client_connection_read(&ss7boost_handle->mcon, &event) == SWITCH_STATUS_SUCCESS) {
struct timeval current; struct timeval current;
struct timeval difftime; struct timeval difftime;
gettimeofday(&current, NULL); gettimeofday(&current,NULL);
timersub(&current, &event->tv, &difftime); timersub (&current, &event->tv, &difftime);
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Socket Event [%s] T=%d:%d\n", switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Socket Event [%s] T=%d:%d\n",
ss7boost_client_event_id_name(event->event_id), (int) difftime.tv_sec, (int) difftime.tv_usec); ss7boost_client_event_id_name(event->event_id),
(int)difftime.tv_sec, (int)difftime.tv_usec);
parse_ss7_event(ss7boost_handle, event); parse_ss7_event(ss7boost_handle, event);
} else { } else {
@ -2073,7 +2152,7 @@ static void *SWITCH_THREAD_FUNC boost_thread_run(switch_thread_t * thread, void
return NULL; return NULL;
} }
static void launch_ss7boost_handle(ss7boost_handle_t * ss7boost_handle) static void launch_ss7boost_handle(ss7boost_handle_t *ss7boost_handle)
{ {
switch_thread_t *thread; switch_thread_t *thread;
switch_threadattr_t *thd_attr = NULL; switch_threadattr_t *thd_attr = NULL;
@ -2165,7 +2244,7 @@ static switch_status_t config_wanpipe(int reload)
} }
analog_channels = switch_xml_child(cfg, "analog_channels"); analog_channels = switch_xml_child(cfg, "analog_channels");
for (channel = switch_xml_child(analog_channels, "channel"); channel; channel = channel->next) { for(channel = switch_xml_child(analog_channels, "channel"); channel; channel = channel->next) {
char *c_type = (char *) switch_xml_attr(channel, "type"); char *c_type = (char *) switch_xml_attr(channel, "type");
char *c_dev = (char *) switch_xml_attr(channel, "device"); char *c_dev = (char *) switch_xml_attr(channel, "device");
char *user = NULL; char *user = NULL;
@ -2320,7 +2399,7 @@ static switch_status_t config_wanpipe(int reload)
fromi = atoi(from); fromi = atoi(from);
toi = atoi(to); toi = atoi(to);
if (fromi > 0 && toi > 0 && fromi < toi && fromi < MAX_SPANS && toi < MAX_SPANS) { if (fromi > 0 && toi > 0 && fromi < toi && fromi < MAX_SPANS && toi < MAX_SPANS) {
for (x = fromi; x <= toi; x++) { for(x = fromi; x <= toi; x++) {
SPANS[current_span]->bchans |= (1 << x); SPANS[current_span]->bchans |= (1 << x);
} }
} else { } else {
@ -2354,14 +2433,18 @@ static switch_status_t config_wanpipe(int reload)
globals.configured_spans = 0; globals.configured_spans = 0;
for (current_span = 1; current_span < MAX_SPANS; current_span++) { for(current_span = 1; current_span < MAX_SPANS; current_span++) {
if (SPANS[current_span]) { if (SPANS[current_span]) {
if (!SPANS[current_span]->l1) { if (!SPANS[current_span]->l1) {
SPANS[current_span]->l1 = PRI_LAYER_1_ULAW; SPANS[current_span]->l1 = PRI_LAYER_1_ULAW;
} }
if (sangoma_init_pri(&SPANS[current_span]->spri, if (sangoma_init_pri(&SPANS[current_span]->spri,
current_span, SPANS[current_span]->dchan, SPANS[current_span]->pswitch, SPANS[current_span]->node, globals.debug)) { current_span,
SPANS[current_span]->dchan,
SPANS[current_span]->pswitch,
SPANS[current_span]->node,
globals.debug)) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Cannot launch span %d\n", current_span); switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Cannot launch span %d\n", current_span);
continue; continue;
} }
@ -2378,3 +2461,6 @@ static switch_status_t config_wanpipe(int reload)
return SWITCH_STATUS_SUCCESS; return SWITCH_STATUS_SUCCESS;
} }

View File

@ -0,0 +1,448 @@
/*****************************************************************************
* aft_api.c AFT T1/E1: HDLC API Sample Code
*
* Author(s): Nenad Corbic <ncorbic@sangoma.com>
*
* Copyright: (c) 2003-2004 Sangoma Technologies Inc.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version
* 2 of the License, or (at your option) any later version.
* ============================================================================
*/
#include <stdlib.h>
#include <stdio.h>
#include <ctype.h>
#include <unistd.h>
#include <sys/time.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <linux/if_wanpipe.h>
#include <string.h>
#include <errno.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#include <sys/types.h>
#include <signal.h>
#include <linux/if.h>
#include <linux/wanpipe_defines.h>
#include <linux/wanpipe_cfg.h>
#include <linux/wanpipe.h>
#include <libsangoma.h>
#include "lib_api.h"
#define MAX_TX_DATA 5000 /* Size of tx data */
#define MAX_FRAMES 5000 /* Number of frames to transmit */
#define MAX_RX_DATA 5000
unsigned short Rx_lgth;
unsigned char Rx_data[MAX_RX_DATA];
unsigned char Tx_data[MAX_TX_DATA + sizeof(wp_tdm_api_rx_hdr_t)];
/* Prototypes */
int MakeConnection(void);
void handle_span_chan( void);
void sig_end(int sigid);
int dev_fd;
FILE *tx_fd=NULL,*rx_fd=NULL;
wanpipe_tdm_api_t tdm_api;
/***************************************************
* HANDLE SOCKET
*
* o Read a socket
* o Cast data received to api_rx_element_t data type
* o The received packet contains 16 bytes header
*
* ------------------------------------------
* | 16 bytes | X bytes ...
* ------------------------------------------
* Header Data
*
* o Data structures:
* ------------------
* typedef struct {
* union {
* struct {
* unsigned char _event_type;
* unsigned char _rbs_rx_bits;
* unsigned int _time_stamp;
* }wp_event;
* struct {
* unsigned char _rbs_rx_bits;
* unsigned int _time_stamp;
* }wp_rx;
* unsigned char reserved[16];
* }wp_rx_hdr_u;
* #define wp_api_event_type wp_rx_hdr_u.wp_event._event_type
* #define wp_api_event_rbs_rx_bits wp_rx_hdr_u.wp_event._rbs_rx_bits
* #define wp_api_event_time_stamp wp_rx_hdr_u.wp_event._time_stamp
* } wp_tdm_api_rx_hdr_t;
*
* typedef struct {
* wp_tdm_api_rx_hdr_t hdr;
* unsigned char data[1];
* } wp_tdm_api_rx_element_t;
*
* typedef struct {
* union {
* struct {
* unsigned char _rbs_rx_bits;
* unsigned int _time_stamp;
* }wp_tx;
* unsigned char reserved[16];
* }wp_tx_hdr_u;
* #define wp_api_time_stamp wp_tx_hdr_u.wp_tx._time_stamp
* } wp_tdm_api_tx_hdr_t;
*
* typedef struct {
* wp_tdm_api_tx_hdr_t hdr;
* unsigned char data[1];
* } wp_tdm_api_tx_element_t;
*
* #define WPTDM_A_BIT 0x08
* #define WPTDM_B_BIT 0x04
* #define WPTDM_C_BIT 0x02
* #define WPTDM_D_BIT 0x01
*
*/
void handle_span_chan(void)
{
unsigned int Rx_count,Tx_count,Tx_length;
wp_tdm_api_rx_element_t* api_rx_el;
wp_tdm_api_tx_element_t * api_tx_el;
fd_set ready,write,oob;
int err,i;
#if 0
int rlen;
int stream_sync=0;
#endif
Rx_count = 0;
Tx_count = 0;
if (tdm_api.wp_tdm_cmd.hdlc) {
Tx_length = tx_size;
} else {
Tx_length = tdm_api.wp_tdm_cmd.usr_mtu_mru;
}
printf("\n\nSocket Handler: Rx=%d Tx=%i TxCnt=%i TxLen=%i TxDelay=%i\n",
read_enable,write_enable,tx_cnt,tx_size,tx_delay);
/* Initialize the Tx Data buffer */
memset(&Tx_data[0],0,MAX_TX_DATA + sizeof(wp_tdm_api_rx_hdr_t));
/* Cast the Tx data packet with the tx element
* structure. We must insert a 16 byte
* driver header, which driver will remove
* before passing packet out the physical port */
api_tx_el = (wp_tdm_api_tx_element_t*)&Tx_data[0];
/* Create a Tx packet based on user info, or
* by deafult incrementing number starting from 0 */
for (i=0;i<Tx_length;i++){
if (tx_data == -1){
api_tx_el->data[i] = (unsigned char)i;
}else{
#if 0
api_tx_el->data[i] = (unsigned char)tx_data+(i%4);
#else
api_tx_el->data[i] = (unsigned char)tx_data;
#endif
}
}
sangoma_tdm_enable_rxhook_events(dev_fd, &tdm_api);
/* Main Rx Tx OOB routine */
for(;;) {
/* Initialize all select() descriptors */
FD_ZERO(&ready);
FD_ZERO(&write);
FD_ZERO(&oob);
FD_SET(dev_fd,&oob);
FD_SET(dev_fd,&ready);
if (write_enable){
FD_SET(dev_fd,&write);
}
/* Select will block, until:
* 1: OOB event, link level change
* 2: Rx data available
* 3: Interface able to Tx */
if(select(dev_fd + 1,&ready, &write, &oob, NULL)){
fflush(stdout);
if (FD_ISSET(dev_fd,&oob)){
/* An OOB event is pending, usually indicating
* a link level change */
err=sangoma_tdm_read_event(dev_fd,&tdm_api);
if(err < 0 ) {
printf("Failed to receive OOB %i , %i\n", Rx_count, err);
err = ioctl(dev_fd,SIOC_WANPIPE_SOCK_STATE,0);
printf("Sock state is %s\n",
(err == 0) ? "CONNECTED" :
(err == 1) ? "DISCONNECTED" :
"CONNECTING");
break;
}
printf("GOT OOB EXCEPTION CMD Exiting\n");
}
if (FD_ISSET(dev_fd,&ready)){
/* An Rx packet is pending
* 1: Read the rx packet into the Rx_data
* buffer. Confirm len > 0
*
* 2: Cast Rx_data to the api_rx_element.
* Thus, removing a 16 byte header
* attached by the driver.
*
* 3. Check error_flag:
* CRC,Abort..etc
*/
memset(Rx_data, 0, sizeof(Rx_data));
err = sangoma_readmsg_tdm(dev_fd,
Rx_data,
sizeof(wp_tdm_api_rx_hdr_t),
&Rx_data[sizeof(wp_tdm_api_rx_hdr_t)],
MAX_RX_DATA, 0);
if (!read_enable){
goto bitstrm_skip_read;
}
/* err indicates bytes received */
if(err <= 0) {
printf("\nError receiving data\n");
break;
}
api_rx_el = (wp_tdm_api_rx_element_t*)&Rx_data[0];
/* Check the packet length */
Rx_lgth = err;
if(Rx_lgth<=0) {
printf("\nShort frame received (%d)\n",
Rx_lgth);
return;
}
#if 0
if (api_rx_el->data[0] == tx_data && api_rx_el->data[1] == (tx_data+1)){
if (!stream_sync){
printf("GOT SYNC %x\n",api_rx_el->data[0]);
}
stream_sync=1;
}else{
if (stream_sync){
printf("OUT OF SYNC: %x\n",api_rx_el->data[0]);
}
}
#endif
++Rx_count;
if (verbose){
#if 0
printf("Received %i Length = %i\n",
Rx_count,Rx_lgth);
printf("Data: ");
for(i=0;i<Rx_lgth; i ++) {
printf("0x%02X ", api_rx_el->data[i]);
}
printf("\n");
#endif
}else{
//putchar('R');
}
#if 0
switch(api_rx_el->hdr.wp_api_event_type){
case WP_TDM_EVENT_DTMF:
printf("DTMV Event: %c (%s:%s)!\n",
api_rx_el->hdr.wp_api_event_dtmf_digit,
(api_rx_el->hdr.wp_api_event_dtmf_type&WP_TDM_EVENT_DTMF_ROUT)?"ROUT":"SOUT",
(api_rx_el->hdr.wp_api_event_dtmf_type&WP_TDM_EVENT_DTMF_PRESET)?"PRESET":"STOP");
break;
case WP_TDM_EVENT_RXHOOK:
printf("RXHOOK Event: %s!\n",
(api_rx_el->hdr.wp_api_event_rxhook_state&WP_TDM_EVENT_RXHOOK_OFF)?"OFF-HOOK":"ON-HOOK");
break;
case WP_TDM_EVENT_RING:
printf("RING Event: %s!\n",
(api_rx_el->hdr.wp_api_event_ring_state&WP_TDM_EVENT_RING_PRESENT)?"PRESENT":"STOP");
break;
}
#endif
if (rx_cnt > 0 && Rx_count >= rx_cnt){
break;
}
bitstrm_skip_read:
;
}
if (FD_ISSET(dev_fd,&write)){
err = sangoma_writemsg_tdm(dev_fd,
Tx_data,16,
&Tx_data[16], Tx_length,
0);
if (err <= 0){
if (errno == EBUSY){
if (verbose){
printf("Sock busy try again!\n");
}
/* Socket busy try sending again !*/
}else{
printf("Faild to send %i \n",errno);
perror("Send: ");
break;
}
}else{
++Tx_count;
if (verbose){
//printf("Packet sent: Sent %i : %i\n",
// err,Tx_count);
}else{
//putchar('T');
}
}
}
if (tx_delay){
usleep(tx_delay);
}
if (tx_cnt && tx_size && Tx_count >= tx_cnt && !(files_used & TX_FILE_USED)){
write_enable=0;
if (rx_cnt > 0){
/* Dont break let rx finish */
}else{
break;
}
}
}
}
sangoma_tdm_disable_rxhook_events(dev_fd, &tdm_api);
if (tx_fd){
fclose(tx_fd);
}
if (rx_fd){
fclose(rx_fd);
}
close (dev_fd);
return;
}
int rxhook_event (int fd, unsigned char state)
{
printf("%d: RXHOOK Event: %s!\n",
fd, (state & WAN_EVENT_RXHOOK_OFF)?"OFF-HOOK":"ON-HOOK");
return 0;
}
/***************************************************************
* Main:
*
* o Make a socket connection to the driver.
* o Call handle_span_chan() to read the socket
*
**************************************************************/
int main(int argc, char* argv[])
{
int proceed;
proceed=init_args(argc,argv);
if (proceed != WAN_TRUE){
usage(argv[0]);
return -1;
}
signal(SIGINT,&sig_end);
memset(&tdm_api,0,sizeof(tdm_api));
tdm_api.wp_tdm_event.wp_rxhook_event = &rxhook_event;
printf("TDM RXHOOK PTR = %p\n",tdm_api.wp_tdm_event.wp_rxhook_event);
dev_fd =-1;
dev_fd = sangoma_open_tdmapi_span_chan(atoi(card_name),atoi(if_name));
if( dev_fd < 0){
printf("Failed to open span chan (%s:%s:%d:%d)\n",
card_name, if_name,
atoi(card_name),atoi(if_name));
exit (1);
}
printf("HANDLING SPAN %i CHAN %i FD=%i\n",
atoi(card_name),atoi(if_name),dev_fd);
sangoma_tdm_set_codec(dev_fd,&tdm_api,WP_NONE);
sangoma_get_full_cfg(dev_fd, &tdm_api);
handle_span_chan();
close(dev_fd);
return 0;
return 0;
};
void sig_end(int sigid)
{
printf("Got Signal %i\n",sigid);
sangoma_tdm_disable_rxhook_events(dev_fd, &tdm_api);
if (tx_fd){
fclose(tx_fd);
}
if (rx_fd){
fclose(rx_fd);
}
if (dev_fd){
close (dev_fd);
}
exit(1);
}