mirror of
https://github.com/signalwire/freeswitch.git
synced 2025-04-07 21:32:56 +00:00
move wanpipe to unsupported please see mod_openzap
git-svn-id: http://svn.freeswitch.org/svn/freeswitch/trunk@9998 d0543943-73ff-0310-b7d9-9358b9ac24b2
This commit is contained in:
parent
d74b12a167
commit
42cb2307d4
@ -1,55 +0,0 @@
|
||||
BASE=../../../..
|
||||
LIBPRI_HOST=http://downloads.digium.com/pub/libpri
|
||||
LIBPRI=libpri-1.2.6
|
||||
LIBPRI_FILE=$(LIBPRI).tar.gz
|
||||
LIBPRI_DIR=$(BASE)/libs/$(LIBPRI)
|
||||
WANPIPE=wanpipe-3.1.1
|
||||
WANPIPE_HOST=ftp://ftp.sangoma.com/linux/current_wanpipe/
|
||||
WANPIPE_FILE=$(WANPIPE).tgz
|
||||
WANPIPE_DIR=$(BASE)/libs/$(WANPIPE)
|
||||
WANPIPE_INCLUDE=$(WANPIPE_DIR)/patches/kdrivers/include
|
||||
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")
|
||||
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 +=-D__LINUX__ -D_REENTRANT -D_GNU_SOURCE -DAFT_A104 -DWANPIPE_TDM_API -I$(switch_srcdir)/libs/libteletone/src -D_GNUC_ -DWANPIPE_TDM_API -w -fPIC
|
||||
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
|
||||
WTF=-fPIC -w -std=gnu99 -I$(BASE)/libs/wanpipe-3.1.0/patches/kdrivers/include -I./libsangoma -I/usr/local/include -I../../../../libs/libpri-1.2.4 -I/usr/src/linux/include -I. -I/usr/include -D__LINUX__ -D_REENTRANT -D_GNU_SOURCE -DAFT_A104 -DWANPIPE_TDM_API -I$(BASE)/libs/libteletone/src -D_GNUC_ -DWANPIPE_TDM_API -w -I$(BASE)/src/include -I$(BASE)/libs/libteletone/src -fPIC -g -O2 -Wall -D_GNU_SOURCE -DHAVE_CONFIG_H
|
||||
|
||||
|
||||
|
||||
include $(BASE)/build/modmake.rules
|
||||
|
||||
mod_wanpipe.o: mod_wanpipe.c
|
||||
@echo Compiling $<...
|
||||
$(CC) $(WTF) -c -o $@ $< || exit 1
|
||||
|
||||
|
||||
$(LIBSANGOMA_DIR)/libsangoma.o: $(LIBSANGOMA_DIR)/libsangoma.c
|
||||
$(CC) -c -I$(WANPIPE_DIR) $(LOCAL_CFLAGS) $(LIBSANGOMA_DIR)/libsangoma.c -o $(LIBSANGOMA_DIR)/libsangoma.o
|
||||
|
||||
$(LIBSANGOMA_DIR)/sangoma_pri.o: $(LIBSANGOMA_DIR)/sangoma_pri.c
|
||||
$(CC) -c -I$(WANPIPE_DIR) $(LOCAL_CFLAGS) $(LIBSANGOMA_DIR)/sangoma_pri.c -o $(LIBSANGOMA_DIR)/sangoma_pri.o
|
||||
|
||||
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):
|
||||
$(GETLIB) $(LIBPRI_HOST) $(LIBPRI_FILE)
|
||||
|
||||
$(WANPIPE_DIR):
|
||||
$(GETLIB) $(WANPIPE_HOST) $(WANPIPE_FILE)
|
||||
|
||||
$(WANPIPE_KO): $(WANPIPE_DIR)
|
||||
cd $(WANPIPE_DIR) && $(MAKE) && $(MAKE) install
|
||||
@$(TOUCH_TARGET)
|
||||
|
||||
$(WANPIPE_INSTALLED_KO): $(WANPIPE_KO)
|
||||
cd $(WANPIPE_DIR) && $(MAKE) install
|
||||
|
||||
local_depend: $(LIBPRI_DIR) $(WANPIPE_KO)
|
||||
|
||||
local_install: $(WANPIPE_INSTALLED_KO)
|
||||
|
||||
local_clean:
|
||||
rm -f libsangoma/*.o
|
@ -1,534 +0,0 @@
|
||||
/*****************************************************************************
|
||||
* 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);
|
||||
}
|
@ -1,341 +0,0 @@
|
||||
/*
|
||||
* SpanDSP - a series of DSP components for telephony
|
||||
*
|
||||
* g711.h - In line A-law and u-law conversion routines
|
||||
*
|
||||
* Written by Steve Underwood <steveu@coppice.org>
|
||||
*
|
||||
* Copyright (C) 2001 Steve Underwood
|
||||
*
|
||||
* Despite my general liking of the GPL, I place this code in the
|
||||
* public domain for the benefit of all mankind - even the slimy
|
||||
* ones who might try to proprietize my work and use it to my
|
||||
* detriment.
|
||||
*
|
||||
* $Id: g711.h,v 1.1 2006/06/07 15:46:39 steveu Exp $
|
||||
*/
|
||||
|
||||
/*! \file */
|
||||
|
||||
/*! \page g711_page A-law and mu-law handling
|
||||
Lookup tables for A-law and u-law look attractive, until you consider the impact
|
||||
on the CPU cache. If it causes a substantial area of your processor cache to get
|
||||
hit too often, cache sloshing will severely slow things down. The main reason
|
||||
these routines are slow in C, is the lack of direct access to the CPU's "find
|
||||
the first 1" instruction. A little in-line assembler fixes that, and the
|
||||
conversion routines can be faster than lookup tables, in most real world usage.
|
||||
A "find the first 1" instruction is available on most modern CPUs, and is a
|
||||
much underused feature.
|
||||
|
||||
If an assembly language method of bit searching is not available, these routines
|
||||
revert to a method that can be a little slow, so the cache thrashing might not
|
||||
seem so bad :(
|
||||
|
||||
Feel free to submit patches to add fast "find the first 1" support for your own
|
||||
favourite processor.
|
||||
|
||||
Look up tables are used for transcoding between A-law and u-law, since it is
|
||||
difficult to achieve the precise transcoding procedure laid down in the G.711
|
||||
specification by other means.
|
||||
*/
|
||||
|
||||
#if !defined(_G711_H_)
|
||||
#define _G711_H_
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#ifndef __inline__
|
||||
#define __inline__ __inline
|
||||
#endif
|
||||
typedef unsigned __int8 uint8_t;
|
||||
typedef __int16 int16_t;
|
||||
typedef __int32 int32_t;
|
||||
typedef unsigned __int16 uint16_t;
|
||||
#endif
|
||||
|
||||
#if defined(__i386__)
|
||||
/*! \brief Find the bit position of the highest set bit in a word
|
||||
\param bits The word to be searched
|
||||
\return The bit number of the highest set bit, or -1 if the word is zero. */
|
||||
static __inline__ int top_bit(unsigned int bits) {
|
||||
int res;
|
||||
|
||||
__asm__ __volatile__(" movl $-1,%%edx;\n" " bsrl %%eax,%%edx;\n":"=d"(res)
|
||||
:"a" (bits));
|
||||
return res;
|
||||
}
|
||||
/*- End of function --------------------------------------------------------*//*! \brief Find the bit position of the lowest set bit in a word
|
||||
\param bits The word to be searched
|
||||
\return The bit number of the lowest set bit, or -1 if the word is zero. */ static __inline__ int bottom_bit(unsigned int bits) {
|
||||
int res;
|
||||
|
||||
__asm__ __volatile__(" movl $-1,%%edx;\n" " bsfl %%eax,%%edx;\n":"=d"(res)
|
||||
:"a" (bits));
|
||||
return res;
|
||||
}
|
||||
/*- End of function --------------------------------------------------------*/
|
||||
#elif defined(__x86_64__)
|
||||
static __inline__ int top_bit(unsigned int bits) {
|
||||
int res;
|
||||
|
||||
__asm__ __volatile__(" movq $-1,%%rdx;\n" " bsrq %%rax,%%rdx;\n":"=d"(res)
|
||||
:"a" (bits));
|
||||
return res;
|
||||
}
|
||||
/*- End of function --------------------------------------------------------*/ static __inline__ int bottom_bit(unsigned int bits) {
|
||||
int res;
|
||||
|
||||
__asm__ __volatile__(" movq $-1,%%rdx;\n" " bsfq %%rax,%%rdx;\n":"=d"(res)
|
||||
:"a" (bits));
|
||||
return res;
|
||||
}
|
||||
/*- End of function --------------------------------------------------------*/
|
||||
#else
|
||||
static __inline__ int top_bit(unsigned int bits) {
|
||||
int i;
|
||||
|
||||
if (bits == 0)
|
||||
return -1;
|
||||
i = 0;
|
||||
if (bits & 0xFFFF0000) {
|
||||
bits &= 0xFFFF0000;
|
||||
i += 16;
|
||||
}
|
||||
if (bits & 0xFF00FF00) {
|
||||
bits &= 0xFF00FF00;
|
||||
i += 8;
|
||||
}
|
||||
if (bits & 0xF0F0F0F0) {
|
||||
bits &= 0xF0F0F0F0;
|
||||
i += 4;
|
||||
}
|
||||
if (bits & 0xCCCCCCCC) {
|
||||
bits &= 0xCCCCCCCC;
|
||||
i += 2;
|
||||
}
|
||||
if (bits & 0xAAAAAAAA) {
|
||||
bits &= 0xAAAAAAAA;
|
||||
i += 1;
|
||||
}
|
||||
return i;
|
||||
}
|
||||
/*- End of function --------------------------------------------------------*/
|
||||
|
||||
static __inline__ int bottom_bit(unsigned int bits) {
|
||||
int i;
|
||||
|
||||
if (bits == 0)
|
||||
return -1;
|
||||
i = 32;
|
||||
if (bits & 0x0000FFFF) {
|
||||
bits &= 0x0000FFFF;
|
||||
i -= 16;
|
||||
}
|
||||
if (bits & 0x00FF00FF) {
|
||||
bits &= 0x00FF00FF;
|
||||
i -= 8;
|
||||
}
|
||||
if (bits & 0x0F0F0F0F) {
|
||||
bits &= 0x0F0F0F0F;
|
||||
i -= 4;
|
||||
}
|
||||
if (bits & 0x33333333) {
|
||||
bits &= 0x33333333;
|
||||
i -= 2;
|
||||
}
|
||||
if (bits & 0x55555555) {
|
||||
bits &= 0x55555555;
|
||||
i -= 1;
|
||||
}
|
||||
return i;
|
||||
}
|
||||
/*- End of function --------------------------------------------------------*/
|
||||
#endif
|
||||
|
||||
/* N.B. It is tempting to use look-up tables for A-law and u-law conversion.
|
||||
* However, you should consider the cache footprint.
|
||||
*
|
||||
* A 64K byte table for linear to x-law and a 512 byte table for x-law to
|
||||
* linear sound like peanuts these days, and shouldn't an array lookup be
|
||||
* real fast? No! When the cache sloshes as badly as this one will, a tight
|
||||
* calculation may be better. The messiest part is normally finding the
|
||||
* segment, but a little inline assembly can fix that on an i386, x86_64 and
|
||||
* many other modern processors.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Mu-law is basically as follows:
|
||||
*
|
||||
* Biased Linear Input Code Compressed Code
|
||||
* ------------------------ ---------------
|
||||
* 00000001wxyza 000wxyz
|
||||
* 0000001wxyzab 001wxyz
|
||||
* 000001wxyzabc 010wxyz
|
||||
* 00001wxyzabcd 011wxyz
|
||||
* 0001wxyzabcde 100wxyz
|
||||
* 001wxyzabcdef 101wxyz
|
||||
* 01wxyzabcdefg 110wxyz
|
||||
* 1wxyzabcdefgh 111wxyz
|
||||
*
|
||||
* Each biased linear code has a leading 1 which identifies the segment
|
||||
* number. The value of the segment number is equal to 7 minus the number
|
||||
* of leading 0's. The quantization interval is directly available as the
|
||||
* four bits wxyz. * The trailing bits (a - h) are ignored.
|
||||
*
|
||||
* Ordinarily the complement of the resulting code word is used for
|
||||
* transmission, and so the code word is complemented before it is returned.
|
||||
*
|
||||
* For further information see John C. Bellamy's Digital Telephony, 1982,
|
||||
* John Wiley & Sons, pps 98-111 and 472-476.
|
||||
*/
|
||||
|
||||
//#define ULAW_ZEROTRAP /* turn on the trap as per the MIL-STD */
|
||||
#define ULAW_BIAS 0x84 /* Bias for linear code. */
|
||||
|
||||
/*! \brief Encode a linear sample to u-law
|
||||
\param linear The sample to encode.
|
||||
\return The u-law value.
|
||||
*/
|
||||
static __inline__ uint8_t linear_to_ulaw(int linear) {
|
||||
uint8_t u_val;
|
||||
int mask;
|
||||
int seg;
|
||||
|
||||
/* Get the sign and the magnitude of the value. */
|
||||
if (linear < 0) {
|
||||
linear = ULAW_BIAS - linear;
|
||||
mask = 0x7F;
|
||||
} else {
|
||||
linear = ULAW_BIAS + linear;
|
||||
mask = 0xFF;
|
||||
}
|
||||
|
||||
seg = top_bit(linear | 0xFF) - 7;
|
||||
|
||||
/*
|
||||
* Combine the sign, segment, quantization bits,
|
||||
* and complement the code word.
|
||||
*/
|
||||
if (seg >= 8)
|
||||
u_val = (uint8_t) (0x7F ^ mask);
|
||||
else
|
||||
u_val = (uint8_t) (((seg << 4) | ((linear >> (seg + 3)) & 0xF)) ^ mask);
|
||||
#ifdef ULAW_ZEROTRAP
|
||||
/* Optional ITU trap */
|
||||
if (u_val == 0)
|
||||
u_val = 0x02;
|
||||
#endif
|
||||
return u_val;
|
||||
}
|
||||
/*- End of function --------------------------------------------------------*/
|
||||
|
||||
/*! \brief Decode an u-law sample to a linear value.
|
||||
\param ulaw The u-law sample to decode.
|
||||
\return The linear value.
|
||||
*/
|
||||
static __inline__ int16_t ulaw_to_linear(uint8_t ulaw) {
|
||||
int t;
|
||||
|
||||
/* Complement to obtain normal u-law value. */
|
||||
ulaw = ~ulaw;
|
||||
/*
|
||||
* Extract and bias the quantization bits. Then
|
||||
* shift up by the segment number and subtract out the bias.
|
||||
*/
|
||||
t = (((ulaw & 0x0F) << 3) + ULAW_BIAS) << (((int) ulaw & 0x70) >> 4);
|
||||
return (int16_t) ((ulaw & 0x80) ? (ULAW_BIAS - t) : (t - ULAW_BIAS));
|
||||
}
|
||||
/*- End of function --------------------------------------------------------*/
|
||||
|
||||
/*
|
||||
* A-law is basically as follows:
|
||||
*
|
||||
* Linear Input Code Compressed Code
|
||||
* ----------------- ---------------
|
||||
* 0000000wxyza 000wxyz
|
||||
* 0000001wxyza 001wxyz
|
||||
* 000001wxyzab 010wxyz
|
||||
* 00001wxyzabc 011wxyz
|
||||
* 0001wxyzabcd 100wxyz
|
||||
* 001wxyzabcde 101wxyz
|
||||
* 01wxyzabcdef 110wxyz
|
||||
* 1wxyzabcdefg 111wxyz
|
||||
*
|
||||
* For further information see John C. Bellamy's Digital Telephony, 1982,
|
||||
* John Wiley & Sons, pps 98-111 and 472-476.
|
||||
*/
|
||||
|
||||
#define ALAW_AMI_MASK 0x55
|
||||
|
||||
/*! \brief Encode a linear sample to A-law
|
||||
\param linear The sample to encode.
|
||||
\return The A-law value.
|
||||
*/
|
||||
static __inline__ uint8_t linear_to_alaw(int linear) {
|
||||
int mask;
|
||||
int seg;
|
||||
|
||||
if (linear >= 0) {
|
||||
/* Sign (bit 7) bit = 1 */
|
||||
mask = ALAW_AMI_MASK | 0x80;
|
||||
} else {
|
||||
/* Sign (bit 7) bit = 0 */
|
||||
mask = ALAW_AMI_MASK;
|
||||
linear = -linear - 8;
|
||||
}
|
||||
|
||||
/* Convert the scaled magnitude to segment number. */
|
||||
seg = top_bit(linear | 0xFF) - 7;
|
||||
if (seg >= 8) {
|
||||
if (linear >= 0) {
|
||||
/* Out of range. Return maximum value. */
|
||||
return (uint8_t) (0x7F ^ mask);
|
||||
}
|
||||
/* We must be just a tiny step below zero */
|
||||
return (uint8_t) (0x00 ^ mask);
|
||||
}
|
||||
/* Combine the sign, segment, and quantization bits. */
|
||||
return (uint8_t) (((seg << 4) | ((linear >> ((seg) ? (seg + 3) : 4)) & 0x0F)) ^ mask);
|
||||
}
|
||||
/*- End of function --------------------------------------------------------*/
|
||||
|
||||
/*! \brief Decode an A-law sample to a linear value.
|
||||
\param alaw The A-law sample to decode.
|
||||
\return The linear value.
|
||||
*/
|
||||
static __inline__ int16_t alaw_to_linear(uint8_t alaw) {
|
||||
int i;
|
||||
int seg;
|
||||
|
||||
alaw ^= ALAW_AMI_MASK;
|
||||
i = ((alaw & 0x0F) << 4);
|
||||
seg = (((int) alaw & 0x70) >> 4);
|
||||
if (seg)
|
||||
i = (i + 0x108) << (seg - 1);
|
||||
else
|
||||
i += 8;
|
||||
return (int16_t) ((alaw & 0x80) ? i : -i);
|
||||
}
|
||||
/*- End of function --------------------------------------------------------*/
|
||||
|
||||
/*! \brief Transcode from A-law to u-law, using the procedure defined in G.711.
|
||||
\param alaw The A-law sample to transcode.
|
||||
\return The best matching u-law value.
|
||||
*/
|
||||
uint8_t alaw_to_ulaw(uint8_t alaw);
|
||||
|
||||
/*! \brief Transcode from u-law to A-law, using the procedure defined in G.711.
|
||||
\param alaw The u-law sample to transcode.
|
||||
\return The best matching A-law value.
|
||||
*/
|
||||
uint8_t ulaw_to_alaw(uint8_t ulaw);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
/*- End of file ------------------------------------------------------------*/
|
@ -1,948 +0,0 @@
|
||||
#include "libsangoma.h"
|
||||
#include <stdarg.h>
|
||||
|
||||
#define DFT_CARD "wanpipe1"
|
||||
|
||||
#if defined(WIN32)
|
||||
//extern int verbose;
|
||||
|
||||
#define DEV_NAME_LEN 100
|
||||
char device_name[DEV_NAME_LEN];
|
||||
|
||||
/* IOCTL management structures and variables*/
|
||||
wan_udp_hdr_t wan_udp;
|
||||
|
||||
#include "win_api_common.h"
|
||||
|
||||
static wan_cmd_api_t api_cmd;
|
||||
static api_tx_hdr_t *tx_hdr = (api_tx_hdr_t *)api_cmd.data;
|
||||
|
||||
/* keeps the LAST (and single) event received */
|
||||
static wp_tdm_api_rx_hdr_t last_tdm_api_event_buffer;
|
||||
|
||||
#endif /* WIN32 */
|
||||
|
||||
void sangoma_socket_close(sng_fd_t *sp)
|
||||
{
|
||||
#if defined(WIN32)
|
||||
if( *sp != INVALID_HANDLE_VALUE){
|
||||
CloseHandle(*sp);
|
||||
*sp = INVALID_HANDLE_VALUE;
|
||||
}
|
||||
#else
|
||||
if (*sp > -1) {
|
||||
close(*sp);
|
||||
*sp = -1;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
int sangoma_socket_waitfor(sng_fd_t fd, int timeout, int flags)
|
||||
{
|
||||
#if defined(WIN32)
|
||||
API_POLL_STRUCT api_poll;
|
||||
|
||||
memset(&api_poll, 0x00, sizeof(API_POLL_STRUCT));
|
||||
|
||||
api_poll.user_flags_bitmap = flags;
|
||||
|
||||
if(DoApiPollCommand(fd, &api_poll)){
|
||||
//failed
|
||||
return 0;
|
||||
}
|
||||
|
||||
switch(api_poll.operation_status)
|
||||
{
|
||||
case SANG_STATUS_RX_DATA_AVAILABLE:
|
||||
break;
|
||||
|
||||
default:
|
||||
prn(1, "Error: sangoma_socket_waitfor(): Unknown Operation Status: %d\n",
|
||||
api_poll.operation_status);
|
||||
return 0;
|
||||
}//switch()
|
||||
|
||||
if(api_poll.poll_events_bitmap == 0){
|
||||
prn(1, "Error: invalid Poll Events bitmap: 0x%X\n",
|
||||
api_poll.poll_events_bitmap);
|
||||
}
|
||||
return api_poll.poll_events_bitmap;
|
||||
#else
|
||||
struct pollfd pfds[1];
|
||||
int res;
|
||||
|
||||
memset(&pfds[0], 0, sizeof(pfds[0]));
|
||||
pfds[0].fd = fd;
|
||||
pfds[0].events = flags;
|
||||
res = poll(pfds, 1, timeout);
|
||||
if (res > 0) {
|
||||
if ((pfds[0].revents & POLLERR)) {
|
||||
res = -1;
|
||||
} else if((pfds[0].revents)) {
|
||||
res = 1;
|
||||
}
|
||||
}
|
||||
|
||||
return res;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
int sangoma_span_chan_toif(int span, int chan, char *interface_name)
|
||||
{
|
||||
sprintf(interface_name,"s%ic%i",span,chan);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int sangoma_interface_toi(char *interface_name, int *span, int *chan)
|
||||
{
|
||||
char *p=NULL, *sp = NULL, *ch = NULL;
|
||||
int ret = 0;
|
||||
char data[FNAME_LEN];
|
||||
|
||||
strncpy(data, interface_name, FNAME_LEN);
|
||||
if ((data[0])) {
|
||||
for (p = data; *p; p++) {
|
||||
if (sp && *p == 'g') {
|
||||
*p = '\0';
|
||||
ch = (p + 1);
|
||||
break;
|
||||
} else if (*p == 'w') {
|
||||
sp = (p + 1);
|
||||
}
|
||||
}
|
||||
|
||||
if(ch && sp) {
|
||||
*span = atoi(sp);
|
||||
*chan = atoi(ch);
|
||||
ret = 1;
|
||||
} else {
|
||||
*span = -1;
|
||||
*chan = -1;
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int sangoma_span_chan_fromif(char *interface_name, int *span, int *chan)
|
||||
{
|
||||
char *p = NULL, *sp = NULL, *ch = NULL;
|
||||
int ret = 0;
|
||||
char data[FNAME_LEN];
|
||||
|
||||
strncpy(data, interface_name, FNAME_LEN);
|
||||
if ((data[0])) {
|
||||
for (p = data; *p; p++) {
|
||||
if (sp && *p == 'c') {
|
||||
*p = '\0';
|
||||
ch = (p + 1);
|
||||
break;
|
||||
} else if (*p == 's') {
|
||||
sp = (p + 1);
|
||||
}
|
||||
}
|
||||
|
||||
if(ch && sp) {
|
||||
*span = atoi(sp);
|
||||
*chan = atoi(ch);
|
||||
ret = 1;
|
||||
} else {
|
||||
*span = -1;
|
||||
*chan = -1;
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
sng_fd_t sangoma_open_tdmapi_span_chan(int span, int chan)
|
||||
{
|
||||
char fname[FNAME_LEN];
|
||||
#if defined(WIN32)
|
||||
|
||||
//NOTE: under Windows Interfaces are zero based but 'chan' is 1 based.
|
||||
// Subtract 1 from 'chan'.
|
||||
_snprintf(fname , FNAME_LEN, "\\\\.\\WANPIPE%d_IF%d", span, chan - 1);
|
||||
|
||||
//prn(verbose, "Opening device: %s...\n", fname);
|
||||
|
||||
return CreateFile( fname,
|
||||
GENERIC_READ | GENERIC_WRITE,
|
||||
FILE_SHARE_READ | FILE_SHARE_WRITE,
|
||||
(LPSECURITY_ATTRIBUTES)NULL,
|
||||
OPEN_EXISTING,
|
||||
FILE_FLAG_NO_BUFFERING | FILE_FLAG_WRITE_THROUGH,
|
||||
(HANDLE)NULL
|
||||
);
|
||||
#else
|
||||
int fd=-1;
|
||||
|
||||
sprintf(fname,"/dev/wptdm_s%dc%d",span,chan);
|
||||
|
||||
fd = open(fname, O_RDWR);
|
||||
|
||||
return fd;
|
||||
#endif
|
||||
}
|
||||
|
||||
sng_fd_t sangoma_create_socket_by_name(char *device, char *card)
|
||||
{
|
||||
int span,chan;
|
||||
sangoma_interface_toi(device,&span,&chan);
|
||||
|
||||
return sangoma_open_tdmapi_span_chan(span,chan);
|
||||
}
|
||||
|
||||
|
||||
sng_fd_t sangoma_open_tdmapi_span(int span)
|
||||
{
|
||||
int i=0;
|
||||
#if defined(WIN32)
|
||||
sng_fd_t fd = INVALID_HANDLE_VALUE;
|
||||
|
||||
for(i = 1; i < 32; i++){
|
||||
if((fd = sangoma_open_tdmapi_span_chan(span, i)) == INVALID_HANDLE_VALUE){
|
||||
//prn(verbose, "Span: %d, chan: %d: is not running, consider 'busy'\n",
|
||||
// span, i);
|
||||
continue;
|
||||
}
|
||||
|
||||
//get the open handle counter
|
||||
wan_udp.wan_udphdr_command = GET_OPEN_HANDLES_COUNTER;
|
||||
wan_udp.wan_udphdr_data_len = 0;
|
||||
|
||||
DoManagementCommand(fd, &wan_udp);
|
||||
if(wan_udp.wan_udphdr_return_code){
|
||||
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.
|
||||
sangoma_socket_close(&fd);
|
||||
continue;
|
||||
}
|
||||
|
||||
//prn(verbose, "open handles counter: %d\n", *(int*)&wan_udp.wan_udphdr_data[0]);
|
||||
if(*(int*)&wan_udp.wan_udphdr_data[0] == 1){
|
||||
//this is the only process using this chan/span, so it is 'free'
|
||||
//prn(verbose, "Found 'free' Span: %d, chan: %d\n",span, i);
|
||||
break;
|
||||
}
|
||||
//don't forget to close!! otherwize counter will stay incremented.
|
||||
sangoma_socket_close(&fd);
|
||||
}//for()
|
||||
|
||||
#else
|
||||
unsigned char fname[FNAME_LEN];
|
||||
int fd=0;
|
||||
for (i=1;i<32;i++){
|
||||
sprintf(fname,"/dev/wptdm_s%dc%d",span,i);
|
||||
fd = open(fname, O_RDWR);
|
||||
if (fd < 0){
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
return fd;
|
||||
}
|
||||
|
||||
static char *cut_path(char *in)
|
||||
{
|
||||
char *p, *ret = in;
|
||||
char delims[] = "/\\";
|
||||
char *i;
|
||||
|
||||
for (i = delims; *i; i++) {
|
||||
p = in;
|
||||
while ((p = strchr(p, *i)) != 0) {
|
||||
ret = ++p;
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
static void default_logger(char *file, const char *func, int line, int level, char *fmt, ...)
|
||||
{
|
||||
char *fp;
|
||||
char data[1024];
|
||||
|
||||
va_list ap;
|
||||
|
||||
fp = cut_path(file);
|
||||
|
||||
va_start(ap, fmt);
|
||||
|
||||
vsnprintf(data, sizeof(data), fmt, ap);
|
||||
|
||||
fprintf(stderr, "%s:%d %s() %s", file, line, func, data);
|
||||
|
||||
va_end(ap);
|
||||
|
||||
}
|
||||
|
||||
sangoma_logger_t global_logger = default_logger;
|
||||
|
||||
void sangoma_set_logger(sangoma_logger_t logger)
|
||||
{
|
||||
global_logger = logger;
|
||||
}
|
||||
|
||||
int sangoma_readmsg_tdm(sng_fd_t fd, void *hdrbuf, int hdrlen, void *databuf, int datalen, int flag)
|
||||
{
|
||||
int rx_len=0;
|
||||
|
||||
#if defined(WIN32)
|
||||
static RX_DATA_STRUCT rx_data;
|
||||
api_header_t *pri;
|
||||
wp_tdm_api_rx_hdr_t *tdm_api_rx_hdr;
|
||||
wp_tdm_api_rx_hdr_t *user_buf = (wp_tdm_api_rx_hdr_t*)hdrbuf;
|
||||
|
||||
if(hdrlen != sizeof(wp_tdm_api_rx_hdr_t)){
|
||||
//error
|
||||
prn(1, "Error: sangoma_readmsg_tdm(): invalid size of user's 'header buffer'.\
|
||||
Should be 'sizeof(wp_tdm_api_rx_hdr_t)'.\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if(DoReadCommand(fd, &rx_data) ){
|
||||
//error
|
||||
prn(1, "Error: DoReadCommand() failed! Check messages log.\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
//use our special buffer at rxdata to hold received data
|
||||
pri = &rx_data.api_header;
|
||||
tdm_api_rx_hdr = (wp_tdm_api_rx_hdr_t*)rx_data.data;
|
||||
|
||||
user_buf->wp_tdm_api_event_type = pri->operation_status;
|
||||
|
||||
switch(pri->operation_status)
|
||||
{
|
||||
case SANG_STATUS_RX_DATA_AVAILABLE:
|
||||
//prn(verbose, "SANG_STATUS_RX_DATA_AVAILABLE\n");
|
||||
|
||||
if(pri->data_length > datalen){
|
||||
rx_len=0;
|
||||
break;
|
||||
}
|
||||
memcpy(databuf, rx_data.data, pri->data_length);
|
||||
rx_len = pri->data_length;
|
||||
break;
|
||||
|
||||
case SANG_STATUS_TDM_EVENT_AVAILABLE:
|
||||
//prn(verbose, "SANG_STATUS_TDM_EVENT_AVAILABLE\n");
|
||||
|
||||
//make event is accessable for the caller directly:
|
||||
memcpy(databuf, rx_data.data, pri->data_length);
|
||||
rx_len = pri->data_length;
|
||||
|
||||
//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));
|
||||
break;
|
||||
|
||||
default:
|
||||
switch(pri->operation_status)
|
||||
{
|
||||
case SANG_STATUS_RX_DATA_TIMEOUT:
|
||||
//no data in READ_CMD_TIMEOUT, try again.
|
||||
prn(1, "Error: Timeout on read.\n");
|
||||
break;
|
||||
|
||||
case SANG_STATUS_BUFFER_TOO_SMALL:
|
||||
//Recieved data longer than the pre-configured maximum.
|
||||
//Maximum length is set in 'Interface Properties',
|
||||
//in the 'Device Manager'.
|
||||
prn(1, "Error: Received data longer than buffer passed to API.\n");
|
||||
break;
|
||||
|
||||
case SANG_STATUS_LINE_DISCONNECTED:
|
||||
//Front end monitoring is enabled and Line is
|
||||
//in disconnected state.
|
||||
//Check the T1/E1 line is in "Connected" state,
|
||||
//alse check the Alarms and the message log.
|
||||
prn(1, "Error: Line disconnected.\n");
|
||||
break;
|
||||
|
||||
default:
|
||||
prn(1, "Rx:Unknown Operation Status: %d\n", pri->operation_status);
|
||||
break;
|
||||
}//switch()
|
||||
return 0;
|
||||
}//switch()
|
||||
|
||||
#else
|
||||
struct msghdr msg;
|
||||
struct iovec iov[2];
|
||||
|
||||
memset(&msg,0,sizeof(struct msghdr));
|
||||
|
||||
iov[0].iov_len=hdrlen;
|
||||
iov[0].iov_base=hdrbuf;
|
||||
|
||||
iov[1].iov_len=datalen;
|
||||
iov[1].iov_base=databuf;
|
||||
|
||||
msg.msg_iovlen=2;
|
||||
msg.msg_iov=iov;
|
||||
|
||||
rx_len = read(fd,&msg,datalen+hdrlen);
|
||||
|
||||
if (rx_len <= sizeof(wp_tdm_api_rx_hdr_t)){
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
rx_len-=sizeof(wp_tdm_api_rx_hdr_t);
|
||||
#endif
|
||||
return rx_len;
|
||||
}
|
||||
|
||||
int sangoma_writemsg_tdm(sng_fd_t fd, void *hdrbuf, int hdrlen, void *databuf, unsigned short datalen, int flag)
|
||||
{
|
||||
int bsent;
|
||||
|
||||
#if defined(WIN32)
|
||||
static TX_DATA_STRUCT local_tx_data;
|
||||
api_header_t *pri;
|
||||
|
||||
pri = &local_tx_data.api_header;
|
||||
|
||||
pri->data_length = datalen;
|
||||
memcpy(local_tx_data.data, databuf, pri->data_length);
|
||||
|
||||
//queue data for transmission
|
||||
if( DoWriteCommand(fd, &local_tx_data)){
|
||||
//error
|
||||
prn(1, "Error: DoWriteCommand() failed!! Check messages log.\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
bsent=0;
|
||||
//check that frame was transmitted
|
||||
switch(local_tx_data.api_header.operation_status)
|
||||
{
|
||||
case SANG_STATUS_SUCCESS:
|
||||
bsent = datalen;
|
||||
break;
|
||||
|
||||
case SANG_STATUS_TX_TIMEOUT:
|
||||
//error
|
||||
prn(1, "****** Error: SANG_STATUS_TX_TIMEOUT ******\n");
|
||||
//Check messages log or look at statistics.
|
||||
break;
|
||||
|
||||
case SANG_STATUS_TX_DATA_TOO_LONG:
|
||||
//Attempt to transmit data longer than the pre-configured maximum.
|
||||
//Maximum length is set in 'Interface Properties',
|
||||
//in the 'Device Manager'.
|
||||
prn(1, "****** SANG_STATUS_TX_DATA_TOO_LONG ******\n");
|
||||
break;
|
||||
|
||||
case SANG_STATUS_TX_DATA_TOO_SHORT:
|
||||
//Minimum is 1 byte for Primary port,
|
||||
// 2 bytes for Secondary port
|
||||
prn(1, "****** SANG_STATUS_TX_DATA_TOO_SHORT ******\n");
|
||||
break;
|
||||
|
||||
case SANG_STATUS_LINE_DISCONNECTED:
|
||||
//Front end monitoring is enabled and Line is
|
||||
//in disconnected state.
|
||||
//Check the T1/E1 line is in "Connected" state,
|
||||
//alse check the Alarms and the message log.
|
||||
prn(1, "****** SANG_STATUS_LINE_DISCONNECTED ******\n");
|
||||
break;
|
||||
|
||||
default:
|
||||
prn(1, "Unknown return code (0x%X) on transmission!\n",
|
||||
local_tx_data.api_header.operation_status);
|
||||
break;
|
||||
}//switch()
|
||||
#else
|
||||
struct msghdr msg;
|
||||
struct iovec iov[2];
|
||||
|
||||
memset(&msg,0,sizeof(struct msghdr));
|
||||
|
||||
iov[0].iov_len=hdrlen;
|
||||
iov[0].iov_base=hdrbuf;
|
||||
|
||||
iov[1].iov_len=datalen;
|
||||
iov[1].iov_base=databuf;
|
||||
|
||||
msg.msg_iovlen=2;
|
||||
msg.msg_iov=iov;
|
||||
|
||||
bsent = write(fd,&msg,datalen+hdrlen);
|
||||
if (bsent > 0){
|
||||
bsent-=sizeof(wp_tdm_api_tx_hdr_t);
|
||||
}
|
||||
#endif
|
||||
return bsent;
|
||||
}
|
||||
|
||||
|
||||
#ifdef WANPIPE_TDM_API
|
||||
|
||||
/*========================================================
|
||||
* Execute TDM command
|
||||
*
|
||||
*/
|
||||
int sangoma_tdm_cmd_exec(sng_fd_t fd, wanpipe_tdm_api_t *tdm_api)
|
||||
{
|
||||
int err;
|
||||
|
||||
#if defined(WIN32)
|
||||
err = tdmv_api_ioctl(fd, &tdm_api->wp_tdm_cmd);
|
||||
#else
|
||||
err = ioctl(fd,SIOC_WANPIPE_TDM_API,&tdm_api->wp_tdm_cmd);
|
||||
if (err < 0){
|
||||
char tmp[50];
|
||||
sprintf(tmp,"TDM API: CMD: %i\n",tdm_api->wp_tdm_cmd.cmd);
|
||||
perror(tmp);
|
||||
return -1;
|
||||
}
|
||||
#endif
|
||||
return err;
|
||||
}
|
||||
|
||||
/*========================================================
|
||||
* Get Full TDM API configuration per channel
|
||||
*
|
||||
*/
|
||||
int sangoma_get_full_cfg(sng_fd_t fd, wanpipe_tdm_api_t *tdm_api)
|
||||
{
|
||||
int err;
|
||||
|
||||
tdm_api->wp_tdm_cmd.cmd = SIOC_WP_TDM_GET_FULL_CFG;
|
||||
|
||||
err=sangoma_tdm_cmd_exec(fd,tdm_api);
|
||||
if (err){
|
||||
return err;
|
||||
}
|
||||
|
||||
printf("TDM API CFG:\n");
|
||||
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_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("\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("\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("\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("\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 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__
|
||||
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
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*========================================================
|
||||
* SET Codec on a particular Channel.
|
||||
*
|
||||
* Available codecs are defined in
|
||||
* /usr/src/linux/include/linux/wanpipe_cfg.h
|
||||
*
|
||||
* enum wan_codec_format {
|
||||
* WP_NONE,
|
||||
* WP_SLINEAR
|
||||
* }
|
||||
*
|
||||
*/
|
||||
int sangoma_tdm_set_codec(sng_fd_t fd, wanpipe_tdm_api_t *tdm_api, int codec)
|
||||
{
|
||||
int err;
|
||||
|
||||
tdm_api->wp_tdm_cmd.cmd = SIOC_WP_TDM_SET_CODEC;
|
||||
tdm_api->wp_tdm_cmd.tdm_codec = codec;
|
||||
|
||||
err=sangoma_tdm_cmd_exec(fd,tdm_api);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
/*========================================================
|
||||
* GET Codec from a particular Channel.
|
||||
*
|
||||
* Available codecs are defined in
|
||||
* /usr/src/linux/include/linux/wanpipe_cfg.h
|
||||
*
|
||||
* enum wan_codec_format {
|
||||
* WP_NONE,
|
||||
* WP_SLINEAR
|
||||
* }
|
||||
*
|
||||
*/
|
||||
int sangoma_tdm_get_codec(sng_fd_t fd, wanpipe_tdm_api_t *tdm_api)
|
||||
{
|
||||
int err;
|
||||
|
||||
tdm_api->wp_tdm_cmd.cmd = SIOC_WP_TDM_GET_CODEC;
|
||||
|
||||
err=sangoma_tdm_cmd_exec(fd,tdm_api);
|
||||
if (err){
|
||||
return err;
|
||||
}
|
||||
|
||||
return tdm_api->wp_tdm_cmd.tdm_codec;
|
||||
}
|
||||
|
||||
|
||||
/*========================================================
|
||||
* SET Rx/Tx Hardware Period in milliseconds.
|
||||
*
|
||||
* Available options are:
|
||||
* 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 err;
|
||||
|
||||
tdm_api->wp_tdm_cmd.cmd = SIOC_WP_TDM_SET_USR_PERIOD;
|
||||
tdm_api->wp_tdm_cmd.usr_period = period;
|
||||
|
||||
err=sangoma_tdm_cmd_exec(fd,tdm_api);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
/*========================================================
|
||||
* GET Rx/Tx Hardware Period in milliseconds.
|
||||
*
|
||||
* Available options are:
|
||||
* 10,20,30,40,50 ms
|
||||
*
|
||||
*/
|
||||
int sangoma_tdm_get_usr_period(sng_fd_t fd, wanpipe_tdm_api_t *tdm_api)
|
||||
{
|
||||
int err;
|
||||
|
||||
tdm_api->wp_tdm_cmd.cmd = SIOC_WP_TDM_GET_USR_PERIOD;
|
||||
|
||||
err=sangoma_tdm_cmd_exec(fd,tdm_api);
|
||||
if (err){
|
||||
return err;
|
||||
}
|
||||
|
||||
return tdm_api->wp_tdm_cmd.usr_period;
|
||||
}
|
||||
|
||||
/*========================================================
|
||||
* GET Current User Hardware Coding Format
|
||||
*
|
||||
* 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 err;
|
||||
tdm_api->wp_tdm_cmd.cmd = SIOC_WP_TDM_GET_HW_CODING;
|
||||
err=sangoma_tdm_cmd_exec(fd,tdm_api);
|
||||
if (err){
|
||||
return err;
|
||||
}
|
||||
return tdm_api->wp_tdm_cmd.hw_tdm_coding;
|
||||
}
|
||||
|
||||
|
||||
/*========================================================
|
||||
* GET Current User MTU/MRU values in bytes.
|
||||
*
|
||||
* The USER MTU/MRU values will change each time a PERIOD
|
||||
* or CODEC is adjusted.
|
||||
*/
|
||||
int sangoma_tdm_get_usr_mtu_mru(sng_fd_t fd, wanpipe_tdm_api_t *tdm_api)
|
||||
{
|
||||
int err;
|
||||
|
||||
tdm_api->wp_tdm_cmd.cmd = SIOC_WP_TDM_GET_USR_MTU_MRU;
|
||||
|
||||
err=sangoma_tdm_cmd_exec(fd,tdm_api);
|
||||
if (err){
|
||||
return err;
|
||||
}
|
||||
|
||||
return tdm_api->wp_tdm_cmd.usr_mtu_mru;
|
||||
}
|
||||
|
||||
/*========================================================
|
||||
* SET TDM Power Level
|
||||
*
|
||||
* 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 err;
|
||||
|
||||
tdm_api->wp_tdm_cmd.cmd = SIOC_WP_TDM_SET_POWER_LEVEL;
|
||||
tdm_api->wp_tdm_cmd.power_level = power;
|
||||
|
||||
err=sangoma_tdm_cmd_exec(fd,tdm_api);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
/*========================================================
|
||||
* GET TDM Power Level
|
||||
*
|
||||
* This option is not implemented yet
|
||||
*
|
||||
*/
|
||||
int sangoma_tdm_get_power_level(sng_fd_t fd, wanpipe_tdm_api_t *tdm_api)
|
||||
{
|
||||
int err;
|
||||
|
||||
tdm_api->wp_tdm_cmd.cmd = SIOC_WP_TDM_GET_POWER_LEVEL;
|
||||
|
||||
err=sangoma_tdm_cmd_exec(fd,tdm_api);
|
||||
if (err){
|
||||
return err;
|
||||
}
|
||||
|
||||
return tdm_api->wp_tdm_cmd.power_level;
|
||||
}
|
||||
|
||||
int sangoma_tdm_flush_bufs(sng_fd_t fd, wanpipe_tdm_api_t *tdm_api)
|
||||
{
|
||||
#if 0
|
||||
tdm_api->wp_tdm_cmd.cmd = SIOC_WP_TDM_FLUSH_BUFFERS;
|
||||
|
||||
err=sangoma_tdm_cmd_exec(fd,tdm_api);
|
||||
if (err){
|
||||
return err;
|
||||
}
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
int sangoma_tdm_enable_rbs_events(sng_fd_t fd, wanpipe_tdm_api_t *tdm_api, int poll_in_sec) {
|
||||
|
||||
int err;
|
||||
|
||||
tdm_api->wp_tdm_cmd.cmd = SIOC_WP_TDM_ENABLE_RBS_EVENTS;
|
||||
tdm_api->wp_tdm_cmd.rbs_poll=poll_in_sec;
|
||||
|
||||
err=sangoma_tdm_cmd_exec(fd,tdm_api);
|
||||
if (err){
|
||||
return err;
|
||||
}
|
||||
|
||||
return tdm_api->wp_tdm_cmd.rbs_poll;
|
||||
}
|
||||
|
||||
|
||||
int sangoma_tdm_disable_rbs_events(sng_fd_t fd, wanpipe_tdm_api_t *tdm_api) {
|
||||
|
||||
int err;
|
||||
tdm_api->wp_tdm_cmd.cmd = SIOC_WP_TDM_DISABLE_RBS_EVENTS;
|
||||
|
||||
err=sangoma_tdm_cmd_exec(fd,tdm_api);
|
||||
if (err){
|
||||
return err;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int sangoma_tdm_write_rbs(sng_fd_t fd, wanpipe_tdm_api_t *tdm_api, unsigned char rbs)
|
||||
{
|
||||
|
||||
int err;
|
||||
tdm_api->wp_tdm_cmd.cmd = SIOC_WP_TDM_WRITE_RBS_BITS;
|
||||
tdm_api->wp_tdm_cmd.rbs_tx_bits=rbs;
|
||||
|
||||
err=sangoma_tdm_cmd_exec(fd,tdm_api);
|
||||
if (err){
|
||||
return err;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int sangoma_tdm_read_event(sng_fd_t fd, wanpipe_tdm_api_t *tdm_api)
|
||||
{
|
||||
wp_tdm_api_rx_hdr_t *rx_event;
|
||||
|
||||
#if defined(WIN32)
|
||||
rx_event = &last_tdm_api_event_buffer;
|
||||
#else
|
||||
int err;
|
||||
|
||||
tdm_api->wp_tdm_cmd.cmd = SIOC_WP_TDM_READ_EVENT;
|
||||
|
||||
err=sangoma_tdm_cmd_exec(fd,tdm_api);
|
||||
if (err){
|
||||
return err;
|
||||
}
|
||||
|
||||
rx_event = &tdm_api->wp_tdm_cmd.event;
|
||||
#endif
|
||||
|
||||
switch (rx_event->wp_tdm_api_event_type){
|
||||
|
||||
case WP_TDM_EVENT_RBS:
|
||||
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) {
|
||||
tdm_api->wp_tdm_event.wp_rbs_event(fd,rx_event->wp_tdm_api_event_rbs_rx_bits);
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case WP_TDM_EVENT_DTMF:
|
||||
printf("%d: GOT DTMF EVENT\n",(int)fd);
|
||||
if (tdm_api->wp_tdm_event.wp_dtmf_event) {
|
||||
tdm_api->wp_tdm_event.wp_dtmf_event(fd,
|
||||
rx_event->wp_tdm_api_event_dtmf_digit,
|
||||
rx_event->wp_tdm_api_event_dtmf_type,
|
||||
rx_event->wp_tdm_api_event_dtmf_port);
|
||||
}
|
||||
break;
|
||||
|
||||
case WP_TDM_EVENT_RXHOOK:
|
||||
printf("%d: GOT RXHOOK EVENT\n",(int)fd);
|
||||
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);
|
||||
}
|
||||
break;
|
||||
|
||||
case WP_TDM_EVENT_RING_DETECT:
|
||||
printf("%d: GOT RXRING EVENT\n",(int)fd);
|
||||
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);
|
||||
}
|
||||
break;
|
||||
|
||||
case WP_TDM_EVENT_RING_TRIP:
|
||||
printf("%d: GOT ROUTING TRIP EVENT\n",(int)fd);
|
||||
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);
|
||||
}
|
||||
break;
|
||||
|
||||
case WP_TDM_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) {
|
||||
tdm_api->wp_tdm_event.wp_fe_alarm_event(fd,
|
||||
rx_event->wp_tdm_api_event_fe_alarm);
|
||||
}
|
||||
|
||||
default:
|
||||
printf("%d: Unknown TDM event!", (int)fd);
|
||||
break;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int sangoma_tdm_enable_dtmf_events(sng_fd_t fd, wanpipe_tdm_api_t *tdm_api)
|
||||
{
|
||||
int err;
|
||||
|
||||
tdm_api->wp_tdm_cmd.cmd = SIOC_WP_TDM_ENABLE_DTMF_EVENTS;
|
||||
err=sangoma_tdm_cmd_exec(fd,tdm_api);
|
||||
if (err){
|
||||
return err;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int sangoma_tdm_disable_dtmf_events(sng_fd_t fd, wanpipe_tdm_api_t *tdm_api)
|
||||
{
|
||||
int err;
|
||||
|
||||
tdm_api->wp_tdm_cmd.cmd = SIOC_WP_TDM_DISABLE_DTMF_EVENTS;
|
||||
err=sangoma_tdm_cmd_exec(fd,tdm_api);
|
||||
if (err){
|
||||
return err;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int sangoma_tdm_enable_rm_dtmf_events(sng_fd_t fd, wanpipe_tdm_api_t *tdm_api)
|
||||
{
|
||||
int err;
|
||||
|
||||
tdm_api->wp_tdm_cmd.cmd = SIOC_WP_TDM_ENABLE_RM_DTMF_EVENTS;
|
||||
err=sangoma_tdm_cmd_exec(fd,tdm_api);
|
||||
if (err){
|
||||
return err;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int sangoma_tdm_disable_rm_dtmf_events(sng_fd_t fd, wanpipe_tdm_api_t *tdm_api)
|
||||
{
|
||||
int err;
|
||||
|
||||
tdm_api->wp_tdm_cmd.cmd = SIOC_WP_TDM_DISABLE_RM_DTMF_EVENTS;
|
||||
err=sangoma_tdm_cmd_exec(fd,tdm_api);
|
||||
if (err){
|
||||
return err;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int sangoma_tdm_enable_rxhook_events(sng_fd_t fd, wanpipe_tdm_api_t *tdm_api)
|
||||
{
|
||||
int err;
|
||||
|
||||
tdm_api->wp_tdm_cmd.cmd = SIOC_WP_TDM_ENABLE_RXHOOK_EVENTS;
|
||||
err=sangoma_tdm_cmd_exec(fd,tdm_api);
|
||||
if (err){
|
||||
return err;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int sangoma_tdm_disable_rxhook_events(sng_fd_t fd, wanpipe_tdm_api_t *tdm_api)
|
||||
{
|
||||
int err;
|
||||
|
||||
tdm_api->wp_tdm_cmd.cmd = SIOC_WP_TDM_DISABLE_RXHOOK_EVENTS;
|
||||
err=sangoma_tdm_cmd_exec(fd,tdm_api);
|
||||
if (err){
|
||||
return err;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*========================================================
|
||||
* GET Front End Alarms
|
||||
*
|
||||
*/
|
||||
int sangoma_tdm_get_fe_alarms(sng_fd_t fd, wanpipe_tdm_api_t *tdm_api)
|
||||
{
|
||||
int err;
|
||||
|
||||
tdm_api->wp_tdm_cmd.cmd = SIOC_WP_TDM_GET_FE_ALARMS;
|
||||
|
||||
err=sangoma_tdm_cmd_exec(fd,tdm_api);
|
||||
if (err){
|
||||
return err;
|
||||
}
|
||||
|
||||
return tdm_api->wp_tdm_cmd.fe_alarms;
|
||||
}
|
||||
|
||||
#endif /* WANPIPE_TDM_API */
|
@ -1,100 +0,0 @@
|
||||
# Microsoft Developer Studio Project File - Name="libsangoma" - Package Owner=<4>
|
||||
# Microsoft Developer Studio Generated Build File, Format Version 6.00
|
||||
# ** DO NOT EDIT **
|
||||
|
||||
# TARGTYPE "Win32 (x86) Static Library" 0x0104
|
||||
|
||||
CFG=libsangoma - Win32 Debug
|
||||
!MESSAGE This is not a valid makefile. To build this project using NMAKE,
|
||||
!MESSAGE use the Export Makefile command and run
|
||||
!MESSAGE
|
||||
!MESSAGE NMAKE /f "libsangoma.mak".
|
||||
!MESSAGE
|
||||
!MESSAGE You can specify a configuration when running NMAKE
|
||||
!MESSAGE by defining the macro CFG on the command line. For example:
|
||||
!MESSAGE
|
||||
!MESSAGE NMAKE /f "libsangoma.mak" CFG="libsangoma - Win32 Debug"
|
||||
!MESSAGE
|
||||
!MESSAGE Possible choices for configuration are:
|
||||
!MESSAGE
|
||||
!MESSAGE "libsangoma - Win32 Release" (based on "Win32 (x86) Static Library")
|
||||
!MESSAGE "libsangoma - Win32 Debug" (based on "Win32 (x86) Static Library")
|
||||
!MESSAGE
|
||||
|
||||
# Begin Project
|
||||
# PROP AllowPerConfigDependencies 0
|
||||
# PROP Scc_ProjName ""
|
||||
# PROP Scc_LocalPath ""
|
||||
CPP=cl.exe
|
||||
RSC=rc.exe
|
||||
|
||||
!IF "$(CFG)" == "libsangoma - Win32 Release"
|
||||
|
||||
# PROP BASE Use_MFC 0
|
||||
# PROP BASE Use_Debug_Libraries 0
|
||||
# PROP BASE Output_Dir "Release"
|
||||
# PROP BASE Intermediate_Dir "Release"
|
||||
# PROP BASE Target_Dir ""
|
||||
# PROP Use_MFC 0
|
||||
# PROP Use_Debug_Libraries 0
|
||||
# PROP Output_Dir "Release"
|
||||
# PROP Intermediate_Dir "Release"
|
||||
# PROP Target_Dir ""
|
||||
# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_MBCS" /D "_LIB" /YX /FD /c
|
||||
# ADD CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_MBCS" /D "_LIB" /YX /FD /c
|
||||
# ADD BASE RSC /l 0x409 /d "NDEBUG"
|
||||
# ADD RSC /l 0x409 /d "NDEBUG"
|
||||
BSC32=bscmake.exe
|
||||
# ADD BASE BSC32 /nologo
|
||||
# ADD BSC32 /nologo
|
||||
LIB32=link.exe -lib
|
||||
# ADD BASE LIB32 /nologo
|
||||
# ADD LIB32 /nologo
|
||||
|
||||
!ELSEIF "$(CFG)" == "libsangoma - Win32 Debug"
|
||||
|
||||
# PROP BASE Use_MFC 0
|
||||
# PROP BASE Use_Debug_Libraries 1
|
||||
# PROP BASE Output_Dir "Debug"
|
||||
# PROP BASE Intermediate_Dir "Debug"
|
||||
# PROP BASE Target_Dir ""
|
||||
# PROP Use_MFC 0
|
||||
# PROP Use_Debug_Libraries 1
|
||||
# PROP Output_Dir "Debug"
|
||||
# PROP Intermediate_Dir "Debug"
|
||||
# PROP Target_Dir ""
|
||||
# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_MBCS" /D "_LIB" /YX /FD /GZ /c
|
||||
# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_MBCS" /D "_LIB" /YX /FD /GZ /c
|
||||
# ADD BASE RSC /l 0x409 /d "_DEBUG"
|
||||
# ADD RSC /l 0x409 /d "_DEBUG"
|
||||
BSC32=bscmake.exe
|
||||
# ADD BASE BSC32 /nologo
|
||||
# ADD BSC32 /nologo
|
||||
LIB32=link.exe -lib
|
||||
# ADD BASE LIB32 /nologo
|
||||
# ADD LIB32 /nologo
|
||||
|
||||
!ENDIF
|
||||
|
||||
# Begin Target
|
||||
|
||||
# Name "libsangoma - Win32 Release"
|
||||
# Name "libsangoma - Win32 Debug"
|
||||
# Begin Group "Source Files"
|
||||
|
||||
# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\libsangoma.c
|
||||
# End Source File
|
||||
# End Group
|
||||
# Begin Group "Header Files"
|
||||
|
||||
# PROP Default_Filter "h;hpp;hxx;hm;inl"
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\win_api_common.h
|
||||
# End Source File
|
||||
# End Group
|
||||
# End Target
|
||||
# End Project
|
@ -1,29 +0,0 @@
|
||||
Microsoft Developer Studio Workspace File, Format Version 6.00
|
||||
# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE!
|
||||
|
||||
###############################################################################
|
||||
|
||||
Project: "libsangoma"=.\libsangoma.dsp - Package Owner=<4>
|
||||
|
||||
Package=<5>
|
||||
{{{
|
||||
}}}
|
||||
|
||||
Package=<4>
|
||||
{{{
|
||||
}}}
|
||||
|
||||
###############################################################################
|
||||
|
||||
Global:
|
||||
|
||||
Package=<5>
|
||||
{{{
|
||||
}}}
|
||||
|
||||
Package=<3>
|
||||
{{{
|
||||
}}}
|
||||
|
||||
###############################################################################
|
||||
|
@ -1,171 +0,0 @@
|
||||
#ifndef _LIBSNAGOMA_H
|
||||
#define _LIBSNAGOMA_H
|
||||
#include <stdio.h>
|
||||
|
||||
#define WANPIPE_TDM_API 1
|
||||
|
||||
#ifdef WIN32
|
||||
#ifndef __WINDOWS__
|
||||
#define __WINDOWS__
|
||||
#endif
|
||||
#include <windows.h>
|
||||
#include <winioctl.h>
|
||||
#include <conio.h>
|
||||
#include <stddef.h> //for offsetof()
|
||||
typedef unsigned __int16 u_int16_t;
|
||||
typedef unsigned __int32 u_int32_t;
|
||||
#include <wanpipe_defines.h> //for 'wan_udp_hdr_t'
|
||||
#include <wanpipe_cfg.h>
|
||||
#ifdef WANPIPE_TDM_API
|
||||
#include <wanpipe_tdm_api.h> //for TDMV API
|
||||
#endif
|
||||
#include <sang_status_defines.h>//return codes
|
||||
#include <sang_api.h> //for IOCTL codes
|
||||
#include <sdla_te1_pmc.h> //RBS definitions
|
||||
#include <sdla_te1.h> //TE1 macros
|
||||
#include <sdla_56k.h> //56k macros
|
||||
#include <sdla_remora.h> //Analog card
|
||||
#include <sdla_te3.h> //T3 card
|
||||
#include <sdla_front_end.h> //front-end (T1/E1/56k) commands
|
||||
#include <sdla_aft_te1.h> //for Wanpipe API
|
||||
|
||||
#define _MYDEBUG
|
||||
#define PROGRAM_NAME "LIBSANGOMA: "
|
||||
#include <DebugOut.h>
|
||||
|
||||
typedef HANDLE sng_fd_t;
|
||||
#else
|
||||
#include <stdlib.h>
|
||||
#include <ctype.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/time.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/signal.h>
|
||||
#include <sys/select.h>
|
||||
#include <sys/wait.h>
|
||||
#include <sys/resource.h>
|
||||
#include <netinet/in.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <linux/if.h>
|
||||
#include <poll.h>
|
||||
#include <signal.h>
|
||||
|
||||
//typedef int sng_fd_t;
|
||||
#include <linux/wanpipe_defines.h>
|
||||
#include <linux/wanpipe_cfg.h>
|
||||
#include <linux/wanpipe.h>
|
||||
#ifdef WANPIPE_TDM_API
|
||||
# include <linux/wanpipe_tdm_api.h>
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#define FNAME_LEN 50
|
||||
#define FUNC_DBG(x) if(0)printf("%s:%d\n", x, __LINE__)
|
||||
#define DBG_PRINT if(1)printf
|
||||
|
||||
typedef wp_tdm_api_rx_hdr_t sangoma_api_hdr_t;
|
||||
|
||||
/* Decodec Span/Chan from interface name */
|
||||
int sangoma_span_chan_toif(int span, int chan, char *interface_name);
|
||||
int sangoma_span_chan_fromif(char *interface_name, int *span, int *chan);
|
||||
int sangoma_interface_toi(char *interface_name, int *span, int *chan);
|
||||
|
||||
sng_fd_t sangoma_create_socket_by_name(char *device, char *card);
|
||||
|
||||
/* Open Span/Chan devices
|
||||
* open_tdmapi_span_chan: open device based on span chan values
|
||||
* sangoma_open_tdmapi_span: open first available device on span
|
||||
*/
|
||||
|
||||
sng_fd_t sangoma_open_tdmapi_span_chan(int span, int chan);
|
||||
sng_fd_t sangoma_open_tdmapi_span(int span);
|
||||
|
||||
#define sangoma_create_socket_intr sangoma_open_tdmapi_span_chan
|
||||
|
||||
/* Device Rx/Tx functions
|
||||
* writemsg_tdm: tx header + data from 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_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_sendmsg_socket sangoma_writemsg_tdm
|
||||
|
||||
#ifdef WANPIPE_TDM_API
|
||||
|
||||
void sangoma_socket_close(sng_fd_t *sp);
|
||||
int sangoma_socket_waitfor(sng_fd_t fd, int timeout, int flags);
|
||||
|
||||
/* Get Full TDM API configuration per chan */
|
||||
int sangoma_get_full_cfg(sng_fd_t fd, wanpipe_tdm_api_t *tdm_api);
|
||||
|
||||
/* 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_get_codec(sng_fd_t fd, wanpipe_tdm_api_t *tdm_api);
|
||||
|
||||
/* 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_get_usr_period(sng_fd_t fd, wanpipe_tdm_api_t *tdm_api);
|
||||
|
||||
/* Get user MTU/MRU values in bytes */
|
||||
int sangoma_tdm_get_usr_mtu_mru(sng_fd_t fd, wanpipe_tdm_api_t *tdm_api);
|
||||
|
||||
/* Not supported yet */
|
||||
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);
|
||||
|
||||
/* Flush buffers from current channel */
|
||||
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_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_read_event(sng_fd_t fd, wanpipe_tdm_api_t *tdm_api);
|
||||
|
||||
/* DTMF Detection on Octasic chip */
|
||||
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);
|
||||
|
||||
/* 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_disable_rm_dtmf_events(sng_fd_t fd, wanpipe_tdm_api_t *tdm_api);
|
||||
|
||||
/* 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_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_cmd_exec(sng_fd_t fd, wanpipe_tdm_api_t *tdm_api);
|
||||
|
||||
#define WP_PRE __FILE__, __FUNCTION__, __LINE__
|
||||
#define WP_LOG_DEBUG WP_PRE, 7
|
||||
#define WP_LOG_INFO WP_PRE, 6
|
||||
#define WP_LOG_NOTICE WP_PRE, 5
|
||||
#define WP_LOG_WARNING WP_PRE, 4
|
||||
#define WP_LOG_ERROR WP_PRE, 3
|
||||
#define WP_LOG_CRIT WP_PRE, 2
|
||||
#define WP_LOG_ALERT WP_PRE, 1
|
||||
#define WP_LOG_EMERG WP_PRE, 0
|
||||
|
||||
typedef void (*sangoma_logger_t)(char *file, const char *func, int line, int level, char *fmt, ...);
|
||||
void sangoma_set_logger(sangoma_logger_t logger);
|
||||
|
||||
extern sangoma_logger_t global_logger;
|
||||
|
||||
#ifndef LIBSANGOMA_GET_HWCODING
|
||||
#define LIBSANGOMA_GET_HWCODING 1
|
||||
#endif
|
||||
int sangoma_tdm_get_hw_coding(int fd, wanpipe_tdm_api_t *tdm_api);
|
||||
|
||||
#endif /* WANPIPE_TDM_API */
|
||||
|
||||
#endif
|
@ -1 +0,0 @@
|
||||
/usr/local/lib
|
@ -1,226 +0,0 @@
|
||||
<?xml version="1.0" encoding="Windows-1252"?>
|
||||
<VisualStudioProject
|
||||
ProjectType="Visual C++"
|
||||
Version="8.00"
|
||||
Name="libsangoma"
|
||||
ProjectGUID="{7E60CC2D-E818-4712-8F16-C0E6EC64982F}"
|
||||
RootNamespace="libsangoma"
|
||||
>
|
||||
<Platforms>
|
||||
<Platform
|
||||
Name="Win32"
|
||||
/>
|
||||
</Platforms>
|
||||
<ToolFiles>
|
||||
</ToolFiles>
|
||||
<Configurations>
|
||||
<Configuration
|
||||
Name="Release|Win32"
|
||||
OutputDirectory=".\Release"
|
||||
IntermediateDirectory=".\Release"
|
||||
ConfigurationType="4"
|
||||
InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC60.vsprops"
|
||||
UseOfMFC="0"
|
||||
ATLMinimizesCRunTimeLibraryUsage="false"
|
||||
CharacterSet="2"
|
||||
>
|
||||
<Tool
|
||||
Name="VCPreBuildEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXMLDataGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCWebServiceProxyGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCMIDLTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
Optimization="2"
|
||||
InlineFunctionExpansion="1"
|
||||
AdditionalIncludeDirectories=".;include\api;include\debug;include\octasic;include\pnp;..\libpri"
|
||||
PreprocessorDefinitions="WIN32;NDEBUG;_LIB;WANPIPE_TDM_API;_CRT_SECURE_NO_DEPRECATE"
|
||||
StringPooling="true"
|
||||
RuntimeLibrary="2"
|
||||
EnableFunctionLevelLinking="true"
|
||||
PrecompiledHeaderFile=".\Release/libsangoma.pch"
|
||||
AssemblerListingLocation=".\Release/"
|
||||
ObjectFile=".\Release/"
|
||||
ProgramDataBaseFileName=".\Release/"
|
||||
WarningLevel="4"
|
||||
WarnAsError="true"
|
||||
SuppressStartupBanner="true"
|
||||
Detect64BitPortabilityProblems="true"
|
||||
DisableSpecificWarnings="4100;4214;4201;4706;4311;4312"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManagedResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCResourceCompilerTool"
|
||||
PreprocessorDefinitions="NDEBUG"
|
||||
Culture="1033"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPreLinkEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCLibrarianTool"
|
||||
OutputFile=".\Release\libsangoma.lib"
|
||||
SuppressStartupBanner="true"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCALinkTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXDCMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCBscMakeTool"
|
||||
SuppressStartupBanner="true"
|
||||
OutputFile=".\Release/libsangoma.bsc"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCFxCopTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPostBuildEventTool"
|
||||
/>
|
||||
</Configuration>
|
||||
<Configuration
|
||||
Name="Debug|Win32"
|
||||
OutputDirectory=".\Debug"
|
||||
IntermediateDirectory=".\Debug"
|
||||
ConfigurationType="4"
|
||||
InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC60.vsprops"
|
||||
UseOfMFC="0"
|
||||
ATLMinimizesCRunTimeLibraryUsage="false"
|
||||
CharacterSet="2"
|
||||
>
|
||||
<Tool
|
||||
Name="VCPreBuildEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXMLDataGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCWebServiceProxyGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCMIDLTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
Optimization="0"
|
||||
AdditionalIncludeDirectories=".;include\api;include\debug;include\octasic;include\pnp;..\libpri"
|
||||
PreprocessorDefinitions="WIN32;_DEBUG;_LIB;__WINDOWS__;WANPIPE_TDM_API;_CRT_SECURE_NO_DEPRECATE"
|
||||
MinimalRebuild="true"
|
||||
BasicRuntimeChecks="3"
|
||||
RuntimeLibrary="3"
|
||||
PrecompiledHeaderFile=".\Debug/libsangoma.pch"
|
||||
AssemblerListingLocation=".\Debug/"
|
||||
ObjectFile=".\Debug/"
|
||||
ProgramDataBaseFileName=".\Debug/"
|
||||
WarningLevel="4"
|
||||
WarnAsError="true"
|
||||
SuppressStartupBanner="true"
|
||||
Detect64BitPortabilityProblems="true"
|
||||
DebugInformationFormat="3"
|
||||
DisableSpecificWarnings="4100;4214;4201;4706;4311;4312"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManagedResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCResourceCompilerTool"
|
||||
PreprocessorDefinitions="_DEBUG"
|
||||
Culture="1033"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPreLinkEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCLibrarianTool"
|
||||
OutputFile=".\Debug\libsangoma.lib"
|
||||
SuppressStartupBanner="true"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCALinkTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXDCMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCBscMakeTool"
|
||||
SuppressStartupBanner="true"
|
||||
OutputFile=".\Debug/libsangoma.bsc"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCFxCopTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPostBuildEventTool"
|
||||
/>
|
||||
</Configuration>
|
||||
</Configurations>
|
||||
<References>
|
||||
</References>
|
||||
<Files>
|
||||
<Filter
|
||||
Name="Source Files"
|
||||
Filter="cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
|
||||
>
|
||||
<File
|
||||
RelativePath="libsangoma.c"
|
||||
>
|
||||
<FileConfiguration
|
||||
Name="Release|Win32"
|
||||
>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
PreprocessorDefinitions=""
|
||||
/>
|
||||
</FileConfiguration>
|
||||
<FileConfiguration
|
||||
Name="Debug|Win32"
|
||||
>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
PreprocessorDefinitions=""
|
||||
/>
|
||||
</FileConfiguration>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\sangoma_pri.c"
|
||||
>
|
||||
</File>
|
||||
</Filter>
|
||||
<Filter
|
||||
Name="Header Files"
|
||||
Filter="h;hpp;hxx;hm;inl"
|
||||
>
|
||||
<File
|
||||
RelativePath=".\libsangoma.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\sangoma_pri.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="win_api_common.h"
|
||||
>
|
||||
</File>
|
||||
</Filter>
|
||||
</Files>
|
||||
<Globals>
|
||||
</Globals>
|
||||
</VisualStudioProject>
|
@ -1,252 +0,0 @@
|
||||
#include <libsangoma.h>
|
||||
#include <sangoma_pri.h>
|
||||
#ifndef HAVE_GETTIMEOFDAY
|
||||
|
||||
#ifdef WIN32
|
||||
#include <mmsystem.h>
|
||||
|
||||
static __inline int gettimeofday(struct timeval *tp, void *nothing)
|
||||
{
|
||||
#ifdef WITHOUT_MM_LIB
|
||||
SYSTEMTIME st;
|
||||
time_t tt;
|
||||
struct tm tmtm;
|
||||
/* mktime converts local to UTC */
|
||||
GetLocalTime(&st);
|
||||
tmtm.tm_sec = st.wSecond;
|
||||
tmtm.tm_min = st.wMinute;
|
||||
tmtm.tm_hour = st.wHour;
|
||||
tmtm.tm_mday = st.wDay;
|
||||
tmtm.tm_mon = st.wMonth - 1;
|
||||
tmtm.tm_year = st.wYear - 1900;
|
||||
tmtm.tm_isdst = -1;
|
||||
tt = mktime(&tmtm);
|
||||
tp->tv_sec = tt;
|
||||
tp->tv_usec = st.wMilliseconds * 1000;
|
||||
#else
|
||||
/**
|
||||
** The earlier time calculations using GetLocalTime
|
||||
** had a time resolution of 10ms.The timeGetTime, part
|
||||
** of multimedia apis offer a better time resolution
|
||||
** of 1ms.Need to link against winmm.lib for this
|
||||
**/
|
||||
unsigned long Ticks = 0;
|
||||
unsigned long Sec = 0;
|
||||
unsigned long Usec = 0;
|
||||
Ticks = timeGetTime();
|
||||
|
||||
Sec = Ticks / 1000;
|
||||
Usec = (Ticks - (Sec * 1000)) * 1000;
|
||||
tp->tv_sec = Sec;
|
||||
tp->tv_usec = Usec;
|
||||
#endif /* WITHOUT_MM_LIB */
|
||||
(void) nothing;
|
||||
return 0;
|
||||
}
|
||||
#endif /* WIN32 */
|
||||
#endif /* HAVE_GETTIMEOFDAY */
|
||||
|
||||
static struct sangoma_pri_event_list SANGOMA_PRI_EVENT_LIST[] = {
|
||||
{0, SANGOMA_PRI_EVENT_ANY, "ANY"},
|
||||
{1, SANGOMA_PRI_EVENT_DCHAN_UP, "DCHAN_UP"},
|
||||
{2, SANGOMA_PRI_EVENT_DCHAN_DOWN, "DCHAN_DOWN"},
|
||||
{3, SANGOMA_PRI_EVENT_RESTART, "RESTART"},
|
||||
{4, SANGOMA_PRI_EVENT_CONFIG_ERR, "CONFIG_ERR"},
|
||||
{5, SANGOMA_PRI_EVENT_RING, "ROUTING"},
|
||||
{6, SANGOMA_PRI_EVENT_HANGUP, "HANGUP"},
|
||||
{7, SANGOMA_PRI_EVENT_RINGING, "RINGING"},
|
||||
{8, SANGOMA_PRI_EVENT_ANSWER, "ANSWER"},
|
||||
{9, SANGOMA_PRI_EVENT_HANGUP_ACK, "HANGUP_ACK"},
|
||||
{10, SANGOMA_PRI_EVENT_RESTART_ACK, "RESTART_ACK"},
|
||||
{11, SANGOMA_PRI_EVENT_FACNAME, "FACNAME"},
|
||||
{12, SANGOMA_PRI_EVENT_INFO_RECEIVED, "INFO_RECEIVED"},
|
||||
{13, SANGOMA_PRI_EVENT_PROCEEDING, "PROCEEDING"},
|
||||
{14, SANGOMA_PRI_EVENT_SETUP_ACK, "SETUP_ACK"},
|
||||
{15, SANGOMA_PRI_EVENT_HANGUP_REQ, "HANGUP_REQ"},
|
||||
{16, SANGOMA_PRI_EVENT_NOTIFY, "NOTIFY"},
|
||||
{17, SANGOMA_PRI_EVENT_PROGRESS, "PROGRESS"},
|
||||
{18, SANGOMA_PRI_EVENT_KEYPAD_DIGIT, "KEYPAD_DIGIT"}
|
||||
};
|
||||
|
||||
|
||||
char *sangoma_pri_event_str(sangoma_pri_event_t event_id)
|
||||
{
|
||||
return SANGOMA_PRI_EVENT_LIST[event_id].name;
|
||||
}
|
||||
|
||||
static int __pri_sangoma_read(struct pri *pri, void *buf, int buflen)
|
||||
{
|
||||
unsigned char tmpbuf[sizeof(wp_tdm_api_rx_hdr_t)];
|
||||
|
||||
|
||||
/* NOTE: This code will be different for A104
|
||||
* A104 receives data + 2byte CRC + 1 byte flag
|
||||
* A101/2 receives data only */
|
||||
|
||||
int res = sangoma_readmsg_socket((sng_fd_t) (pri->fd),
|
||||
tmpbuf, sizeof(wp_tdm_api_rx_hdr_t),
|
||||
buf, buflen,
|
||||
0);
|
||||
if (res > 0) {
|
||||
#ifdef WANPIPE_LEGACY_A104
|
||||
/* Prior 2.3.4 release A104 API passed up
|
||||
* 3 extra bytes: 2 CRC + 1 FLAG,
|
||||
* PRI is expecting only 2 CRC bytes, thus we
|
||||
* must remove 1 flag byte */
|
||||
res--;
|
||||
#else
|
||||
/* Add 2 byte CRC and set it to ZERO */
|
||||
memset(&((unsigned char *) buf)[res], 0, 2);
|
||||
res += 2;
|
||||
#endif
|
||||
} else {
|
||||
res = 0;
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
static int __pri_sangoma_write(struct pri *pri, void *buf, int buflen)
|
||||
{
|
||||
unsigned char tmpbuf[sizeof(wp_tdm_api_rx_hdr_t)];
|
||||
int res;
|
||||
|
||||
|
||||
memset(&tmpbuf[0], 0, sizeof(wp_tdm_api_rx_hdr_t));
|
||||
|
||||
if (buflen < 1) {
|
||||
/* HDLC Frame must be greater than 2byte CRC */
|
||||
fprintf(stderr, "%s: Got short frame %i\n", __FUNCTION__, buflen);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* FIXME: This might cause problems with other libraries
|
||||
* We must remove 2 bytes from buflen because
|
||||
* libpri sends 2 fake CRC bytes */
|
||||
res = sangoma_sendmsg_socket((sng_fd_t) (pri->fd), tmpbuf, sizeof(wp_tdm_api_rx_hdr_t), buf, (unsigned short) buflen - 2, 0);
|
||||
if (res > 0) {
|
||||
res = buflen;
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
int sangoma_init_pri(struct sangoma_pri *spri, int span, int dchan, int swtype, int node, int debug)
|
||||
{
|
||||
int ret = -1;
|
||||
sng_fd_t dfd = 0;
|
||||
|
||||
memset(spri, 0, sizeof(struct sangoma_pri));
|
||||
|
||||
if ((dfd = sangoma_open_tdmapi_span_chan(span, dchan)) < 0) {
|
||||
fprintf(stderr, "Unable to open DCHAN %d for span %d (%s)\n", dchan, span, strerror(errno));
|
||||
} else {
|
||||
if ((spri->pri = pri_new_cb((int) dfd, node, swtype, __pri_sangoma_read, __pri_sangoma_write, NULL))) {
|
||||
spri->span = span;
|
||||
spri->dchan = dchan;
|
||||
spri->swtype = swtype;
|
||||
spri->node = node;
|
||||
spri->debug = debug;
|
||||
pri_set_debug(spri->pri, debug);
|
||||
ret = 0;
|
||||
} else {
|
||||
fprintf(stderr, "Unable to create PRI\n");
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
int sangoma_one_loop(struct sangoma_pri *spri)
|
||||
{
|
||||
fd_set rfds, efds;
|
||||
struct timeval now = { 0, 0 }, *next;
|
||||
pri_event *event;
|
||||
int sel;
|
||||
|
||||
if (spri->on_loop) {
|
||||
spri->on_loop(spri);
|
||||
}
|
||||
|
||||
FD_ZERO(&rfds);
|
||||
FD_ZERO(&efds);
|
||||
|
||||
#ifdef _MSC_VER
|
||||
//Windows macro for FD_SET includes a warning C4127: conditional expression is constant
|
||||
#pragma warning(push)
|
||||
#pragma warning(disable:4127)
|
||||
#endif
|
||||
|
||||
FD_SET(spri->pri->fd, &rfds);
|
||||
FD_SET(spri->pri->fd, &efds);
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#pragma warning(pop)
|
||||
#endif
|
||||
|
||||
if ((next = pri_schedule_next(spri->pri))) {
|
||||
gettimeofday(&now, NULL);
|
||||
now.tv_sec = next->tv_sec - now.tv_sec;
|
||||
now.tv_usec = next->tv_usec - now.tv_usec;
|
||||
if (now.tv_usec < 0) {
|
||||
now.tv_usec += 1000000;
|
||||
now.tv_sec -= 1;
|
||||
}
|
||||
if (now.tv_sec < 0) {
|
||||
now.tv_sec = 0;
|
||||
now.tv_usec = 0;
|
||||
}
|
||||
}
|
||||
|
||||
sel = select(spri->pri->fd + 1, &rfds, NULL, &efds, next ? &now : NULL);
|
||||
event = NULL;
|
||||
|
||||
if (FD_ISSET(spri->pri->fd, &efds)) {
|
||||
wanpipe_tdm_api_t tdm_api = {0};
|
||||
|
||||
sangoma_tdm_read_event(spri->pri->fd, &tdm_api);
|
||||
global_logger(WP_LOG_ERROR, "DCHANNEL ERROR! [span %d]\n", spri->span);
|
||||
}
|
||||
|
||||
if (!sel) {
|
||||
event = pri_schedule_run(spri->pri);
|
||||
} else if (sel > 0) {
|
||||
event = pri_check_event(spri->pri);
|
||||
}
|
||||
|
||||
if (event) {
|
||||
event_handler handler;
|
||||
/* 0 is catchall event handler */
|
||||
if ((handler = spri->eventmap[event->e] ? spri->eventmap[event->e] : spri->eventmap[0] ? spri->eventmap[0] : NULL)) {
|
||||
handler(spri, event->e, event);
|
||||
} else {
|
||||
fprintf(stderr, "No event handler found for event %d.\n", event->e);
|
||||
}
|
||||
}
|
||||
|
||||
return sel;
|
||||
}
|
||||
|
||||
int sangoma_run_pri(struct sangoma_pri *spri)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
for (;;) {
|
||||
ret = sangoma_one_loop(spri);
|
||||
if (ret < 0) {
|
||||
|
||||
#ifndef WIN32 //This needs to be adressed fror WIN32 still
|
||||
if (errno == EINTR) {
|
||||
/* Igonore an interrupted system call */
|
||||
continue;
|
||||
}
|
||||
#endif
|
||||
printf("Error = %i\n", ret);
|
||||
perror("Sangoma Run Pri: ");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
|
||||
}
|
@ -1,103 +0,0 @@
|
||||
/*****************************************************************************
|
||||
* libsangoma.c AFT T1/E1: HDLC API Code Library
|
||||
*
|
||||
* Author(s): Anthony Minessale II <anthmct@yahoo.com>
|
||||
* Nenad Corbic <ncorbic@sangoma.com>
|
||||
*
|
||||
* Copyright: (c) 2005 Anthony Minessale II
|
||||
*
|
||||
* 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.
|
||||
* ============================================================================
|
||||
*/
|
||||
|
||||
#ifndef _SANGOMA_PRI_H
|
||||
#define _SANGOMA_PRI_H
|
||||
#include <libpri.h>
|
||||
#include <pri_internal.h>
|
||||
|
||||
|
||||
#define SANGOMA_MAX_CHAN_PER_SPAN 32
|
||||
|
||||
typedef enum {
|
||||
SANGOMA_PRI_EVENT_ANY = 0,
|
||||
SANGOMA_PRI_EVENT_DCHAN_UP = PRI_EVENT_DCHAN_UP,
|
||||
SANGOMA_PRI_EVENT_DCHAN_DOWN = PRI_EVENT_DCHAN_DOWN,
|
||||
SANGOMA_PRI_EVENT_RESTART = PRI_EVENT_RESTART,
|
||||
SANGOMA_PRI_EVENT_CONFIG_ERR = PRI_EVENT_CONFIG_ERR,
|
||||
SANGOMA_PRI_EVENT_RING = PRI_EVENT_RING,
|
||||
SANGOMA_PRI_EVENT_HANGUP = PRI_EVENT_HANGUP,
|
||||
SANGOMA_PRI_EVENT_RINGING = PRI_EVENT_RINGING,
|
||||
SANGOMA_PRI_EVENT_ANSWER = PRI_EVENT_ANSWER,
|
||||
SANGOMA_PRI_EVENT_HANGUP_ACK = PRI_EVENT_HANGUP_ACK,
|
||||
SANGOMA_PRI_EVENT_RESTART_ACK = PRI_EVENT_RESTART_ACK,
|
||||
SANGOMA_PRI_EVENT_FACNAME = PRI_EVENT_FACNAME,
|
||||
SANGOMA_PRI_EVENT_INFO_RECEIVED = PRI_EVENT_INFO_RECEIVED,
|
||||
SANGOMA_PRI_EVENT_PROCEEDING = PRI_EVENT_PROCEEDING,
|
||||
SANGOMA_PRI_EVENT_SETUP_ACK = PRI_EVENT_SETUP_ACK,
|
||||
SANGOMA_PRI_EVENT_HANGUP_REQ = PRI_EVENT_HANGUP_REQ,
|
||||
SANGOMA_PRI_EVENT_NOTIFY = PRI_EVENT_NOTIFY,
|
||||
SANGOMA_PRI_EVENT_PROGRESS = PRI_EVENT_PROGRESS,
|
||||
SANGOMA_PRI_EVENT_KEYPAD_DIGIT = PRI_EVENT_KEYPAD_DIGIT
|
||||
} sangoma_pri_event_t;
|
||||
|
||||
typedef enum {
|
||||
SANGOMA_PRI_NETWORK = PRI_NETWORK,
|
||||
SANGOMA_PRI_CPE = PRI_CPE
|
||||
} sangoma_pri_node_t;
|
||||
|
||||
typedef enum {
|
||||
SANGOMA_PRI_SWITCH_UNKNOWN = PRI_SWITCH_UNKNOWN,
|
||||
SANGOMA_PRI_SWITCH_NI2 = PRI_SWITCH_NI2,
|
||||
SANGOMA_PRI_SWITCH_DMS100 = PRI_SWITCH_DMS100,
|
||||
SANGOMA_PRI_SWITCH_LUCENT5E = PRI_SWITCH_LUCENT5E,
|
||||
SANGOMA_PRI_SWITCH_ATT4ESS = PRI_SWITCH_ATT4ESS,
|
||||
SANGOMA_PRI_SWITCH_EUROISDN_E1 = PRI_SWITCH_EUROISDN_E1,
|
||||
SANGOMA_PRI_SWITCH_EUROISDN_T1 = PRI_SWITCH_EUROISDN_T1,
|
||||
SANGOMA_PRI_SWITCH_NI1 = PRI_SWITCH_NI1,
|
||||
SANGOMA_PRI_SWITCH_GR303_EOC = PRI_SWITCH_GR303_EOC,
|
||||
SANGOMA_PRI_SWITCH_GR303_TMC = PRI_SWITCH_GR303_TMC,
|
||||
SANGOMA_PRI_SWITCH_QSIG = PRI_SWITCH_QSIG
|
||||
} sangoma_pri_switch_t;
|
||||
|
||||
typedef enum {
|
||||
SANGOMA_PRI_READY = (1 << 0)
|
||||
} sangoma_pri_flag_t;
|
||||
|
||||
struct sangoma_pri;
|
||||
typedef int (*event_handler) (struct sangoma_pri *, sangoma_pri_event_t, pri_event *);
|
||||
typedef int (*loop_handler) (struct sangoma_pri *);
|
||||
#define MAX_EVENT 18
|
||||
|
||||
struct sangoma_pri {
|
||||
struct pri *pri;
|
||||
int span;
|
||||
int dchan;
|
||||
unsigned int flags;
|
||||
void *private_info;
|
||||
event_handler eventmap[MAX_EVENT + 1];
|
||||
loop_handler on_loop;
|
||||
int dfd;
|
||||
int swtype;
|
||||
int node;
|
||||
int debug;
|
||||
};
|
||||
|
||||
struct sangoma_pri_event_list {
|
||||
int event_id;
|
||||
int pri_event;
|
||||
char *name;
|
||||
};
|
||||
|
||||
|
||||
|
||||
#define SANGOMA_MAP_PRI_EVENT(spri, event, func) spri.eventmap[event] = func;
|
||||
|
||||
char *sangoma_pri_event_str(sangoma_pri_event_t event_id);
|
||||
int sangoma_one_loop(struct sangoma_pri *spri);
|
||||
int sangoma_init_pri(struct sangoma_pri *spri, int span, int dchan, int swtype, int node, int debug);
|
||||
int sangoma_run_pri(struct sangoma_pri *spri);
|
||||
|
||||
#endif
|
@ -1,160 +0,0 @@
|
||||
/*****************************************************************************
|
||||
* win_api_common.h - Sangoma API for MS Windows. Abstraction of common API calls.
|
||||
*
|
||||
* Author(s): David Rokhvarg <davidr@sangoma.com>
|
||||
*
|
||||
* Copyright: (c) 1984-2006 Sangoma Technologies Inc.
|
||||
*
|
||||
* ============================================================================
|
||||
*/
|
||||
|
||||
#ifndef _WIN_API_COMMON_H
|
||||
#define _WIN_API_COMMON_H
|
||||
|
||||
static
|
||||
int tdmv_api_ioctl(HANDLE fd, wanpipe_tdm_api_cmd_t * tdm_api_cmd)
|
||||
{
|
||||
DWORD ln;
|
||||
unsigned char id = 0;
|
||||
int err = 0;
|
||||
|
||||
wan_udp.wan_udphdr_request_reply = 0x01;
|
||||
wan_udp.wan_udphdr_id = id;
|
||||
wan_udp.wan_udphdr_return_code = WAN_UDP_TIMEOUT_CMD;
|
||||
|
||||
wan_udp.wan_udphdr_command = WAN_TDMV_API_IOCTL;
|
||||
wan_udp.wan_udphdr_data_len = sizeof(wanpipe_tdm_api_cmd_t);
|
||||
|
||||
//copy data from caller's buffer to driver's buffer
|
||||
memcpy(wan_udp.wan_udphdr_data, (void *) tdm_api_cmd, sizeof(wanpipe_tdm_api_cmd_t));
|
||||
|
||||
if (DeviceIoControl(fd,
|
||||
IoctlManagementCommand,
|
||||
(LPVOID) & wan_udp, sizeof(wan_udp_hdr_t), (LPVOID) & wan_udp, sizeof(wan_udp_hdr_t), (LPDWORD) (&ln),
|
||||
(LPOVERLAPPED) NULL) == FALSE) {
|
||||
//actual ioctl failed
|
||||
err = 1;
|
||||
prn(1, "Error: tdmv_api_ioctl(): DeviceIoControl failed!!\n");
|
||||
return err;
|
||||
} else {
|
||||
err = 0;
|
||||
}
|
||||
|
||||
if (wan_udp.wan_udphdr_return_code != WAN_CMD_OK) {
|
||||
//ioctl ok, but command failed
|
||||
prn(1, "Error: tdmv_api_ioctl(): command failed! Return code: 0x%X.\n", wan_udp.wan_udphdr_return_code);
|
||||
return 2;
|
||||
}
|
||||
//copy data from driver's buffer to caller's buffer
|
||||
memcpy((void *) tdm_api_cmd, wan_udp.wan_udphdr_data, sizeof(wanpipe_tdm_api_cmd_t));
|
||||
return 0;
|
||||
}
|
||||
|
||||
static
|
||||
int wanpipe_api_ioctl(HANDLE fd, wan_cmd_api_t * api_cmd)
|
||||
{
|
||||
DWORD ln;
|
||||
unsigned char id = 0;
|
||||
int err = 0;
|
||||
|
||||
wan_udp.wan_udphdr_request_reply = 0x01;
|
||||
wan_udp.wan_udphdr_id = id;
|
||||
wan_udp.wan_udphdr_return_code = WAN_UDP_TIMEOUT_CMD;
|
||||
|
||||
wan_udp.wan_udphdr_command = SIOC_WANPIPE_API;
|
||||
wan_udp.wan_udphdr_data_len = sizeof(wan_cmd_api_t);
|
||||
|
||||
//copy data from caller's buffer to driver's buffer
|
||||
memcpy(wan_udp.wan_udphdr_data, (void *) api_cmd, sizeof(wan_cmd_api_t));
|
||||
|
||||
if (DeviceIoControl(fd,
|
||||
IoctlManagementCommand,
|
||||
(LPVOID) & wan_udp, sizeof(wan_udp_hdr_t), (LPVOID) & wan_udp, sizeof(wan_udp_hdr_t), (LPDWORD) (&ln),
|
||||
(LPOVERLAPPED) NULL) == FALSE) {
|
||||
err = 1;
|
||||
prn(1, "Error: wanpipe_api_ioctl(): DeviceIoControl failed!!\n");
|
||||
return err;
|
||||
} else {
|
||||
err = 0;
|
||||
}
|
||||
|
||||
if (wan_udp.wan_udphdr_return_code != WAN_CMD_OK) {
|
||||
prn(1, "Error: wanpipe_api_ioctl(): command failed! Return code: 0x%X.\n", wan_udp.wan_udphdr_return_code);
|
||||
return 2;
|
||||
}
|
||||
//copy data from driver's buffer to caller's buffer
|
||||
memcpy((void *) api_cmd, wan_udp.wan_udphdr_data, sizeof(wan_cmd_api_t));
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Blocking read command. If used after DoApiPollCommand(),
|
||||
// it will return immediatly, without blocking.
|
||||
static USHORT DoReadCommand(HANDLE drv, RX_DATA_STRUCT * pRx)
|
||||
{
|
||||
DWORD ln;
|
||||
|
||||
if (DeviceIoControl(drv, IoctlReadCommand, (LPVOID) NULL, 0L, (LPVOID) pRx, sizeof(RX_DATA_STRUCT), (LPDWORD) (&ln), (LPOVERLAPPED) NULL) == FALSE) {
|
||||
//check messages log
|
||||
prn(1, "Error: DoReadCommand(): DeviceIoControl failed!\n");
|
||||
return 1;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
// Blocking write command. If used after DoApiPollCommand(),
|
||||
// it will return immediatly, without blocking.
|
||||
static UCHAR DoWriteCommand(HANDLE drv, TX_DATA_STRUCT * pTx)
|
||||
{
|
||||
DWORD ln;
|
||||
|
||||
if (DeviceIoControl(drv,
|
||||
IoctlWriteCommand,
|
||||
(LPVOID) pTx, (ULONG) sizeof(TX_DATA_STRUCT), (LPVOID) pTx, sizeof(TX_DATA_STRUCT), (LPDWORD) (&ln),
|
||||
(LPOVERLAPPED) NULL) == FALSE) {
|
||||
//check messages log
|
||||
prn(1, "Error: DoWriteCommand(): DeviceIoControl failed!\n");
|
||||
return 1;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
// Blocking API Poll command.
|
||||
static USHORT DoApiPollCommand(HANDLE drv, API_POLL_STRUCT * api_poll_ptr)
|
||||
{
|
||||
DWORD ln;
|
||||
|
||||
if (DeviceIoControl(drv, IoctlApiPoll, (LPVOID) NULL, 0L, (LPVOID) api_poll_ptr, sizeof(API_POLL_STRUCT), (LPDWORD) (&ln), (LPOVERLAPPED) NULL) ==
|
||||
FALSE) {
|
||||
//check messages log
|
||||
prn(1, "Error: DoApiPollCommand(): DeviceIoControl failed!\n");
|
||||
return 1;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
static
|
||||
int DoManagementCommand(HANDLE drv, wan_udp_hdr_t * wan_udp)
|
||||
{
|
||||
DWORD ln;
|
||||
static unsigned char id = 0;
|
||||
|
||||
wan_udp->wan_udphdr_request_reply = 0x01;
|
||||
wan_udp->wan_udphdr_id = id++;
|
||||
wan_udp->wan_udphdr_return_code = WAN_UDP_TIMEOUT_CMD;
|
||||
|
||||
if (DeviceIoControl(drv,
|
||||
IoctlManagementCommand,
|
||||
(LPVOID) wan_udp, sizeof(wan_udp_hdr_t), (LPVOID) wan_udp, sizeof(wan_udp_hdr_t), (LPDWORD) (&ln), (LPOVERLAPPED) NULL) == FALSE) {
|
||||
//check messages log
|
||||
prn(1, "Error: DoManagementCommand(): DeviceIoControl failed!\n");
|
||||
return 1;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#endif /* _WIN_API_COMMON_H */
|
File diff suppressed because it is too large
Load Diff
@ -1,78 +0,0 @@
|
||||
/****************************************************************************
|
||||
* sigboost.h $Revision: 1.1 $
|
||||
*
|
||||
* Definitions for the sigboost interface.
|
||||
*
|
||||
* WARNING WARNING WARNING
|
||||
*
|
||||
* This file is used by sangoma_mgd and perhaps other programs. Any changes
|
||||
* to this file must be coordinated with other user programs,
|
||||
*
|
||||
* Copyright (C) 2005 Xygnada Technology, Inc.
|
||||
*
|
||||
****************************************************************************/
|
||||
#ifndef _SIGBOOST_H_
|
||||
#define _SIGBOOST_H_
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
enum e_sigboost_event_id_values {
|
||||
SIGBOOST_EVENT_CALL_START = 0x80, /*128 */
|
||||
SIGBOOST_EVENT_CALL_START_ACK = 0x81, /*129 */
|
||||
SIGBOOST_EVENT_CALL_START_NACK = 0x82, /*130 */
|
||||
SIGBOOST_EVENT_CALL_START_NACK_ACK = 0x83, /*131 */
|
||||
SIGBOOST_EVENT_CALL_ANSWERED = 0x84, /*132 */
|
||||
SIGBOOST_EVENT_CALL_STOPPED = 0x85, /*133 */
|
||||
SIGBOOST_EVENT_CALL_STOPPED_ACK = 0x86, /*134 */
|
||||
SIGBOOST_EVENT_SYSTEM_RESTART = 0x87, /*135 */
|
||||
SIGBOOST_EVENT_HEARTBEAT = 0x88, /*136 */
|
||||
};
|
||||
|
||||
enum e_sigboost_release_cause_values {
|
||||
SIGBOOST_RELEASE_CAUSE_UNDEFINED = 0x00,
|
||||
SIGBOOST_RELEASE_CAUSE_NORMAL = 0x90,
|
||||
SIGBOOST_RELEASE_CAUSE_BUSY = 0x91,
|
||||
SIGBOOST_RELEASE_CAUSE_CALLED_NOT_EXIST = 0x92,
|
||||
SIGBOOST_RELEASE_CAUSE_CIRCUIT_RESET = 0x93,
|
||||
SIGBOOST_RELEASE_CAUSE_NOANSWER = 0x94
|
||||
};
|
||||
|
||||
enum e_sigboost_call_setup_ack_nack_cause_values {
|
||||
SIGBOOST_CALL_SETUP_CIRCUIT_RESET = 0x10,
|
||||
SIGBOOST_CALL_SETUP_NACK_CKT_START_TIMEOUT = 0x11,
|
||||
SIGBOOST_CALL_SETUP_NACK_ALL_CKTS_BUSY = 0x12,
|
||||
SIGBOOST_CALL_SETUP_NACK_CALLED_NUM_TOO_BIG = 0x13,
|
||||
SIGBOOST_CALL_SETUP_NACK_CALLING_NUM_TOO_BIG = 0x14,
|
||||
SIGBOOST_CALL_SETUP_NACK_CALLED_NUM_TOO_SMALL = 0x15,
|
||||
SIGBOOST_CALL_SETUP_NACK_CALLING_NUM_TOO_SMALL = 0x16,
|
||||
};
|
||||
|
||||
#define MAX_DIALED_DIGITS 31
|
||||
|
||||
/* Next two defines are used to create the range of values for call_setup_id
|
||||
* in the t_sigboost structure.
|
||||
* 0..((CORE_MAX_SPANS * CORE_MAX_CHAN_PER_SPAN) - 1) */
|
||||
#define CORE_MAX_SPANS 200
|
||||
#define CORE_MAX_CHAN_PER_SPAN 30
|
||||
#define MAX_PENDING_CALLS CORE_MAX_SPANS * CORE_MAX_CHAN_PER_SPAN
|
||||
/* 0..(MAX_PENDING_CALLS-1) is range of call_setup_id below */
|
||||
|
||||
#pragma pack(1)
|
||||
typedef struct {
|
||||
uint32_t event_id;
|
||||
uint32_t seqno;
|
||||
uint32_t call_setup_id;
|
||||
uint32_t trunk_group;
|
||||
uint32_t span;
|
||||
uint32_t chan;
|
||||
uint32_t called_number_digits_count;
|
||||
int8_t called_number_digits[MAX_DIALED_DIGITS + 1]; /* it's a null terminated string */
|
||||
uint32_t calling_number_digits_count; /* it's an array */
|
||||
int8_t calling_number_digits[MAX_DIALED_DIGITS + 1]; /* it's a null terminated string */
|
||||
uint32_t release_cause;
|
||||
struct timeval tv;
|
||||
uint32_t calling_number_presentation;
|
||||
} t_sigboost;
|
||||
#pragma pack()
|
||||
|
||||
#endif
|
@ -1,243 +0,0 @@
|
||||
/*
|
||||
* FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
|
||||
* Copyright (C) 2005/2006, Anthony Minessale II <anthmct@yahoo.com>
|
||||
*
|
||||
* Version: MPL 1.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Anthony Minessale II <anthmct@yahoo.com>
|
||||
* Portions created by the Initial Developer are Copyright (C)
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
*
|
||||
* Anthony Minessale II <anthmct@yahoo.com>
|
||||
* Nenad Corbic <ncorbic@sangoma.com>
|
||||
*
|
||||
*
|
||||
* ss7boost_client.c Client for the SS7Boost Protocol
|
||||
*
|
||||
*/
|
||||
#include <ss7boost_client.h>
|
||||
#include <switch.h>
|
||||
|
||||
|
||||
extern unsigned int txseq;
|
||||
extern unsigned int rxseq;
|
||||
|
||||
struct ss7boost_client_map {
|
||||
uint32_t event_id;
|
||||
char *name;
|
||||
};
|
||||
|
||||
static struct ss7boost_client_map ss7boost_client_table[] = {
|
||||
{SIGBOOST_EVENT_CALL_START, "CALL_START"},
|
||||
{SIGBOOST_EVENT_CALL_START_ACK, "CALL_START_ACK"},
|
||||
{SIGBOOST_EVENT_CALL_START_NACK, "CALL_START_NACK"},
|
||||
{SIGBOOST_EVENT_CALL_START_NACK_ACK, "CALL_START_NACK_ACK"},
|
||||
{SIGBOOST_EVENT_CALL_ANSWERED, "CALL_ANSWERED"},
|
||||
{SIGBOOST_EVENT_CALL_STOPPED, "CALL_STOPPED"},
|
||||
{SIGBOOST_EVENT_CALL_STOPPED_ACK, "CALL_STOPPED_ACK"},
|
||||
{SIGBOOST_EVENT_SYSTEM_RESTART, "SYSTEM_RESTART"},
|
||||
{SIGBOOST_EVENT_HEARTBEAT, "HEARTBEAT"},
|
||||
};
|
||||
|
||||
|
||||
|
||||
static switch_status_t create_udp_socket(ss7boost_client_connection_t *mcon, char *local_ip, int local_port, char *ip, int port)
|
||||
{
|
||||
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "connect %s:%d->%s:%d\n", local_ip, local_port, ip, port);
|
||||
|
||||
if (switch_sockaddr_info_get(&mcon->local_addr, local_ip, SWITCH_UNSPEC, local_port, 0, mcon->pool) != SWITCH_STATUS_SUCCESS) {
|
||||
goto fail;
|
||||
}
|
||||
|
||||
if (switch_sockaddr_info_get(&mcon->remote_addr, ip, SWITCH_UNSPEC, port, 0, mcon->pool) != SWITCH_STATUS_SUCCESS) {
|
||||
goto fail;
|
||||
}
|
||||
|
||||
if (switch_socket_create(&mcon->socket, AF_INET, SOCK_DGRAM, 0, mcon->pool) == SWITCH_STATUS_SUCCESS) {
|
||||
if (switch_socket_bind(mcon->socket, mcon->local_addr) != SWITCH_STATUS_SUCCESS) {
|
||||
goto fail;
|
||||
}
|
||||
} else {
|
||||
goto fail;
|
||||
}
|
||||
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Created boost connection %s:%d->%s:%d\n", local_ip, local_port, ip, port);
|
||||
return SWITCH_STATUS_SUCCESS;
|
||||
|
||||
fail:
|
||||
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Failure creating boost connection %s:%d->%s:%d\n", local_ip, local_port, ip, port);
|
||||
return SWITCH_STATUS_FALSE;
|
||||
}
|
||||
|
||||
|
||||
|
||||
SWITCH_DECLARE(switch_status_t) ss7boost_client_connection_close(ss7boost_client_connection_t *mcon)
|
||||
{
|
||||
switch_socket_close(mcon->socket);
|
||||
mcon->socket = NULL;
|
||||
memset(mcon, 0, sizeof(*mcon));
|
||||
|
||||
return SWITCH_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
SWITCH_DECLARE(switch_status_t) ss7boost_client_connection_open(ss7boost_client_connection_t *mcon,
|
||||
char *local_ip, int local_port, char *ip, int port, switch_memory_pool_t *pool)
|
||||
{
|
||||
memset(mcon, 0, sizeof(*mcon));
|
||||
mcon->pool = pool;
|
||||
|
||||
if (create_udp_socket(mcon, local_ip, local_port, ip, port) == SWITCH_STATUS_SUCCESS) {
|
||||
switch_mutex_init(&mcon->mutex, SWITCH_MUTEX_NESTED, mcon->pool);
|
||||
return SWITCH_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
memset(mcon, 0, sizeof(*mcon));
|
||||
return SWITCH_STATUS_FALSE;
|
||||
}
|
||||
|
||||
SWITCH_DECLARE(switch_status_t) ss7boost_client_connection_read(ss7boost_client_connection_t *mcon, ss7boost_client_event_t **event)
|
||||
{
|
||||
unsigned int fromlen = sizeof(struct sockaddr_in);
|
||||
switch_size_t bytes = 0;
|
||||
|
||||
bytes = sizeof(mcon->event);
|
||||
|
||||
if (switch_socket_recvfrom(mcon->local_addr, mcon->socket, 0, (void *) &mcon->event, &bytes) != SWITCH_STATUS_SUCCESS) {
|
||||
bytes = 0;
|
||||
}
|
||||
|
||||
if (bytes == sizeof(mcon->event) || bytes == (sizeof(mcon->event) - sizeof(uint32_t))) {
|
||||
if (rxseq != mcon->event.seqno) {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "------------------------------------------\n");
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Critical Error: Invalid Sequence Number Expect=%i Rx=%i\n", rxseq, mcon->event.seqno);
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "------------------------------------------\n");
|
||||
}
|
||||
rxseq++;
|
||||
|
||||
*event = &mcon->event;
|
||||
return SWITCH_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
return SWITCH_STATUS_FALSE;
|
||||
}
|
||||
|
||||
SWITCH_DECLARE(switch_status_t) ss7boost_client_connection_write(ss7boost_client_connection_t *mcon, ss7boost_client_event_t *event)
|
||||
{
|
||||
int err;
|
||||
switch_size_t len;
|
||||
|
||||
if (!event) {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Critical Error: No Event Device\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (event->span < 0 || event->chan < 0 || event->span > 7 || event->chan > 30) {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "------------------------------------------\n");
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Critical Error: Invalid Span=%i Chan=%i\n", event->span, event->chan);
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "------------------------------------------\n");
|
||||
}
|
||||
#ifdef WIN32
|
||||
//TODO set the tv with win func
|
||||
#else
|
||||
gettimeofday(&event->tv, NULL);
|
||||
#endif
|
||||
|
||||
switch_mutex_lock(mcon->mutex);
|
||||
event->seqno = txseq++;
|
||||
len = sizeof(*event);
|
||||
if (switch_socket_sendto(mcon->socket, mcon->remote_addr, 0, (void *) event, &len) != SWITCH_STATUS_SUCCESS) {
|
||||
err = -1;
|
||||
}
|
||||
switch_mutex_unlock(mcon->mutex);
|
||||
|
||||
if (len != sizeof(ss7boost_client_event_t)) {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Write Error: [%d][%d][%s]\n", mcon->socket, errno, strerror(errno));
|
||||
err = -1;
|
||||
}
|
||||
|
||||
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG,
|
||||
"\nTX EVENT\n"
|
||||
"===================================\n"
|
||||
" tType: %s (%0x HEX)\n"
|
||||
" tSpan: [%d]\n"
|
||||
" tChan: [%d]\n"
|
||||
" tCalledNum: %s\n"
|
||||
" tCallingNum: %s\n"
|
||||
" tCause: %d\n"
|
||||
" tInterface: [w%dg%d]\n"
|
||||
" tEvent ID: [%d]\n"
|
||||
" tSetup ID: [%d]\n"
|
||||
" tSeq: [%d]\n"
|
||||
"===================================\n"
|
||||
"\n",
|
||||
ss7boost_client_event_id_name(event->event_id),
|
||||
event->event_id,
|
||||
event->span + 1,
|
||||
event->chan + 1,
|
||||
(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->release_cause, event->span + 1, event->chan + 1, event->event_id, event->call_setup_id, event->seqno);
|
||||
|
||||
|
||||
return err ? SWITCH_STATUS_FALSE : SWITCH_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
SWITCH_DECLARE(void) ss7boost_client_call_init(ss7boost_client_event_t *event, char *calling, char *called, int setup_id)
|
||||
{
|
||||
memset(event, 0, sizeof(ss7boost_client_event_t));
|
||||
event->event_id = SIGBOOST_EVENT_CALL_START;
|
||||
|
||||
if (calling) {
|
||||
strncpy((char *) event->calling_number_digits, calling, sizeof(event->calling_number_digits) - 1);
|
||||
event->calling_number_digits_count = strlen(calling);
|
||||
}
|
||||
|
||||
if (called) {
|
||||
strncpy((char *) event->called_number_digits, called, sizeof(event->called_number_digits) - 1);
|
||||
event->called_number_digits_count = strlen(called);
|
||||
}
|
||||
|
||||
event->call_setup_id = setup_id;
|
||||
|
||||
}
|
||||
|
||||
SWITCH_DECLARE(void) ss7boost_client_event_init(ss7boost_client_event_t *event, ss7boost_client_event_id_t event_id, int chan, int span)
|
||||
{
|
||||
memset(event, 0, sizeof(ss7boost_client_event_t));
|
||||
event->event_id = event_id;
|
||||
event->chan = chan;
|
||||
event->span = span;
|
||||
}
|
||||
|
||||
SWITCH_DECLARE(char *) ss7boost_client_event_id_name(uint32_t event_id)
|
||||
{
|
||||
int x;
|
||||
char *ret = NULL;
|
||||
|
||||
for (x = 0; x < sizeof(ss7boost_client_table) / sizeof(struct ss7boost_client_map); x++) {
|
||||
if (ss7boost_client_table[x].event_id == event_id) {
|
||||
ret = ss7boost_client_table[x].name;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
@ -1,101 +0,0 @@
|
||||
/*
|
||||
* FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
|
||||
* Copyright (C) 2005/2006, Anthony Minessale II <anthmct@yahoo.com>
|
||||
*
|
||||
* Version: MPL 1.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Anthony Minessale II <anthmct@yahoo.com>
|
||||
* Portions created by the Initial Developer are Copyright (C)
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
*
|
||||
* Anthony Minessale II <anthmct@yahoo.com>
|
||||
* Nenad Corbic <ncorbic@sangoma.com>
|
||||
*
|
||||
*
|
||||
* ss7boost_client.h Client for the SS7Boost Protocol
|
||||
*
|
||||
*/
|
||||
#ifndef _SS7BOOST_CLIENT_H
|
||||
#define _SS7BOOST_CLIENT_H
|
||||
|
||||
#include <ctype.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <stdlib.h>
|
||||
#include <errno.h>
|
||||
#include <stdarg.h>
|
||||
#include <stdio.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <stdarg.h>
|
||||
#include <netdb.h>
|
||||
#include <sigboost.h>
|
||||
#include <pthread.h>
|
||||
#include <sys/time.h>
|
||||
#include <switch.h>
|
||||
|
||||
|
||||
|
||||
#define ss7boost_client_test_flag(p,flag) ({ \
|
||||
((p)->flags & (flag)); \
|
||||
})
|
||||
|
||||
#define ss7boost_client_set_flag(p,flag) do { \
|
||||
((p)->flags |= (flag)); \
|
||||
} while (0)
|
||||
|
||||
#define ss7boost_client_clear_flag(p,flag) do { \
|
||||
((p)->flags &= ~(flag)); \
|
||||
} while (0)
|
||||
|
||||
#define ss7boost_client_copy_flags(dest,src,flagz) do { \
|
||||
(dest)->flags &= ~(flagz); \
|
||||
(dest)->flags |= ((src)->flags & (flagz)); \
|
||||
} while (0)
|
||||
|
||||
typedef t_sigboost ss7boost_client_event_t;
|
||||
typedef uint32_t ss7boost_client_event_id_t;
|
||||
|
||||
struct ss7boost_client_connection {
|
||||
switch_socket_t *socket;
|
||||
switch_sockaddr_t *local_addr;
|
||||
switch_sockaddr_t *remote_addr;
|
||||
ss7boost_client_event_t event;
|
||||
unsigned int flags;
|
||||
switch_mutex_t *mutex;
|
||||
switch_memory_pool_t *pool;
|
||||
};
|
||||
|
||||
typedef enum {
|
||||
MSU_FLAG_EVENT = (1 << 0)
|
||||
} ss7boost_client_flag_t;
|
||||
|
||||
typedef struct ss7boost_client_connection ss7boost_client_connection_t;
|
||||
|
||||
SWITCH_DECLARE(switch_status_t) ss7boost_client_connection_close(ss7boost_client_connection_t * mcon);
|
||||
SWITCH_DECLARE(switch_status_t) ss7boost_client_connection_open(ss7boost_client_connection_t * mcon,
|
||||
char *local_ip, int local_port, char *ip, int port, switch_memory_pool_t *pool);
|
||||
SWITCH_DECLARE(switch_status_t) ss7boost_client_connection_read(ss7boost_client_connection_t * mcon, ss7boost_client_event_t ** event);
|
||||
SWITCH_DECLARE(switch_status_t) ss7boost_client_connection_write(ss7boost_client_connection_t * mcon, ss7boost_client_event_t * event);
|
||||
SWITCH_DECLARE(void) ss7boost_client_event_init(ss7boost_client_event_t * event, ss7boost_client_event_id_t event_id, int chan, int span);
|
||||
SWITCH_DECLARE(void) ss7boost_client_call_init(ss7boost_client_event_t * event, char *calling, char *called, int setup_id);
|
||||
SWITCH_DECLARE(char *) ss7boost_client_event_id_name(uint32_t event_id);
|
||||
|
||||
#endif
|
@ -1,425 +0,0 @@
|
||||
/*****************************************************************************
|
||||
* 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);
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user