expand configurability of mod_wanpipe
git-svn-id: http://svn.freeswitch.org/svn/freeswitch/trunk@593 d0543943-73ff-0310-b7d9-9358b9ac24b2
This commit is contained in:
parent
109a721323
commit
0137fc0c02
|
@ -75,15 +75,24 @@ typedef enum {
|
||||||
static struct {
|
static struct {
|
||||||
int debug;
|
int debug;
|
||||||
int panic;
|
int panic;
|
||||||
int span;
|
|
||||||
int dchan;
|
|
||||||
int node;
|
|
||||||
int pswitch;
|
|
||||||
int bytes_per_frame;
|
int bytes_per_frame;
|
||||||
char *dialplan;
|
char *dialplan;
|
||||||
struct sangoma_pri *spri;
|
|
||||||
} globals;
|
} globals;
|
||||||
|
|
||||||
|
struct wanpipe_pri_span {
|
||||||
|
int span;
|
||||||
|
int dchan;
|
||||||
|
unsigned int bchans;
|
||||||
|
int node;
|
||||||
|
int pswitch;
|
||||||
|
char *dialplan;
|
||||||
|
unsigned int l1;
|
||||||
|
unsigned int dp;
|
||||||
|
struct sangoma_pri spri;
|
||||||
|
};
|
||||||
|
|
||||||
|
#define MAX_SPANS 128
|
||||||
|
static struct wanpipe_pri_span *SPANS[MAX_SPANS];
|
||||||
|
|
||||||
|
|
||||||
struct private_object {
|
struct private_object {
|
||||||
|
@ -146,6 +155,31 @@ static int str2switch(char *swtype)
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static int str2l1(char *l1)
|
||||||
|
{
|
||||||
|
if (!strcasecmp(l1, "alaw"))
|
||||||
|
return PRI_LAYER_1_ALAW;
|
||||||
|
|
||||||
|
return PRI_LAYER_1_ULAW;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int str2dp(char *dp)
|
||||||
|
{
|
||||||
|
if (!strcasecmp(dp, "international"))
|
||||||
|
return PRI_INTERNATIONAL_ISDN;
|
||||||
|
if (!strcasecmp(dp, "national"))
|
||||||
|
return PRI_NATIONAL_ISDN;
|
||||||
|
if (!strcasecmp(dp, "local"))
|
||||||
|
return PRI_LOCAL_ISDN;
|
||||||
|
if (!strcasecmp(dp, "private"))
|
||||||
|
return PRI_PRIVATE;
|
||||||
|
if (!strcasecmp(dp, "unknown"))
|
||||||
|
return PRI_UNKNOWN;
|
||||||
|
|
||||||
|
return PRI_UNKNOWN;
|
||||||
|
}
|
||||||
|
|
||||||
static const switch_endpoint_interface wanpipe_endpoint_interface;
|
static const switch_endpoint_interface wanpipe_endpoint_interface;
|
||||||
|
|
||||||
static void set_global_dialplan(char *dialplan);
|
static void set_global_dialplan(char *dialplan);
|
||||||
|
@ -248,14 +282,13 @@ static switch_status wanpipe_on_hangup(switch_core_session *session)
|
||||||
struct channel_map *chanmap;
|
struct channel_map *chanmap;
|
||||||
|
|
||||||
|
|
||||||
chanmap = globals.spri->private;
|
|
||||||
|
|
||||||
channel = switch_core_session_get_channel(session);
|
channel = switch_core_session_get_channel(session);
|
||||||
assert(channel != NULL);
|
assert(channel != NULL);
|
||||||
|
|
||||||
tech_pvt = switch_core_session_get_private(session);
|
tech_pvt = switch_core_session_get_private(session);
|
||||||
assert(tech_pvt != NULL);
|
assert(tech_pvt != NULL);
|
||||||
|
|
||||||
|
chanmap = tech_pvt->spri->private;
|
||||||
|
|
||||||
sangoma_socket_close(&tech_pvt->socket);
|
sangoma_socket_close(&tech_pvt->socket);
|
||||||
|
|
||||||
|
@ -318,61 +351,114 @@ static switch_status wanpipe_outgoing_channel(switch_core_session *session, swit
|
||||||
if (outbound_profile) {
|
if (outbound_profile) {
|
||||||
char name[128];
|
char name[128];
|
||||||
switch_caller_profile *caller_profile;
|
switch_caller_profile *caller_profile;
|
||||||
|
struct sangoma_pri *spri;
|
||||||
|
int span = 0, autospan = 0, autochan = 0;
|
||||||
|
char *num, *p;
|
||||||
|
int channo = 0;
|
||||||
|
struct channel_map *chanmap = NULL;
|
||||||
|
|
||||||
caller_profile = switch_caller_profile_clone(*new_session, outbound_profile);
|
caller_profile = switch_caller_profile_clone(*new_session, outbound_profile);
|
||||||
|
num = caller_profile->destination_number;
|
||||||
|
if ((p = strchr(num, '/'))) {
|
||||||
|
*p++ = '\0';
|
||||||
|
if (*num != 'a') {
|
||||||
|
span = atoi(num);
|
||||||
|
} else {
|
||||||
|
span = 1;
|
||||||
|
autospan = 1;
|
||||||
|
}
|
||||||
|
num = p;
|
||||||
|
if ((p = strchr(num, '/'))) {
|
||||||
|
*p++ = '\0';
|
||||||
|
if (*num == 'a') {
|
||||||
|
autochan = 1;
|
||||||
|
} else if (*num == 'A') {
|
||||||
|
autochan = -1;
|
||||||
|
} else {
|
||||||
|
channo = atoi(num);
|
||||||
|
}
|
||||||
|
caller_profile->destination_number = p;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
switch_channel_set_caller_profile(channel, caller_profile);
|
switch_channel_set_caller_profile(channel, caller_profile);
|
||||||
tech_pvt->caller_profile = caller_profile;
|
tech_pvt->caller_profile = caller_profile;
|
||||||
snprintf(name, sizeof(name), "WanPipe/%s-%04x", caller_profile->destination_number, rand() & 0xffff);
|
snprintf(name, sizeof(name), "WanPipe/%s-%04x", caller_profile->destination_number, rand() & 0xffff);
|
||||||
switch_channel_set_name(channel, name);
|
switch_channel_set_name(channel, name);
|
||||||
if ((tech_pvt->call = pri_new_call(globals.spri->pri))) {
|
|
||||||
struct pri_sr *sr;
|
|
||||||
struct channel_map *chanmap;
|
|
||||||
int channel = 0;
|
|
||||||
int mtu_mru;
|
|
||||||
wanpipe_tdm_api_t tdm_api;
|
|
||||||
|
|
||||||
chanmap = globals.spri->private;
|
do {
|
||||||
for(channel = 1; channel < SANGOMA_MAX_CHAN_PER_SPAN; channel++) {
|
if ((spri = &SPANS[span]->spri)) {
|
||||||
if (!chanmap->map[channel]) {
|
chanmap = spri->private;
|
||||||
switch_console_printf(SWITCH_CHANNEL_CONSOLE, "Choosing channel %d\n", channel);
|
if (channo == 0) {
|
||||||
|
if (autochan > 0) {
|
||||||
|
for(channo = 1; channo < SANGOMA_MAX_CHAN_PER_SPAN; channo++) {
|
||||||
|
if ((SPANS[span]->bchans & (1 << channo)) && !chanmap->map[channo]) {
|
||||||
|
switch_console_printf(SWITCH_CHANNEL_CONSOLE, "Choosing channel %d\n", channo);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if (autochan < 0) {
|
||||||
|
for(channo = SANGOMA_MAX_CHAN_PER_SPAN; channo > 0; channo--) {
|
||||||
|
if ((SPANS[span]->bchans & (1 << channo)) && !chanmap->map[channo]) {
|
||||||
|
switch_console_printf(SWITCH_CHANNEL_CONSOLE, "Choosing channel %d\n", channo);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (channo <= 0 || channo == (SANGOMA_MAX_CHAN_PER_SPAN)) {
|
||||||
|
switch_console_printf(SWITCH_CHANNEL_CONSOLE, "No Free Channels!\n");
|
||||||
|
channo = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (channo) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (channel == (SANGOMA_MAX_CHAN_PER_SPAN)) {
|
} while(autospan && span < MAX_SPANS && !spri && !channo);
|
||||||
switch_console_printf(SWITCH_CHANNEL_CONSOLE, "No Free Channels!\n");
|
|
||||||
switch_core_session_destroy(new_session);
|
|
||||||
return SWITCH_STATUS_GENERR;
|
if (!spri || channo == 0 || channo == (SANGOMA_MAX_CHAN_PER_SPAN)) {
|
||||||
}
|
switch_console_printf(SWITCH_CHANNEL_CONSOLE, "No Free Channels!\n");
|
||||||
|
switch_core_session_destroy(new_session);
|
||||||
|
return SWITCH_STATUS_GENERR;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (spri && (tech_pvt->call = pri_new_call(spri->pri))) {
|
||||||
|
struct pri_sr *sr;
|
||||||
|
int mtu_mru;
|
||||||
|
wanpipe_tdm_api_t tdm_api;
|
||||||
|
|
||||||
sr = pri_sr_new();
|
sr = pri_sr_new();
|
||||||
pri_sr_set_channel(sr, channel, 0, 0);
|
pri_sr_set_channel(sr, channo, 0, 0);
|
||||||
pri_sr_set_bearer(sr, 0, PRI_LAYER_1_ULAW);
|
pri_sr_set_bearer(sr, 0, SPANS[span]->l1);
|
||||||
pri_sr_set_called(sr, caller_profile->destination_number, PRI_NATIONAL_ISDN, 1);
|
pri_sr_set_called(sr, caller_profile->destination_number, SPANS[span]->dp, 1);
|
||||||
pri_sr_set_caller(sr,
|
pri_sr_set_caller(sr,
|
||||||
caller_profile->caller_id_number,
|
caller_profile->caller_id_number,
|
||||||
caller_profile->caller_id_name,
|
caller_profile->caller_id_name,
|
||||||
PRI_NATIONAL_ISDN,
|
SPANS[span]->dp,
|
||||||
PRES_ALLOWED_USER_NUMBER_PASSED_SCREEN);
|
PRES_ALLOWED_USER_NUMBER_PASSED_SCREEN);
|
||||||
pri_sr_set_redirecting(sr,
|
pri_sr_set_redirecting(sr,
|
||||||
caller_profile->caller_id_number,
|
caller_profile->caller_id_number,
|
||||||
PRI_NATIONAL_ISDN,
|
SPANS[span]->dp,
|
||||||
PRES_ALLOWED_USER_NUMBER_PASSED_SCREEN,
|
PRES_ALLOWED_USER_NUMBER_PASSED_SCREEN,
|
||||||
PRI_REDIR_UNCONDITIONAL);
|
PRI_REDIR_UNCONDITIONAL);
|
||||||
|
|
||||||
if (pri_setup(globals.spri->pri, tech_pvt->call , sr)) {
|
if (pri_setup(spri->pri, tech_pvt->call , sr)) {
|
||||||
switch_core_session_destroy(new_session);
|
switch_core_session_destroy(new_session);
|
||||||
pri_sr_free(sr);
|
pri_sr_free(sr);
|
||||||
return SWITCH_STATUS_GENERR;
|
return SWITCH_STATUS_GENERR;
|
||||||
}
|
}
|
||||||
if ((tech_pvt->socket = sangoma_create_socket_intr(globals.spri->span, channel)) < 0) {
|
if ((tech_pvt->socket = sangoma_create_socket_intr(spri->span, channo)) < 0) {
|
||||||
switch_console_printf(SWITCH_CHANNEL_CONSOLE, "Can't open fd!\n");
|
switch_console_printf(SWITCH_CHANNEL_CONSOLE, "Can't open fd!\n");
|
||||||
switch_core_session_destroy(new_session);
|
switch_core_session_destroy(new_session);
|
||||||
pri_sr_free(sr);
|
pri_sr_free(sr);
|
||||||
return SWITCH_STATUS_GENERR;
|
return SWITCH_STATUS_GENERR;
|
||||||
}
|
}
|
||||||
pri_sr_free(sr);
|
pri_sr_free(sr);
|
||||||
chanmap->map[channel] = *new_session;
|
chanmap->map[channo] = *new_session;
|
||||||
tech_pvt->spri = globals.spri;
|
tech_pvt->spri = spri;
|
||||||
|
|
||||||
mtu_mru = sangoma_tdm_get_usr_mtu_mru(tech_pvt->socket, &tdm_api);
|
mtu_mru = sangoma_tdm_get_usr_mtu_mru(tech_pvt->socket, &tdm_api);
|
||||||
switch_console_printf(SWITCH_CHANNEL_CONSOLE, "MTU is %d\n", mtu_mru);
|
switch_console_printf(SWITCH_CHANNEL_CONSOLE, "MTU is %d\n", mtu_mru);
|
||||||
|
@ -535,12 +621,16 @@ static const switch_loadable_module_interface wanpipe_module_interface = {
|
||||||
SWITCH_MOD_DECLARE(switch_status) switch_module_load(const switch_loadable_module_interface **interface, char *filename)
|
SWITCH_MOD_DECLARE(switch_status) switch_module_load(const switch_loadable_module_interface **interface, char *filename)
|
||||||
{
|
{
|
||||||
|
|
||||||
|
memset(SPANS, 0, sizeof(SPANS));
|
||||||
|
|
||||||
if (switch_core_new_memory_pool(&module_pool) != SWITCH_STATUS_SUCCESS) {
|
if (switch_core_new_memory_pool(&module_pool) != SWITCH_STATUS_SUCCESS) {
|
||||||
switch_console_printf(SWITCH_CHANNEL_CONSOLE, "OH OH no pool\n");
|
switch_console_printf(SWITCH_CHANNEL_CONSOLE, "OH OH no pool\n");
|
||||||
return SWITCH_STATUS_TERM;
|
return SWITCH_STATUS_TERM;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* start the pri's */
|
||||||
|
config_wanpipe(0);
|
||||||
|
|
||||||
/* connect my internal structure to the blank pointer passed to me */
|
/* connect my internal structure to the blank pointer passed to me */
|
||||||
*interface = &wanpipe_module_interface;
|
*interface = &wanpipe_module_interface;
|
||||||
|
|
||||||
|
@ -678,7 +768,7 @@ static int on_ring(struct sangoma_pri *spri, sangoma_pri_event_t event_type, pri
|
||||||
memset(tech_pvt, 0, sizeof(*tech_pvt));
|
memset(tech_pvt, 0, sizeof(*tech_pvt));
|
||||||
channel = switch_core_session_get_channel(session);
|
channel = switch_core_session_get_channel(session);
|
||||||
switch_core_session_set_private(session, tech_pvt);
|
switch_core_session_set_private(session, tech_pvt);
|
||||||
sprintf(name, "w%dg%d", globals.span, event->ring.channel);
|
sprintf(name, "w%dg%d", spri->span, event->ring.channel);
|
||||||
switch_channel_set_name(channel, name);
|
switch_channel_set_name(channel, name);
|
||||||
} else {
|
} else {
|
||||||
switch_console_printf(SWITCH_CHANNEL_CONSOLE, "Hey where is my memory pool?\n");
|
switch_console_printf(SWITCH_CHANNEL_CONSOLE, "Hey where is my memory pool?\n");
|
||||||
|
@ -784,24 +874,34 @@ static void *pri_thread_run(switch_thread *thread, void *obj)
|
||||||
|
|
||||||
spri->on_loop = check_flags;
|
spri->on_loop = check_flags;
|
||||||
spri->private = &chanmap;
|
spri->private = &chanmap;
|
||||||
globals.spri = spri;
|
|
||||||
sangoma_run_pri(spri);
|
sangoma_run_pri(spri);
|
||||||
|
|
||||||
free(spri);
|
free(spri);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void pri_thread_launch(struct sangoma_pri *spri)
|
||||||
|
{
|
||||||
|
switch_thread *thread;
|
||||||
|
switch_threadattr_t *thd_attr = NULL;
|
||||||
|
|
||||||
|
switch_threadattr_create(&thd_attr, module_pool);
|
||||||
|
switch_threadattr_detach_set(thd_attr, 1);
|
||||||
|
switch_thread_create(&thread, thd_attr, pri_thread_run, spri, module_pool);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
static int config_wanpipe(int reload)
|
static int config_wanpipe(int reload)
|
||||||
{
|
{
|
||||||
switch_config cfg;
|
switch_config cfg;
|
||||||
char *var, *val;
|
char *var, *val;
|
||||||
int count = 0;
|
int count = 0;
|
||||||
struct sangoma_pri *spri;
|
|
||||||
char *cf = "wanpipe.conf";
|
char *cf = "wanpipe.conf";
|
||||||
|
int current_span = 0;
|
||||||
|
|
||||||
globals.bytes_per_frame = DEFAULT_BYTES_PER_FRAME;
|
globals.bytes_per_frame = DEFAULT_BYTES_PER_FRAME;
|
||||||
|
|
||||||
|
|
||||||
if (!switch_config_open_file(&cfg, cf)) {
|
if (!switch_config_open_file(&cfg, cf)) {
|
||||||
switch_console_printf(SWITCH_CHANNEL_CONSOLE, "open of %s failed\n", cf);
|
switch_console_printf(SWITCH_CHANNEL_CONSOLE, "open of %s failed\n", cf);
|
||||||
return SWITCH_STATUS_TERM;
|
return SWITCH_STATUS_TERM;
|
||||||
|
@ -811,45 +911,98 @@ static int config_wanpipe(int reload)
|
||||||
if (!strcasecmp(cfg.category, "settings")) {
|
if (!strcasecmp(cfg.category, "settings")) {
|
||||||
if (!strcmp(var, "debug")) {
|
if (!strcmp(var, "debug")) {
|
||||||
globals.debug = atoi(val);
|
globals.debug = atoi(val);
|
||||||
} else if (!strcmp(var, "span")) {
|
|
||||||
globals.span = atoi(val);
|
|
||||||
} else if (!strcmp(var, "dchan")) {
|
|
||||||
globals.dchan = atoi(val);
|
|
||||||
} else if (!strcmp(var, "node")) {
|
|
||||||
globals.node = str2node(val);
|
|
||||||
} else if (!strcmp(var, "switch")) {
|
|
||||||
globals.pswitch = str2switch(val);
|
|
||||||
} else if (!strcmp(var, "bpf")) {
|
} else if (!strcmp(var, "bpf")) {
|
||||||
globals.bytes_per_frame = atoi(val);
|
globals.bytes_per_frame = atoi(val);
|
||||||
} else if (!strcmp(var, "dialplan")) {
|
}
|
||||||
set_global_dialplan(val);
|
} else if (!strcasecmp(cfg.category, "span")) {
|
||||||
|
if (!strcmp(var, "span")) {
|
||||||
|
current_span = atoi(val);
|
||||||
|
if (current_span <= 0 || current_span > MAX_SPANS) {
|
||||||
|
switch_console_printf(SWITCH_CHANNEL_CONSOLE, "Invalid SPAN!\n");
|
||||||
|
current_span = 0;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (!SPANS[current_span]) {
|
||||||
|
if (!(SPANS[current_span] = switch_core_alloc(module_pool, sizeof(*SPANS[current_span])))) {
|
||||||
|
switch_console_printf(SWITCH_CHANNEL_CONSOLE, "MEMORY ERROR\n");
|
||||||
|
break;;
|
||||||
|
}
|
||||||
|
SPANS[current_span]->span = current_span;
|
||||||
|
}
|
||||||
|
|
||||||
|
} else {
|
||||||
|
if (!current_span) {
|
||||||
|
switch_console_printf(SWITCH_CHANNEL_CONSOLE, "Invalid option %s when no span defined.\n", var);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!strcmp(var, "dchan")) {
|
||||||
|
SPANS[current_span]->dchan = atoi(val);
|
||||||
|
} else if (!strcmp(var, "bchan")) {
|
||||||
|
char from[128];
|
||||||
|
char *to;
|
||||||
|
switch_copy_string(from, val, sizeof(from));
|
||||||
|
if ((to = strchr(from, '-'))) {
|
||||||
|
int fromi, toi, x = 0;
|
||||||
|
*to++ = '\0';
|
||||||
|
fromi = atoi(from);
|
||||||
|
toi = atoi(to);
|
||||||
|
if (fromi > 0 && toi > 0 && fromi < toi && fromi < MAX_SPANS && toi < MAX_SPANS) {
|
||||||
|
for(x = fromi; x <= toi; x++) {
|
||||||
|
SPANS[current_span]->bchans |= (1 << x);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
switch_console_printf(SWITCH_CHANNEL_CONSOLE, "Invalid bchan range!\n");
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
int i = atoi(val);
|
||||||
|
if (i > 0 && i < 31) {
|
||||||
|
SPANS[current_span]->bchans |= (1 << i);
|
||||||
|
} else {
|
||||||
|
switch_console_printf(SWITCH_CHANNEL_CONSOLE, "Invalid bchan!\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if (!strcmp(var, "node")) {
|
||||||
|
SPANS[current_span]->node = str2node(val);
|
||||||
|
} else if (!strcmp(var, "switch")) {
|
||||||
|
SPANS[current_span]->pswitch = str2switch(val);
|
||||||
|
} else if (!strcmp(var, "dp")) {
|
||||||
|
SPANS[current_span]->dp = str2dp(val);
|
||||||
|
} else if (!strcmp(var, "l1")) {
|
||||||
|
SPANS[current_span]->l1 = str2l1(val);
|
||||||
|
} else if (!strcmp(var, "dialplan")) {
|
||||||
|
set_global_dialplan(val);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
switch_config_close_file(&cfg);
|
switch_config_close_file(&cfg);
|
||||||
|
|
||||||
if (!globals.dialplan) {
|
if (!globals.dialplan) {
|
||||||
set_global_dialplan("default");
|
set_global_dialplan("default");
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((spri = switch_core_alloc(module_pool, sizeof(*spri)))) {
|
for(current_span = 1; current_span < MAX_SPANS; current_span++) {
|
||||||
memset(spri, 0, sizeof(*spri));
|
if (SPANS[current_span]) {
|
||||||
sangoma_init_pri(spri, globals.span, globals.dchan, 23, globals.pswitch, globals.node, globals.debug);
|
switch_console_printf(SWITCH_CHANNEL_CONSOLE, "Launch span %d\n", current_span);
|
||||||
|
if (!SPANS[current_span]->l1) {
|
||||||
pri_thread_run(NULL, spri);
|
SPANS[current_span]->l1 = PRI_LAYER_1_ULAW;
|
||||||
|
}
|
||||||
} else {
|
sangoma_init_pri(&SPANS[current_span]->spri,
|
||||||
switch_console_printf(SWITCH_CHANNEL_CONSOLE, "error!\n");
|
current_span,
|
||||||
|
SPANS[current_span]->dchan,
|
||||||
|
SPANS[current_span]->pswitch,
|
||||||
|
SPANS[current_span]->node,
|
||||||
|
globals.debug);
|
||||||
|
pri_thread_launch(&SPANS[current_span]->spri);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
return count;
|
return count;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
SWITCH_MOD_DECLARE(switch_status) switch_module_runtime(void)
|
|
||||||
{
|
|
||||||
config_wanpipe(0);
|
|
||||||
return SWITCH_STATUS_TERM;
|
|
||||||
}
|
|
||||||
|
|
Loading…
Reference in New Issue