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.
/* 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;
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)) {
{
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,
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;
}
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 = {
}
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));
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;
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;
/* 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);
}
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) {
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;