]> git.ipfire.org Git - thirdparty/freeswitch.git/commitdiff
freetdm: convert ftmod_isdn to use (+ pri_spans) to use ftdm_configure_span_signaling...
authorStefan Knoblich <s.knoblich@axsentis.de>
Sun, 14 Nov 2010 14:44:50 +0000 (15:44 +0100)
committerStefan Knoblich <s.knoblich@axsentis.de>
Sun, 14 Nov 2010 14:44:50 +0000 (15:44 +0100)
Signed-off-by: Stefan Knoblich <s.knoblich@axsentis.de>
libs/freetdm/mod_freetdm/mod_freetdm.c
libs/freetdm/src/ftmod/ftmod_isdn/ftmod_isdn.c

index 4fda283aebb284c23e7fdf10a6d0e07f25b8d390..aaddbf69f071ad3c57804faff5a6fefb2b27baa3 100755 (executable)
@@ -2923,102 +2923,49 @@ static switch_status_t load_config(void)
 
        if ((spans = switch_xml_child(cfg, "pri_spans"))) {
                for (myspan = switch_xml_child(spans, "span"); myspan; myspan = myspan->next) {
-                       char *id = (char *) switch_xml_attr(myspan, "id");
                        char *name = (char *) switch_xml_attr(myspan, "name");
+                       ftdm_conf_parameter_t spanparameters[10];
                        ftdm_status_t zstatus = FTDM_FAIL;
                        const char *context = "default";
                        const char *dialplan = "XML";
-                       //Q921NetUser_t mode = Q931_TE;
-                       //Q931Dialect_t dialect = Q931_Dialect_National;
-                       char *mode = NULL;
-                       char *dialect = NULL;
-                       uint32_t span_id = 0;
+                       unsigned paramindex = 0;
                        ftdm_span_t *span = NULL;
-                       const char *tonegroup = NULL;
-                       char *digit_timeout = NULL;
-                       const char *opts = "none";
-                       uint32_t to = 0;
-                       int q921loglevel = -1;
-                       int q931loglevel = -1;
-                       
-                       // quick debug
-                       //switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "ID: '%s', Name:'%s'\n",id,name);
+                       uint32_t span_id = 0;
 
-                       for (param = switch_xml_child(myspan, "param"); param; param = param->next) {
+                       if (!name) {
+                               switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "span missing required attribute 'name'\n");
+                               continue;
+                       }
+
+                       for (param = switch_xml_child(myspan, "param"); param && paramindex < 10; param = param->next) {
                                char *var = (char *) switch_xml_attr_soft(param, "name");
                                char *val = (char *) switch_xml_attr_soft(param, "value");
 
-                               if (!strcasecmp(var, "tonegroup")) {
-                                       tonegroup = val;
-                               } else if (!strcasecmp(var, "mode")) {
-                                       mode = val;
-                               } else if (!strcasecmp(var, "dialect")) {
-                                       dialect = val;
-                               } else if (!strcasecmp(var, "q921loglevel")) {
-                    if ((q921loglevel = switch_log_str2level(val)) == SWITCH_LOG_INVALID) {
-                        q921loglevel = -1;
-                    }
-                               } else if (!strcasecmp(var, "q931loglevel")) {
-                    if ((q931loglevel = switch_log_str2level(val)) == SWITCH_LOG_INVALID) {
-                        q931loglevel = -1;
-                    }
-                               } else if (!strcasecmp(var, "context")) {
+                               if (ftdm_array_len(spanparameters) == paramindex) {
+                                       ftdm_log(FTDM_LOG_ERROR, "Too many parameters for pri span '%s', ignoring everything after '%s'\n", name, var);
+                                       break;
+                               }
+
+                               if (!strcasecmp(var, "context")) {
                                        context = val;
-                               } else if (!strcasecmp(var, "opts")) {
-                                       opts = val;
                                } else if (!strcasecmp(var, "dialplan")) {
                                        dialplan = val;
-                               } else if (!strcasecmp(var, "digit_timeout") || !strcasecmp(var, "digit-timeout")) {
-                                       digit_timeout = val;
-                               }
-                       }
-       
-                       if (!id && !name) {
-                               switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "span missing required param 'id'\n");
-                               continue;
-                       }
-                       
-                       if (name) {
-                               zstatus = ftdm_span_find_by_name(name, &span);
-                       } else {
-                               if (switch_is_number(id)) {
-                                       span_id = atoi(id);
-                                       zstatus = ftdm_span_find(span_id, &span);
-                               }
-
-                               if (zstatus != FTDM_SUCCESS) {
-                                       zstatus = ftdm_span_find_by_name(id, &span);
+                               } else {
+                                       spanparameters[paramindex].var = var;
+                                       spanparameters[paramindex].val = val;
+                                       paramindex++;
                                }
                        }
 
-                       if (digit_timeout) {
-                               to = atoi(digit_timeout);
-                       }
-                       
+                       zstatus = ftdm_span_find_by_name(name, &span);
                        if (zstatus != FTDM_SUCCESS) {
-                               ftdm_log(FTDM_LOG_ERROR, "Error finding FreeTDM span id:%s name:%s\n", switch_str_nil(id), switch_str_nil(name));
+                               ftdm_log(FTDM_LOG_ERROR, "Error finding FreeTDM span %s\n", name);
                                continue;
                        }
 
-                       if (!span_id) {
-                               span_id = ftdm_span_get_id(span);
-                       }
-
-                       if (!tonegroup) {
-                               tonegroup = "us";
-                       }
-                       
-                       if (ftdm_configure_span(span, "isdn", on_clear_channel_signal, 
-                                                                  "mode", mode,
-                                                                  "dialect", dialect,
-                                                                  "digit_timeout", &to,
-                                                                  "opts", opts,
-                                                                  "tonemap", tonegroup,
-                                                                  "q921loglevel", q921loglevel,
-                                                                  "q931loglevel", q931loglevel,
-                                                                  FTDM_TAG_END) != FTDM_SUCCESS) {
-                               ftdm_log(FTDM_LOG_ERROR, "Error starting FreeTDM span %d mode: %s dialect: %s error: %s\n", span_id, 
-                                               mode, dialect, ftdm_span_get_last_error(span));
+                       span_id = ftdm_span_get_id(span);
+                       if (ftdm_configure_span_signaling(span, "isdn", on_clear_channel_signal, spanparameters) != FTDM_SUCCESS) {
+                               ftdm_log(FTDM_LOG_ERROR, "Error configuring FreeTDM span %s\n", name);
                                continue;
                        }
 
index 2b34552950fcdaada2ec8e00b6b51c449a8dbcd6..c5294bf1b2b5e5769888362340e7c77ad1b736f5 100644 (file)
 #define DEFAULT_NATIONAL_PREFIX        "0"
 #define DEFAULT_INTERNATIONAL_PREFIX   "00"
 
+static const char *ftdm_span_get_trunk_type_str(const ftdm_span_t *span)
+{
+       return ftdm_trunk_type2str(span->trunk_type);
+}
+
 /*****************************************************************************************
  * PCAP
  *          Based on Helmut Kuper's (<helmut.kuper@ewetel.de>) implementation,
@@ -2266,9 +2271,8 @@ static ftdm_status_t ftdm_isdn_start(ftdm_span_t *span)
 
 static int32_t parse_loglevel(const char *level)
 {
-       if (!level) {
+       if (!level)
                return -1;
-       }
 
        if (!strcasecmp(level, "debug")) {
                return FTDM_LOG_LEVEL_DEBUG;
@@ -2291,53 +2295,53 @@ static int32_t parse_loglevel(const char *level)
        }
 }
 
-static uint32_t parse_opts(const char *in)
+static int parse_opts(const char *in, uint32_t *flags)
 {
-       uint32_t flags = 0;
-
-       if (!in) {
-               return 0;
-       }
+       if (!in || !flags)
+               return -1;
 
        if (strstr(in, "suggest_channel")) {
-               flags |= FTDM_ISDN_OPT_SUGGEST_CHANNEL;
+               *flags |= FTDM_ISDN_OPT_SUGGEST_CHANNEL;
        }
-
        if (strstr(in, "omit_display")) {
-               flags |= FTDM_ISDN_OPT_OMIT_DISPLAY_IE;
+               *flags |= FTDM_ISDN_OPT_OMIT_DISPLAY_IE;
        }
-
        if (strstr(in, "disable_tones")) {
-               flags |= FTDM_ISDN_OPT_DISABLE_TONES;
+               *flags |= FTDM_ISDN_OPT_DISABLE_TONES;
        }
 
-       return flags;
+       return 0;
 }
 
-static uint32_t parse_dialect(const char *in)
+static int parse_dialect(const char *in, uint32_t *dialect)
 {
-       if (!in) {
-               return Q931_Dialect_Count;
-       }
+       if (!in || !dialect)
+               return -1;
 
 #if __UNSUPPORTED__
        if (!strcasecmp(in, "national")) {
-               return Q931_Dialect_National;
+               *dialect = Q931_Dialect_National;
+               return 0;
        }
        if (!strcasecmp(in, "dms")) {
-               return Q931_Dialect_DMS;
+               *dialect = Q931_Dialect_DMS;
+               return 0;
        }
 #endif
        if (!strcasecmp(in, "5ess")) {
-               return Q931_Dialect_5ESS;
+               *dialect = Q931_Dialect_5ESS;
+               return 0;
        }
-       if (!strcasecmp(in, "dss1")) {
-               return Q931_Dialect_DSS1;
+       if (!strcasecmp(in, "dss1") || !strcasecmp(in, "euroisdn")) {
+               *dialect = Q931_Dialect_DSS1;
+               return 0;
        }
        if (!strcasecmp(in, "q931")) {
-               return Q931_Dialect_Q931;
+               *dialect = Q931_Dialect_Q931;
+               return 0;
        }
-       return Q931_Dialect_Count;
+
+       return -1;
 }
 
 
@@ -2563,44 +2567,80 @@ done:
        return FTDM_SUCCESS;
 }
 
-static FIO_SIG_CONFIGURE_FUNCTION(isdn_configure_span)
+static int parse_mode(const char *mode)
+{
+       if (!mode)
+               return -1;
+
+       if (!strcasecmp(mode, "user") || !strcasecmp(mode, "cpe")) {
+               return Q931_TE;
+       }
+       if (!strcasecmp(mode, "net") || !strcasecmp(mode, "network")) {
+               return Q931_NT;
+       }
+
+       return -1;
+}
+
+static FIO_CONFIGURE_SPAN_SIGNALING_FUNCTION(isdn_configure_span)
 {
-       uint32_t i, x = 0;
-       ftdm_channel_t *dchans[2] = { 0 };
-       ftdm_isdn_data_t *isdn_data;
-       const char *tonemap = "us";
-       char *var, *val;
        Q931Dialect_t dialect = Q931_Dialect_National;
+       ftdm_channel_t *dchan = NULL;
+       ftdm_isdn_data_t *isdn_data;
        int32_t digit_timeout = 0;
+       const char *tonemap = "us";
+       int dchan_count = 0, bchan_count = 0;
        int q921loglevel = -1;
        int q931loglevel = -1;
+       uint32_t i;
 
        if (span->signal_type) {
-               snprintf(span->last_error, sizeof(span->last_error), "Span is already configured for signalling [%d].", span->signal_type);
+               ftdm_log(FTDM_LOG_ERROR, "Span is already configured for signalling [%d]\n", span->signal_type);
+               snprintf(span->last_error, sizeof(span->last_error), "Span is already configured for signalling [%d]", span->signal_type);
                return FTDM_FAIL;
        }
 
-       if (span->trunk_type >= FTDM_TRUNK_NONE) {
-               ftdm_log(FTDM_LOG_WARNING, "Invalid trunk type '%s' defaulting to T1.\n", ftdm_trunk_type2str(span->trunk_type));
+       if (ftdm_span_get_trunk_type(span) >= FTDM_TRUNK_NONE) {
+               ftdm_log(FTDM_LOG_WARNING, "Invalid trunk type '%s' defaulting to T1\n", ftdm_span_get_trunk_type_str(span));
                span->trunk_type = FTDM_TRUNK_T1;
        }
 
-       for(i = 1; i <= span->chan_count; i++) {
-               if (span->channels[i]->type == FTDM_CHAN_TYPE_DQ921) {
-                       if (x > 1) {
-                               snprintf(span->last_error, sizeof(span->last_error), "Span has more than 2 D-Channels!");
+       for (i = 1; i <= ftdm_span_get_chan_count(span); i++) {
+               ftdm_channel_t *chan = ftdm_span_get_channel(span, i);
+
+               switch (ftdm_channel_get_type(chan)) {
+               case FTDM_CHAN_TYPE_DQ921:
+                       if (dchan_count > 1) {
+                               ftdm_log(FTDM_LOG_ERROR, "Span has more than 1 D-Channel!\n");
+                               snprintf(span->last_error, sizeof(span->last_error), "Span has more than 1 D-Channel!");
                                return FTDM_FAIL;
                        }
 
-                       if (ftdm_channel_open(span->span_id, i, &dchans[x]) == FTDM_SUCCESS) {
-                               ftdm_log(FTDM_LOG_DEBUG, "opening d-channel #%d %d:%d\n", x, dchans[x]->span_id, dchans[x]->chan_id);
-                               dchans[x]->state = FTDM_CHANNEL_STATE_UP;
-                               x++;
+                       if (ftdm_channel_open(ftdm_span_get_id(span), i, &dchan) == FTDM_SUCCESS) {
+                               ftdm_log(FTDM_LOG_DEBUG, "opening d-channel #%d %d:%d\n", dchan_count,
+                                       ftdm_channel_get_span_id(dchan), ftdm_channel_get_id(dchan));
+                               dchan->state = FTDM_CHANNEL_STATE_UP;
                        }
+
+                       dchan_count++;
+                       break;
+
+               case FTDM_CHAN_TYPE_B:
+                       bchan_count++;
+                       break;
+
+               default:
+                       break;
                }
        }
-       if (!x) {
-               snprintf(span->last_error, sizeof(span->last_error), "Span has no D-Channels!");
+       if (!dchan_count) {
+               ftdm_log(FTDM_LOG_ERROR, "Span has no D-Channel!\n");
+               snprintf(span->last_error, sizeof(span->last_error), "Span has no D-Channel!");
+               return FTDM_FAIL;
+       }
+       if (!bchan_count) {
+               ftdm_log(FTDM_LOG_ERROR, "Span has no B-Channels!\n");
+               snprintf(span->last_error, sizeof(span->last_error), "Span has no B-Channels!");
                return FTDM_FAIL;
        }
 
@@ -2611,52 +2651,55 @@ static FIO_SIG_CONFIGURE_FUNCTION(isdn_configure_span)
        isdn_data->mode = Q931_TE;
        dialect = Q931_Dialect_Q931;
 
-       while((var = va_arg(ap, char *))) {
+       for (i = 0; ftdm_parameters[i].var; i++) {
+               const char *var = ftdm_parameters[i].var;
+               const char *val = ftdm_parameters[i].val;
+
+               if (!val) {
+                       ftdm_log(FTDM_LOG_ERROR, "Variable '%s' has no value\n", var);
+                       return FTDM_FAIL;
+               }
+
                if (!strcasecmp(var, "mode")) {
-                       if (!(val = va_arg(ap, char *))) {
-                               break;
+                       if ((isdn_data->mode = parse_mode(val)) < 0) {
+                               ftdm_log(FTDM_LOG_ERROR, "Invalid/unknown mode '%s'\n", val);
+                               snprintf(span->last_error, sizeof(span->last_error), "Invalid/unknown mode [%s]!", val);
+                               return FTDM_FAIL;
                        }
-                       isdn_data->mode = strcasecmp(val, "net") ? Q931_TE : Q931_NT;
                } else if (!strcasecmp(var, "dialect")) {
-                       if (!(val = va_arg(ap, char *))) {
-                               break;
-                       }
-                       dialect = parse_dialect(val);
-                       if (dialect == Q931_Dialect_Count) {
+                       if (parse_dialect(val, &dialect) < 0) {
+                               ftdm_log(FTDM_LOG_ERROR, "Invalid/unknown dialect '%s'\n", val);
                                snprintf(span->last_error, sizeof(span->last_error), "Invalid/unknown dialect [%s]!", val);
                                return FTDM_FAIL;
                        }
                } else if (!strcasecmp(var, "opts")) {
-                       if (!(val = va_arg(ap, char *))) {
-                               break;
+                       if (parse_opts(val, &isdn_data->opts) < 0) {
+                               ftdm_log(FTDM_LOG_ERROR, "Invalid/unknown options '%s'\n", val);
+                               snprintf(span->last_error, sizeof(span->last_error), "Invalid/unknown options [%s]!", val);
+                               return FTDM_FAIL;
                        }
-                       isdn_data->opts = parse_opts(val);
                } else if (!strcasecmp(var, "tonemap")) {
-                       if (!(val = va_arg(ap, char *))) {
-                               break;
-                       }
                        tonemap = (const char *)val;
                } else if (!strcasecmp(var, "digit_timeout")) {
-                       int *optp;
-                       if (!(optp = va_arg(ap, int *))) {
-                               break;
+                       digit_timeout = atoi(val);
+                       if (digit_timeout < 3000 || digit_timeout > 30000) {
+                               ftdm_log(FTDM_LOG_WARNING, "Digit timeout %d ms outside of range (3000 - 30000 ms), using default (10000 ms)\n", digit_timeout);
+                               digit_timeout = DEFAULT_DIGIT_TIMEOUT;
                        }
-                       digit_timeout = *optp;
                } else if (!strcasecmp(var, "q921loglevel")) {
-                       q921loglevel = va_arg(ap, int);
-                       if (q921loglevel < Q921_LOG_NONE) {
-                               q921loglevel = Q921_LOG_NONE;
-                       } else if (q921loglevel > Q921_LOG_DEBUG) {
-                               q921loglevel = Q921_LOG_DEBUG;
+                       if ((q921loglevel = parse_loglevel(val)) < 0) {
+                               ftdm_log(FTDM_LOG_ERROR, "Invalid/unknown loglevel '%s'\n", val);
+                               snprintf(span->last_error, sizeof(span->last_error), "Invalid/unknown loglevel [%s]!", val);
+                               return FTDM_FAIL;
                        }
                } else if (!strcasecmp(var, "q931loglevel")) {
-                       q931loglevel = va_arg(ap, int);
-                       if (q931loglevel < Q931_LOG_NONE) {
-                               q931loglevel = Q931_LOG_NONE;
-                       } else if (q931loglevel > Q931_LOG_DEBUG) {
-                               q931loglevel = Q931_LOG_DEBUG;
+                       if ((q931loglevel = parse_loglevel(val)) < 0) {
+                               ftdm_log(FTDM_LOG_ERROR, "Invalid/unknown loglevel '%s'\n", val);
+                               snprintf(span->last_error, sizeof(span->last_error), "Invalid/unknown loglevel [%s]!", val);
+                               return FTDM_FAIL;
                        }
                } else {
+                       ftdm_log(FTDM_LOG_ERROR, "Unknown parameter '%s'\n", var);
                        snprintf(span->last_error, sizeof(span->last_error), "Unknown parameter [%s]", var);
                        return FTDM_FAIL;
                }
@@ -2665,39 +2708,35 @@ static FIO_SIG_CONFIGURE_FUNCTION(isdn_configure_span)
        if (!digit_timeout) {
                digit_timeout = DEFAULT_DIGIT_TIMEOUT;
        }
-       else if (digit_timeout < 3000 || digit_timeout > 30000) {
-               ftdm_log(FTDM_LOG_WARNING, "Digit timeout %d ms outside of range (3000 - 30000 ms), using default (10000 ms)\n", digit_timeout);
-               digit_timeout = DEFAULT_DIGIT_TIMEOUT;
-       }
 
        /* allocate per b-chan data */
        if (isdn_data->mode == Q931_NT) {
                ftdm_isdn_bchan_data_t *data;
 
-               data = malloc(span->chan_count * sizeof(ftdm_isdn_bchan_data_t));
+               data = malloc(bchan_count * sizeof(ftdm_isdn_bchan_data_t));
                if (!data) {
                        return FTDM_FAIL;
                }
 
-               for (i = 1; i <= span->chan_count; i++, data++) {
-                       if (span->channels[i]->type == FTDM_CHAN_TYPE_B) {
-                               span->channels[i]->mod_data = data;
+               for (i = 1; i <= ftdm_span_get_chan_count(span); i++, data++) {
+                       ftdm_channel_t *chan = ftdm_span_get_channel(span, i);
+
+                       if (ftdm_channel_get_type(chan) == FTDM_CHAN_TYPE_B) {
+                               chan->mod_data = data;
                                memset(data, 0, sizeof(ftdm_isdn_bchan_data_t));
                        }
                }
        }
 
-       isdn_data->sig_cb    = sig_cb;
-       isdn_data->dchans[0] = dchans[0];
-       isdn_data->dchans[1] = dchans[1];
-       isdn_data->dchan     = isdn_data->dchans[0];
+       isdn_data->sig_cb = sig_cb;
+       isdn_data->dchan  = dchan;
        isdn_data->digit_timeout = digit_timeout;
 
        Q921_InitTrunk(&isdn_data->q921,
                                   0,
                                   0,
                                   isdn_data->mode,
-                                  span->trunk_type == FTDM_TRUNK_BRI_PTMP ? Q921_PTMP : Q921_PTP,
+                                  (ftdm_span_get_trunk_type(span) == FTDM_TRUNK_BRI_PTMP) ? Q921_PTMP : Q921_PTP,
                                   0,
                                   ftdm_isdn_921_21,
                                   (Q921Tx23CB_t)ftdm_isdn_921_23,
@@ -2798,7 +2837,7 @@ ftdm_module_t ftdm_module = {
        .io_unload     = NULL,
        .sig_load      = isdn_load,
        .sig_unload    = isdn_unload,
-       .sig_configure = isdn_configure_span
+       .configure_span_signaling = isdn_configure_span
 };
 
 /* For Emacs: