root/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_cfg.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. parse_yesno
  2. add_local_number
  3. parse_switchtype
  4. parse_signalling
  5. set_switchtype_defaults
  6. ftmod_isdn_parse_cfg

   1 /*
   2  * Copyright (c) 2010, Sangoma Technologies
   3  * David Yat Sin <davidy@sangoma.com>
   4  * All rights reserved.
   5  *
   6  * Redistribution and use in source and binary forms, with or without
   7  * modification, are permitted provided that the following conditions
   8  * are met:
   9  *
  10  * * Redistributions of source code must retain the above copyright
  11  * notice, this list of conditions and the following disclaimer.
  12  *
  13  * * Redistributions in binary form must reproduce the above copyright
  14  * notice, this list of conditions and the following disclaimer in the
  15  * documentation and/or other materials provided with the distribution.
  16  *
  17  * * Neither the name of the original author; nor the names of any contributors
  18  * may be used to endorse or promote products derived from this software
  19  * without specific prior written permission.
  20  *
  21  *
  22  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  23  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  24  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  25  * A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER
  26  * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
  27  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
  28  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
  29  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
  30  * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
  31  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  32  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  33  ******************************************************************************/
  34 
  35 #include "ftmod_sangoma_isdn.h"
  36 
  37 static ftdm_status_t parse_switchtype(const char* switch_name, ftdm_span_t *span);
  38 static ftdm_status_t parse_signalling(const char* signalling, ftdm_span_t *span);
  39 static ftdm_status_t add_local_number(const char* val, ftdm_span_t *span);
  40 static ftdm_status_t parse_yesno(const char* var, const char* val, uint8_t *target);
  41 static ftdm_status_t set_switchtype_defaults(ftdm_span_t *span);
  42 
  43 extern ftdm_sngisdn_data_t      g_sngisdn_data;
  44 
  45 static ftdm_status_t parse_yesno(const char* var, const char* val, uint8_t *target)
  46 {
  47         if (ftdm_true(val)) {
  48                 *target = SNGISDN_OPT_TRUE; 
  49         } else {
  50                 *target = SNGISDN_OPT_FALSE;
  51         }
  52         return FTDM_SUCCESS;
  53 }
  54 
  55 static ftdm_status_t add_local_number(const char* val, ftdm_span_t *span)
  56 {
  57         sngisdn_span_data_t *signal_data = (sngisdn_span_data_t*) span->signal_data;
  58 
  59         if (signal_data->num_local_numbers >= SNGISDN_NUM_LOCAL_NUMBERS) {
  60                 ftdm_log(FTDM_LOG_ERROR, "%s: Maximum number of local-numbers exceeded (max:%d)\n", span->name, SNGISDN_NUM_LOCAL_NUMBERS);
  61                 return FTDM_FAIL;
  62         }
  63         
  64         signal_data->local_numbers[signal_data->num_local_numbers++] = ftdm_strdup(val);
  65         return FTDM_SUCCESS;
  66 }
  67 
  68 static ftdm_status_t parse_switchtype(const char* switch_name, ftdm_span_t *span)
  69 {
  70         unsigned i;
  71         ftdm_iterator_t *chaniter = NULL;
  72         ftdm_iterator_t *curr = NULL;   
  73         sngisdn_dchan_data_t *dchan_data;
  74         sngisdn_span_data_t *signal_data = (sngisdn_span_data_t*) span->signal_data;
  75         
  76         switch(span->trunk_type) {
  77                 case FTDM_TRUNK_T1:
  78                         if (!strcasecmp(switch_name, "ni2") ||
  79                                 !strcasecmp(switch_name, "national")) {
  80                                 signal_data->switchtype = SNGISDN_SWITCH_NI2;
  81                         } else if (!strcasecmp(switch_name, "5ess")) {
  82                                 signal_data->switchtype = SNGISDN_SWITCH_5ESS;
  83                         } else if (!strcasecmp(switch_name, "4ess")) {
  84                                 signal_data->switchtype = SNGISDN_SWITCH_4ESS;
  85                         } else if (!strcasecmp(switch_name, "dms100")) {
  86                                 signal_data->switchtype = SNGISDN_SWITCH_DMS100;
  87                         } else {
  88                                 ftdm_log(FTDM_LOG_ERROR, "%s:Unsupported switchtype %s for trunktype:%s\n", span->name, switch_name, ftdm_trunk_type2str(span->trunk_type));
  89                                 return FTDM_FAIL;
  90                         }
  91                         break;
  92                 case FTDM_TRUNK_E1:
  93                         if (!strcasecmp(switch_name, "euroisdn") ||
  94                                 !strcasecmp(switch_name, "etsi")) {
  95                                 signal_data->switchtype = SNGISDN_SWITCH_EUROISDN;
  96                         } else if (!strcasecmp(switch_name, "qsig")) {
  97                                 signal_data->switchtype = SNGISDN_SWITCH_QSIG;
  98                         } else {
  99                                 ftdm_log(FTDM_LOG_ERROR, "%s:Unsupported switchtype %s for trunktype:%s\n", span->name, switch_name, ftdm_trunk_type2str(span->trunk_type));
 100                                 return FTDM_FAIL;
 101                         }
 102                         break;
 103                 case FTDM_TRUNK_BRI:
 104                 case FTDM_TRUNK_BRI_PTMP:
 105                         if (!strcasecmp(switch_name, "euroisdn") ||
 106                                 !strcasecmp(switch_name, "etsi")) {
 107                                 signal_data->switchtype = SNGISDN_SWITCH_EUROISDN;
 108                         } else if (!strcasecmp(switch_name, "insnet") ||
 109                                                 !strcasecmp(switch_name, "ntt")) {
 110                                 signal_data->switchtype = SNGISDN_SWITCH_INSNET;
 111                         } else {
 112                                 ftdm_log(FTDM_LOG_ERROR, "%s:Unsupported switchtype %s for trunktype:%s\n", span->name, switch_name, ftdm_trunk_type2str(span->trunk_type));
 113                                 return FTDM_FAIL;
 114                         }
 115                         ftdm_set_flag(span, FTDM_SPAN_USE_AV_RATE);
 116                         ftdm_set_flag(span, FTDM_SPAN_PWR_SAVING);
 117                          /* can be > 1 for some BRI variants */
 118                         break;
 119                 default:
 120                         ftdm_log(FTDM_LOG_ERROR, "%s:Unsupported trunktype:%s\n", span->name, switch_name, ftdm_trunk_type2str(span->trunk_type));
 121                         return FTDM_FAIL;
 122         }
 123         /* see if we have profile with this switch_type already */
 124         for (i=1; i <= g_sngisdn_data.num_cc; i++) {
 125                 if (g_sngisdn_data.ccs[i].switchtype == signal_data->switchtype &&
 126                         g_sngisdn_data.ccs[i].trunktype == span->trunk_type) {
 127                         break;
 128                 }
 129         }
 130         /* need to create a new switch_type */
 131         if (i > g_sngisdn_data.num_cc) {
 132                 g_sngisdn_data.num_cc++;
 133                 g_sngisdn_data.ccs[i].switchtype = signal_data->switchtype;
 134                 g_sngisdn_data.ccs[i].trunktype = span->trunk_type;
 135                 ftdm_log(FTDM_LOG_DEBUG, "%s: New switchtype:%s  cc_id:%u\n", span->name, switch_name, i);
 136         }
 137 
 138         /* add this span to its ent_cc */
 139         signal_data->cc_id = i;
 140 
 141         /* create a new dchan */ /* for NFAS - no-dchan on b-channels-only links */
 142         g_sngisdn_data.num_dchan++;
 143         signal_data->dchan_id = g_sngisdn_data.num_dchan;
 144 
 145         dchan_data = &g_sngisdn_data.dchans[signal_data->dchan_id];
 146         dchan_data->num_spans++;
 147 
 148         signal_data->span_id = dchan_data->num_spans;
 149         dchan_data->spans[signal_data->span_id] = signal_data;
 150 
 151         g_sngisdn_data.spans[signal_data->link_id] = signal_data;
 152         
 153         ftdm_log(FTDM_LOG_DEBUG, "%s: cc_id:%d dchan_id:%d span_id:%d link_id:%d\n", span->name, signal_data->cc_id, signal_data->dchan_id, signal_data->span_id, signal_data->link_id);
 154 
 155         
 156         chaniter = ftdm_span_get_chan_iterator(span, NULL);
 157         for (curr = chaniter; curr; curr = ftdm_iterator_next(curr)) {
 158                 int32_t chan_id;
 159                 ftdm_channel_t *ftdmchan = (ftdm_channel_t*)ftdm_iterator_current(curr);
 160                 if (ftdmchan->type == FTDM_CHAN_TYPE_DQ921) {
 161                         /* set the d-channel */
 162                         signal_data->dchan = ftdmchan;
 163                 } else {
 164                         /* Add the channels to the span */
 165                         /* NFAS is not supported on E1, so span_id will always be 1 for E1 so this will work for E1 as well */
 166                         chan_id = ((signal_data->span_id-1)*NUM_T1_CHANNELS_PER_SPAN)+ftdmchan->physical_chan_id;
 167                         dchan_data->channels[chan_id] = (sngisdn_chan_data_t*)ftdmchan->call_data;
 168                         dchan_data->num_chans++;
 169                 }
 170         }
 171         ftdm_iterator_free(chaniter);
 172         return FTDM_SUCCESS;
 173 }
 174 
 175 static ftdm_status_t parse_signalling(const char* signalling, ftdm_span_t *span)
 176 {
 177         sngisdn_span_data_t *signal_data = (sngisdn_span_data_t*) span->signal_data;
 178         if (!strcasecmp(signalling, "net") ||
 179                 !strcasecmp(signalling, "pri_net")||
 180                 !strcasecmp(signalling, "bri_net")) {
 181 
 182                 signal_data->signalling = SNGISDN_SIGNALING_NET;
 183         } else if (!strcasecmp(signalling, "cpe") ||
 184                 !strcasecmp(signalling, "pri_cpe")||
 185                 !strcasecmp(signalling, "bri_cpe")) {
 186 
 187                 signal_data->signalling = SNGISDN_SIGNALING_CPE;
 188         } else {
 189                 ftdm_log(FTDM_LOG_ERROR, "Unsupported signalling/interface %s\n", signalling);
 190                 return FTDM_FAIL;
 191         }
 192         return FTDM_SUCCESS;
 193 }
 194 
 195 static ftdm_status_t set_switchtype_defaults(ftdm_span_t *span)
 196 {
 197         sngisdn_span_data_t *signal_data = (sngisdn_span_data_t*) span->signal_data;
 198         switch(signal_data->switchtype) {
 199                 case SNGISDN_SWITCH_NI2:
 200                 case SNGISDN_SWITCH_5ESS:
 201                 case SNGISDN_SWITCH_4ESS:
 202                 case SNGISDN_SWITCH_DMS100:
 203                         if (span->default_caller_data.dnis.plan >= FTDM_NPI_INVALID) {
 204                                 ftdm_set_npi("isdn", &span->default_caller_data.dnis.plan);
 205                         }
 206                         if (span->default_caller_data.dnis.type >= FTDM_TON_INVALID) {
 207                                 ftdm_set_ton("national", &span->default_caller_data.dnis.type);
 208                         }
 209                         if (span->default_caller_data.cid_num.plan >= FTDM_NPI_INVALID) {
 210                                 ftdm_set_npi("isdn", &span->default_caller_data.cid_num.plan);
 211                         }
 212                         if (span->default_caller_data.cid_num.type >= FTDM_TON_INVALID) {
 213                                 ftdm_set_ton("national", &span->default_caller_data.cid_num.type);
 214                         }
 215                         if (span->default_caller_data.rdnis.plan >= FTDM_NPI_INVALID) {
 216                                 ftdm_set_npi("isdn", &span->default_caller_data.rdnis.plan);
 217                         }
 218                         if (span->default_caller_data.rdnis.type >= FTDM_TON_INVALID) {
 219                                 ftdm_set_ton("national", &span->default_caller_data.rdnis.type);
 220                         }
 221                         break;
 222                 case SNGISDN_SWITCH_EUROISDN:
 223                 case SNGISDN_SWITCH_QSIG:
 224                 case SNGISDN_SWITCH_INSNET:
 225                         if (span->default_caller_data.dnis.plan >= FTDM_NPI_INVALID) {
 226                                 ftdm_set_npi("unknown", &span->default_caller_data.dnis.plan);
 227                         }
 228                         if (span->default_caller_data.dnis.type >= FTDM_TON_INVALID) {
 229                                 ftdm_set_ton("unknown", &span->default_caller_data.dnis.type);
 230                         }
 231                         if (span->default_caller_data.cid_num.plan >= FTDM_NPI_INVALID) {
 232                                 ftdm_set_npi("unknown", &span->default_caller_data.cid_num.plan);
 233                         }
 234                         if (span->default_caller_data.cid_num.type >= FTDM_TON_INVALID) {
 235                                 ftdm_set_ton("unknown", &span->default_caller_data.cid_num.type);
 236                         }
 237                         if (span->default_caller_data.rdnis.plan >= FTDM_NPI_INVALID) {
 238                                 ftdm_set_npi("unknown", &span->default_caller_data.rdnis.plan);
 239                         }
 240                         if (span->default_caller_data.rdnis.type >= FTDM_TON_INVALID) {
 241                                 ftdm_set_ton("unknown", &span->default_caller_data.rdnis.type);
 242                         }
 243                         break;
 244                 case SNGISDN_SWITCH_INVALID:
 245                 default:
 246                         ftdm_log(FTDM_LOG_ERROR, "Unsupported switchtype[%d]\n", signal_data->switchtype);
 247                         return FTDM_FAIL;
 248         }
 249         return FTDM_SUCCESS;
 250 }
 251 
 252 ftdm_status_t ftmod_isdn_parse_cfg(ftdm_conf_parameter_t *ftdm_parameters, ftdm_span_t *span)
 253 {
 254         unsigned paramindex;
 255         const char *var, *val;
 256         sngisdn_span_data_t *signal_data = (sngisdn_span_data_t*) span->signal_data;
 257         /* Set defaults here */
 258         signal_data->tei = 0;
 259         signal_data->min_digits = 8;
 260         signal_data->overlap_dial = SNGISDN_OPT_DEFAULT;
 261         signal_data->setup_arb = SNGISDN_OPT_DEFAULT;
 262         signal_data->facility_ie_decode = SNGISDN_OPT_DEFAULT;
 263         signal_data->ignore_cause_value = SNGISDN_OPT_DEFAULT;
 264         signal_data->timer_t3 = 8;
 265         signal_data->restart_opt = SNGISDN_OPT_DEFAULT;
 266         signal_data->link_id = span->span_id;
 267         
 268         span->default_caller_data.dnis.plan = FTDM_NPI_INVALID;
 269         span->default_caller_data.dnis.type = FTDM_TON_INVALID;
 270         span->default_caller_data.cid_num.plan = FTDM_NPI_INVALID;
 271         span->default_caller_data.cid_num.type = FTDM_TON_INVALID;
 272         span->default_caller_data.rdnis.plan = FTDM_NPI_INVALID;
 273         span->default_caller_data.rdnis.type = FTDM_TON_INVALID;
 274 
 275         span->default_caller_data.bearer_capability = IN_ITC_SPEECH;
 276         /* Cannot set default bearer_layer1 yet, as we do not know the switchtype */
 277         span->default_caller_data.bearer_layer1 = FTDM_INVALID_INT_PARM;
 278 
 279         for (paramindex = 0; ftdm_parameters[paramindex].var; paramindex++) {
 280                 ftdm_log(FTDM_LOG_DEBUG, "Sangoma ISDN key=value, %s=%s\n", ftdm_parameters[paramindex].var, ftdm_parameters[paramindex].val);
 281                 var = ftdm_parameters[paramindex].var;
 282                 val = ftdm_parameters[paramindex].val;
 283                 
 284                 if (!strcasecmp(var, "switchtype")) {
 285                         if (parse_switchtype(val, span) != FTDM_SUCCESS) {
 286                                 return FTDM_FAIL;
 287                         }
 288                         if (set_switchtype_defaults(span) != FTDM_SUCCESS) {
 289                                 return FTDM_FAIL;
 290                         }
 291                 } else if (!strcasecmp(var, "signalling") ||
 292                                    !strcasecmp(var, "interface")) {
 293                         if (parse_signalling(val, span) != FTDM_SUCCESS) {
 294                                 return FTDM_FAIL;
 295                         }
 296                 } else if (!strcasecmp(var, "tei")) {
 297                         uint8_t tei = atoi(val);
 298                         if (tei > 127) {
 299                                 ftdm_log(FTDM_LOG_ERROR, "Invalid TEI %d, valid values are (0-127)", tei);
 300                                 return FTDM_FAIL;
 301                         }
 302                         signal_data->tei = tei;
 303                 } else if (!strcasecmp(var, "overlap")) {
 304                         if (!strcasecmp(val, "yes")) {
 305                                 signal_data->overlap_dial = SNGISDN_OPT_TRUE;
 306                         } else if (!strcasecmp(val, "no")) {
 307                                 signal_data->overlap_dial = SNGISDN_OPT_FALSE;
 308                         } else {
 309                                 ftdm_log(FTDM_LOG_ERROR, "Invalid value for parameter:%s:%s\n", var, val);
 310                         }
 311                 } else if (!strcasecmp(var, "setup-arbitration")) {
 312                         parse_yesno(var, val, &signal_data->setup_arb);
 313                 } else if (!strcasecmp(var, "facility")) {
 314                         parse_yesno(var, val, &signal_data->facility);
 315                 } else if (!strcasecmp(var, "min_digits")) {
 316                         signal_data->min_digits = atoi(val);
 317                 } else if (!strcasecmp(var, "outbound-called-ton")) {
 318                         ftdm_set_ton(val, &span->default_caller_data.dnis.type);
 319                 } else if (!strcasecmp(var, "outbound-called-npi")) {
 320                         ftdm_set_npi(val, &span->default_caller_data.dnis.plan);
 321                 } else if (!strcasecmp(var, "outbound-calling-ton")) {
 322                         ftdm_set_ton(val, &span->default_caller_data.cid_num.type);
 323                 } else if (!strcasecmp(var, "outbound-calling-npi")) {
 324                         ftdm_set_npi(val, &span->default_caller_data.cid_num.plan);
 325                 } else if (!strcasecmp(var, "outbound-rdnis-ton")) {
 326                         ftdm_set_ton(val, &span->default_caller_data.rdnis.type);
 327                 } else if (!strcasecmp(var, "outbound-rdnis-npi")) {
 328                         ftdm_set_npi(val, &span->default_caller_data.rdnis.plan);
 329                 } else if (!strcasecmp(var, "outbound-bearer_cap")) {
 330                         ftdm_set_bearer_capability(val, (uint8_t*)&span->default_caller_data.bearer_capability);
 331                 } else if (!strcasecmp(var, "outbound-bearer_layer1")) {
 332                         ftdm_set_bearer_layer1(val, (uint8_t*)&span->default_caller_data.bearer_layer1);
 333                 } else if (!strcasecmp(var, "channel-restart-on-link-up")) {
 334                         parse_yesno(var, val, &signal_data->restart_opt);
 335                 } else if (!strcasecmp(var, "local-number")) {                  
 336                         if (add_local_number(val, span) != FTDM_SUCCESS) {
 337                                 return FTDM_FAIL;
 338                         }
 339                 } else if (!strcasecmp(var, "facility-timeout")) {
 340                         signal_data->facility_timeout = atoi(val);
 341                         if (signal_data->facility_timeout < 0) {
 342                                 signal_data->facility_timeout = 0;
 343                         }
 344                 } else if (!strcasecmp(var, "facility-ie-decode")) {
 345                         parse_yesno(var, val, &signal_data->facility_ie_decode);
 346                 } else if (!strcasecmp(var, "ignore-cause-value")) {
 347                         parse_yesno(var, val, &signal_data->ignore_cause_value);
 348                 } else if (!strcasecmp(var, "q931-raw-trace")) {
 349                         parse_yesno(var, val, &signal_data->raw_trace_q931);
 350                 } else if (!strcasecmp(var, "q921-raw-trace")) {
 351                         parse_yesno(var, val, &signal_data->raw_trace_q921);
 352                 } else {
 353                         ftdm_log(FTDM_LOG_WARNING, "Ignoring unknown parameter %s\n", ftdm_parameters[paramindex].var);
 354                 }
 355         }
 356         
 357         if (signal_data->switchtype == SNGISDN_SWITCH_INVALID) {
 358                 ftdm_log(FTDM_LOG_ERROR, "%s: switchtype not specified", span->name);
 359                 return FTDM_FAIL;
 360         }
 361         if (signal_data->signalling == SNGISDN_SIGNALING_INVALID) {
 362                 ftdm_log(FTDM_LOG_ERROR, "%s: signalling not specified", span->name);
 363                 return FTDM_FAIL;
 364         }
 365 
 366         if (span->default_caller_data.bearer_layer1 == FTDM_INVALID_INT_PARM) {
 367                 if (signal_data->switchtype == SNGISDN_SWITCH_EUROISDN) {
 368                         span->default_caller_data.bearer_layer1 = IN_UIL1_G711ULAW;
 369                 } else {
 370                         span->default_caller_data.bearer_layer1 = IN_UIL1_G711ALAW;
 371                 }
 372         }
 373         return FTDM_SUCCESS;
 374 }
 375 
 376 
 377 /******************************************************************************/
 378 /* For Emacs:
 379  * Local Variables:
 380  * mode:c
 381  * indent-tabs-mode:t
 382  * tab-width:4
 383  * c-basic-offset:4
 384  * End:
 385  * For VIM:
 386  * vim:set softtabstop=4 shiftwidth=4 tabstop=4:
 387  */

/* [<][>][^][v][top][bottom][index][help] */