📄 config.c
字号:
/* config.c - chan_ss7 configuration
*
* Copyright (C) 2006, Sifira A/S.
*
* Author: Anders Baekgaard <ab@sifira.dk>
* Anders Baekgaard <ab@dicea.dk>
*
* This file is part of chan_ss7.
*
* chan_ss7 is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* chan_ss7 is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with chan_ss7; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include <errno.h>
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <time.h>
#include <sys/param.h>
#include <arpa/inet.h>
#include <sys/socket.h>
#include <unistd.h>
#include <fcntl.h>
#include <netdb.h>
#include <netinet/in.h>
#include <pthread.h>
#include <signal.h>
#include <sys/poll.h>
#include <sys/ioctl.h>
#include "asterisk/config.h"
#include "asterisk/logger.h"
#include "asterisk/strings.h"
#include "asterisk/abstract_jb.h"
#include "config.h"
int is_mtp3d = 0;
struct host* this_host;
int n_linksets;
struct linkset linksets[MAX_LINKSETS];
int n_links;
struct link links[MAX_LINKS];
int n_hosts;
struct host hosts[MAX_HOSTS];
int clusterlistenport;
/*! Global jitterbuffer configuration - by default, jb is disabled */
static struct ast_jb_conf default_jbconf =
{
.flags = 0,
.max_size = -1,
.resync_threshold = -1,
.impl = "",
};
static struct ast_jb_conf global_jbconf;
int is_combined_linkset(struct linkset* ls1, struct linkset* ls2)
{
if (ls1 == ls2)
return 1;
if ((ls1->combined && *ls1->combined) && ls2->combined &&
(strcmp(ls1->combined, ls2->combined) == 0))
return 1;
return 0;
}
static int load_config_jitter(struct ast_config *cfg)
{
struct ast_variable *v;
/* Copy the default jb config over global_jbconf */
memcpy(&global_jbconf, &default_jbconf, sizeof(struct ast_jb_conf));
v = ast_variable_browse(cfg, "jitter");
while(v != NULL) {
!ast_jb_read_conf(&global_jbconf, v->name, v->value);
v = v->next;
}
return 0;
}
struct ast_jb_conf *ss7_get_global_jbconf() {
return &global_jbconf;
}
/* Lookup linkset for destination point code */
struct linkset* find_linkset_for_dpc(int pc, int cic)
{
int i;
for (i = 0; i < n_linksets; i++)
if ((linksets[i].dpc == pc) && (cic >= linksets[i].first_cic) && (cic <= linksets[i].last_cic))
return &linksets[i];
return NULL;
}
struct linkset* lookup_linkset(char* name) {
int i;
for (i = 0; i < n_linksets; i++) {
if (!strcmp(linksets[i].name, name))
return &linksets[i];
}
return NULL;
}
static struct link* lookup_link(char* name) {
int i;
for (i = 0; i < n_links; i++) {
if (!strcmp(links[i].name, name))
return &links[i];
}
return NULL;
}
static struct host* lookup_host(char* name) {
int i;
for (i = 0; i < n_hosts; i++)
if (!strcmp(hosts[i].name, name))
return &hosts[i];
return NULL;
}
struct host* lookup_host_by_addr(struct in_addr addr)
{
int i, j;
for (i = 0; i < n_hosts; i++)
for (j = 0; j < hosts[i].n_ifs; j++)
if (memcmp(&hosts[i].ifs[j].addr, &addr, sizeof(addr)) == 0)
return &hosts[i];
return NULL;
}
struct host* lookup_host_by_id(int hostix)
{
if (hostix >= n_hosts)
return NULL;
return &hosts[hostix];
}
static int make_host_schannels(void)
{
int k;
struct link* llink = NULL;
if (this_host->n_spans == 0) {
ast_log(LOG_ERROR, "No links defined in configuration for host '%s'.\n", this_host->name);
return -1;
}
for (k = 0; k < this_host->n_spans; k++) {
struct link* link = this_host->spans[k].link;
int connector = this_host->spans[k].connector;
link->first_zapid = (connector-1) * 32 - (connector-1);
if (link->enabled) {
llink = link;
if ((link->schannel > 0) && (!link->remote))
this_host->schannels[this_host->n_schannels++] = link;
}
}
if (!llink) {
ast_log(LOG_ERROR, "No links enabled on host '%s'.\n", this_host->name);
return -1;
}
return 0;
}
static struct host* find_my_host(void)
{
struct host* host;
char buf[128];
gethostname(buf, sizeof(buf)-1);
if ((host = lookup_host(buf)) == NULL) {
ast_log(LOG_ERROR, "Unable to find host configuration for host '%s'.\n", buf);
}
return host;
}
static void show_config(void)
{
int i;
for (i = 0; i < n_hosts; i++) {
ast_log(LOG_DEBUG, "Host %s, links %d, ifs %d\n", hosts[i].name, hosts[i].n_spans, hosts[i].n_ifs);
}
}
static int load_config_linkset(struct ast_config *cfg, char* cat)
{
struct ast_variable *v;
char *context = "default";
char *language = "";
char *linkset_name = &cat[strlen("linkset-")];
struct linkset* linkset = &linksets[n_linksets];
int has_enabled = 0, has_context = 0, has_language = 0, has_hunt_policy = 0, has_use_connect = 0, has_enable_st = 0, has_subservice = 0;
int i;
if (n_linksets == MAX_LINKSETS) {
ast_log(LOG_ERROR, "Too many linksets defined. Max %d\n", MAX_LINKSETS);
return -1;
}
linkset->t35_value = 15000;
linkset->t35_action = 0;
linkset->context = NULL;
linkset->language = NULL;
linkset->n_schannels = 0;
linkset->dpc = 0;
linkset->dni_chunk_limit = 0;
linkset->loadshare = LOADSHARE_COMBINED_LINKSET;
linkset->inservice = 0;
linkset->combined = 0;
context = "default";
language = "";
v = ast_variable_browse(cfg, cat);
while(v != NULL) {
if(0 == strcasecmp(v->name, "context")) {
context = v->value;
has_context = 1;
} else if(0 == strcasecmp(v->name, "language")) {
language = v->value;
has_language = 1;
} else if(0 == strcasecmp(v->name, "variant")) { /* By lin.miao@openvox.cn */
if(0 == strcasecmp(v->value, "CHINA")) {
linkset->variant = CHINA_SS7;
} else if(0 == strcasecmp(v->value, "ITU")) {
linkset->variant = ITU_SS7;
} else {
ast_log(LOG_ERROR, "Error invalid SS7 variant '%s'.\n", v->value);
return -1;
}
} else if(0 == strcasecmp(v->name, "combined")) {
linkset->combined = strdup(v->value);
}
else if(0 == strcasecmp(v->name, "hunting_policy")) {
if(0 == strcasecmp(v->value, "odd_lru")) {
linkset->hunt_policy = HUNT_ODD_LRU;
} else if(0 == strcasecmp(v->value, "even_mru")) {
linkset->hunt_policy = HUNT_EVEN_MRU;
} else if(0 == strcasecmp(v->value, "seq_lth")) {
linkset->hunt_policy = HUNT_SEQ_LTH;
} else if(0 == strcasecmp(v->value, "seq_htl")) {
linkset->hunt_policy = HUNT_SEQ_HTL;
} else {
ast_log(LOG_ERROR, "Error invalid hunting policy '%s'.\n", v->value);
return -1;
}
has_hunt_policy = 1;
} else if(0 == strcasecmp(v->name, "enabled")) {
if ((strcasecmp(v->value, "yes") != 0) && (strcasecmp(v->value, "no") != 0)) {
ast_log(LOG_ERROR, "Invalid value '%s' for enabled entry for linkset '%s'.\n", v->value, linkset_name);
return -1;
}
linkset->enabled = strcasecmp(v->value, "yes") == 0;
has_enabled = 1;
} else if(0 == strcasecmp(v->name, "use_connect")) {
if ((strcasecmp(v->value, "yes") != 0) && (strcasecmp(v->value, "no") != 0)) {
ast_log(LOG_ERROR, "Invalid value '%s' for use_connect entry for linkset '%s'.\n", v->value, linkset_name);
return -1;
}
linkset->use_connect = strcasecmp(v->value, "yes") == 0;
has_use_connect = 1;
} else if(0 == strcasecmp(v->name, "enable_st")) {
if ((strcasecmp(v->value, "yes") != 0) && (strcasecmp(v->value, "no") != 0)) {
ast_log(LOG_ERROR, "Invalid value '%s' for enable_st entry for linkset '%s'.\n", v->value, linkset_name);
return -1;
}
linkset->enable_st = strcasecmp(v->value, "yes") == 0;
has_enable_st = 1;
} else if(0 == strcasecmp(v->name, "subservice")) {
if (strcasecmp(v->value, "auto") == 0) {
linkset->subservice = -1;
}
else if (strcasecmp(v->value, "international") == 0) {
linkset->subservice = 0;
}
else if (strcasecmp(v->value, "national") == 0) {
linkset->subservice = 0x8;
}
else if (strcasecmp(v->value, "local") == 0)
{
linkset->subservice = 0x18;
//ast_log(LOG_ERROR, "=======================Invalid value '%s' for subservice entry for linkset '%s'.\n", v->value, linkset_name);
}
else if(sscanf(v->value, "%i", &linkset->subservice) == 1) {}
else {
ast_log(LOG_ERROR, "Invalid value '%s' for subservice entry for linkset '%s'.\n", v->value, linkset_name);
return -1;
}
has_subservice = 1;
} else if(0 == strcasecmp(v->name, "loadshare")) {
if (strcasecmp(v->value, "none") == 0) {
linkset->loadshare = LOADSHARE_NONE;
}
else if (strcasecmp(v->value, "linkset") == 0) {
linkset->loadshare = LOADSHARE_LINKSET;
}
else if (strcasecmp(v->value, "combined") == 0) {
linkset->loadshare = LOADSHARE_COMBINED_LINKSET;
}
else {
ast_log(LOG_ERROR, "Invalid value '%s' for loadshare entry for linkset '%s'.\n", v->value, linkset_name);
return -1;
}
} else if(0 == strcasecmp(v->name, "t35")) {
char action_buf[100];
if(sscanf(v->value, "%d,%s", &linkset->t35_value, action_buf) != 2) {
ast_log(LOG_ERROR, "Invalid synax in '%s' for t35 entry for linkset '%s'.\n", v->value, linkset_name);
return -1;
}
if (strcasecmp(action_buf, "st") == 0)
linkset->t35_action = 1;
else if (strcasecmp(action_buf, "timeout") == 0)
linkset->t35_action = 0;
else {
ast_log(LOG_ERROR, "Invalid t35 action '%s'.\n", action_buf);
return -1;
}
} else if(0 == strcasecmp(v->name, "dni_chunk_limit")) {
if(sscanf(v->value, "%d", &linkset->dni_chunk_limit) != 1) {
ast_log(LOG_ERROR, "Invalid synax in '%s' for dni_chunk_limit entry for linkset '%s'.\n", v->value, linkset_name);
return -1;
}
if (linkset->dni_chunk_limit < 0 || linkset->dni_chunk_limit > 99) {
ast_log(LOG_ERROR, "Invalid value '%s' for config option '%s', aborting.\n", v->value, v->name);
return -1;
}
} else {
ast_log(LOG_ERROR, "Unknown config option '%s', aborting.\n", v->name);
return -1;
}
v = v->next;
}
if (!has_hunt_policy) {
ast_log(LOG_ERROR, "Missing hunt_policy entry for linkset '%s'\n", linkset_name);
return -1;
}
if (!has_enabled) {
ast_log(LOG_ERROR, "Missing enabled entry for linkset '%s'\n", linkset_name);
return -1;
}
if (!has_use_connect) {
ast_log(LOG_ERROR, "Missing use_connect entry for linkset '%s'\n", linkset_name);
return -1;
}
if (!has_enable_st) {
ast_log(LOG_ERROR, "Missing enable_st entry for linkset '%s'\n", linkset_name);
return -1;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -