]> git.ipfire.org Git - thirdparty/freeswitch.git/commitdiff
some changes
authorAnthony Minessale <anthony.minessale@gmail.com>
Sat, 1 Mar 2008 00:48:36 +0000 (00:48 +0000)
committerAnthony Minessale <anthony.minessale@gmail.com>
Sat, 1 Mar 2008 00:48:36 +0000 (00:48 +0000)
git-svn-id: http://svn.openzap.org/svn/openzap/trunk@420 a93c3328-9c30-0410-af19-c9cd2b2d52af

libs/freetdm/mod_openzap/mod_openzap.c
libs/freetdm/src/include/openzap.h
libs/freetdm/src/include/ss7_boost_client.h
libs/freetdm/src/include/zap_types.h
libs/freetdm/src/ss7_boost_client.c
libs/freetdm/src/zap_analog.c
libs/freetdm/src/zap_io.c
libs/freetdm/src/zap_isdn.c
libs/freetdm/src/zap_ss7_boost.c

index fcd635434e2434a8568850c5b9bea82f8c808b6c..4763a52b8629eaad131819462430680da4bed608 100644 (file)
@@ -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;
                        }
index 67693b0c771f1c84fc47ad9eb5b83d6eb5996c88..6261e2e57fd8a6a8683127c2fa4832a12b8899f2 100644 (file)
@@ -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:
index c7ad5493ee928989294b24bab747117b16a6eec9..d2fee452bca47afb7e87c633a3bba55a80b96f6b 100644 (file)
 #include <stdarg.h>
 #include <netdb.h>
 #include <sigboost.h>
-#include <pthread.h>
 #include <sys/time.h>
 
-
-
-
 #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 {
index d1db4ed5e1752cf87be4e2413ee1cc5ac3d28be4..84b0243eca61e7626c859c0e440d7096f3fd41c5 100644 (file)
@@ -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:
index 254d10c3bf37434467b7a312046062778a915bc3..dc0151e2ab2a3f87e4a46a874bab45121b064e15 100644 (file)
@@ -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;
 }
index 63e360df10aa31d1268b2695eefba707528f585d..7e6027e06bbfceca2d46012c10cd6e6dff974805 100644 (file)
@@ -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]) {
index 0c9af51e6715b30438f74adf36f9bdb90b463503..6ba6fec39d67abcba151d123f89db5297635d2a8 100644 (file)
@@ -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:
index 34cef4846772c927c555c35d70e6bbe8550d01bd..8af35ef12ab6e39baec197c183cc90b21631483f 100644 (file)
@@ -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;
index 1c51822afee310c5dd607e6efcc95a92c77d8b96..bd1507c9bd28f58b974bcea85a1c89fb9e0d9c9a 100644 (file)
@@ -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);
+       if (!(zchan = find_zchan(span, event))) {
+               goto error;
+       }
 
-               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 (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 (activity) {
+                       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 (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);
+                       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;
 }