update
git-svn-id: http://svn.openzap.org/svn/openzap/trunk@159 a93c3328-9c30-0410-af19-c9cd2b2d52af
This commit is contained in:
parent
219ac87d22
commit
b06e0aeea2
|
@ -65,7 +65,9 @@ PWD=$(shell pwd)
|
|||
INCS=-I$(PWD)/$(SRC)//include -I$(PWD)/$(SRC)//isdn/include
|
||||
CFLAGS=$(ZAP_CFLAGS) $(INCS)
|
||||
MYLIB=libopenzap.a
|
||||
TMP=-I../libpri-1.2.4 -I$(SRC)/include -I./src -w
|
||||
LIBPRIA=libpri.a
|
||||
LIBPRI=./libpri
|
||||
TMP=-I$(LIBPRI) -I$(SRC)/include -I./src -w
|
||||
|
||||
include general.makefile $(ZAP_MODS)
|
||||
|
||||
|
@ -84,14 +86,17 @@ testisdn: $(SRC)/testisdn.c $(MYLIB)
|
|||
testanalog: $(SRC)/testanalog.c $(MYLIB)
|
||||
$(CC) $(INCS) -L. $(SRC)/testanalog.c -o testanalog -lopenzap -lm -lpthread
|
||||
|
||||
priserver.o: $(SRC)/priserver.c
|
||||
$(SRC)/priserver.o: $(SRC)/priserver.c
|
||||
$(CC) $(INCS) $(TMP) -c $(SRC)/priserver.c -o $(SRC)/priserver.o
|
||||
|
||||
$(SRC)/sangoma_pri.o: $(SRC)/sangoma_pri.c
|
||||
$(CC) $(INCS) $(TMP) -c $(SRC)/sangoma_pri.c -o $(SRC)/sangoma_pri.o
|
||||
|
||||
priserver: $(MYLIB) $(SRC)/priserver.o $(SRC)/sangoma_pri.o
|
||||
$(CC) $(SRC)/sangoma_pri.o $(SRC)/priserver.o -L. -o priserver -lopenzap -lm -lpthread ../../libpri-1.2.4/libpri.a
|
||||
$(LIBPRI)/$(LIBPRIA):
|
||||
cd libpri && make
|
||||
|
||||
priserver: $(MYLIB) $(SRC)/priserver.o $(SRC)/sangoma_pri.o $(LIBPRI)/$(LIBPRIA)
|
||||
$(CC) $(SRC)/sangoma_pri.o $(SRC)/priserver.o -L. -o priserver -lopenzap -lm -lpthread $(LIBPRI)/$(LIBPRIA)
|
||||
|
||||
$(SRC)/zap_io.o: $(SRC)/zap_io.c
|
||||
$(CC) $(MOD_CFLAGS) $(CC_CFLAGS) $(CFLAGS) -c $< -o $@
|
||||
|
@ -117,8 +122,9 @@ mod_openzap-install: mod_openzap
|
|||
cd mod_openzap && make install
|
||||
|
||||
mod_openzap-clean:
|
||||
cd mod_openzap && make clean
|
||||
@if [ -f mod_openzap/mod_openzap.so ] ; then cd mod_openzap && make clean ; fi
|
||||
|
||||
clean: mod_openzap-clean
|
||||
rm -f $(SRC)/*.o $(SRC)/isdn/*.o $(MYLIB) *~ \#* testapp priserver testisdn testanalog
|
||||
@if [ -f $(LIBPRI)/$(LIBPRIA) ] ; then cd $(LIBPRI) && make clean ; fi
|
||||
|
||||
|
|
|
@ -0,0 +1,316 @@
|
|||
/*****************************************************************************
|
||||
* priserver.c Refactoring of pritest.c
|
||||
*
|
||||
* 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.
|
||||
* ============================================================================
|
||||
*/
|
||||
|
||||
#include "openzap.h"
|
||||
#include <sangoma_pri.h>
|
||||
#include <signal.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/time.h>
|
||||
#include <sys/resource.h>
|
||||
#include <sys/wait.h>
|
||||
|
||||
typedef struct {
|
||||
int pid;
|
||||
q931_call call;
|
||||
void *pri;
|
||||
int ready;
|
||||
}call_info_t;
|
||||
|
||||
|
||||
#define SANGOMA_MAX_CHAN_PER_SPAN 32
|
||||
|
||||
static call_info_t pidmap[SANGOMA_MAX_CHAN_PER_SPAN];
|
||||
|
||||
ZIO_EVENT_CB_FUNCTION(my_zap_event_handler)
|
||||
{
|
||||
if (event->e_type = ZAP_EVENT_DTMF) {
|
||||
char *dtmf = event->data;
|
||||
printf("DTMF %s\n", dtmf);
|
||||
}
|
||||
}
|
||||
|
||||
/* Stupid runtime process to play a file to a b channel*/
|
||||
#define BYTES 320
|
||||
#define MAX_BYTES 1000
|
||||
|
||||
static int ready = 1;
|
||||
|
||||
static void handle_SIGINT(int sig)
|
||||
{
|
||||
if (sig) {
|
||||
ready = 0;
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
static void launch_channel(struct sangoma_pri *spri, int channo)
|
||||
{
|
||||
pid_t pid;
|
||||
int fd = 0, file = 0, inlen = 0, outlen = 0;
|
||||
unsigned char inframe[MAX_BYTES], outframe[MAX_BYTES];
|
||||
fd_set readfds;
|
||||
int mtu_mru=BYTES / 2;
|
||||
int err;
|
||||
zap_channel_t *chan;
|
||||
zap_codec_t codec = ZAP_CODEC_SLIN;
|
||||
unsigned ms = 20;
|
||||
unsigned int lead = 50;
|
||||
int ifd = -1;
|
||||
zap_tone_type_t tt = ZAP_TONE_DTMF;
|
||||
char dtmf[] = "1234567890";
|
||||
int loops = 0;
|
||||
|
||||
pid = fork();
|
||||
|
||||
if (pid) {
|
||||
pidmap[channo-1].pid = pid;
|
||||
printf("-- Launching process %d to handle channel %d\n", pid, channo);
|
||||
return;
|
||||
}
|
||||
|
||||
signal(SIGINT, handle_SIGINT);
|
||||
|
||||
//ifd = open("/nfs/sounds/ptest.raw", O_WRONLY|O_CREAT|O_TRUNC, 777);
|
||||
|
||||
memset(inframe, 0, MAX_BYTES);
|
||||
memset(outframe, 0, MAX_BYTES);
|
||||
|
||||
if (zap_channel_open("wanpipe", spri->span, channo, &chan) != ZAP_SUCCESS) {
|
||||
printf("DEBUG cant open fd!\n");
|
||||
}
|
||||
|
||||
|
||||
|
||||
#if 1
|
||||
if (zap_channel_command(chan, ZAP_COMMAND_SET_CODEC, &codec) != ZAP_SUCCESS) {
|
||||
printf("Critical Error: Failed to set driver codec!\n");
|
||||
zap_channel_close(&chan);
|
||||
exit(-1);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if 1
|
||||
if (zap_channel_command(chan, ZAP_COMMAND_ENABLE_TONE_DETECT, &tt) != ZAP_SUCCESS) {
|
||||
printf("Critical Error: Failed to set dtmf detect!\n");
|
||||
zap_channel_close(&chan);
|
||||
exit(-1);
|
||||
}
|
||||
zap_channel_set_event_callback(chan, my_zap_event_handler);
|
||||
#endif
|
||||
|
||||
|
||||
if (zap_channel_command(chan, ZAP_COMMAND_SET_INTERVAL, &ms) != ZAP_SUCCESS) {
|
||||
printf("Critical Error: Failed to set codec interval!\n");
|
||||
zap_channel_close(&chan);
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
file = open("sound.raw", O_RDONLY);
|
||||
if (file < 0){
|
||||
printf("Critical Error: Failed to open sound file!\n");
|
||||
zap_channel_close(&chan);
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
|
||||
while(ready) {
|
||||
zap_wait_flag_t flags = ZAP_READ;
|
||||
zap_size_t len;
|
||||
loops++;
|
||||
|
||||
if (lead) {
|
||||
lead--;
|
||||
}
|
||||
|
||||
if (!lead && loops == 300) {
|
||||
#if 1
|
||||
if (zap_channel_command(chan, ZAP_COMMAND_SEND_DTMF, dtmf) != ZAP_SUCCESS) {
|
||||
printf("Critical Error: Failed to send dtmf\n");
|
||||
zap_channel_close(&chan);
|
||||
exit(-1);
|
||||
}
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
if (zap_channel_wait(chan, &flags, 2000) != ZAP_SUCCESS) {
|
||||
printf("wait FAIL! [%s]\n", chan->last_error);
|
||||
break;
|
||||
}
|
||||
|
||||
if (flags & ZAP_READ) {
|
||||
len = MAX_BYTES;
|
||||
if (zap_channel_read(chan, inframe, &len) == ZAP_SUCCESS) {
|
||||
//printf("READ: %d\n", len);
|
||||
//write(ifd, inframe, len);
|
||||
if(!lead && (outlen = read(file, outframe, len)) <= 0) {
|
||||
break;
|
||||
}
|
||||
|
||||
} else {
|
||||
printf("READ FAIL! %d [%s]\n", len, chan->last_error);
|
||||
break;
|
||||
}
|
||||
if (lead) {
|
||||
continue;
|
||||
}
|
||||
zap_channel_write(chan, outframe, &len);
|
||||
} else {
|
||||
printf("BREAK");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
printf("loop done\n");
|
||||
|
||||
//sangoma_get_full_cfg(fd, &tdm_api);
|
||||
close(file);
|
||||
//close(ifd);
|
||||
|
||||
|
||||
if (zap_channel_close(&chan) != ZAP_SUCCESS) {
|
||||
printf("Critical Error: Failed to close channel [%s]\n", chan->last_error);
|
||||
}
|
||||
|
||||
printf("Call Handler: Process Finished\n");
|
||||
exit(0);
|
||||
}
|
||||
|
||||
|
||||
/* Event Handlers */
|
||||
|
||||
static int on_info(struct sangoma_pri *spri, sangoma_pri_event_t event_type, pri_event *event)
|
||||
{
|
||||
printf( "number is: %s\n", event->ring.callednum);
|
||||
if(strlen(event->ring.callednum) > 3) {
|
||||
printf( "final number is: %s\n", event->ring.callednum);
|
||||
pri_answer(spri->pri, event->ring.call, 0, 1);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int on_hangup(struct sangoma_pri *spri, sangoma_pri_event_t event_type, pri_event *event)
|
||||
{
|
||||
//pri_hangup(spri->pri, event->hangup.call, event->hangup.cause);
|
||||
printf("-- Hanging up channel %d\n", event->hangup.channel);
|
||||
if(pidmap[event->hangup.channel-1].pid) {
|
||||
pri_hangup(spri->pri, event->hangup.call, 16);
|
||||
pri_destroycall(spri->pri, event->hangup.call);
|
||||
kill(pidmap[event->hangup.channel-1].pid, SIGINT);
|
||||
pidmap[event->hangup.channel-1].pid = 0;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int on_ring(struct sangoma_pri *spri, sangoma_pri_event_t event_type, pri_event *event)
|
||||
{
|
||||
printf("-- Ring on channel %d (from %s to %s), answering...\n", event->ring.channel, event->ring.callingnum, event->ring.callednum);
|
||||
pri_answer(spri->pri, event->ring.call, event->ring.channel, 1);
|
||||
memcpy(&pidmap[event->ring.channel-1].call, event->ring.call, sizeof(q931_call));
|
||||
pidmap[event->ring.channel-1].pri=spri->pri;
|
||||
pidmap[event->ring.channel-1].call = *event->ring.call;
|
||||
launch_channel(spri, event->ring.channel);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int on_restart(struct sangoma_pri *spri, sangoma_pri_event_t event_type, pri_event *event)
|
||||
{
|
||||
printf("-- Restarting channel %d\n", event->restart.channel);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int on_anything(struct sangoma_pri *spri, sangoma_pri_event_t event_type, pri_event *event)
|
||||
{
|
||||
printf("%s: Caught Event %d (%s)\n", __FUNCTION__, event_type, sangoma_pri_event_str(event_type));
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Generic Reaper */
|
||||
static void chan_ended(int sig)
|
||||
{
|
||||
int status;
|
||||
int x;
|
||||
struct rusage rusage;
|
||||
pid_t pid;
|
||||
pid = wait4(-1, &status, WNOHANG, &rusage);
|
||||
|
||||
printf("-- PID %d ended\n", pid);
|
||||
|
||||
for (x=0;x<SANGOMA_MAX_CHAN_PER_SPAN;x++) {
|
||||
if (pid == pidmap[x].pid) {
|
||||
pidmap[x].pid = 0;
|
||||
if (pidmap[x].pri){
|
||||
int err=pri_hangup(pidmap[x].pri, &pidmap[x].call, 16);
|
||||
//pri_destroycall(pidmap[x].pri, &pidmap[x].call);
|
||||
printf("Hanging up on PID %i Err=%i\n",pid,err);
|
||||
}
|
||||
|
||||
pidmap[x].pri=NULL;
|
||||
signal(SIGCHLD, chan_ended);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (pid > -1) {
|
||||
fprintf(stderr, "--!! Unknown PID %d exited\n", pid);
|
||||
signal(SIGCHLD, chan_ended);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/* Our Program */
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
struct sangoma_pri spri;
|
||||
int debug = 0;
|
||||
if (argv[1]) {
|
||||
debug = atoi(argv[1]);
|
||||
}
|
||||
|
||||
zap_global_set_default_logger(ZAP_LOG_LEVEL_DEBUG);
|
||||
if (zap_global_init() != ZAP_SUCCESS) {
|
||||
fprintf(stderr, "Error loading OpenZAP\n");
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
printf("OpenZAP loaded\n");
|
||||
|
||||
|
||||
|
||||
if (sangoma_init_pri(&spri,
|
||||
1, // span
|
||||
24, // dchan
|
||||
SANGOMA_PRI_SWITCH_DMS100,
|
||||
SANGOMA_PRI_CPE,
|
||||
debug) < 0) {
|
||||
return -1;
|
||||
}
|
||||
//spri.pri->debug = (PRI_DEBUG_Q931_DUMP | PRI_DEBUG_Q921_DUMP | PRI_DEBUG_Q921_RAW | PRI_DEBUG_Q921_STATE);
|
||||
|
||||
//pri_set_debug(&spri.pri, (PRI_DEBUG_Q931_DUMP | PRI_DEBUG_Q921_DUMP | PRI_DEBUG_Q921_RAW | PRI_DEBUG_Q921_STATE));
|
||||
|
||||
SANGOMA_MAP_PRI_EVENT(spri, SANGOMA_PRI_EVENT_ANY, on_anything);
|
||||
SANGOMA_MAP_PRI_EVENT(spri, SANGOMA_PRI_EVENT_RING, on_ring);
|
||||
SANGOMA_MAP_PRI_EVENT(spri, SANGOMA_PRI_EVENT_HANGUP, on_hangup);
|
||||
SANGOMA_MAP_PRI_EVENT(spri, SANGOMA_PRI_EVENT_HANGUP_REQ, on_hangup);
|
||||
SANGOMA_MAP_PRI_EVENT(spri, SANGOMA_PRI_EVENT_INFO_RECEIVED, on_info);
|
||||
SANGOMA_MAP_PRI_EVENT(spri, SANGOMA_PRI_EVENT_RESTART, on_restart);
|
||||
|
||||
signal(SIGCHLD, chan_ended);
|
||||
sangoma_run_pri(&spri);
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -0,0 +1,240 @@
|
|||
/*****************************************************************************
|
||||
* sangoma_pri.c libpri Sangoma integration
|
||||
*
|
||||
* 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.
|
||||
* ============================================================================
|
||||
*/
|
||||
|
||||
#include "openzap.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, "RING"},
|
||||
{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"}
|
||||
};
|
||||
|
||||
#define LINE "--------------------------------------------------------------------------------"
|
||||
|
||||
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)
|
||||
{
|
||||
struct sangoma_pri *spri = (struct sangoma_pri *) pri->userdata;
|
||||
zap_size_t len = buflen;
|
||||
int res;
|
||||
char bb[4096] = "";
|
||||
|
||||
|
||||
if (zap_channel_read(spri->zdchan, buf, &len) != ZAP_SUCCESS) {
|
||||
printf("D-READ FAIL! [%s]\n", spri->zdchan->last_error);
|
||||
return 0;
|
||||
}
|
||||
res = (int)len;
|
||||
memset(&((unsigned char*)buf)[res],0,2);
|
||||
res+=2;
|
||||
|
||||
print_bits(buf, res-2, bb, sizeof(bb), 1);
|
||||
zap_log(ZAP_LOG_DEBUG, "READ %d\n%s\n%s\n\n", res-2, LINE, bb);
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
static int __pri_sangoma_write(struct pri *pri, void *buf, int buflen)
|
||||
{
|
||||
struct sangoma_pri *spri = (struct sangoma_pri *) pri->userdata;
|
||||
int res;
|
||||
zap_size_t len = buflen -2;
|
||||
char bb[4096] = "";
|
||||
|
||||
if (zap_channel_write(spri->zdchan, buf, &len) != ZAP_SUCCESS) {
|
||||
printf("D-WRITE FAIL! [%s]\n", spri->zdchan->last_error);
|
||||
return 0;
|
||||
}
|
||||
|
||||
print_bits(buf, (int)buflen-2, bb, sizeof(bb), 1);
|
||||
zap_log(ZAP_LOG_DEBUG, "WRITE %d\n%s\n%s\n\n", (int)buflen-2, LINE, bb);
|
||||
|
||||
return (int) buflen;
|
||||
}
|
||||
|
||||
int sangoma_init_pri(struct sangoma_pri *spri, int span, int dchan, int swtype, int node, int debug)
|
||||
{
|
||||
int ret = -1;
|
||||
zap_socket_t dfd = 0;
|
||||
|
||||
memset(spri, 0, sizeof(struct sangoma_pri));
|
||||
|
||||
if (zap_channel_open("wanpipe", span, dchan, &spri->zdchan) != ZAP_SUCCESS) {
|
||||
fprintf(stderr, "Unable to open DCHAN %d for span %d (%s)\n", dchan, span, strerror(errno));
|
||||
} else {
|
||||
if ((spri->pri = pri_new_cb(spri->zdchan->sockfd, node, swtype, __pri_sangoma_read, __pri_sangoma_write, spri))){
|
||||
spri->span = span;
|
||||
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 (!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;
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,100 @@
|
|||
/*****************************************************************************
|
||||
* 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;
|
||||
zap_channel_t *zdchan;
|
||||
};
|
||||
|
||||
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
|
Loading…
Reference in New Issue