]> git.ipfire.org Git - thirdparty/freeswitch.git/commitdiff
OPENZAP-238: [freetdm] Fix gsm signaling status reporting
authorMoises Silva <moy@sangoma.com>
Mon, 6 Jul 2015 01:31:34 +0000 (21:31 -0400)
committerMoises Silva <moy@sangoma.com>
Fri, 13 Nov 2015 07:57:39 +0000 (02:57 -0500)
libs/freetdm/src/ftmod/ftmod_gsm/ftmod_gsm.c
libs/freetdm/src/ftmod/ftmod_wanpipe/ftmod_wanpipe.c

index 341297daa8ae585541caa6e61ee622c529707e0b..6d8eb9f4310319597a4c40cc7f98c6abe6b80381 100755 (executable)
@@ -126,6 +126,7 @@ typedef struct ftdm_gsm_span_data_s {
        ftdm_bool_t startup_forwarding_disabled;
        char startup_commands[20][50];
        ftdm_gsm_flag_t flags;
+       ftdm_bool_t sig_up;
 } ftdm_gsm_span_data_t;
 
 // command handler function type.
@@ -188,17 +189,6 @@ static ftdm_io_interface_t g_ftdm_gsm_interface;
 /*                              implementation                                  */
 /*                                                                              */
 /********************************************************************************/
