diff --git a/libs/freetdm/mod_openzap/mod_openzap.c b/libs/freetdm/mod_openzap/mod_openzap.c index fcd635434e..4763a52b86 100644 --- a/libs/freetdm/mod_openzap/mod_openzap.c +++ b/libs/freetdm/mod_openzap/mod_openzap.c @@ -847,10 +847,27 @@ static switch_call_cause_t channel_outgoing_channel(switch_core_session_t *sessi direction = ZAP_BOTTOM_UP; chan_id = 0; } + + if (switch_test_flag(outbound_profile, SWITCH_CPF_SCREEN)) { + caller_data.screen = 1; + } + + if (switch_test_flag(outbound_profile, SWITCH_CPF_HIDE_NUMBER)) { + caller_data.pres = 1; + } + + if (!switch_strlen_zero(dest)) { + zap_set_string(caller_data.ani.digits, dest); + } + +#if 0 + if (!switch_strlen_zero(outbound_profile->rdnis)) { + zap_set_string(caller_data.rdnis.digits, outbound_profile->rdnis); + } +#endif - zap_set_string(caller_data.ani, dest); zap_set_string(caller_data.cid_name, outbound_profile->caller_id_name); - zap_set_string(caller_data.cid_num, outbound_profile->caller_id_number); + zap_set_string(caller_data.cid_num.digits, outbound_profile->caller_id_number); if (chan_id) { status = zap_channel_open(span_id, chan_id, &zchan); @@ -952,11 +969,11 @@ zap_status_t zap_channel_from_event(zap_sigmsg_t *sigmsg, switch_core_session_t switch_set_string(sigmsg->channel->caller_data.cid_name, sigmsg->channel->chan_name); } - if (switch_strlen_zero(sigmsg->channel->caller_data.cid_num)) { - if (!switch_strlen_zero(sigmsg->channel->caller_data.ani)) { - switch_set_string(sigmsg->channel->caller_data.cid_num, sigmsg->channel->caller_data.ani); + if (switch_strlen_zero(sigmsg->channel->caller_data.cid_num.digits)) { + if (!switch_strlen_zero(sigmsg->channel->caller_data.ani.digits)) { + switch_set_string(sigmsg->channel->caller_data.cid_num.digits, sigmsg->channel->caller_data.ani.digits); } else { - switch_set_string(sigmsg->channel->caller_data.cid_num, sigmsg->channel->chan_number); + switch_set_string(sigmsg->channel->caller_data.cid_num.digits, sigmsg->channel->chan_number); } } @@ -964,16 +981,25 @@ zap_status_t zap_channel_from_event(zap_sigmsg_t *sigmsg, switch_core_session_t "OpenZAP", SPAN_CONFIG[sigmsg->channel->span_id].dialplan, sigmsg->channel->caller_data.cid_name, - sigmsg->channel->caller_data.cid_num, + sigmsg->channel->caller_data.cid_num.digits, NULL, - sigmsg->channel->caller_data.ani, + sigmsg->channel->caller_data.ani.digits, sigmsg->channel->caller_data.aniII, - sigmsg->channel->caller_data.rdnis, + sigmsg->channel->caller_data.rdnis.digits, (char *) modname, SPAN_CONFIG[sigmsg->channel->span_id].context, - sigmsg->channel->caller_data.dnis); + sigmsg->channel->caller_data.dnis.digits); + assert(tech_pvt->caller_profile != NULL); - + + if (sigmsg->channel->caller_data.screen == 1 || sigmsg->channel->caller_data.screen == 3) { + switch_set_flag(tech_pvt->caller_profile, SWITCH_CPF_SCREEN); + } + + if (sigmsg->channel->caller_data.pres) { + switch_set_flag(tech_pvt->caller_profile, SWITCH_CPF_HIDE_NAME | SWITCH_CPF_HIDE_NUMBER); + } + snprintf(name, sizeof(name), "OpenZAP/%s", tech_pvt->caller_profile->destination_number); switch_channel_set_name(channel, name); switch_channel_set_caller_profile(channel, tech_pvt->caller_profile); @@ -1254,12 +1280,12 @@ static ZIO_SIGNAL_CB_FUNCTION(on_fxs_signal) return status; } -static ZIO_SIGNAL_CB_FUNCTION(on_isdn_signal) +static ZIO_SIGNAL_CB_FUNCTION(on_clear_channel_signal) { switch_core_session_t *session = NULL; switch_channel_t *channel = NULL; - zap_log(ZAP_LOG_DEBUG, "got ISDN sig [%s]\n", zap_signal_event2str(sigmsg->event_id)); + zap_log(ZAP_LOG_DEBUG, "got clear channel sig [%s]\n", zap_signal_event2str(sigmsg->event_id)); switch(sigmsg->event_id) { case ZAP_SIGEVENT_START: @@ -1553,7 +1579,7 @@ static switch_status_t load_config(void) continue; } - if (zap_isdn_configure_span(span, mode, dialect, on_isdn_signal) != ZAP_SUCCESS) { + if (zap_isdn_configure_span(span, mode, dialect, on_clear_channel_signal) != ZAP_SUCCESS) { zap_log(ZAP_LOG_ERROR, "Error starting OpenZAP span %d mode: %d dialect: %d error: %s\n", span_id, mode, dialect, span->last_error); continue; } @@ -1616,7 +1642,7 @@ static switch_status_t load_config(void) continue; } - if (zap_ss7_boost_configure_span(span, local_ip, local_port, remote_ip, remote_port, on_isdn_signal) != ZAP_SUCCESS) { + if (zap_ss7_boost_configure_span(span, local_ip, local_port, remote_ip, remote_port, on_clear_channel_signal) != ZAP_SUCCESS) { zap_log(ZAP_LOG_ERROR, "Error starting OpenZAP span %d error: %s\n", span_id, span->last_error); continue; } diff --git a/libs/freetdm/src/include/openzap.h b/libs/freetdm/src/include/openzap.h index 67693b0c77..6261e2e57f 100644 --- a/libs/freetdm/src/include/openzap.h +++ b/libs/freetdm/src/include/openzap.h @@ -307,14 +307,22 @@ struct zap_fsk_modulator { int16_t sample_buffer[64]; }; +typedef struct { + char digits[25]; + uint8_t type; + uint8_t plan; +} zap_number_t; + struct zap_caller_data { - char cid_name[80]; - char cid_num[80]; char cid_date[8]; - char ani[25]; + char cid_name[80]; + zap_number_t cid_num; + zap_number_t ani; + zap_number_t dnis; + zap_number_t rdnis; char aniII[25]; - char dnis[25]; - char rdnis[25]; + uint8_t screen; + uint8_t pres; char collected[25]; int CRV; int hangup_cause; @@ -413,6 +421,7 @@ struct zap_span { zap_data_type_t data_type; uint32_t span_id; uint32_t chan_count; + uint32_t active_count; zap_span_flag_t flags; struct zap_io_interface *zio; zio_event_cb_t event_callback; @@ -455,6 +464,7 @@ struct zap_io_interface { zio_span_next_event_t next_event; }; + zap_size_t zap_fsk_modulator_generate_bit(zap_fsk_modulator_t *fsk_trans, int8_t bit, int16_t *buf, zap_size_t buflen); int32_t zap_fsk_modulator_generate_carrier_bits(zap_fsk_modulator_t *fsk_trans, uint32_t bits); void zap_fsk_modulator_generate_chan_sieze(zap_fsk_modulator_t *fsk_trans); @@ -545,6 +555,27 @@ ZIO_CODEC_FUNCTION(zio_alaw2ulaw); #define zap_mutex_unlock(_x) _zap_mutex_unlock(_x) #endif + +static __inline__ void zap_set_state_all(zap_span_t *span, zap_channel_state_t state) +{ + uint32_t j; + zap_mutex_lock(span->mutex); + for(j = 1; j <= span->chan_count; j++) { + zap_set_state_locked((&span->channels[j]), state); + } + zap_mutex_unlock(span->mutex); +} + +static __inline__ void zap_set_flag_all(zap_span_t *span, uint32_t flag) +{ + uint32_t j; + zap_mutex_lock(span->mutex); + for(j = 1; j <= span->chan_count; j++) { + zap_set_flag_locked((&span->channels[j]), flag); + } + zap_mutex_unlock(span->mutex); +} + #endif /* For Emacs: diff --git a/libs/freetdm/src/include/ss7_boost_client.h b/libs/freetdm/src/include/ss7_boost_client.h index c7ad5493ee..d2fee452bc 100644 --- a/libs/freetdm/src/include/ss7_boost_client.h +++ b/libs/freetdm/src/include/ss7_boost_client.h @@ -51,12 +51,8 @@ #include #include #include -#include #include - - - #define ss7bc_test_flag(p,flag) ({ \ ((p)->flags & (flag)); \ }) @@ -93,13 +89,15 @@ struct ss7bc_connection { struct hostent remote_hp; struct hostent local_hp; unsigned int flags; - pthread_mutex_t lock; + zap_mutex_t *mutex; FILE *log; unsigned int txseq; unsigned int rxseq; unsigned int txwindow; unsigned int rxseq_reset; ss7bc_ip_cfg_t cfg; + uint32_t hb_elapsed; + int up; }; typedef enum { diff --git a/libs/freetdm/src/include/zap_types.h b/libs/freetdm/src/include/zap_types.h index d1db4ed5e1..84b0243eca 100644 --- a/libs/freetdm/src/include/zap_types.h +++ b/libs/freetdm/src/include/zap_types.h @@ -261,7 +261,8 @@ typedef enum { typedef enum { ZAP_SPAN_CONFIGURED = (1 << 0), ZAP_SPAN_READY = (1 << 1), - ZAP_SPAN_STATE_CHANGE = (1 << 2) + ZAP_SPAN_STATE_CHANGE = (1 << 2), + ZAP_SPAN_SUSPENDED = (1 << 3) } zap_span_flag_t; typedef enum { @@ -329,7 +330,10 @@ typedef enum { ZAP_CHANNEL_CALLERID_DETECT = (1 << 17), ZAP_CHANNEL_OUTBOUND = (1 << 18), ZAP_CHANNEL_SUSPENDED = (1 << 19), - ZAP_CHANNEL_3WAY = (1 << 20) + ZAP_CHANNEL_3WAY = (1 << 20), + ZAP_CHANNEL_PROGRESS = (1 << 21), + ZAP_CHANNEL_MEDIA = (1 << 22), + ZAP_CHANNEL_ANSWERED = (1 << 23) } zap_channel_flag_t; typedef struct zap_channel zap_channel_t; @@ -489,6 +493,7 @@ typedef enum { ZAP_CAUSE_MEDIA_TIMEOUT = 604 } zap_call_cause_t; + #endif /* For Emacs: diff --git a/libs/freetdm/src/ss7_boost_client.c b/libs/freetdm/src/ss7_boost_client.c index 254d10c3bf..dc0151e2ab 100644 --- a/libs/freetdm/src/ss7_boost_client.c +++ b/libs/freetdm/src/ss7_boost_client.c @@ -118,6 +118,8 @@ static int create_conn_socket(ss7bc_connection_t *mcon, char *local_ip, int loca } } + zap_mutex_create(&mcon->mutex); + return mcon->socket; } @@ -126,6 +128,8 @@ int ss7bc_connection_close(ss7bc_connection_t *mcon) if (mcon->socket > -1) { close(mcon->socket); } + + zap_mutex_destroy(&mcon->mutex); memset(mcon, 0, sizeof(*mcon)); mcon->socket = -1; @@ -147,25 +151,25 @@ int ss7bc_exec_command(ss7bc_connection_t *mcon, int span, int chan, int id, int ss7bc_event_init(&oevent, cmd, chan, span); oevent.release_cause = cause; + if (cmd == SIGBOOST_EVENT_SYSTEM_RESTART) { + mcon->rxseq_reset = 1; + mcon->txseq = 0; + mcon->rxseq = 0; + mcon->txwindow = 0; + } + if (id >= 0) { oevent.call_setup_id = id; } - isup_exec_cmd_retry: - if (ss7bc_connection_write(mcon, &oevent) <= 0){ - --retry; - if (retry <= 0) { - zap_log(ZAP_LOG_WARNING, - "Critical System Error: Failed to tx on ISUP socket: %s\n", - strerror(errno)); + while (ss7bc_connection_write(mcon, &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, - "System Warning: Failed to tx on ISUP socket: %s :retry %i\n", - strerror(errno),retry); + zap_log(ZAP_LOG_WARNING, "Failed to tx on ISUP socket: %s :retry %i\n", strerror(errno), retry); + zap_sleep(1); } - - goto isup_exec_cmd_retry; } return 0; @@ -176,21 +180,17 @@ 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) { 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 (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; + mcon->rxseq = mcon->event.fseqno; return &mcon->event; } errno=EAGAIN; @@ -202,44 +202,15 @@ ss7bc_event_t *ss7bc_connection_read(ss7bc_connection_t *mcon, int iteration) 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; + zap_log(ZAP_LOG_CRIT, "Invalid Sequence Number Expect=%i Rx=%i\n", mcon->rxseq, mcon->event.fseqno); 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"); + zap_log(ZAP_LOG_CRIT, "Invalid Event length from boost rxlen=%i evsz=%i\n", bytes, sizeof(mcon->event)); + return NULL; } } @@ -249,43 +220,16 @@ ss7bc_event_t *ss7bc_connection_read(ss7bc_connection_t *mcon, int iteration) 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 + 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))) { 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"); + zap_log(ZAP_LOG_CRIT, "Critical Error: PQ Invalid Event lenght from boost rxlen=%i evsz=%i\n", bytes, sizeof(mcon->event)); + return NULL; } } @@ -296,58 +240,30 @@ ss7bc_event_t *ss7bc_connection_readp(ss7bc_connection_t *mcon, int iteration) 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"); - + zap_log(ZAP_LOG_CRIT, "Critical Error: TX Cmd=%s Invalid Span=%i Chan=%i\n", ss7bc_event_id_name(event->event_id), event->span,event->chan); 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); + zap_mutex_lock(mcon->mutex); + 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)); + zap_mutex_unlock(mcon->mutex); 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", + 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, @@ -358,41 +274,6 @@ int ss7bc_connection_write(ss7bc_connection_t *mcon, ss7bc_event_t *event) (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; } diff --git a/libs/freetdm/src/zap_analog.c b/libs/freetdm/src/zap_analog.c index 63e360df10..7e6027e06b 100644 --- a/libs/freetdm/src/zap_analog.c +++ b/libs/freetdm/src/zap_analog.c @@ -138,15 +138,15 @@ static void send_caller_id(zap_channel_t *zchan) zap_fsk_data_init(&fsk_data, databuf, sizeof(databuf)); zap_fsk_data_add_mdmf(&fsk_data, MDMF_DATETIME, (uint8_t *) time_str, 8); - if (zap_strlen_zero(zchan->caller_data.cid_num)) { + if (zap_strlen_zero(zchan->caller_data.cid_num.digits)) { mt = MDMF_NO_NUM; - zap_set_string(zchan->caller_data.cid_num, "O"); - } else if (!strcasecmp(zchan->caller_data.cid_num, "P") || !strcasecmp(zchan->caller_data.cid_num, "O")) { + zap_set_string(zchan->caller_data.cid_num.digits, "O"); + } else if (!strcasecmp(zchan->caller_data.cid_num.digits, "P") || !strcasecmp(zchan->caller_data.cid_num.digits, "O")) { mt = MDMF_NO_NUM; } else { mt = MDMF_PHONE_NUM; } - zap_fsk_data_add_mdmf(&fsk_data, mt, (uint8_t *) zchan->caller_data.cid_num, (uint8_t)strlen(zchan->caller_data.cid_num)); + zap_fsk_data_add_mdmf(&fsk_data, mt, (uint8_t *) zchan->caller_data.cid_num.digits, (uint8_t)strlen(zchan->caller_data.cid_num.digits)); if (zap_strlen_zero(zchan->caller_data.cid_name)) { mt = MDMF_NO_NAME; @@ -396,9 +396,9 @@ static void *zap_analog_channel_run(zap_thread_t *me, void *obj) sig.event_id = ZAP_SIGEVENT_START; if (zchan->type == ZAP_CHAN_TYPE_FXO) { - zap_set_string(zchan->caller_data.dnis, zchan->chan_number); + zap_set_string(zchan->caller_data.dnis.digits, zchan->chan_number); } else { - zap_set_string(zchan->caller_data.dnis, dtmf); + zap_set_string(zchan->caller_data.dnis.digits, dtmf); } analog_data->sig_cb(&sig); @@ -556,11 +556,11 @@ static void *zap_analog_channel_run(zap_thread_t *me, void *obj) zap_log(ZAP_LOG_ERROR, "Failure indication detected!\n"); zap_set_state_locked(zchan, ZAP_CHANNEL_STATE_BUSY); } else if (zchan->detected_tones[ZAP_TONEMAP_DIAL]) { - if (zap_strlen_zero(zchan->caller_data.ani)) { + if (zap_strlen_zero(zchan->caller_data.ani.digits)) { zap_log(ZAP_LOG_ERROR, "No Digits to send!\n"); zap_set_state_locked(zchan, ZAP_CHANNEL_STATE_BUSY); } else { - if (zap_channel_command(zchan, ZAP_COMMAND_SEND_DTMF, zchan->caller_data.ani) != ZAP_SUCCESS) { + if (zap_channel_command(zchan, ZAP_COMMAND_SEND_DTMF, zchan->caller_data.ani.digits) != ZAP_SUCCESS) { zap_log(ZAP_LOG_ERROR, "Send Digits Failed [%s]\n", zchan->last_error); zap_set_state_locked(zchan, ZAP_CHANNEL_STATE_BUSY); } else { @@ -570,7 +570,7 @@ static void *zap_analog_channel_run(zap_thread_t *me, void *obj) zchan->needed_tones[ZAP_TONEMAP_FAIL1] = 1; zchan->needed_tones[ZAP_TONEMAP_FAIL2] = 1; zchan->needed_tones[ZAP_TONEMAP_FAIL3] = 1; - dial_timeout = ((zchan->dtmf_on + zchan->dtmf_off) * strlen(zchan->caller_data.ani)) + 2000; + dial_timeout = ((zchan->dtmf_on + zchan->dtmf_off) * strlen(zchan->caller_data.ani.digits)) + 2000; } } } else if (zchan->detected_tones[ZAP_TONEMAP_RING]) { diff --git a/libs/freetdm/src/zap_io.c b/libs/freetdm/src/zap_io.c index 0c9af51e67..6ba6fec39d 100644 --- a/libs/freetdm/src/zap_io.c +++ b/libs/freetdm/src/zap_io.c @@ -669,6 +669,23 @@ zap_status_t zap_channel_set_state(zap_channel_t *zchan, zap_channel_state_t sta } if (ok) { + if (state == ZAP_CHANNEL_STATE_PROGRESS) { + zap_set_flag(zchan, ZAP_CHANNEL_PROGRESS); + } else if (state == ZAP_CHANNEL_STATE_UP) { + zap_set_flag(zchan, ZAP_CHANNEL_PROGRESS); + zap_set_flag(zchan, ZAP_CHANNEL_MEDIA); + zap_set_flag(zchan, ZAP_CHANNEL_ANSWERED); + } else if (state == ZAP_CHANNEL_STATE_PROGRESS_MEDIA) { + zap_set_flag(zchan, ZAP_CHANNEL_PROGRESS); + zap_set_flag(zchan, ZAP_CHANNEL_MEDIA); + } + + if (zchan->state == ZAP_CHANNEL_STATE_DOWN) { + zchan->span->active_count++; + } else if (state == ZAP_CHANNEL_STATE_DOWN) { + zchan->span->active_count--; + } + zap_set_flag(zchan, ZAP_CHANNEL_STATE_CHANGE); zap_set_flag(zchan->span, ZAP_SPAN_STATE_CHANGE); zchan->last_state = zchan->state; @@ -690,6 +707,12 @@ zap_status_t zap_channel_open_any(uint32_t span_id, zap_direction_t direction, c zap_mutex_lock(globals.mutex); + if (globals.spans[span_id].active_count >= globals.spans[span_id].chan_count) { + zap_log(ZAP_LOG_CRIT, "All circuits are busy.\n"); + *zchan = NULL; + goto done; + } + if (span_id && globals.spans[span_id].channel_request) { status = globals.spans[span_id].channel_request(&globals.spans[span_id], direction, caller_data, zchan); goto done; @@ -1587,14 +1610,14 @@ zap_status_t zap_channel_read(zap_channel_t *zchan, void *data, zap_size_t *data if (mlen > sizeof(zchan->caller_data.ani)) { mlen = sizeof(zchan->caller_data.ani); } - zap_set_string(zchan->caller_data.ani, str); - zap_set_string(zchan->caller_data.cid_num, zchan->caller_data.ani); + zap_set_string(zchan->caller_data.ani.digits, str); + zap_set_string(zchan->caller_data.cid_num.digits, zchan->caller_data.ani.digits); } break; case MDMF_NO_NUM: { - zap_set_string(zchan->caller_data.ani, *str == 'P' ? "private" : "unknown"); - zap_set_string(zchan->caller_data.cid_name, zchan->caller_data.ani); + zap_set_string(zchan->caller_data.ani.digits, *str == 'P' ? "private" : "unknown"); + zap_set_string(zchan->caller_data.cid_name, zchan->caller_data.ani.digits); } break; case MDMF_PHONE_NAME: diff --git a/libs/freetdm/src/zap_isdn.c b/libs/freetdm/src/zap_isdn.c index 34cef48467..8af35ef12a 100644 --- a/libs/freetdm/src/zap_isdn.c +++ b/libs/freetdm/src/zap_isdn.c @@ -220,10 +220,10 @@ static L3INT zap_isdn_931_34(void *pvt, L2UCHAR *msg, L2INT mlen) zchan->span->channels_remote_crv[gen->CRV] = zchan; memset(&zchan->caller_data, 0, sizeof(zchan->caller_data)); - zap_set_string(zchan->caller_data.cid_num, (char *)callingnum->Digit); + zap_set_string(zchan->caller_data.cid_num.digits, (char *)callingnum->Digit); zap_set_string(zchan->caller_data.cid_name, (char *)callingnum->Digit); - zap_set_string(zchan->caller_data.ani, (char *)callingnum->Digit); - zap_set_string(zchan->caller_data.dnis, (char *)callednum->Digit); + zap_set_string(zchan->caller_data.ani.digits, (char *)callingnum->Digit); + zap_set_string(zchan->caller_data.dnis.digits, (char *)callednum->Digit); zchan->caller_data.CRV = gen->CRV; if (cplen > sizeof(zchan->caller_data.raw_data)) { @@ -472,17 +472,17 @@ static __inline__ void state_advance(zap_channel_t *zchan) /* 10 User-provided, verified and failed */ /* 11 Network provided */ CallingNum.ScreenInd = 0; - CallingNum.Size = CallingNum.Size + (unsigned char)strlen(zchan->caller_data.cid_num); + CallingNum.Size = CallingNum.Size + (unsigned char)strlen(zchan->caller_data.cid_num.digits); gen->CallingNum = Q931AppendIE((L3UCHAR *) gen, (L3UCHAR *) &CallingNum); ptrCallingNum = Q931GetIEPtr(gen->CallingNum, gen->buf); - zap_copy_string((char *)ptrCallingNum->Digit, zchan->caller_data.cid_num, strlen(zchan->caller_data.cid_num)+1); + zap_copy_string((char *)ptrCallingNum->Digit, zchan->caller_data.cid_num.digits, strlen(zchan->caller_data.cid_num.digits)+1); CalledNum.TypNum = 2; CalledNum.NumPlanID = 1; - CalledNum.Size = CalledNum.Size + (unsigned char)strlen(zchan->caller_data.ani); + CalledNum.Size = CalledNum.Size + (unsigned char)strlen(zchan->caller_data.ani.digits); gen->CalledNum = Q931AppendIE((L3UCHAR *) gen, (L3UCHAR *) &CalledNum); ptrCalledNum = Q931GetIEPtr(gen->CalledNum, gen->buf); - zap_copy_string((char *)ptrCalledNum->Digit, zchan->caller_data.ani, strlen(zchan->caller_data.ani)+1); + zap_copy_string((char *)ptrCalledNum->Digit, zchan->caller_data.ani.digits, strlen(zchan->caller_data.ani.digits)+1); Q931Rx43(&isdn_data->q931, (L3UCHAR *) gen, gen->Size); zchan->span->channels_local_crv[gen->CRV] = zchan; diff --git a/libs/freetdm/src/zap_ss7_boost.c b/libs/freetdm/src/zap_ss7_boost.c index 1c51822afe..bd1507c9bd 100644 --- a/libs/freetdm/src/zap_ss7_boost.c +++ b/libs/freetdm/src/zap_ss7_boost.c @@ -53,7 +53,7 @@ typedef struct { static ss7_boost_request_id_t current_request = 0; -static ss7_boost_request_t OUTBOUND_REQUESTS[ZAP_MAX_CHANNELS_SPAN] = {{ 0 }}; +static ss7_boost_request_t OUTBOUND_REQUESTS[MAX_PENDING_CALLS] = {{ 0 }}; static zap_mutex_t *request_mutex = NULL; static zap_mutex_t *signal_mutex = NULL; @@ -63,7 +63,7 @@ static ss7_boost_request_id_t next_request_id(void) ss7_boost_request_id_t r; zap_mutex_lock(request_mutex); - if (current_request == ZAP_MAX_CHANNELS_SPAN) { + if (current_request == MAX_PENDING_CALLS) { current_request = 0; } r = current_request++; @@ -90,31 +90,51 @@ static zap_channel_t *find_zchan(zap_span_t *span, ss7bc_event_t *event) static ZIO_CHANNEL_REQUEST_FUNCTION(ss7_boost_channel_request) { zap_ss7_boost_data_t *ss7_boost_data = span->signal_data; - zap_status_t status = ZAP_SUCCESS; - ss7_boost_request_id_t r = next_request_id(); + zap_status_t status = ZAP_FAIL; + ss7_boost_request_id_t r; ss7bc_event_t event = {0}; int sanity = 60000; - ss7bc_call_init(&event, caller_data->cid_num, caller_data->ani, r); + if (zap_test_flag(span, ZAP_SPAN_SUSPENDED)) { + zap_log(ZAP_LOG_CRIT, "SPAN is not online.\n"); + *zchan = NULL; + return ZAP_FAIL; + } + + if (span->active_count >= span->chan_count) { + zap_log(ZAP_LOG_CRIT, "All circuits are busy.\n"); + *zchan = NULL; + return ZAP_FAIL; + } + + r = next_request_id(); + + ss7bc_call_init(&event, caller_data->cid_num.digits, caller_data->ani.digits, r); + zap_set_string(event.redirection_string, caller_data->rdnis.digits); + + OUTBOUND_REQUESTS[r].status = BST_WAITING; OUTBOUND_REQUESTS[r].span = span; if (ss7bc_connection_write(&ss7_boost_data->mcon, &event) <= 0) { zap_log(ZAP_LOG_CRIT, "Failed to tx on ISUP socket [%s]\n", strerror(errno)); status = ZAP_FAIL; + *zchan = NULL; goto done; } - while(OUTBOUND_REQUESTS[r].status == BST_WAITING) { + while(zap_running() && OUTBOUND_REQUESTS[r].status == BST_WAITING) { zap_sleep(1); if (!--sanity) { status = ZAP_FAIL; + *zchan = NULL; goto done; } } if (OUTBOUND_REQUESTS[r].status == BST_READY) { *zchan = OUTBOUND_REQUESTS[r].zchan; + status = ZAP_SUCCESS; } done: @@ -141,7 +161,7 @@ static void handle_call_start_ack(ss7bc_connection_t *mcon, ss7bc_event_t *event if (zap_channel_open_chan(zchan) != ZAP_SUCCESS) { zap_log(ZAP_LOG_ERROR, "OPEN ERROR [%s]\n", zchan->last_error); } else { - zap_set_state_locked(zchan, ZAP_CHANNEL_STATE_DIALING); + zap_set_state_locked(zchan, ZAP_CHANNEL_STATE_PROGRESS_MEDIA); OUTBOUND_REQUESTS[event->call_setup_id].zchan = zchan; return; } @@ -152,7 +172,7 @@ static void handle_call_start_ack(ss7bc_connection_t *mcon, ss7bc_event_t *event event->chan, event->call_setup_id, SIGBOOST_EVENT_CALL_STOPPED, - 0); + ZAP_CAUSE_DESTINATION_OUT_OF_ORDER); OUTBOUND_REQUESTS[event->call_setup_id].status = BST_FAIL; } @@ -175,14 +195,23 @@ static void handle_call_stop(zap_span_t *span, ss7bc_connection_t *mcon, ss7bc_e zap_channel_t *zchan; if ((zchan = find_zchan(span, event))) { + zchan->caller_data.hangup_cause = event->release_cause; zap_set_state_locked(zchan, ZAP_CHANNEL_STATE_TERMINATING); + + ss7bc_exec_command(mcon, + event->span, + event->chan, + 0, + SIGBOOST_EVENT_CALL_STOPPED_ACK, + 0); + } else { ss7bc_exec_command(mcon, event->span, event->chan, 0, SIGBOOST_EVENT_CALL_STOPPED, - 0); + ZAP_CAUSE_DESTINATION_OUT_OF_ORDER); } } @@ -198,7 +227,7 @@ static void handle_call_answer(zap_span_t *span, ss7bc_connection_t *mcon, ss7bc event->chan, 0, SIGBOOST_EVENT_CALL_STOPPED, - 0); + ZAP_CAUSE_DESTINATION_OUT_OF_ORDER); } } @@ -206,46 +235,92 @@ static void handle_call_start(zap_span_t *span, ss7bc_connection_t *mcon, ss7bc_ { zap_channel_t *zchan; - if ((zchan = find_zchan(span, event))) { - ss7bc_exec_command(mcon, - event->span, - event->chan, - 0, - SIGBOOST_EVENT_CALL_START_ACK, - 0); - - zap_set_state_locked(zchan, ZAP_CHANNEL_STATE_RING); - } else { - ss7bc_exec_command(mcon, - event->span, - event->chan, - 0, - SIGBOOST_EVENT_CALL_START_NACK, - 0); + if (!(zchan = find_zchan(span, event))) { + goto error; } + + if (zap_channel_open_chan(zchan) != ZAP_SUCCESS) { + goto error; + } + + ss7bc_exec_command(mcon, + event->span, + event->chan, + 0, + SIGBOOST_EVENT_CALL_START_ACK, + 0); + + zap_set_string(zchan->caller_data.cid_num.digits, (char *)event->calling_number_digits); + zap_set_string(zchan->caller_data.cid_name, (char *)event->calling_number_digits); + zap_set_string(zchan->caller_data.ani.digits, (char *)event->calling_number_digits); + zap_set_string(zchan->caller_data.dnis.digits, (char *)event->called_number_digits); + zap_set_string(zchan->caller_data.rdnis.digits, (char *)event->redirection_string); + zchan->caller_data.screen = event->calling_number_screening_ind; + zchan->caller_data.pres = event->calling_number_presentation; + zap_set_state_locked(zchan, ZAP_CHANNEL_STATE_RING); + return; + + error: + + ss7bc_exec_command(mcon, + event->span, + event->chan, + 0, + SIGBOOST_EVENT_CALL_START_NACK, + 0); + } static void handle_heartbeat(ss7bc_connection_t *mcon, ss7bc_event_t *event) { - int err = ss7bc_connection_write(mcon, event); + int err; + + err = ss7bc_connection_write(mcon, event); + if (err <= 0) { zap_log(ZAP_LOG_CRIT, "Failed to tx on ISUP socket [%s]: %s\n", strerror(errno)); } + + mcon->hb_elapsed = 0; return; } -static void handle_restart_ack(ss7bc_connection_t *mcon, ss7bc_event_t *event) +static void handle_restart_ack(ss7bc_connection_t *mcon, zap_span_t *span, ss7bc_event_t *event) { mcon->rxseq_reset = 0; + mcon->up = 1; + zap_set_state_all(span, ZAP_CHANNEL_STATE_RESTART); + zap_clear_flag_locked(span, ZAP_SPAN_SUSPENDED); + mcon->hb_elapsed = 0; } static int parse_ss7_event(zap_span_t *span, ss7bc_connection_t *mcon, ss7bc_event_t *event) { zap_mutex_lock(signal_mutex); + 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") + ); + + 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), @@ -260,6 +335,7 @@ static int parse_ss7_event(zap_span_t *span, ss7bc_connection_t *mcon, ss7bc_eve ); + switch(event->event_id) { case SIGBOOST_EVENT_CALL_START: @@ -293,7 +369,7 @@ static int parse_ss7_event(zap_span_t *span, ss7bc_connection_t *mcon, ss7bc_eve //handle_call_stop(event); break; case SIGBOOST_EVENT_SYSTEM_RESTART_ACK: - handle_restart_ack(mcon,event); + handle_restart_ack(mcon, span, event); break; case SIGBOOST_EVENT_AUTO_CALL_GAP_ABATE: //handle_gap_abate(event); @@ -303,6 +379,8 @@ static int parse_ss7_event(zap_span_t *span, ss7bc_connection_t *mcon, ss7bc_eve break; } + end: + zap_mutex_unlock(signal_mutex); return 0; @@ -316,9 +394,8 @@ static __inline__ void state_advance(zap_channel_t *zchan) zap_sigmsg_t sig; zap_status_t status; - zap_log(ZAP_LOG_ERROR, "%d:%d STATE [%s]\n", - zchan->span_id, zchan->chan_id, zap_channel_state2str(zchan->state)); - + zap_log(ZAP_LOG_DEBUG, "%d:%d STATE [%s]\n", zchan->span_id, zchan->chan_id, zap_channel_state2str(zchan->state)); + memset(&sig, 0, sizeof(sig)); sig.chan_id = zchan->chan_id; sig.span_id = zchan->span_id; @@ -330,15 +407,16 @@ static __inline__ void state_advance(zap_channel_t *zchan) zap_channel_done(zchan); } break; + case ZAP_CHANNEL_STATE_PROGRESS_MEDIA: case ZAP_CHANNEL_STATE_PROGRESS: { if (zap_test_flag(zchan, ZAP_CHANNEL_OUTBOUND)) { - sig.event_id = ZAP_SIGEVENT_PROGRESS; + sig.event_id = ZAP_SIGEVENT_PROGRESS_MEDIA; if ((status = ss7_boost_data->signal_cb(&sig) != ZAP_SUCCESS)) { zap_set_state_locked(zchan, ZAP_CHANNEL_STATE_HANGUP); } } else { - //send progress + } } break; @@ -357,18 +435,8 @@ static __inline__ void state_advance(zap_channel_t *zchan) { if (zchan->last_state > ZAP_CHANNEL_STATE_HANGUP) { zap_set_state_locked(zchan, ZAP_CHANNEL_STATE_HANGUP); - } - } - break; - case ZAP_CHANNEL_STATE_PROGRESS_MEDIA: - { - if (zap_test_flag(zchan, ZAP_CHANNEL_OUTBOUND)) { - sig.event_id = ZAP_SIGEVENT_PROGRESS_MEDIA; - if ((status = ss7_boost_data->signal_cb(&sig) != ZAP_SUCCESS)) { - zap_set_state_locked(zchan, ZAP_CHANNEL_STATE_HANGUP); - } } else { - // send alerting + zap_set_state_locked(zchan, ZAP_CHANNEL_STATE_DOWN); } } break; @@ -380,7 +448,12 @@ static __inline__ void state_advance(zap_channel_t *zchan) zap_set_state_locked(zchan, ZAP_CHANNEL_STATE_HANGUP); } } else { - // send connect + ss7bc_exec_command(mcon, + zchan->physical_span_id-1, + zchan->physical_chan_id-1, + 0, + SIGBOOST_EVENT_CALL_ANSWERED, + 0); } } break; @@ -395,7 +468,7 @@ static __inline__ void state_advance(zap_channel_t *zchan) zchan->physical_chan_id-1, 0, SIGBOOST_EVENT_CALL_STOPPED, - 0); + zchan->caller_data.hangup_cause); zap_set_state_locked(zchan, ZAP_CHANNEL_STATE_DOWN); } @@ -410,6 +483,10 @@ static __inline__ void state_advance(zap_channel_t *zchan) } } +static __inline__ void init_outgoing_array(void) +{ + memset(&OUTBOUND_REQUESTS, 0, sizeof(OUTBOUND_REQUESTS)); +} static __inline__ void check_state(zap_span_t *span) { @@ -429,13 +506,13 @@ static __inline__ void check_state(zap_span_t *span) } } - 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; + ss7_boost_data->pcon = ss7_boost_data->mcon; @@ -460,7 +537,9 @@ static void *zap_ss7_boost_run(zap_thread_t *me, void *obj) mcon = &ss7_boost_data->mcon; pcon = &ss7_boost_data->pcon; - mcon->rxseq_reset = 1; + top: + + init_outgoing_array(); ss7bc_exec_command(mcon, 0, @@ -471,7 +550,7 @@ static void *zap_ss7_boost_run(zap_thread_t *me, void *obj) while (zap_running() && zap_test_flag(ss7_boost_data, ZAP_SS7_BOOST_RUNNING)) { fd_set rfds, efds; - struct timeval tv = { 0, 100000 }; + struct timeval tv = { 0, ms * 1000 }; int max, activity, i = 0; ss7bc_event_t *event = NULL; @@ -488,28 +567,34 @@ static void *zap_ss7_boost_run(zap_thread_t *me, void *obj) goto error; } - if (!activity) { - continue; - } - - if (FD_ISSET(pcon->socket, &efds) || FD_ISSET(mcon->socket, &efds)) { - goto error; - } - - if (FD_ISSET(pcon->socket, &rfds)) { - if ((event = ss7bc_connection_readp(pcon, i))) { - parse_ss7_event(span, pcon, event); + if (activity) { + if (FD_ISSET(pcon->socket, &efds) || FD_ISSET(mcon->socket, &efds)) { + goto error; } - } - if (FD_ISSET(mcon->socket, &rfds)) { - if ((event = ss7bc_connection_read(mcon, i))) { - parse_ss7_event(span, mcon, event); + if (FD_ISSET(pcon->socket, &rfds)) { + if ((event = ss7bc_connection_readp(pcon, i))) { + parse_ss7_event(span, pcon, event); + } else goto top; + } + + if (FD_ISSET(mcon->socket, &rfds)) { + if ((event = ss7bc_connection_read(mcon, i))) { + parse_ss7_event(span, mcon, event); + } else goto top; } } check_state(span); + mcon->hb_elapsed += ms; + if (mcon->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"); + } + } goto end; @@ -568,7 +653,8 @@ zap_status_t zap_ss7_boost_configure_span(zap_span_t *span, span->signal_type = ZAP_SIGTYPE_SS7BOOST; span->outgoing_call = ss7_boost_outgoing_call; span->channel_request = ss7_boost_channel_request; - + zap_set_flag_locked(span, ZAP_SPAN_SUSPENDED); + return ZAP_SUCCESS; }