freetdm: GSM read and write initialization

This commit is contained in:
Gideon Sadan 2011-12-22 19:31:28 -05:00 committed by Moises Silva
parent 9cb67dd0c7
commit f891fefcb1
1 changed files with 287 additions and 47 deletions

View File

@ -55,14 +55,85 @@
#include <freetdm.h>
#include <private/ftdm_core.h>
#define MAX_SPANS 32
typedef struct ftdm_gsm_span_data_s {
ftdm_span_t *span;
fio_signal_cb_t sig_cb;
ftdm_conf_parameter_t *ftdm_parameters;
}ftdm_gsm_span_data_t;
static ftdm_gsm_span_data_t spans_info[MAX_SPANS];
static int n_spans_info = 0;
typedef struct ftdm_gsm_data_s {
wat_interface_t wat_interface;
} ftdm_gsm_data_t;
ftdm_span_t *get_span(int span_id);
ftdm_span_t *get_span(int span_id)
{
int i;
for(i=0; i< n_spans_info;i++)
{
if(spans_info[i].span->span_id == span_id) {
return spans_info[i].span;
}
}
return NULL;
}
ftdm_channel_t *get_channel(int span_id, int channel_id);
ftdm_channel_t *get_channel(int span_id, int channel_id)
{
ftdm_channel_t *ftdmchan = NULL;
ftdm_span_t * span = get_span(span_id);
if(!span){
return NULL;
}
ftdm_iterator_t *citer = ftdm_span_get_chan_iterator(span, NULL);
for ( ; citer; citer = ftdm_iterator_next(citer)) {
ftdmchan = ftdm_iterator_current(citer);
if(ftdmchan->chan_id == channel_id) {
ftdm_iterator_free(citer);
return ftdmchan;
}
}
ftdm_iterator_free(citer);
return NULL;
}
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;
}
/* wat callbacks */
void on_wat_sigstatus_change(unsigned char span_id, wat_sigstatus_t sigstatus);
void on_wat_span_alarm(unsigned char span_id, wat_alarm_t alarm);
@ -85,18 +156,30 @@ void on_wat_log_span(uint8_t span_id, uint8_t level, char *fmt, ...);
/* gsm_data->wat_interface.wat_log = on_log; */
/* gsm_data->wat_interface.wat_log_span = on_log_span; */
/* gsm_data->wat_interface.wat
_log_span = on_log_span; */
/* gsm_data->wat_interface.wat_malloc = on_wat_malloc;*/
/* gsm_data->wat_interface.wat_calloc = on_wat_calloc;*/
/* gsm_data->wat_interface.wat_free = on_wat_free;*/
/* gsm_data->wat_interface.wat_free = on_wat_frspanee;*/
int on_wat_span_write(unsigned char span_id, void *buffer, unsigned len)
{
int res = 0;
/*
ftdm_log(FTDM_LOG_DEBUG, "!!! on_wat_span_write(%d, %s, int)\n", span_id, buffer, len);
*/
ftdm_channel_t * ftdm_chan = get_channel(span_id, 2);
ftdm_size_t outsize = len;
ftdm_channel_lock(ftdm_chan);
ftdm_status_t status = ftdm_channel_write(ftdm_chan, (void *)buffer, len, &outsize);
ftdm_channel_unlock(ftdm_chan);
if (FTDM_FAIL == status) {
return -1;
}
return (int)outsize;
return res;
}
void on_wat_sigstatus_change(unsigned char span_id, wat_sigstatus_t sigstatus)
@ -109,7 +192,7 @@ void on_wat_sigstatus_change(unsigned char span_id, wat_sigstatus_t sigstatus)
void on_wat_span_alarm(unsigned char span_id, wat_alarm_t alrm)
{
fprintf(stdout, "span:%d Alarm received\n", span_id);
return;ftdm_log(FTDM_LOG_DEBUG, "Registered interface to WAT Library\n");
return;
}
void on_wat_con_ind(unsigned char span_id, uint8_t call_id, wat_con_event_t *con_event)
@ -153,23 +236,72 @@ void on_wat_sms_sts(unsigned char span_id, uint8_t sms_id, wat_sms_status_t *sta
void on_wat_log(uint8_t level, char *fmt, ...)
{
int ftdm_level;
va_list argptr;
va_start(argptr, fmt);
char buff[10001];
switch(level)
{
case WAT_LOG_CRIT: ftdm_level = FTDM_LOG_LEVEL_CRIT; break;
case WAT_LOG_ERROR: ftdm_level = FTDM_LOG_LEVEL_ERROR; break;
default:
case WAT_LOG_WARNING: ftdm_level = FTDM_LOG_LEVEL_WARNING; break;
case WAT_LOG_INFO: ftdm_level = FTDM_LOG_LEVEL_INFO; break;
case WAT_LOG_NOTICE: ftdm_level = FTDM_LOG_LEVEL_NOTICE; break;
case WAT_LOG_DEBUG: ftdm_level = FTDM_LOG_LEVEL_DEBUG; break;
};
vsprintf(buff, fmt, argptr);
ftdm_log(FTDM_PRE, ftdm_level, "WAT :%s", buff);
va_end(argptr);
}
void *on_wat_malloc(size_t size)
{
return NULL;
return ftdm_malloc(size);
}
void *on_wat_calloc(size_t nmemb, size_t size)
{
return NULL;
return ftdm_calloc(nmemb, size);
}
void on_wat_free(void *ptr)
{
ftdm_free(ptr);
}
void on_wat_log_span(uint8_t span_id, uint8_t level, char *fmt, ...)
{
int ftdm_level;
va_list argptr;
va_start(argptr, fmt);
char buff[10001];
switch(level)
{
case WAT_LOG_CRIT: ftdm_level = FTDM_LOG_LEVEL_CRIT; break;
case WAT_LOG_ERROR: ftdm_level = FTDM_LOG_LEVEL_ERROR; break;
default:
case WAT_LOG_WARNING: ftdm_level = FTDM_LOG_LEVEL_WARNING; break;
case WAT_LOG_INFO: ftdm_level = FTDM_LOG_LEVEL_INFO; break;
case WAT_LOG_NOTICE: ftdm_level = FTDM_LOG_LEVEL_NOTICE; break;
case WAT_LOG_DEBUG: ftdm_level = FTDM_LOG_LEVEL_DEBUG; break;
};
vsprintf(buff, fmt, argptr);
ftdm_log(FTDM_PRE, ftdm_level, "WAT span %d:%s", span_id, buff);
va_end(argptr);
}
@ -346,8 +478,26 @@ static FIO_CONFIGURE_SPAN_SIGNALING_FUNCTION(ftdm_gsm_configure_span_signaling)
const char *var = NULL;
const char *val = NULL;
if (n_spans_info >= MAX_SPANS) {
snprintf(span->last_error, sizeof(span->last_error), "MAX_SPANS Exceeded !!!\n");
ftdm_log(FTDM_LOG_DEBUG, span->last_error);
return FTDM_FAIL;
}
memset(&spans_info[n_spans_info], 0 ,sizeof(spans_info[n_spans_info]));
spans_info[n_spans_info].span = span;
spans_info[n_spans_info].sig_cb = sig_cb;
spans_info[n_spans_info].ftdm_parameters = ftdm_parameters;
n_spans_info ++;
ftdm_gsm_data_t *gsm_data = malloc(sizeof(*gsm_data));
if (!gsm_data) {
snprintf(span->last_error, sizeof(span->last_error), "Failed to allocate GSM data.");
return FTDM_FAIL;
}
@ -357,37 +507,6 @@ static FIO_CONFIGURE_SPAN_SIGNALING_FUNCTION(ftdm_gsm_configure_span_signaling)
/* */
ftdm_log(FTDM_LOG_DEBUG, "Registering interface to WAT Library...\n");
gsm_data->wat_interface.wat_sigstatus_change = on_wat_sigstatus_change;
gsm_data->wat_interface.wat_span_write = on_wat_span_write;
gsm_data->wat_interface.wat_log = on_wat_log;
gsm_data->wat_interface.wat_log_span = on_wat_log_span;
gsm_data->wat_interface.wat_malloc = on_wat_malloc;
gsm_data->wat_interface.wat_calloc = on_wat_calloc;
gsm_data->wat_interface.wat_free = on_wat_free;
gsm_data->wat_interface.wat_alarm = on_wat_span_alarm;
gsm_data->wat_interface.wat_con_ind = on_wat_con_ind;
gsm_data->wat_interface.wat_con_sts = on_wat_con_sts;
gsm_data->wat_interface.wat_rel_ind = on_wat_rel_ind;
gsm_data->wat_interface.wat_rel_cfm = on_wat_rel_cfm;
gsm_data->wat_interface.wat_sms_ind = on_wat_sms_ind;
gsm_data->wat_interface.wat_sms_sts = on_wat_sms_sts;
if (wat_register(&gsm_data->wat_interface)) {
snprintf(span->last_error, sizeof(span->last_error), "Failed to register WAT Library !!!\n");
ftdm_log(FTDM_LOG_DEBUG, "FAILED Registering interface to WAT Library...\n");
return FTDM_FAIL;
}
ftdm_log(FTDM_LOG_DEBUG, "Registered interface to WAT Library\n");
/* */
ftdm_assert_return(sig_cb != NULL, FTDM_FAIL, "No signaling cb provided\n");
@ -426,7 +545,7 @@ ftdm_log(FTDM_LOG_DEBUG, "Registering interface to WAT Library...\n");
span->signal_cb = sig_cb;
span->signal_type = FTDM_SIGTYPE_GSM;
span->signal_data = NULL; /* Gideon, plz fill me with gsm span specific data (you allocate and free) */
span->signal_data = gsm_data; /* Gideon, plz fill me with gsm span specific data (you allocate and free) */
span->outgoing_call = gsm_outgoing_call;
span->get_span_sig_status = ftdm_gsm_get_span_sig_status;
span->set_span_sig_status = ftdm_gsm_set_span_sig_status;
@ -442,6 +561,8 @@ ftdm_log(FTDM_LOG_DEBUG, "Registering interface to WAT Library...\n");
/* we can skip states (going straight from RING to UP) */
ftdm_set_flag(span, FTDM_SPAN_USE_SKIP_STATES);
#if 0
/* setup the scheduler (create if needed) */
snprintf(schedname, sizeof(schedname), "ftmod_r2_%s", span->name);
@ -449,6 +570,69 @@ ftdm_log(FTDM_LOG_DEBUG, "Registering interface to WAT Library...\n");
spanpvt->sched = r2data->sched;
#endif
ftdm_log(FTDM_LOG_DEBUG, "Registering interface to WAT Library...\n");
gsm_data->wat_interface.wat_sigstatus_change = on_wat_sigstatus_change;
gsm_data->wat_interface.wat_span_write = on_wat_span_write;
gsm_data->wat_interface.wat_log = on_wat_log;
gsm_data->wat_interface.wat_log_span = on_wat_log_span;
gsm_data->wat_interface.wat_malloc = on_wat_malloc;
gsm_data->wat_interface.wat_calloc = on_wat_calloc;
gsm_data->wat_interface.wat_free = on_wat_free;
gsm_data->wat_interface.wat_alarm = on_wat_span_alarm;
gsm_data->wat_interface.wat_con_ind = on_wat_con_ind;
gsm_data->wat_interface.wat_con_sts = on_wat_con_sts;
gsm_data->wat_interface.wat_rel_ind = on_wat_rel_ind;
gsm_data->wat_interface.wat_rel_cfm = on_wat_rel_cfm;
gsm_data->wat_interface.wat_sms_ind = on_wat_sms_ind;
gsm_data->wat_interface.wat_sms_sts = on_wat_sms_sts;
if (wat_register(&gsm_data->wat_interface)) {
snprintf(span->last_error, sizeof(span->last_error), "Failed to register WAT Library !!!\n");
ftdm_log(FTDM_LOG_DEBUG, "FAILED Registering interface to WAT Library...\n");
return FTDM_FAIL;
}
ftdm_log(FTDM_LOG_DEBUG, "Registered interface to WAT Library\n");
ftdm_log(FTDM_LOG_DEBUG, "Configuring span\n");
//sng_fd_t dev;
//sangoma_wait_obj_t *waitable;
//unsigned char wat_span_id;
wat_span_config_t _wat_span_config;
_wat_span_config.moduletype = WAT_MODULE_TELIT;
_wat_span_config.timeout_cid_num = 10;
if (wat_span_config(span->span_id, &_wat_span_config)) {
fprintf(stderr, "Failed to configure span!!\n");
return FTDM_FAIL;
}
fprintf(stdout, "Starting span\n");
if (wat_span_start(span->span_id)) {
fprintf(stderr, "Failed to start span!!\n");
return FTDM_FAIL;
}
return FTDM_SUCCESS;
}
@ -459,8 +643,13 @@ static void *ftdm_gsm_run(ftdm_thread_t *me, void *obj)
ftdm_span_t *span = (ftdm_span_t *) obj;
ftdm_iterator_t *chaniter = NULL;
ftdm_iterator_t *citer = NULL;
int waitms = 10;
int waitms = 10, i;
ftdm_status_t status;
short *poll_events = ftdm_malloc(sizeof(short) * span->chan_count);
unsigned next;
ftdm_log(FTDM_LOG_DEBUG, "GSM monitor thread for span %s started\n", span->name);
chaniter = ftdm_span_get_chan_iterator(span, NULL);
@ -468,8 +657,23 @@ static void *ftdm_gsm_run(ftdm_thread_t *me, void *obj)
ftdm_log(FTDM_LOG_CRIT, "Failed to allocate channel iterator for span %s!\n", span->name);
goto done;
}
ftdmchan = get_channel(span->span_id, 2);
if (ftdm_channel_open_chan(ftdmchan) != FTDM_SUCCESS) {
ftdm_log_chan(ftdmchan, FTDM_LOG_ERROR, "Failed to open channel during incoming call! [%s]\n", ftdmchan->last_error);
return NULL;
}
while (ftdm_running()) {
wat_span_run(span->span_id);
next = wat_span_schedule_next(span->span_id);
if(next < waitms) {
next = waitms;
}
#if 0
/* run any span timers */
ftdm_sched_run(r2data->sched);
@ -483,8 +687,8 @@ static void *ftdm_gsm_run(ftdm_thread_t *me, void *obj)
memset(poll_events, 0, sizeof(short)*span->chan_count);
citer = ftdm_span_get_chan_iterator(span, chaniter);
if (!citer) {
ftdm_log(FTDM_LOG_CRIT, "Failed to allocate channel iterator for span %s!\n", span->name);
goto done;
ftdm_log(Fshort *poll_events = ftdm_malloc(sizeof(short) * span->chan_count);TDM_LOG_CRIT, "Failed to allocate channel iterator for span %s!\n", span->name);
goto done;short *poll_events = ftdm_malloc(sizeof(short) * span->chan_count);
}
for (i = 0; citer; citer = ftdm_iterator_next(citer), i++) {
ftdmchan = ftdm_iterator_current(citer);
@ -497,7 +701,7 @@ static void *ftdm_gsm_run(ftdm_thread_t *me, void *obj)
status = ftdm_span_poll_event(span, waitms, poll_events);
/* run any span timers */
ftdm_sched_run(r2data->sched);
ftdm_sched_runshort *poll_events = ftdm_malloc(sizeof(short) * span->chan_count);(r2data->sched);
#endif
ftdm_sleep(waitms);
@ -513,6 +717,33 @@ static void *ftdm_gsm_run(ftdm_thread_t *me, void *obj)
ftdm_channel_advance_states(ftdmchan);
ftdm_channel_unlock(ftdmchan);
}
for(i=0;i< span->chan_count; i++)
poll_events[i] = FTDM_EVENTS;
poll_events[1] |= FTDM_READ;
status = ftdm_span_poll_event(span, next, poll_events);
if(FTDM_SUCCESS == status)
{
ftdm_channel_lock(ftdmchan);
ftdm_channel_t * ftdm_chan = get_channel(span->span_id, 2);
char buffer[11];
int n = read_channel(ftdm_chan , buffer, sizeof(buffer));
ftdm_channel_unlock(ftdmchan);
if(n > 0) {
wat_span_process_read(span->span_id, buffer, n);
/*
ftdm_log(FTDM_LOG_DEBUG, "!!! read_channel got %d bytes\n", n);
*/
}
else {
ftdm_sleep(waitms);
}
}
}
@ -544,6 +775,16 @@ static FIO_API_FUNCTION(ftdm_gsm_api)
uint8_t current = 0, revision = 0, age = 0;
wat_version(&current, &revision, &age);
stream->write_function(stream, "libwat GSM VERSION: %d.%d.%d\n", current, revision, age);
stream->write_function(stream, "+OK.\n");
goto done;
}
if (!strcasecmp(argv[0], "status")) {
/*wat_chip_info_t* chip_info = wat_span_get_chip_info(span->span_id); */
stream->write_function(stream, "+OK.\n");
goto done;
}
@ -571,7 +812,6 @@ static FIO_IO_LOAD_FUNCTION(ftdm_gsm_io_init)
return FTDM_SUCCESS;
}
static FIO_SIG_LOAD_FUNCTION(ftdm_gsm_init)
{
/* this is called on module load */