ftdm_status_t sngisdn_transfer(ftdm_channel_t *ftdmchan) { const char* args; char *p; char *type = NULL; char *target = NULL; ftdm_status_t status = FTDM_FAIL; sngisdn_chan_data_t *sngisdn_info = ftdmchan->call_data; unsigned i; args = ftdm_usrmsg_get_var(ftdmchan->usrmsg, "transfer_arg"); if (ftdm_strlen_zero(args)) { ftdm_log_chan_msg(ftdmchan, FTDM_LOG_ERROR, "Cannot perform transfer because call_transfer_arg variable is not set\n"); goto done; } type = ftdm_strdup(args); if ((p = strchr(type, '/'))) { target = ftdm_strdup(p+1); *p = '\0'; } if (ftdm_strlen_zero(type) || ftdm_strlen_zero(target)) { ftdm_log_chan(ftdmchan, FTDM_LOG_ERROR, "Invalid parameters for transfer %s, expected <type>/<target>\n", args); goto done; } if (sngisdn_info->transfer_data.type != SNGISDN_TRANSFER_NONE) { ftdm_log_chan(ftdmchan, FTDM_LOG_ERROR, "Cannot perform transfer because an existing transfer transfer is pending (%s)\n", sngisdn_transfer_type2str(sngisdn_info->transfer_data.type)); goto done; } ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "Transfer requested type:%s target:%s\n", type, target); for (i = 0; i < ftdm_array_len(transfer_interfaces); i++ ) { if (!strcasecmp(transfer_interfaces[i].name, type)) { /* Depending on the transfer type, the transfer function may change the * channel state to UP, or last_state, but the transfer function will always result in * an immediate state change if FTDM_SUCCESS is returned */ status = transfer_interfaces[i].func(ftdmchan, transfer_interfaces[i].type, target); goto done; } } ftdm_log_chan(ftdmchan, FTDM_LOG_ERROR, "Invalid transfer type:%s\n", type); done: if (status != FTDM_SUCCESS) { ftdm_set_state(ftdmchan, ftdmchan->last_state); } ftdm_safe_free(type); ftdm_safe_free(target); return status; }
ftdm_status_t sngisdn_add_var(sngisdn_chan_data_t *sngisdn_info, const char* var, const char* val) { char *t_name = 0, *t_val = 0; if (!var || !val) { return FTDM_FAIL; } if (!sngisdn_info->variables) { /* initialize on first use */ sngisdn_info->variables = create_hashtable(16, ftdm_hash_hashfromstring, ftdm_hash_equalkeys); ftdm_assert_return(sngisdn_info->variables, FTDM_FAIL, "Failed to create hash table\n"); } t_name = ftdm_strdup(var); t_val = ftdm_strdup(val); hashtable_insert(sngisdn_info->variables, t_name, t_val, HASHTABLE_FLAG_FREE_KEY | HASHTABLE_FLAG_FREE_VALUE); return FTDM_SUCCESS; }
static ftdm_status_t add_local_number(const char* val, ftdm_span_t *span) { sngisdn_span_data_t *signal_data = (sngisdn_span_data_t*) span->signal_data; if (signal_data->num_local_numbers >= SNGISDN_NUM_LOCAL_NUMBERS) { ftdm_log(FTDM_LOG_ERROR, "%s: Maximum number of local-numbers exceeded (max:%d)\n", span->name, SNGISDN_NUM_LOCAL_NUMBERS); return FTDM_FAIL; } signal_data->local_numbers[signal_data->num_local_numbers++] = ftdm_strdup(val); return FTDM_SUCCESS; }
// Commnand API entry point static FIO_API_FUNCTION(ftdm_gsm_api) { char *mycmd = NULL, *argv[10] = { 0 }; int argc = 0; int i; ftdm_status_t status = FTDM_FAIL; ftdm_status_t syntax = FTDM_FAIL; if (data) { mycmd = ftdm_strdup(data); argc = ftdm_separate_string(mycmd, ' ', argv, (sizeof(argv) / sizeof(argv[0]))); } if(argc > 0) { for(i=0;i<sizeof(GSM_COMMANDS)/sizeof(GSM_COMMANDS[0]);i++) { if(strcasecmp(argv[0],GSM_COMMANDS[i].CMD)==0) { if(argc -1 >= GSM_COMMANDS[i].Argc) { syntax = FTDM_SUCCESS; status = GSM_COMMANDS[i].Handler(stream, &argv[1], argc-1); } break; } } } if(FTDM_SUCCESS != syntax) { stream->write_function(stream, "%s", FT_SYNTAX); } else if(FTDM_SUCCESS != status) { stream->write_function(stream, "%s Command Failed\r\n", GSM_COMMANDS[i].CMD); } ftdm_safe_free(mycmd); return FTDM_SUCCESS; }
static FIO_API_FUNCTION(ftdm_pritap_api) { char *mycmd = NULL, *argv[10] = { 0 }; int argc = 0; if (data) { mycmd = ftdm_strdup(data); argc = ftdm_separate_string(mycmd, ' ', argv, (sizeof(argv) / sizeof(argv[0]))); } if (argc > 2) { if (!strcasecmp(argv[0], "debug")) { ftdm_span_t *span = NULL; if (ftdm_span_find_by_name(argv[1], &span) == FTDM_SUCCESS) { pritap_t *pritap = span->signal_data; if (span->start != ftdm_pritap_start) { stream->write_function(stream, "%s: -ERR invalid span.\n", __FILE__); goto done; } pri_set_debug(pritap->pri, parse_debug(argv[2])); stream->write_function(stream, "%s: +OK debug set.\n", __FILE__); goto done; } else { stream->write_function(stream, "%s: -ERR invalid span.\n", __FILE__); goto done; } } } stream->write_function(stream, "%s: -ERR invalid command.\n", __FILE__); done: ftdm_safe_free(mycmd); return FTDM_SUCCESS; }
/** * \brief Initialises an freetdm Wanpipe span from a configuration string * \param span FreeTDM span * \param str Configuration string * \param type FreeTDM span type * \param name FreeTDM span name * \param number FreeTDM span number * \return Success or failure */ static FIO_CONFIGURE_SPAN_FUNCTION(wanpipe_configure_span) { int items, i; char *mydata, *item_list[10]; char *sp, *ch, *mx; unsigned char cas_bits = 0; int channo; int spanno; int top = 0; unsigned configured = 0; assert(str != NULL); mydata = ftdm_strdup(str); assert(mydata != NULL); items = ftdm_separate_string(mydata, ',', item_list, (sizeof(item_list) / sizeof(item_list[0]))); for(i = 0; i < items; i++) { sp = item_list[i]; if ((ch = strchr(sp, ':'))) { *ch++ = '\0'; } if (!(sp && ch)) { ftdm_log(FTDM_LOG_ERROR, "No valid wanpipe span and channel was specified\n"); continue; } channo = atoi(ch); spanno = atoi(sp); if (channo < 0) { ftdm_log(FTDM_LOG_ERROR, "Invalid channel number %d\n", channo); continue; } if (spanno < 0) { ftdm_log(FTDM_LOG_ERROR, "Invalid span number %d\n", channo); continue; } if ((mx = strchr(ch, '-'))) { mx++; top = atoi(mx) + 1; } else { top = channo + 1; } if (top < 0) { ftdm_log(FTDM_LOG_ERROR, "Invalid range number %d\n", top); continue; } if (FTDM_CHAN_TYPE_CAS == type && ftdm_config_get_cas_bits(ch, &cas_bits)) { ftdm_log(FTDM_LOG_ERROR, "Failed to get CAS bits in CAS channel\n"); continue; } configured += wp_open_range(span, spanno, channo, top, type, name, number, cas_bits); } ftdm_safe_free(mydata); return configured; }
static ftdm_status_t parse_trunkgroup(const char *_trunkgroup) { int i; char *p, *name, *dchan_span, *backup_span, *trunkgroup; uint8_t num_spans = 0; ftdm_status_t ret = FTDM_SUCCESS; trunkgroup = ftdm_strdup(_trunkgroup); p = name = dchan_span = backup_span = NULL; /* format: name, num_chans, dchan_span, [backup_span] */ i = 0; for (p = strtok(trunkgroup, ","); p; p = strtok(NULL, ",")) { while (*p == ' ') { p++; } switch(i++) { case 0: name = ftdm_strdup(p); break; case 1: num_spans = atoi(p); break; case 2: dchan_span = ftdm_strdup(p); break; case 3: backup_span = ftdm_strdup(p); } } if (!name || !dchan_span || num_spans <= 0) { ftdm_log(FTDM_LOG_ERROR, "Invalid parameters for trunkgroup:%s\n", _trunkgroup); ret = FTDM_FAIL; goto done; } for (i = 0; i < g_sngisdn_data.num_nfas; i++) { if (!ftdm_strlen_zero(g_sngisdn_data.nfass[i].name) && !strcasecmp(g_sngisdn_data.nfass[i].name, name)) { /* We already configured this trunkgroup */ goto done; } } /* Trunk group was not found, need to configure it */ strncpy(g_sngisdn_data.nfass[i].name, name, sizeof(g_sngisdn_data.nfass[i].name)); g_sngisdn_data.nfass[i].num_spans = num_spans; strncpy(g_sngisdn_data.nfass[i].dchan_span_name, dchan_span, sizeof(g_sngisdn_data.nfass[i].dchan_span_name)); if (backup_span) { strncpy(g_sngisdn_data.nfass[i].backup_span_name, backup_span, sizeof(g_sngisdn_data.nfass[i].backup_span_name)); } g_sngisdn_data.num_nfas++; done: ftdm_safe_free(trunkgroup); ftdm_safe_free(name); ftdm_safe_free(dchan_span); ftdm_safe_free(backup_span); return ret; }
static ftdm_status_t parse_spanmap(const char *_spanmap, ftdm_span_t *span) { int i; char *p, *name, *spanmap; uint8_t logical_span_id = 0; ftdm_status_t ret = FTDM_SUCCESS; sngisdn_span_data_t *signal_data = (sngisdn_span_data_t*) span->signal_data; spanmap = ftdm_strdup(_spanmap); p = name = NULL; i = 0; for (p = strtok(spanmap, ","); p; p = strtok(NULL, ",")) { while (*p == ' ') { p++; } switch(i++) { case 0: name = ftdm_strdup(p); break; case 1: logical_span_id = atoi(p); break; } } if (!name) { ftdm_log(FTDM_LOG_ERROR, "Invalid spanmap syntax %s\n", _spanmap); ret = FTDM_FAIL; goto done; } for (i = 0; i < g_sngisdn_data.num_nfas; i++) { if (!ftdm_strlen_zero(g_sngisdn_data.nfass[i].name) && !strcasecmp(g_sngisdn_data.nfass[i].name, name)) { signal_data->nfas.trunk = &g_sngisdn_data.nfass[i]; break; } } if (!signal_data->nfas.trunk) { ftdm_log(FTDM_LOG_ERROR, "Could not find trunkgroup with name %s\n", name); ret = FTDM_FAIL; goto done; } if (signal_data->nfas.trunk->spans[logical_span_id]) { ftdm_log(FTDM_LOG_ERROR, "trunkgroup:%s already had a span with logical span id:%d\n", name, logical_span_id); } else { signal_data->nfas.trunk->spans[logical_span_id] = signal_data; signal_data->nfas.interface_id = logical_span_id; } if (!strcasecmp(signal_data->ftdm_span->name, signal_data->nfas.trunk->dchan_span_name)) { signal_data->nfas.sigchan = SNGISDN_NFAS_DCHAN_PRIMARY; signal_data->nfas.trunk->dchan = signal_data; } if (!strcasecmp(signal_data->ftdm_span->name, signal_data->nfas.trunk->backup_span_name)) { signal_data->nfas.sigchan = SNGISDN_NFAS_DCHAN_BACKUP; signal_data->nfas.trunk->backup = signal_data; } done: ftdm_safe_free(spanmap); ftdm_safe_free(name); return ret; }