-static int read_channel(ftdm_channel_t *ftdm_chan , const void *buf, int size)
-{
-       ftdm_size_t outsize = size;
-       ftdm_status_t status = ftdm_channel_read(ftdm_chan, (void *)buf, &outsize);
-       if (FTDM_FAIL == status) {
-               return -1;
-       }
-       return (int)outsize;
-}
-
-
 static int on_wat_span_write(unsigned char span_id, void *buffer, unsigned len)
 {
        ftdm_span_t *span = NULL;
@@ -256,17 +246,14 @@ static void ftdm_gsm_enable_conditional_forwarding(void *data)
 
 static void on_wat_span_status(unsigned char span_id, wat_span_status_t *status)
 {
-       ftdm_span_t *span = NULL;
        ftdm_gsm_span_data_t *gsm_data = NULL;
-       if (!(span = get_span_by_id(span_id, &gsm_data))) {
-               return;
-       }
+       ftdm_span_t *span = get_span_by_id(span_id, &gsm_data);
 
        switch (status->type) {
        case WAT_SPAN_STS_READY:
                {
                        int i = 0;
-                       ftdm_log(FTDM_LOG_INFO, "span %d: Ready\n", span_id);
+                       ftdm_log(FTDM_LOG_INFO, "span %s: Ready\n", span->name);
                        for (i = 0; !ftdm_strlen_zero_buf(gsm_data->startup_commands[i]); i++) {
                                ftdm_log(FTDM_LOG_INFO, "span %d: Executing startup command '%s'\n", span_id, gsm_data->startup_commands[i]);
                                if (WAT_SUCCESS != wat_cmd_req(span_id, gsm_data->startup_commands[i], NULL, NULL)) {
@@ -279,8 +266,10 @@ static void on_wat_span_status(unsigned char span_id, wat_span_status_t *status)
                {
                        if (status->sts.sigstatus == WAT_SIGSTATUS_UP) {
                                ftdm_log_chan_msg(gsm_data->bchan, FTDM_LOG_INFO, "Signaling is now up\n");
+                               gsm_data->sig_up = FTDM_TRUE;
                        } else {
                                ftdm_log_chan_msg(gsm_data->bchan, FTDM_LOG_INFO, "Signaling is now down\n");
+                               gsm_data->sig_up = FTDM_FALSE;
                        }
                        if (gsm_data->init_conditional_forwarding == FTDM_TRUE && !ftdm_strlen_zero_buf(gsm_data->conditional_forward_number)) {
                                ftdm_sched_timer(gsm_data->sched, "conditional_forwarding_delay", 1000,
@@ -293,17 +282,17 @@ static void on_wat_span_status(unsigned char span_id, wat_span_status_t *status)
                break;
        case WAT_SPAN_STS_SIM_INFO_READY:
                {
-                       ftdm_log(FTDM_LOG_INFO, "span %d: SIM information ready\n", span_id);
+                       ftdm_log(FTDM_LOG_INFO, "span %s: SIM information ready\n", span->name);
                }
                break;
        case WAT_SPAN_STS_ALARM:
                {
-                       ftdm_log(FTDM_LOG_INFO, "span %d: Alarm received\n", span_id);
+                       ftdm_log(FTDM_LOG_INFO, "span %s: Alarm received\n", span->name);
                }
                break;
        default:
                {
-                       ftdm_log(FTDM_LOG_INFO, "span %d: Unhandled span status notification %d\n", span_id, status->type);
+                       ftdm_log(FTDM_LOG_INFO, "span %s: Unhandled span status notification %d\n", span->name, status->type);
                }
                break;
        }
@@ -621,31 +610,28 @@ static ftdm_status_t ftdm_gsm_destroy(ftdm_span_t *span)
 
 static FIO_CHANNEL_GET_SIG_STATUS_FUNCTION(ftdm_gsm_get_channel_sig_status)
 {
-       if (ftdm_test_flag(ftdmchan, FTDM_CHANNEL_SIG_UP)) {
-               *status = FTDM_SIG_STATE_UP;
-       }
-       else {
-               *status = FTDM_SIG_STATE_DOWN;
-       }
-       *status = FTDM_SIG_STATE_UP;
+       ftdm_gsm_span_data_t *gsm_data = ftdmchan->span->signal_data;
+       *status = gsm_data->sig_up ? FTDM_SIG_STATE_UP : FTDM_SIG_STATE_DOWN;
        return FTDM_SUCCESS;
-
 }
 
 static FIO_CHANNEL_SET_SIG_STATUS_FUNCTION(ftdm_gsm_set_channel_sig_status)
 {
-       return FTDM_SUCCESS;
+       ftdm_log(FTDM_LOG_ERROR, "You cannot set the signaling status for GSM channels (%s)\n", ftdmchan->span->name);
+       return FTDM_FAIL;
 }
 
 static FIO_SPAN_GET_SIG_STATUS_FUNCTION(ftdm_gsm_get_span_sig_status)
 {
-       *status = FTDM_SIG_STATE_UP;
+       ftdm_gsm_span_data_t *gsm_data = span->signal_data;
+       *status = gsm_data->sig_up ? FTDM_SIG_STATE_UP : FTDM_SIG_STATE_DOWN;
        return FTDM_SUCCESS;
 }
 
 static FIO_SPAN_SET_SIG_STATUS_FUNCTION(ftdm_gsm_set_span_sig_status)
 {
-       return FTDM_SUCCESS;
+       ftdm_log(FTDM_LOG_ERROR, "You cannot set the signaling status for GSM spans (%s)\n", span->name);
+       return FTDM_FAIL;
 }
 
 static ftdm_state_map_t gsm_state_map = {
@@ -913,6 +899,12 @@ static ftdm_status_t ftdm_gsm_state_advance(ftdm_channel_t *ftdmchan)
                }
                break;
 
+       case FTDM_CHANNEL_STATE_RESET:
+               {
+                       ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_DOWN);
+               }
+               break;
+
        default:
                {
                        ftdm_log_chan(ftdmchan, FTDM_LOG_ERROR, "Unhandled channel state: %s\n", ftdm_channel_state2str(ftdmchan->state));
@@ -1228,7 +1220,9 @@ static void *ftdm_gsm_run(ftdm_thread_t *me, void *obj)
        ftdm_interrupt_t *data_sources[2] = {NULL, NULL};
        ftdm_wait_flag_t flags = FTDM_READ | FTDM_EVENTS;
        ftdm_status_t status = FTDM_SUCCESS;
-       char buffer[1025] = { 0 };
+       ftdm_alarm_flag_t alarms;
+       char buffer[1024] = { 0 };
+       ftdm_size_t bufsize = 0;
        int waitms = 0;
        
        gsm_data = span->signal_data;
@@ -1244,6 +1238,19 @@ static void *ftdm_gsm_run(ftdm_thread_t *me, void *obj)
                goto done;
        }
 
+       /* Do not start if the link layer is not ready yet */
+       ftdm_channel_get_alarms(gsm_data->dchan, &alarms);
+       if (alarms != FTDM_ALARM_NONE) {
+               ftdm_log(FTDM_LOG_WARNING, "Delaying initialization of span %s until alarms are cleared\n", span->name);
+               while (ftdm_running() && ftdm_test_flag(gsm_data, FTDM_GSM_SPAN_STARTED) && alarms != FTDM_ALARM_NONE) {
+                       ftdm_channel_get_alarms(gsm_data->dchan, &alarms);
+                       ftdm_sleep(100);
+               }
+               if (!ftdm_running() || !ftdm_test_flag(gsm_data, FTDM_GSM_SPAN_STARTED)) {
+                       goto done;
+               }
+       }
+
        if (wat_span_start(span->span_id)) {
                ftdm_log(FTDM_LOG_ERROR, "Failed to start span %s!\n", span->name);
                goto done;
@@ -1264,14 +1271,16 @@ static void *ftdm_gsm_run(ftdm_thread_t *me, void *obj)
                /* check if this channel has a state change pending and process it if needed */
                ftdm_channel_lock(gsm_data->bchan);
                ftdm_channel_advance_states(gsm_data->bchan);
+
                if (FTDM_SUCCESS == status && (flags & FTDM_READ)) {
-                       int n = 0;
-                       n = read_channel(gsm_data->dchan, buffer, sizeof(buffer) - 1);
-                       if (n > 0) {
-                               wat_span_process_read(span->span_id, buffer, n);
+                       bufsize = sizeof(buffer);
+                       status = ftdm_channel_read(gsm_data->dchan, buffer, &bufsize);
+                       if (status == FTDM_SUCCESS && bufsize > 0) {
+                               wat_span_process_read(span->span_id, buffer, bufsize);
                                buffer[0] = 0;
                        }
                }
+
                ftdm_channel_advance_states(gsm_data->bchan);
                ftdm_channel_unlock(gsm_data->bchan);
 
index 0e8b73e9c0f28f6f9a22ce8baf0c06586330bbfa..58b5c9ca0ec3d7cc24fc9322a70fcb1c4896ef79 100755 (executable)
@@ -1394,13 +1394,11 @@ static FIO_GET_ALARMS_FUNCTION(wanpipe_get_alarms)
        }
 
        if (!ftdmchan->alarm_flags) {
-               if (FTDM_IS_DIGITAL_CHANNEL(ftdmchan)) {
-                       ftdm_channel_hw_link_status_t sangoma_status = 0;
-                       /* there is a bug in wanpipe where alarms were not properly set when they should be
-                        * on at application startup, until that is fixed we check the link status here too */
-                       ftdm_channel_command(ftdmchan, FTDM_COMMAND_GET_LINK_STATUS, &sangoma_status);
-                       ftdmchan->alarm_flags = sangoma_status == FTDM_HW_LINK_DISCONNECTED ? FTDM_ALARM_RED : FTDM_ALARM_NONE;
-               } 
+               /* there is a bug in wanpipe where alarms were not properly set when they should be
+                * on at application startup, until that is fixed we check the link status here too */
+               ftdm_channel_hw_link_status_t sangoma_status = 0;
+               ftdm_channel_command(ftdmchan, FTDM_COMMAND_GET_LINK_STATUS, &sangoma_status);
+               ftdmchan->alarm_flags = sangoma_status == FTDM_HW_LINK_DISCONNECTED ? FTDM_ALARM_RED : FTDM_ALARM_NONE;
        }
 
        if (alarms) {
@@ -1425,33 +1423,33 @@ static __inline__ ftdm_status_t wanpipe_channel_process_event(ftdm_channel_t *fc
        case WP_API_EVENT_LINK_STATUS:
                {
                        if (FTDM_IS_DIGITAL_CHANNEL(fchan)) {
-                       switch(tdm_api->wp_tdm_cmd.event.wp_tdm_api_event_link_status) {
-                       case WP_TDMAPI_EVENT_LINK_STATUS_CONNECTED:
-                               /* *event_id = FTDM_OOB_ALARM_CLEAR; */
-                               ftdm_log_chan_msg(fchan, FTDM_LOG_DEBUG, "Ignoring wanpipe link connected event\n");
-                               break;
-                       default:
-                               /* *event_id = FTDM_OOB_ALARM_TRAP; */
-                               ftdm_log_chan_msg(fchan, FTDM_LOG_DEBUG, "Ignoring wanpipe link disconnected event\n");
-                               break;
-                       };
-                       /* The WP_API_EVENT_ALARM event should be used to clear alarms */
-                       *event_id = FTDM_OOB_NOOP;
-                    } else {
-                       switch(tdm_api->wp_tdm_cmd.event.wp_tdm_api_event_link_status) {
-                       case WP_TDMAPI_EVENT_LINK_STATUS_CONNECTED:
-                               /* *event_id = FTDM_OOB_ALARM_CLEAR; */
-                               ftdm_log_chan_msg(fchan, FTDM_LOG_DEBUG, "Using analog link connected event as alarm clear\n");
-                               *event_id = FTDM_OOB_ALARM_CLEAR;
-                               fchan->alarm_flags = FTDM_ALARM_NONE;
-                               break;
-                       default:
-                               /* *event_id = FTDM_OOB_ALARM_TRAP; */
-                               ftdm_log_chan_msg(fchan, FTDM_LOG_DEBUG, "Using analog link disconnected event as alarm trap\n");
-                               *event_id = FTDM_OOB_ALARM_TRAP;
-                               fchan->alarm_flags = FTDM_ALARM_RED;
-                               break;
-                       };
+                               switch(tdm_api->wp_tdm_cmd.event.wp_tdm_api_event_link_status) {
+                               case WP_TDMAPI_EVENT_LINK_STATUS_CONNECTED:
+                                       /* *event_id = FTDM_OOB_ALARM_CLEAR; */
+                                       ftdm_log_chan_msg(fchan, FTDM_LOG_DEBUG, "Ignoring wanpipe link connected event\n");
+                                       break;
+                               default:
+                                       /* *event_id = FTDM_OOB_ALARM_TRAP; */
+                                       ftdm_log_chan_msg(fchan, FTDM_LOG_DEBUG, "Ignoring wanpipe link disconnected event\n");
+                                       break;
+                               }
+                               /* The WP_API_EVENT_ALARM event should be used to clear alarms */
+                               *event_id = FTDM_OOB_NOOP;
+                       } else {
+                               switch(tdm_api->wp_tdm_cmd.event.wp_tdm_api_event_link_status) {
+                               case WP_TDMAPI_EVENT_LINK_STATUS_CONNECTED:
+                                       /* *event_id = FTDM_OOB_ALARM_CLEAR; */
+                                       ftdm_log_chan_msg(fchan, FTDM_LOG_DEBUG, "Using analog link connected event as alarm clear\n");
+                                       *event_id = FTDM_OOB_ALARM_CLEAR;
+                                       fchan->alarm_flags = FTDM_ALARM_NONE;
+                                       break;
+                               default:
+                                       /* *event_id = FTDM_OOB_ALARM_TRAP; */
+                                       ftdm_log_chan_msg(fchan, FTDM_LOG_DEBUG, "Using analog link disconnected event as alarm trap\n");
+                                       *event_id = FTDM_OOB_ALARM_TRAP;
+                                       fchan->alarm_flags = FTDM_ALARM_RED;
+                                       break;
+                               }
                        }
                }
                break;