freetdm: GSM read and write initialization
This commit is contained in:
parent
9cb67dd0c7
commit
f891fefcb1
|
@ -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(¤t, &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 */
|
||||
|
|
Loading…
Reference in New Issue