]> git.ipfire.org Git - thirdparty/freeswitch.git/commitdiff
freetdm: GSM read and write initialization
authorGideon Sadan <gsadan@sangoma.com>
Fri, 23 Dec 2011 00:31:28 +0000 (19:31 -0500)
committerMoises Silva <moy@sangoma.com>
Mon, 7 May 2012 19:11:58 +0000 (15:11 -0400)
libs/freetdm/src/ftmod/ftmod_gsm/ftmod_gsm.c

index f0b62e36acdc795c37a2372f6002325f715e3afa..23bb118270b31b3bc558038803f8f854e4580b84 100644 (file)
 #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;
-       
-       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,46 +478,33 @@ static FIO_CONFIGURE_SPAN_SIGNALING_FUNCTION(ftdm_gsm_configure_span_signaling)
        const char *var = NULL;
        const char *val = NULL;
 
-       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.");
+
+       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(gsm_data,0, sizeof(*gsm_data));
 
+       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_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_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;
        }
-       ftdm_log(FTDM_LOG_DEBUG, "Registered interface to WAT Library\n");
+       memset(gsm_data,0, sizeof(*gsm_data));
 
 
- /* */
 /* */
 
 
 
@@ -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(&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 */