From fe7744a96eb7f88f710d84e30499dd7c3fc19e09 Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Wed, 30 Jul 2008 22:15:28 +0000 Subject: [PATCH] update boost git-svn-id: http://svn.openzap.org/svn/openzap/trunk@507 a93c3328-9c30-0410-af19-c9cd2b2d52af --- libs/openzap/src/include/openzap.h | 12 ++ libs/openzap/src/include/sigboost.h | 53 ++++-- libs/openzap/src/include/ss7_boost_client.h | 14 +- libs/openzap/src/include/zap_ss7_boost.h | 3 +- libs/openzap/src/ss7_boost_client.c | 181 +++++++++++++++++--- libs/openzap/src/zap_ss7_boost.c | 162 +++++++++++------- 6 files changed, 321 insertions(+), 104 deletions(-) diff --git a/libs/openzap/src/include/openzap.h b/libs/openzap/src/include/openzap.h index e8ee4fe890..4fb5c737ad 100644 --- a/libs/openzap/src/include/openzap.h +++ b/libs/openzap/src/include/openzap.h @@ -595,6 +595,18 @@ static __inline__ void zap_set_state_all(zap_span_t *span, zap_channel_state_t s zap_mutex_unlock(span->mutex); } +static __inline__ int zap_check_state_all(zap_span_t *span, zap_channel_state_t state) +{ + uint32_t j; + for(j = 1; j <= span->chan_count; j++) { + if (span->channels[j].state != state || zap_test_flag((&span->channels[j]), ZAP_CHANNEL_STATE_CHANGE)) { + return 0; + } + } + + return 1; +} + static __inline__ void zap_set_flag_all(zap_span_t *span, uint32_t flag) { uint32_t j; diff --git a/libs/openzap/src/include/sigboost.h b/libs/openzap/src/include/sigboost.h index 009e4b26c6..a5a147cd11 100644 --- a/libs/openzap/src/include/sigboost.h +++ b/libs/openzap/src/include/sigboost.h @@ -1,5 +1,5 @@ /**************************************************************************** - * sigboost.h $Revision: 1.3 $ + * sigboost.h $Revision: 1.5 $ * * Definitions for the sigboost interface. * @@ -33,12 +33,12 @@ enum e_sigboost_event_id_values SIGBOOST_EVENT_INSERT_CHECK_LOOP = 0x8a, /*138*/ SIGBOOST_EVENT_REMOVE_CHECK_LOOP = 0x8b, /*139*/ SIGBOOST_EVENT_AUTO_CALL_GAP_ABATE = 0x8c, /*140*/ + SIGBOOST_EVENT_DIGIT_IN = 0x8d, /*141*/ }; 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 */ @@ -59,7 +59,6 @@ enum e_sigboost_call_setup_ack_nack_cause_values }; #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. @@ -68,37 +67,63 @@ enum e_sigboost_call_setup_ack_nack_cause_values #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 +#define SIZE_RDNIS 128 #pragma pack(1) typedef struct { uint32_t event_id; + /* delete sequence numbers - SCTP does not need them */ 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 span; + uint8_t chan; + struct timeval tv; uint8_t called_number_digits_count; char called_number_digits [MAX_DIALED_DIGITS + 1]; /* it's a null terminated string */ uint8_t calling_number_digits_count; /* it's an array */ char calling_number_digits [MAX_DIALED_DIGITS + 1]; /* it's a null terminated string */ - 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 calling_name[MAX_DIALED_DIGITS + 1]; + uint16_t redirection_string_size; char redirection_string [SIZE_RDNIS]; /* it's a null terminated string */ /* redir string format: * http://www.ss7box.com/wiki/tiki-index.php?page=Call+Redirection * */ -} t_sigboost; +} t_sigboost_callstart; + +#define MIN_SIZE_CALLSTART_MSG (sizeof(t_sigboost_callstart) - SIZE_RDNIS) + +typedef struct +{ + uint32_t event_id; + /* delete sequence numbers - SCTP does not need them */ + uint32_t fseqno; + uint32_t bseqno; + uint16_t call_setup_id; + uint32_t trunk_group; + uint8_t span; + uint8_t chan; + struct timeval tv; + uint8_t release_cause; +} t_sigboost_short; #pragma pack() +static inline int boost_full_event(int event_id) +{ + switch (event_id) { + case SIGBOOST_EVENT_CALL_START: + case SIGBOOST_EVENT_DIGIT_IN: + return 1; + default: + return 0; + } + + return 0; +} + #endif diff --git a/libs/openzap/src/include/ss7_boost_client.h b/libs/openzap/src/include/ss7_boost_client.h index 4184f5385e..f28f1900f3 100644 --- a/libs/openzap/src/include/ss7_boost_client.h +++ b/libs/openzap/src/include/ss7_boost_client.h @@ -70,7 +70,8 @@ (dest)->flags |= ((src)->flags & (flagz)); \ } while (0) -typedef t_sigboost ss7bc_event_t; +typedef t_sigboost_callstart ss7bc_event_t; +typedef t_sigboost_short ss7bc_short_event_t; typedef uint32_t ss7bc_event_id_t; typedef struct ss7bc_ip_cfg @@ -117,14 +118,19 @@ static inline void sctp_no_nagle(int socket) 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); +ss7bc_event_t *__ss7bc_connection_read(ss7bc_connection_t *mcon, int iteration, const char *file, const char *func, int line); +ss7bc_event_t *__ss7bc_connection_readp(ss7bc_connection_t *mcon, int iteration, const char *file, const char *func, int line); int __ss7bc_connection_write(ss7bc_connection_t *mcon, ss7bc_event_t *event, const char *file, const char *func, int line); +int __ss7bc_connection_writep(ss7bc_connection_t *mcon, ss7bc_event_t *event, const char *file, const char *func, int line); #define ss7bc_connection_write(_m,_e) __ss7bc_connection_write(_m, _e, __FILE__, __func__, __LINE__) -void ss7bc_event_init(ss7bc_event_t *event, ss7bc_event_id_t event_id, int chan, int span); +#define ss7bc_connection_writep(_m,_e) __ss7bc_connection_writep(_m, _e, __FILE__, __func__, __LINE__) +#define ss7bc_connection_read(_m,_e) __ss7bc_connection_read(_m, _e, __FILE__, __func__, __LINE__) +#define ss7bc_connection_readp(_m,_e) __ss7bc_connection_readp(_m, _e, __FILE__, __func__, __LINE__) +void ss7bc_event_init(ss7bc_short_event_t *event, ss7bc_event_id_t event_id, int chan, int span); void ss7bc_call_init(ss7bc_event_t *event, const char *calling, const char *called, int setup_id); const char *ss7bc_event_id_name(uint32_t event_id); int ss7bc_exec_command(ss7bc_connection_t *mcon, int span, int chan, int id, int cmd, int cause); +int ss7bc_exec_commandp(ss7bc_connection_t *pcon, int span, int chan, int id, int cmd, int cause); #endif diff --git a/libs/openzap/src/include/zap_ss7_boost.h b/libs/openzap/src/include/zap_ss7_boost.h index e3c7901c45..c5496b8aed 100644 --- a/libs/openzap/src/include/zap_ss7_boost.h +++ b/libs/openzap/src/include/zap_ss7_boost.h @@ -37,7 +37,8 @@ #include "openzap.h" typedef enum { - ZAP_SS7_BOOST_RUNNING = (1 << 0) + ZAP_SS7_BOOST_RUNNING = (1 << 0), + ZAP_SS7_BOOST_RESTARTING = (1 << 1) } zap_ss7_boost_flag_t; typedef struct zap_ss7_boost_data { diff --git a/libs/openzap/src/ss7_boost_client.c b/libs/openzap/src/ss7_boost_client.c index f12f1018a8..5699455854 100644 --- a/libs/openzap/src/ss7_boost_client.c +++ b/libs/openzap/src/ss7_boost_client.c @@ -69,6 +69,41 @@ static struct ss7bc_map ss7bc_table[] = { +static void ss7bc_print_event_call(ss7bc_connection_t *mcon, ss7bc_event_t *event, int priority, int dir,const char *file, const char *func, int line) +{ + if (event->event_id == SIGBOOST_EVENT_HEARTBEAT) + return; + zap_log(file, func, line, ZAP_LOG_LEVEL_DEBUG, "%s EVENT: %s:(%X) [w%dg%d] CSid=%i Seq=%i Cn=[%s] Cd=[%s] Ci=[%s]\n", + dir ? "TX":"RX", + ss7bc_event_id_name(event->event_id), + event->event_id, + event->span+1, + event->chan+1, + event->call_setup_id, + event->fseqno, + strlen(event->calling_name)?event->calling_name:"N/A", + (event->called_number_digits_count ? (char *) event->called_number_digits : "N/A"), + (event->calling_number_digits_count ? (char *) event->calling_number_digits : "N/A") + ); + +} +static void ss7bc_print_event_short(ss7bc_connection_t *mcon,ss7bc_short_event_t *event, int priority, int dir,const char *file, const char *func, int line) +{ + if (event->event_id == SIGBOOST_EVENT_HEARTBEAT) + return; + zap_log(file, func, line, ZAP_LOG_LEVEL_DEBUG, "%s EVENT (%s): %s:(%X) [w%dg%d] Rc=%i CSid=%i Seq=%i \n", + dir ? "TX":"RX", + priority ? "P":"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); +} + + static int create_conn_socket(ss7bc_connection_t *mcon, char *local_ip, int local_port, char *ip, int port) { int rc; @@ -161,13 +196,13 @@ int ss7bc_connection_open(ss7bc_connection_t *mcon, char *local_ip, int local_po int ss7bc_exec_command(ss7bc_connection_t *mcon, int span, int chan, int id, int cmd, int cause) { - ss7bc_event_t oevent; + ss7bc_short_event_t oevent; int retry = 5; ss7bc_event_init(&oevent, cmd, chan, span); oevent.release_cause = cause; - if (cmd == SIGBOOST_EVENT_SYSTEM_RESTART) { + if (cmd == SIGBOOST_EVENT_SYSTEM_RESTART || cmd == SIGBOOST_EVENT_SYSTEM_RESTART_ACK) { mcon->rxseq_reset = 1; mcon->txseq = 0; mcon->rxseq = 0; @@ -178,7 +213,33 @@ int ss7bc_exec_command(ss7bc_connection_t *mcon, int span, int chan, int id, int oevent.call_setup_id = id; } - while (ss7bc_connection_write(mcon, &oevent) <= 0) { + while (ss7bc_connection_write(mcon, (ss7bc_event_t*)&oevent) <= 0) { + if (--retry <= 0) { + zap_log(ZAP_LOG_CRIT, "Failed to tx on ISUP socket: %s\n", strerror(errno)); + return -1; + } else { + zap_log(ZAP_LOG_WARNING, "Failed to tx on ISUP socket: %s :retry %i\n", strerror(errno), retry); + zap_sleep(1); + } + } + + return 0; +} + + +int ss7bc_exec_commandp(ss7bc_connection_t *pcon, int span, int chan, int id, int cmd, int cause) +{ + ss7bc_short_event_t oevent; + int retry = 5; + + ss7bc_event_init(&oevent, cmd, chan, span); + oevent.release_cause = cause; + + if (id >= 0) { + oevent.call_setup_id = id; + } + + while (ss7bc_connection_writep(pcon, (ss7bc_event_t*)&oevent) <= 0) { if (--retry <= 0) { zap_log(ZAP_LOG_CRIT, "Failed to tx on ISUP socket: %s\n", strerror(errno)); return -1; @@ -193,16 +254,39 @@ int ss7bc_exec_command(ss7bc_connection_t *mcon, int span, int chan, int id, int -ss7bc_event_t *ss7bc_connection_read(ss7bc_connection_t *mcon, int iteration) +ss7bc_event_t *__ss7bc_connection_read(ss7bc_connection_t *mcon, int iteration, const char *file, const char *func, int line) { unsigned int fromlen = sizeof(struct sockaddr_in); int bytes = 0; + int msg_ok = 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))) { + /* Must check for < 0 cannot rely on bytes > MIN_SIZE_... compiler issue */ + if (bytes < 0) { + msg_ok=0; + } else if ((bytes >= MIN_SIZE_CALLSTART_MSG) && boost_full_event(mcon->event.event_id)) { + msg_ok=1; + + } else if (bytes == sizeof(ss7bc_short_event_t)) { + msg_ok=1; + + } else { + msg_ok=0; + } + + if (msg_ok){ + + if (boost_full_event(mcon->event.event_id)) { + ss7bc_print_event_call(mcon,&mcon->event, 0, 0, file,func,line); + } else { + ss7bc_print_event_short(mcon,(ss7bc_short_event_t*)&mcon->event, 0, 0, file,func,line); + } + +#if 0 +/* NC: NOT USED ANY MORE */ if (mcon->rxseq_reset) { if (mcon->event.event_id == SIGBOOST_EVENT_SYSTEM_RESTART_ACK) { zap_log(ZAP_LOG_DEBUG, "Rx sync ok\n"); @@ -213,6 +297,7 @@ ss7bc_event_t *ss7bc_connection_read(ss7bc_connection_t *mcon, int iteration) zap_log(ZAP_LOG_DEBUG, "Waiting for rx sync...\n"); return NULL; } +#endif mcon->txwindow = mcon->txseq - mcon->event.bseqno; mcon->rxseq++; @@ -233,14 +318,21 @@ ss7bc_event_t *ss7bc_connection_read(ss7bc_connection_t *mcon, int iteration) return NULL; } -ss7bc_event_t *ss7bc_connection_readp(ss7bc_connection_t *mcon, int iteration) +ss7bc_event_t *__ss7bc_connection_readp(ss7bc_connection_t *mcon, int iteration, const char *file, const char *func, int line) { unsigned int fromlen = sizeof(struct sockaddr_in); 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 (bytes == sizeof(ss7bc_short_event_t)) { + + if (boost_full_event(mcon->event.event_id)) { + ss7bc_print_event_call(mcon,&mcon->event, 1, 0, file,func,line); + } else { + ss7bc_print_event_short(mcon,(ss7bc_short_event_t*)&mcon->event, 1, 0, file,func,line); + } + return &mcon->event; } else { if (iteration == 0) { @@ -256,6 +348,7 @@ ss7bc_event_t *ss7bc_connection_readp(ss7bc_connection_t *mcon, int iteration) int __ss7bc_connection_write(ss7bc_connection_t *mcon, ss7bc_event_t *event, const char *file, const char *func, int line) { int err; + int event_size=sizeof(ss7bc_event_t); if (!event || mcon->socket < 0 || !mcon->mutex) { zap_log(file, func, line, ZAP_LOG_LEVEL_CRIT, "Critical Error: No Event Device\n"); @@ -269,30 +362,71 @@ int __ss7bc_connection_write(ss7bc_connection_t *mcon, ss7bc_event_t *event, con return -1; } + if (!boost_full_event(event->event_id)) { + event_size=sizeof(ss7bc_short_event_t); + } + gettimeofday(&event->tv,NULL); zap_mutex_lock(mcon->mutex); - event->fseqno = mcon->txseq++; + if (event->event_id == SIGBOOST_EVENT_SYSTEM_RESTART_ACK) { + mcon->txseq=0; + mcon->rxseq=0; + event->fseqno=0; + } else { + 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)); + err = sendto(mcon->socket, event, event_size, 0, (struct sockaddr *) &mcon->remote_addr, sizeof(mcon->remote_addr)); + zap_mutex_unlock(mcon->mutex); - if (err != sizeof(ss7bc_event_t)) { + if (err != event_size) { err = -1; abort(); } + + if (boost_full_event(event->event_id)) { + ss7bc_print_event_call(mcon,event, 0, 1,file,func,line); + } else { + ss7bc_print_event_short(mcon,(ss7bc_short_event_t*)event, 0, 1,file,func,line); + } + + return err; +} + + +int __ss7bc_connection_writep(ss7bc_connection_t *mcon, ss7bc_event_t *event, const char *file, const char *func, int line) +{ + int err; + int event_size=sizeof(ss7bc_event_t); + + if (!event || mcon->socket < 0 || !mcon->mutex) { + zap_log(file, func, line, ZAP_LOG_LEVEL_CRIT, "Critical Error: No Event Device\n"); + return -EINVAL; + abort(); + } + + if (!boost_full_event(event->event_id)) { + event_size=sizeof(ss7bc_short_event_t); + } + + gettimeofday(&event->tv,NULL); - zap_log(file, func, line, ZAP_LOG_LEVEL_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") - ); + zap_mutex_lock(mcon->mutex); + err = sendto(mcon->socket, event, event_size, 0, (struct sockaddr *) &mcon->remote_addr, sizeof(mcon->remote_addr)); + zap_mutex_unlock(mcon->mutex); + + if (err != event_size) { + err = -1; + abort(); + } + + if (boost_full_event(event->event_id)) { + ss7bc_print_event_call(mcon,event, 1, 1,file,func,line); + } else { + ss7bc_print_event_short(mcon,(ss7bc_short_event_t*)event, 1, 1,file,func,line); + } return err; } @@ -317,9 +451,9 @@ void ss7bc_call_init(ss7bc_event_t *event, const char *calling, const char *call } -void ss7bc_event_init(ss7bc_event_t *event, ss7bc_event_id_t event_id, int chan, int span) +void ss7bc_event_init(ss7bc_short_event_t *event, ss7bc_event_id_t event_id, int chan, int span) { - memset(event, 0, sizeof(ss7bc_event_t)); + memset(event, 0, sizeof(ss7bc_short_event_t)); event->event_id = event_id; event->chan = chan; event->span = span; @@ -340,6 +474,7 @@ const char *ss7bc_event_id_name(uint32_t event_id) return ret; } + /* For Emacs: * Local Variables: * mode:c diff --git a/libs/openzap/src/zap_ss7_boost.c b/libs/openzap/src/zap_ss7_boost.c index 08e1d65417..0238a50437 100644 --- a/libs/openzap/src/zap_ss7_boost.c +++ b/libs/openzap/src/zap_ss7_boost.c @@ -54,7 +54,7 @@ typedef enum { typedef struct { ss7_boost_request_status_t status; - ss7bc_event_t event; + ss7bc_short_event_t event; zap_span_t *span; zap_channel_t *zchan; } ss7_boost_request_t; @@ -136,7 +136,7 @@ static ss7_boost_request_id_t __next_request_id(const char *func, int line) } #define next_request_id() __next_request_id(__FUNCTION__, __LINE__) -static zap_channel_t *find_zchan(zap_span_t *span, ss7bc_event_t *event, int force) +static zap_channel_t *find_zchan(zap_span_t *span, ss7bc_short_event_t *event, int force) { int i; zap_channel_t *zchan = NULL; @@ -273,7 +273,7 @@ static ZIO_CHANNEL_OUTGOING_CALL_FUNCTION(ss7_boost_outgoing_call) return status; } -static void handle_call_start_ack(ss7bc_connection_t *mcon, ss7bc_event_t *event) +static void handle_call_start_ack(ss7bc_connection_t *mcon, ss7bc_short_event_t *event) { zap_channel_t *zchan; @@ -316,7 +316,7 @@ static void handle_call_start_ack(ss7bc_connection_t *mcon, ss7bc_event_t *event } -static void handle_call_done(zap_span_t *span, ss7bc_connection_t *mcon, ss7bc_event_t *event) +static void handle_call_done(zap_span_t *span, ss7bc_connection_t *mcon, ss7bc_short_event_t *event) { zap_channel_t *zchan; int r = 0; @@ -346,7 +346,7 @@ static void handle_call_done(zap_span_t *span, ss7bc_connection_t *mcon, ss7bc_e release_request_id_span_chan(event->span, event->chan); } -static void handle_call_start_nack(zap_span_t *span, ss7bc_connection_t *mcon, ss7bc_event_t *event) +static void handle_call_start_nack(zap_span_t *span, ss7bc_connection_t *mcon, ss7bc_short_event_t *event) { zap_channel_t *zchan; @@ -395,7 +395,7 @@ static void handle_call_start_nack(zap_span_t *span, ss7bc_connection_t *mcon, s } -static void handle_call_stop(zap_span_t *span, ss7bc_connection_t *mcon, ss7bc_event_t *event) +static void handle_call_stop(zap_span_t *span, ss7bc_connection_t *mcon, ss7bc_short_event_t *event) { zap_channel_t *zchan; @@ -434,7 +434,7 @@ static void handle_call_stop(zap_span_t *span, ss7bc_connection_t *mcon, ss7bc_e release_request_id_span_chan(event->span, event->chan); } -static void handle_call_answer(zap_span_t *span, ss7bc_connection_t *mcon, ss7bc_event_t *event) +static void handle_call_answer(zap_span_t *span, ss7bc_connection_t *mcon, ss7bc_short_event_t *event) { zap_channel_t *zchan; @@ -465,7 +465,7 @@ static void handle_call_start(zap_span_t *span, ss7bc_connection_t *mcon, ss7bc_ { zap_channel_t *zchan; - if (!(zchan = find_zchan(span, event, 0))) { + if (!(zchan = find_zchan(span, (ss7bc_short_event_t*)event, 0))) { goto error; } @@ -498,12 +498,11 @@ static void handle_call_start(zap_span_t *span, ss7bc_connection_t *mcon, ss7bc_ } -static void handle_heartbeat(ss7bc_connection_t *mcon, ss7bc_event_t *event) +static void handle_heartbeat(ss7bc_connection_t *mcon, ss7bc_short_event_t *event) { int err; - - err = ss7bc_connection_write(mcon, event); + err = ss7bc_connection_writep(mcon, (ss7bc_event_t*)event); if (err <= 0) { zap_log(ZAP_LOG_CRIT, "Failed to tx on ISUP socket [%s]: %s\n", strerror(errno)); @@ -514,16 +513,64 @@ static void handle_heartbeat(ss7bc_connection_t *mcon, ss7bc_event_t *event) return; } -static void handle_restart_ack(ss7bc_connection_t *mcon, zap_span_t *span, ss7bc_event_t *event) +static void handle_restart_ack(ss7bc_connection_t *mcon, zap_span_t *span, ss7bc_short_event_t *event) { - mcon->rxseq_reset = 0; +#if 0 +/* NC: Clear suspended on RESTART ACK */ + mcon->rxseq_reset = 0; mcon->up = 1; zap_set_state_all(span, ZAP_CHANNEL_STATE_RESTART); zap_clear_flag_locked(span, ZAP_SPAN_SUSPENDED); +#endif mcon->hb_elapsed = 0; } -static int parse_ss7_event(zap_span_t *span, ss7bc_connection_t *mcon, ss7bc_event_t *event) + +static void handle_restart(ss7bc_connection_t *mcon, zap_span_t *span, ss7bc_short_event_t *event) +{ + zap_ss7_boost_data_t *ss7_boost_data = span->signal_data; + + mcon->rxseq_reset = 0; + mcon->up = 1; + + zap_set_flag_locked(span, ZAP_SPAN_SUSPENDED); + zap_set_state_all(span, ZAP_CHANNEL_STATE_RESTART); + zap_set_flag(ss7_boost_data, ZAP_SS7_BOOST_RESTARTING); + + mcon->hb_elapsed = 0; +} + +static void handle_incoming_digit(ss7bc_connection_t *mcon, zap_span_t *span, ss7bc_event_t *event) +{ + zap_channel_t *zchan = NULL; + char digits[MAX_DIALED_DIGITS + 2] = ""; + + if (!(zchan = find_zchan(span, (ss7bc_short_event_t *)event, 1))) { + zap_log(ZAP_LOG_ERROR, "Invalid channel\n"); + return; + } + + if (event->called_number_digits_count == 0) { + zap_log(ZAP_LOG_WARNING, "Error Incoming digit with len %s %d [w%dg%d]\n", + event->called_number_digits, + event->called_number_digits_count, + event->span+1, event->chan+1); + return; + } + + zap_log(ZAP_LOG_WARNING, "Incoming digit with len %s %d [w%dg%d]\n", + event->called_number_digits, + event->called_number_digits_count, + event->span+1, event->chan+1); + + memcpy(digits, event->called_number_digits, event->called_number_digits_count); + zap_channel_queue_dtmf(zchan, digits); + + return; +} + + +static int parse_ss7_event(zap_span_t *span, ss7bc_connection_t *mcon, ss7bc_short_event_t *event) { zap_mutex_lock(signal_mutex); @@ -532,47 +579,19 @@ static int parse_ss7_event(zap_span_t *span, ss7bc_connection_t *mcon, ss7bc_eve goto end; } - if (zap_test_flag(span, ZAP_SPAN_SUSPENDED) && - event->event_id != SIGBOOST_EVENT_SYSTEM_RESTART_ACK && event->event_id != SIGBOOST_EVENT_HEARTBEAT) { - - zap_log(ZAP_LOG_WARNING, - "INVALID 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") - ); - + event->event_id != SIGBOOST_EVENT_SYSTEM_RESTART_ACK && + event->event_id != SIGBOOST_EVENT_HEARTBEAT && + event->event_id != SIGBOOST_EVENT_SYSTEM_RESTART) { goto end; } - - zap_log(ZAP_LOG_DEBUG, - "RX 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") - ); - - assert(event->call_setup_id <= MAX_REQ_ID); switch(event->event_id) { case SIGBOOST_EVENT_CALL_START: - handle_call_start(span, mcon, event); + handle_call_start(span, mcon, (ss7bc_event_t*)event); break; case SIGBOOST_EVENT_CALL_STOPPED: handle_call_stop(span, mcon, event); @@ -605,9 +624,15 @@ static int parse_ss7_event(zap_span_t *span, ss7bc_connection_t *mcon, ss7bc_eve case SIGBOOST_EVENT_SYSTEM_RESTART_ACK: handle_restart_ack(mcon, span, event); break; + case SIGBOOST_EVENT_SYSTEM_RESTART: + handle_restart(mcon, span, event); + break; case SIGBOOST_EVENT_AUTO_CALL_GAP_ABATE: //handle_gap_abate(event); break; + case SIGBOOST_EVENT_DIGIT_IN: + handle_incoming_digit(mcon, span, (ss7bc_event_t*)event); + break; default: zap_log(ZAP_LOG_WARNING, "No handler implemented for [%s]\n", ss7bc_event_id_name(event->event_id)); break; @@ -681,11 +706,7 @@ static __inline__ void state_advance(zap_channel_t *zchan) break; case ZAP_CHANNEL_STATE_RESTART: { - if (zchan->last_state != ZAP_CHANNEL_STATE_HANGUP && zchan->last_state != ZAP_CHANNEL_STATE_DOWN) { - zap_set_state_locked(zchan, ZAP_CHANNEL_STATE_HANGUP); - } else { - zap_set_state_locked(zchan, ZAP_CHANNEL_STATE_DOWN); - } + zap_set_state_locked(zchan, ZAP_CHANNEL_STATE_DOWN); } break; case ZAP_CHANNEL_STATE_UP: @@ -789,6 +810,8 @@ static __inline__ void init_outgoing_array(void) static __inline__ void check_state(zap_span_t *span) { + zap_ss7_boost_data_t *ss7_boost_data = span->signal_data; + if (zap_test_flag(span, ZAP_SPAN_STATE_CHANGE)) { uint32_t j; zap_clear_flag_locked(span, ZAP_SPAN_STATE_CHANGE); @@ -802,6 +825,22 @@ static __inline__ void check_state(zap_span_t *span) } } } + + if (zap_test_flag(ss7_boost_data, ZAP_SS7_BOOST_RESTARTING)) { + if (zap_check_state_all(span, ZAP_CHANNEL_STATE_DOWN)) { + ss7bc_exec_command(&ss7_boost_data->mcon, + 0, + 0, + -1, + SIGBOOST_EVENT_SYSTEM_RESTART_ACK, + 0); + zap_clear_flag(ss7_boost_data, ZAP_SS7_BOOST_RESTARTING); + zap_clear_flag_locked(span, ZAP_SPAN_SUSPENDED); + ss7_boost_data->mcon.hb_elapsed = 0; + } + } + + } @@ -810,7 +849,7 @@ static void *zap_ss7_boost_run(zap_thread_t *me, void *obj) zap_span_t *span = (zap_span_t *) obj; zap_ss7_boost_data_t *ss7_boost_data = span->signal_data; ss7bc_connection_t *mcon, *pcon; - uint32_t ms = 10;//, too_long = 60000; + uint32_t ms = 10, too_long = 5000; ss7_boost_data->pcon = ss7_boost_data->mcon; @@ -823,12 +862,12 @@ static void *zap_ss7_boost_run(zap_thread_t *me, void *obj) zap_log(ZAP_LOG_DEBUG, "Error: Opening MCON Socket [%d] %s\n", ss7_boost_data->mcon.socket, strerror(errno)); goto end; } - + if (ss7bc_connection_open(&ss7_boost_data->pcon, ss7_boost_data->pcon.cfg.local_ip, ++ss7_boost_data->pcon.cfg.local_port, ss7_boost_data->pcon.cfg.remote_ip, - ss7_boost_data->pcon.cfg.remote_port) < 0) { + ++ss7_boost_data->pcon.cfg.remote_port) < 0) { zap_log(ZAP_LOG_DEBUG, "Error: Opening PCON Socket [%d] %s\n", ss7_boost_data->pcon.socket, strerror(errno)); goto end; } @@ -841,7 +880,7 @@ static void *zap_ss7_boost_run(zap_thread_t *me, void *obj) init_outgoing_array(); - ss7bc_exec_command(mcon, + ss7bc_exec_commandp(pcon, 0, 0, -1, @@ -855,7 +894,7 @@ static void *zap_ss7_boost_run(zap_thread_t *me, void *obj) ss7bc_event_t *event = NULL; if (!zap_running()) { - ss7bc_exec_command(mcon, + ss7bc_exec_commandp(pcon, 0, 0, -1, @@ -884,27 +923,26 @@ static void *zap_ss7_boost_run(zap_thread_t *me, void *obj) if (FD_ISSET(pcon->socket, &rfds)) { if ((event = ss7bc_connection_readp(pcon, i))) { - parse_ss7_event(span, mcon, event); + parse_ss7_event(span, pcon, (ss7bc_short_event_t*)event); } //else goto top; } if (FD_ISSET(mcon->socket, &rfds)) { if ((event = ss7bc_connection_read(mcon, i))) { - parse_ss7_event(span, mcon, event); + parse_ss7_event(span, mcon, (ss7bc_short_event_t*)event); } //else goto top; } } check_state(span); - mcon->hb_elapsed += ms; -#if 0 - if (mcon->hb_elapsed >= too_long && (mcon->up || !zap_test_flag(span, ZAP_SPAN_SUSPENDED))) { + pcon->hb_elapsed += ms; + + if (pcon->hb_elapsed >= too_long && (mcon->up || !zap_test_flag(span, ZAP_SPAN_SUSPENDED))) { zap_set_state_all(span, ZAP_CHANNEL_STATE_RESTART); zap_set_flag_locked(span, ZAP_SPAN_SUSPENDED); mcon->up = 0; zap_log(ZAP_LOG_CRIT, "Lost Heartbeat!\n"); } -#endif }