From 0b25d3af9fcc808be41a3516cb2f88639aa69493 Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Tue, 12 Feb 2008 00:54:57 +0000 Subject: [PATCH] initial addition of ss7boost client code git-svn-id: http://svn.openzap.org/svn/openzap/trunk@392 a93c3328-9c30-0410-af19-c9cd2b2d52af --- libs/openzap/Makefile | 12 +- libs/openzap/src/include/sigboost.h | 104 +++++ libs/openzap/src/include/ss7_boost_client.h | 137 +++++++ libs/openzap/src/ss7_boost_client.c | 415 ++++++++++++++++++++ 4 files changed, 666 insertions(+), 2 deletions(-) create mode 100644 libs/openzap/src/include/sigboost.h create mode 100644 libs/openzap/src/include/ss7_boost_client.h create mode 100644 libs/openzap/src/ss7_boost_client.c diff --git a/libs/openzap/Makefile b/libs/openzap/Makefile index a569b23a24..848e5fe2e9 100644 --- a/libs/openzap/Makefile +++ b/libs/openzap/Makefile @@ -66,7 +66,8 @@ $(SRC)/isdn/5ESSStateNT.c \ $(SRC)/isdn/5ESSStateTE.c \ $(SRC)/isdn/Q932mes.c \ $(SRC)/zap_zt.c \ -$(SRC)/zap_wanpipe.c +$(SRC)/zap_wanpipe.c\ +$(SRC)/ss7_boost_client.c OBJS=\ $(SRC)/hashtable.o \ @@ -104,7 +105,8 @@ $(SRC)/isdn/5ESSStateNT.o \ $(SRC)/isdn/5ESSStateTE.o \ $(SRC)/isdn/Q932mes.o \ $(SRC)/zap_zt.o \ -$(SRC)/zap_wanpipe.o +$(SRC)/zap_wanpipe.o\ +$(SRC)/ss7_boost_client.o #SRCS=$(shell echo $(OBJS) | sed "s/\.o/\.c/g") @@ -129,6 +131,7 @@ $(SRC)/include/zap_threadmutex.h \ $(SRC)/include/zap_types.h \ $(SRC)/include/zap_wanpipe.h \ $(SRC)/include/zap_zt.h \ +$(SRC)/include/ss7_boost_client.h \ $(SRC)/isdn/include/mfifo.h \ $(SRC)/isdn/include/national.h \ $(SRC)/isdn/include/DMS.h \ @@ -147,6 +150,11 @@ LIBPRIA=libpri.a LIBPRI=./libpri TMP=-I$(LIBPRI) -I$(SRC)/include -I./src -w +SCTP_H=$(shell ls /usr/include/netinet/sctp.h 2>/dev/null) +ifneq ($(SCTP_H),) +CFLAGS += -DSS7BC_USE_SCTP +endif + PIKA_DIR=$(shell ls -d /usr/include/pika 2>/dev/null) PIKA_LIB=$(shell ls /usr/lib/libpikahmpapi.so 2>/dev/null) diff --git a/libs/openzap/src/include/sigboost.h b/libs/openzap/src/include/sigboost.h new file mode 100644 index 0000000000..009e4b26c6 --- /dev/null +++ b/libs/openzap/src/include/sigboost.h @@ -0,0 +1,104 @@ +/**************************************************************************** + * sigboost.h $Revision: 1.3 $ + * + * 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 +#include + +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_SYSTEM_RESTART_ACK = 0x88, /*136*/ + /* Following IDs are ss7boost to sangoma_mgd only. */ + SIGBOOST_EVENT_HEARTBEAT = 0x89, /*137*/ + SIGBOOST_EVENT_INSERT_CHECK_LOOP = 0x8a, /*138*/ + SIGBOOST_EVENT_REMOVE_CHECK_LOOP = 0x8b, /*139*/ + SIGBOOST_EVENT_AUTO_CALL_GAP_ABATE = 0x8c, /*140*/ +}; +enum e_sigboost_release_cause_values +{ + SIGBOOST_RELEASE_CAUSE_UNDEFINED = 0, + SIGBOOST_RELEASE_CAUSE_NORMAL = 16, + SIGBOOST_RELEASE_CAUSE_BUSY = 17, + /* probable elimination */ + //SIGBOOST_RELEASE_CAUSE_BUSY = 0x91, /* 145 */ + //SIGBOOST_RELEASE_CAUSE_CALLED_NOT_EXIST = 0x92, /* 146 */ + //SIGBOOST_RELEASE_CAUSE_CIRCUIT_RESET = 0x93, /* 147 */ + //SIGBOOST_RELEASE_CAUSE_NOANSWER = 0x94, /* 148 */ +}; + +enum e_sigboost_call_setup_ack_nack_cause_values +{ + SIGBOOST_CALL_SETUP_NACK_ALL_CKTS_BUSY = 117, /* unused Q.850 value */ + SIGBOOST_CALL_SETUP_NACK_TEST_CKT_BUSY = 118, /* unused Q.850 value */ + SIGBOOST_CALL_SETUP_NACK_INVALID_NUMBER = 28, + /* probable elimination */ + //SIGBOOST_CALL_SETUP_RESERVED = 0x00, + //SIGBOOST_CALL_SETUP_CIRCUIT_RESET = 0x10, + //SIGBOOST_CALL_SETUP_NACK_CKT_START_TIMEOUT = 0x11, + //SIGBOOST_CALL_SETUP_NACK_AUTO_CALL_GAP = 0x17, +}; + +#define MAX_DIALED_DIGITS 31 +#define MAX_CALLING_NAME 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 */ +#define SIZE_RDNIS 80 + +//#undef MSGWINDOW +#define MSGWINDOW + +#pragma pack(1) +typedef struct +{ + uint32_t event_id; + uint32_t fseqno; +#ifdef MSGWINDOW + uint32_t bseqno; +#endif + uint16_t call_setup_id; + uint32_t trunk_group; + uint32_t span; + uint32_t chan; + uint8_t called_number_digits_count; + char called_number_digits [MAX_DIALED_DIGITS + 1]; /* it's a null terminated string */ + uint8_t calling_number_digits_count; /* it's an array */ + char calling_number_digits [MAX_DIALED_DIGITS + 1]; /* it's a null terminated string */ + uint8_t release_cause; + struct timeval tv; + /* ref. Q.931 Table 4-11 and Q.951 Section 3 */ + uint8_t calling_number_screening_ind; + uint8_t calling_number_presentation; + char redirection_string [SIZE_RDNIS]; /* it's a null terminated string */ + /* redir string format: + * http://www.ss7box.com/wiki/tiki-index.php?page=Call+Redirection + * */ +} t_sigboost; +#pragma pack() + +#endif diff --git a/libs/openzap/src/include/ss7_boost_client.h b/libs/openzap/src/include/ss7_boost_client.h new file mode 100644 index 0000000000..33a9e39a62 --- /dev/null +++ b/libs/openzap/src/include/ss7_boost_client.h @@ -0,0 +1,137 @@ +/* + * Copyright (c) 2007, Anthony Minessale II, Nenad Corbic + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * * Neither the name of the original author; nor the names of any contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER + * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef _SS7BC_H +#define _SS7BC_H + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + + + + +#define ss7bc_test_flag(p,flag) ({ \ + ((p)->flags & (flag)); \ + }) + +#define ss7bc_set_flag(p,flag) do { \ + ((p)->flags |= (flag)); \ + } while (0) + +#define ss7bc_clear_flag(p,flag) do { \ + ((p)->flags &= ~(flag)); \ + } while (0) + +#define ss7bc_copy_flags(dest,src,flagz) do { \ + (dest)->flags &= ~(flagz); \ + (dest)->flags |= ((src)->flags & (flagz)); \ + } while (0) + +typedef t_sigboost ss7bc_event_t; +typedef uint32_t ss7bc_event_id_t; + +typedef struct smg_ip_cfg +{ + char local_ip[25]; + int local_port; + char remote_ip[25]; + int remote_port; +}smg_ip_cfg_t; + +struct ss7bc_connection { + zap_socket_t socket; + struct sockaddr_in local_addr; + struct sockaddr_in remote_addr; + ss7bc_event_t event; + struct hostent remote_hp; + struct hostent local_hp; + unsigned int flags; + pthread_mutex_t lock; + FILE *log; + unsigned int txseq; + unsigned int rxseq; + unsigned int txwindow; + unsigned int rxseq_reset; + smg_ip_cfg_t cfg; +}; + +typedef enum { + MSU_FLAG_EVENT = (1 << 0) +} ss7bc_flag_t; + +typedef struct ss7bc_connection ss7bc_connection_t; + +/* disable nagle's algorythm */ +static inline void sctp_no_nagle(int socket) +{ + int flag = 1; + setsockopt(socket, IPPROTO_SCTP, SCTP_NODELAY, (char *) &flag, sizeof(int)); +} + +int ss7bc_connection_close(ss7bc_connection_t *mcon); +int ss7bc_connection_open(ss7bc_connection_t *mcon, char *local_ip, int local_port, char *ip, int port); +ss7bc_event_t *ss7bc_connection_read(ss7bc_connection_t *mcon, int iteration); +ss7bc_event_t *ss7bc_connection_readp(ss7bc_connection_t *mcon, int iteration); +int ss7bc_connection_write(ss7bc_connection_t *mcon, ss7bc_event_t *event); +void ss7bc_event_init(ss7bc_event_t *event, ss7bc_event_id_t event_id, int chan, int span); +void ss7bc_call_init(ss7bc_event_t *event, char *calling, char *called, int setup_id); +char *ss7bc_event_id_name(uint32_t event_id); + +#endif + + +/* For Emacs: + * Local Variables: + * mode:c + * indent-tabs-mode:t + * tab-width:4 + * c-basic-offset:4 + * End: + * For VIM: + * vim:set softtabstop=4 shiftwidth=4 tabstop=4 expandtab: + */ diff --git a/libs/openzap/src/ss7_boost_client.c b/libs/openzap/src/ss7_boost_client.c new file mode 100644 index 0000000000..058d52d306 --- /dev/null +++ b/libs/openzap/src/ss7_boost_client.c @@ -0,0 +1,415 @@ +/* + * Copyright (c) 2007, Anthony Minessale II, Nenad Corbic + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * * Neither the name of the original author; nor the names of any contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER + * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "openzap.h" +#include + +#ifndef gethostbyname_r +extern int gethostbyname_r (__const char *__restrict __name, + struct hostent *__restrict __result_buf, + char *__restrict __buf, size_t __buflen, + struct hostent **__restrict __result, + int *__restrict __h_errnop); +#endif + +struct ss7bc_map { + uint32_t event_id; + char *name; +}; + +static struct ss7bc_map ss7bc_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_SYSTEM_RESTART_ACK, "SYSTEM_RESTART_ACK"}, + {SIGBOOST_EVENT_HEARTBEAT, "HEARTBEAT"}, + {SIGBOOST_EVENT_INSERT_CHECK_LOOP, "LOOP START"}, + {SIGBOOST_EVENT_REMOVE_CHECK_LOOP, "LOOP STOP"} +}; + + + +static int create_conn_socket(ss7bc_connection_t *mcon, char *local_ip, int local_port, char *ip, int port) +{ + int rc; + struct hostent *result, *local_result; + char buf[512], local_buf[512]; + int err = 0; + + memset(&mcon->remote_hp, 0, sizeof(mcon->remote_hp)); + memset(&mcon->local_hp, 0, sizeof(mcon->local_hp)); +#ifdef SS7BC_USE_SCTP + mcon->socket = socket(AF_INET, SOCK_SEQPACKET, IPPROTO_SCTP); +#else + mcon->socket = socket(AF_INET, SOCK_DGRAM, 0); +#endif + + zap_log(ZAP_LOG_DEBUG, "Creating L=%s:%d R=%s:%d\n", + local_ip,local_port,ip,port); + + if (mcon->socket >= 0) { + int flag; + + flag = 1; + gethostbyname_r(ip, &mcon->remote_hp, buf, sizeof(buf), &result, &err); + gethostbyname_r(local_ip, &mcon->local_hp, local_buf, sizeof(local_buf), &local_result, &err); + if (result && local_result) { + mcon->remote_addr.sin_family = mcon->remote_hp.h_addrtype; + memcpy((char *) &mcon->remote_addr.sin_addr.s_addr, mcon->remote_hp.h_addr_list[0], mcon->remote_hp.h_length); + mcon->remote_addr.sin_port = htons(port); + + mcon->local_addr.sin_family = mcon->local_hp.h_addrtype; + memcpy((char *) &mcon->local_addr.sin_addr.s_addr, mcon->local_hp.h_addr_list[0], mcon->local_hp.h_length); + mcon->local_addr.sin_port = htons(local_port); + +#ifdef SS7BC_USE_SCTP + setsockopt(mcon->socket, IPPROTO_SCTP, SCTP_NODELAY, + (char *)&flag, sizeof(int)); +#endif + + if ((rc = bind(mcon->socket, + (struct sockaddr *) &mcon->local_addr, + sizeof(mcon->local_addr))) < 0) { + close(mcon->socket); + mcon->socket = -1; + } else { +#ifdef SS7BC_USE_SCTP + rc=listen(mcon->socket,100); + if (rc) { + close(mcon->socket); + mcon->socket = -1; + } +#endif + } + } + } + + return mcon->socket; +} + +int ss7bc_connection_close(ss7bc_connection_t *mcon) +{ + close(mcon->socket); + mcon->socket = -1; + memset(mcon, 0, sizeof(*mcon)); + + return 0; +} + +int ss7bc_connection_open(ss7bc_connection_t *mcon, char *local_ip, int local_port, char *ip, int port) +{ + create_conn_socket(mcon, local_ip, local_port, ip, port); + return mcon->socket; +} + +ss7bc_event_t *ss7bc_connection_read(ss7bc_connection_t *mcon, int iteration) +{ + unsigned int fromlen = sizeof(struct sockaddr_in); +#if 0 + ss7bc_event_t *event = &mcon->event; +#endif + int bytes = 0; + + bytes = recvfrom(mcon->socket, &mcon->event, sizeof(mcon->event), MSG_DONTWAIT, + (struct sockaddr *) &mcon->local_addr, &fromlen); + + if (bytes == sizeof(mcon->event) || + bytes == (sizeof(mcon->event)-sizeof(uint32_t))) { + + if (mcon->rxseq_reset) { + if (mcon->event.event_id == SIGBOOST_EVENT_SYSTEM_RESTART_ACK) { + zap_log(ZAP_LOG_DEBUG, "Rx sync ok\n"); + mcon->rxseq=mcon->event.fseqno; + return &mcon->event; + } + errno=EAGAIN; + zap_log(ZAP_LOG_DEBUG, "Waiting for rx sync...\n"); + return NULL; + } + + mcon->txwindow = mcon->txseq - mcon->event.bseqno; + mcon->rxseq++; + + if (mcon->rxseq != mcon->event.fseqno) { + zap_log(ZAP_LOG_DEBUG, + "------------------------------------------\n"); + zap_log(ZAP_LOG_DEBUG, + "Critical Error: Invalid Sequence Number Expect=%i Rx=%i\n", + mcon->rxseq,mcon->event.fseqno); + zap_log(ZAP_LOG_DEBUG, + "------------------------------------------\n"); + } + +#if 0 + /* Debugging only not to be used in production because span/chan can be invalid */ + if (mcon->event.span < 0 || mcon->event.chan < 0 || mcon->event.span > 16 || mcon->event.chan > 31) { + zap_log(ZAP_LOG_DEBUG, + "------------------------------------------\n"); + zap_log(ZAP_LOG_DEBUG, + "Critical Error: RX Cmd=%s Invalid Span=%i Chan=%i\n", + ss7bc_event_id_name(event->event_id), event->span,event->chan); + zap_log(ZAP_LOG_DEBUG, + "------------------------------------------\n"); + + errno=EAGAIN; + return NULL; + } +#endif + + + + + return &mcon->event; + } else { + if (iteration == 0) { + zap_log(ZAP_LOG_DEBUG, + "------------------------------------------\n"); + zap_log(ZAP_LOG_DEBUG, + "Critical Error: Invalid Event lenght from boost rxlen=%i evsz=%i\n", + bytes, sizeof(mcon->event)); + zap_log(ZAP_LOG_DEBUG, + "------------------------------------------\n"); + } + } + + return NULL; +} + +ss7bc_event_t *ss7bc_connection_readp(ss7bc_connection_t *mcon, int iteration) +{ + unsigned int fromlen = sizeof(struct sockaddr_in); +#if 0 + ss7bc_event_t *event = &mcon->event; +#endif + int bytes = 0; + + bytes = recvfrom(mcon->socket, &mcon->event, sizeof(mcon->event), MSG_DONTWAIT, + (struct sockaddr *) &mcon->local_addr, &fromlen); + + if (bytes == sizeof(mcon->event) || + bytes == (sizeof(mcon->event)-sizeof(uint32_t))) { + +#if 0 + /* Debugging only not to be used in production because span/chan can be invalid */ + if (mcon->event.span < 0 || mcon->event.chan < 0 || mcon->event.span > 16 || mcon->event.chan > 31) { + zap_log(ZAP_LOG_DEBUG, + "------------------------------------------\n"); + zap_log(ZAP_LOG_DEBUG, + "Critical Error: RXp Cmd=%s Invalid Span=%i Chan=%i\n", + ss7bc_event_id_name(event->event_id), event->span,event->chan); + zap_log(ZAP_LOG_DEBUG, + "------------------------------------------\n"); + + errno=EAGAIN; + return NULL; + } +#endif + + return &mcon->event; + } else { + if (iteration == 0) { + zap_log(ZAP_LOG_DEBUG, + "------------------------------------------\n"); + zap_log(ZAP_LOG_DEBUG, + "Critical Error: PQ Invalid Event lenght from boost rxlen=%i evsz=%i\n", + bytes, sizeof(mcon->event)); + zap_log(ZAP_LOG_DEBUG, + "------------------------------------------\n"); + } + } + + return NULL; +} + + +int ss7bc_connection_write(ss7bc_connection_t *mcon, ss7bc_event_t *event) +{ + int err; + if (!event) { + zap_log(ZAP_LOG_DEBUG, "Critical Error: No Event Device\n"); + return -EINVAL; + } + + if (event->span > 16 || event->chan > 31) { + zap_log(ZAP_LOG_DEBUG, + "------------------------------------------\n"); + zap_log(ZAP_LOG_DEBUG, + "Critical Error: TX Cmd=%s Invalid Span=%i Chan=%i\n", + ss7bc_event_id_name(event->event_id), event->span,event->chan); + zap_log(ZAP_LOG_DEBUG, + "------------------------------------------\n"); + + return -1; + } + + gettimeofday(&event->tv,NULL); + + pthread_mutex_lock(&mcon->lock); + event->fseqno=mcon->txseq++; + event->bseqno=mcon->rxseq; + err=sendto(mcon->socket, event, sizeof(ss7bc_event_t), 0, + (struct sockaddr *) &mcon->remote_addr, sizeof(mcon->remote_addr)); + pthread_mutex_unlock(&mcon->lock); + + if (err != sizeof(ss7bc_event_t)) { + err = -1; + } + +#if 0 + zap_log(ZAP_LOG_DEBUG, "TX EVENT\n"); + zap_log(ZAP_LOG_DEBUG, "===================================\n"); + zap_log(ZAP_LOG_DEBUG, " tType: %s (%0x HEX)\n", + ss7bc_event_id_name(event->event_id),event->event_id); + zap_log(ZAP_LOG_DEBUG, " tSpan: [%d]\n",event->span+1); + zap_log(ZAP_LOG_DEBUG, " tChan: [%d]\n",event->chan+1); + zap_log(ZAP_LOG_DEBUG, " tCalledNum: %s\n", + (event->called_number_digits_count ? (char *) event->called_number_digits : "N/A")); + zap_log(ZAP_LOG_DEBUG, " tCallingNum: %s\n", + (event->calling_number_digits_count ? (char *) event->calling_number_digits : "N/A")); + zap_log(ZAP_LOG_DEBUG, " tCause: %d\n",event->release_cause); + zap_log(ZAP_LOG_DEBUG, " tInterface: [w%dg%d]\n",event->span+1,event->chan+1); + zap_log(ZAP_LOG_DEBUG, " tEvent ID: [%d]\n",event->event_id); + zap_log(ZAP_LOG_DEBUG, " tSetup ID: [%d]\n",event->call_setup_id); + zap_log(ZAP_LOG_DEBUG, " tSeq: [%d]\n",event->fseqno); + zap_log(ZAP_LOG_DEBUG, "===================================\n"); +#endif + +#if 1 + zap_log(ZAP_LOG_DEBUG, + "TX EVENT: %s:(%X) [w%dg%d] Rc=%i CSid=%i Seq=%i Cd=[%s] Ci=[%s]\n", + ss7bc_event_id_name(event->event_id), + event->event_id, + event->span+1, + event->chan+1, + event->release_cause, + event->call_setup_id, + event->fseqno, + (event->called_number_digits_count ? (char *) event->called_number_digits : "N/A"), + (event->calling_number_digits_count ? (char *) event->calling_number_digits : "N/A") + ); +#endif + + +#if 0 + + zap_log(ZAP_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", + ss7bc_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->fseqno + ); +#endif + + + return err; +} + +void ss7bc_call_init(ss7bc_event_t *event, char *calling, char *called, int setup_id) +{ + memset(event, 0, sizeof(ss7bc_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; + +} + +void ss7bc_event_init(ss7bc_event_t *event, ss7bc_event_id_t event_id, int chan, int span) +{ + memset(event, 0, sizeof(ss7bc_event_t)); + event->event_id = event_id; + event->chan = chan; + event->span = span; +} + +char *ss7bc_event_id_name(uint32_t event_id) +{ + unsigned int x; + char *ret = NULL; + + for (x = 0 ; x < sizeof(ss7bc_table)/sizeof(struct ss7bc_map); x++) { + if (ss7bc_table[x].event_id == event_id) { + ret = ss7bc_table[x].name; + break; + } + } + + return ret; +} + +/* For Emacs: + * Local Variables: + * mode:c + * indent-tabs-mode:t + * tab-width:4 + * c-basic-offset:4 + * End: + * For VIM: + * vim:set softtabstop=4 shiftwidth=4 tabstop=4 expandtab: + */ +