From f891fefcb166a3c5f054b3e88aac2225ca99435a Mon Sep 17 00:00:00 2001 From: Gideon Sadan Date: Thu, 22 Dec 2011 19:31:28 -0500 Subject: [PATCH] freetdm: GSM read and write initialization --- libs/freetdm/src/ftmod/ftmod_gsm/ftmod_gsm.c | 334 ++++++++++++++++--- 1 file changed, 287 insertions(+), 47 deletions(-) diff --git a/libs/freetdm/src/ftmod/ftmod_gsm/ftmod_gsm.c b/libs/freetdm/src/ftmod/ftmod_gsm/ftmod_gsm.c index f0b62e36ac..23bb118270 100644 --- a/libs/freetdm/src/ftmod/ftmod_gsm/ftmod_gsm.c +++ b/libs/freetdm/src/ftmod/ftmod_gsm/ftmod_gsm.c @@ -55,14 +55,85 @@ #include #include +#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; - - return res; +/* + 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; + + } 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,24 +236,73 @@ 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,12 +657,27 @@ 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); - + #endif /* deliver the actual channel events to the user now without any channel locking */ ftdm_span_trigger_signals(span); @@ -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 */