config.c

来自「asterisk1.4.6版本下 7#信令驱动 源码」· C语言 代码 · 共 1,121 行 · 第 1/3 页

C
1,121
字号
	  ast_log(LOG_ERROR, "Too many links defined for host '%s' (max %d).\n", host->name, MAX_LINKS_PER_HOST);
	  return -1;
	}
	if(sscanf(p, "%[^:]:%d", linkname_buf, &host->spans[host->n_spans].connector) != 2) {
	  ast_log(LOG_DEBUG, "linkname '%s', no %d \n", linkname_buf, host->spans[host->n_spans].connector);
	  ast_log(LOG_ERROR, "Invalid link specification '%s' for host '%s'.\n", p, host_name);
	  return -1;
	}
	if ((host->spans[host->n_spans].connector < 1) || (host->spans[host->n_spans].connector > MAX_E1_CONNECTOR_NO)) {
	  ast_log(LOG_ERROR, "Connector no. %d for link '%s' not in range 1..%d.\n", host->spans[host->n_spans].connector, v->value, MAX_E1_CONNECTOR_NO);
	  return -1;
	}
	ast_log(LOG_DEBUG, "linkname '%s', no %d \n", linkname_buf, host->spans[host->n_spans].connector);
	for (i = 0; i < host->n_spans; i++) {
	  if (host->spans[i].connector == host->spans[host->n_spans].connector) {
	    ast_log(LOG_ERROR, "Connector no. %d specified twice for host '%s.'\n", host->spans[host->n_spans].connector, host->name);
	    return -1;
	  }
	}
	host->spans[host->n_spans].link = lookup_link(linkname_buf);
	if (!host->spans[host->n_spans].link) {
	  ast_log(LOG_ERROR, "Link '%s' not found while parsing host '%s'.\n", linkname_buf, host_name);
	  return -1;
	}
	if (host->spans[host->n_spans].link->on_host) {
	  ast_log(LOG_ERROR, "Link '%s' belongs to both  host '%s' and '%s'.\n", linkname_buf, host_name, host->spans[host->n_spans].link->on_host->name);
	  return -1;
	}
	host->spans[host->n_spans].link->on_host = host;
	host->n_spans++;
	ast_log(LOG_DEBUG, "host n_spans %d \n", host->n_spans);
	p = strsep(&spec, ",");
      }
      has_links = 1;
    } else if(0 == strncasecmp(v->name, "if-", 3)) {
      in_addr_t addr;
      if (host->n_ifs == MAX_IFS_PER_HOST) {
	ast_log(LOG_ERROR, "Too many interfaces defined for host '%s' (max %d).\n", host->name, MAX_IFS_PER_HOST);
	return -1;
      }
      if ((addr = inet_addr(v->value)) == INADDR_NONE) {
	ast_log(LOG_ERROR, "Invalid IP address '%s' for interface '%s' for host '%s'.\n", v->value, v->value, host_name);
	return -1;
      }
      memcpy(&host->ifs[host->n_ifs].addr, &addr, sizeof(addr));
      host->ifs[host->n_ifs].name = strdup(&v->name[3]);
      host->n_ifs++;
      has_if = 1;
    } else if(0 == strcasecmp(v->name, "ssn")) {
      if(sscanf(v->value, "%i", &host->ssn) != 1) {
	  ast_log(LOG_ERROR, "Invalid ssn value '%s' for host '%s'.\n", v->value, host_name);
	  return -1;
	}
    } else if(0 == strcasecmp(v->name, "globaltitle")) {
      if(sscanf(v->value, "%hhi, %hhi, %hhi, %s", &host->global_title.translation_type, &host->global_title.nature_of_address, &host->global_title.numbering_plan, host->global_title.addr) != 4) {
	  ast_log(LOG_ERROR, "Invalid globaltitle value '%s' for host '%s'.\n", v->value, host_name);
	  return -1;
      }
    } else if(0 == strcasecmp(v->name, "route")) {
      char route_spec_buf[500] = {0,};
      ast_copy_string(route_spec_buf, v->value, sizeof(route_spec_buf));
      ast_log(LOG_DEBUG, "route '%s' \n", route_spec_buf);
      spec = &route_spec_buf[0];
      p = strsep(&spec, ",");
      while(p && *p) {
	char dest_buf[100];
	char linkset_buf[100];
	struct linkset* linkset;
	if (host->n_routes == MAX_ROUTES_PER_HOST) {
	  ast_log(LOG_ERROR, "Too many routes defined for host '%s' (max %d).\n", host->name, MAX_ROUTES_PER_HOST);
	  return -1;
	}
	while ((*p == ' ') || (*p == '\t'))
	  p++;
	if(sscanf(p, "%[0-9]:%s", dest_buf, linkset_buf) != 2) {
	  if(sscanf(p, ":%s", linkset_buf) != 1) {
	    ast_log(LOG_ERROR, "Invalid route specification '%s' for host '%s'.\n", p, host_name);
	    return -1;
	  }
	  *dest_buf = '\0';
	}
	linkset = lookup_linkset(linkset_buf);
	if (!linkset) {
	  ast_log(LOG_ERROR, "Unknown linkset '%s' for route '%s' for host '%s'\n", linkset_buf, p, host_name);
	  return -1;
	}
	host->routes[host->n_routes].destaddr = strdup(dest_buf);
	host->routes[host->n_routes].destlinkset = linkset;
	host->n_routes++;
	p = strsep(&spec, ",");
      }
    } else {
      ast_log(LOG_ERROR, "Unknown config option '%s', aborting.\n", v->name);
      return -1;
    }
    v = v->next;
  }
  if (!has_opc) {
    ast_log(LOG_ERROR, "Missing opc entry for host '%s'.\n", host_name);
    return -1;
  }
  if (!has_dpc) {
    ast_log(LOG_ERROR, "Missing dpc entry for host '%s'.\n", host_name);
    return -1;
  }
  if (!has_links) {
    ast_log(LOG_ERROR, "Missing links entry for host '%s'.\n", host_name);
    return -1;
  }
  if (!has_enabled) {
    ast_log(LOG_ERROR, "Missing enabled entry for host '%s'.\n", host_name);
    return -1;
  }
  if (!has_if) {
    ast_log(LOG_WARNING, "Missing interface entries for host '%s'.\n", host_name);
  }
  host->n_receivers = 0;
  host->state = STATE_UNKNOWN;
  host->has_signalling_receivers = 0;
  ast_log(LOG_DEBUG, "host %s, n_spans %d \n", host->name, host->n_spans);
  n_hosts++;
  return 0;
}

static int load_config_cluster(struct ast_config *cfg)
{
  struct ast_variable *v;
  struct link* link;
  struct host* host;
  struct receiver* receiver;
  int i, j;
  char *p;

  char *spec;
  char dup_spec_buf[100] = {0,};
  int has_port = 0;

  v = ast_variable_browse(cfg, "cluster");
  while(v != NULL) {
    if (strcasecmp(v->name, "port") == 0) {
      if(sscanf(v->value, "%d", &clusterlistenport) != 1) {
	ast_log(LOG_ERROR, "The port entry '%s' in cluster section is not valid.\n", v->name);
	return -1;
      }
      has_port = 1;
      v = v->next;
      continue;
    }
    if ((link = lookup_link(v->name)) == NULL) {
      ast_log(LOG_ERROR, "The link '%s' is not defined while parsing cluster category.\n", v->name);
      return -1;
    }
    host = NULL;
    for (i = 0; i < n_hosts; i++) {
      for (j = 0; j < hosts[i].n_spans; j++) {
	if (hosts[i].spans[j].link == link) {
	  host = &hosts[i];
	  break;
	}
      }
    }
    if (link->enabled) {
      if (host) {
	if (host->n_receivers == MAX_LINKS_PER_HOST) {
	  ast_log(LOG_ERROR, "Too many receivers defined for host '%s' (max %d).\n", host->name, MAX_LINKS_PER_HOST);
	  return -1;
	}
	ast_log(LOG_DEBUG, "found link '%s'  on %s\n", v->name, host->name);
	receiver = &host->receivers[host->n_receivers];
	receiver->receiverix = host->n_receivers++;
	receiver->n_targets = 0;
	link->receiver = receiver;
	ast_copy_string(dup_spec_buf, v->value, sizeof(dup_spec_buf));
	spec = &dup_spec_buf[0];
	p = strsep(&spec, ",");
	while(p) {
	  char host_name_buf[100];
	  char if_name_buf[100];
	  struct host* target_host;
	  struct ipinterface* target_if = NULL;
	  char* if_name = &if_name_buf[3];

	  if(sscanf(p, "%[^#]#%s", host_name_buf, if_name_buf) != 2) {
	    ast_log(LOG_ERROR, "Invalid host#if specification '%s'.\n", p);
	    return -1;
	  }
	  if ((target_host = lookup_host(host_name_buf)) == NULL) {
	    ast_log(LOG_ERROR, "Host '%s' not found in dup spec '%s'.\n", host_name_buf, p);
	    return -1;
	  }
	  if (strncasecmp(if_name_buf, "if-", 3)) {
	    ast_log(LOG_ERROR, "Invalid interface name: '%s' in dup spec '%s'.\n", host_name_buf, p);
	    return -1;
	  }
	  for (i = 0; i < n_hosts; i++) {
	    if (!strcmp(hosts[i].name, host_name_buf)) {
	      for (j = 0; j < hosts[i].n_ifs; j++) {
		if (!strcmp(hosts[i].ifs[j].name, if_name)) {
		  target_if = &hosts[i].ifs[j];
		  break;
		}
	      }
	    }
	  }
	  if (!target_if) {
	    ast_log(LOG_ERROR, "Interface '%s' not found for host '%s'.\n", if_name_buf, host_name_buf);
	    return -1;
	  }
	  if (receiver->n_targets == 2*MAX_HOSTS) {
	    ast_log(LOG_ERROR, "Too many targets defined for link '%s' (max %d).\n", link->name, 2*MAX_HOSTS);
	    return -1;
	  }
	  receiver->targets[receiver->n_targets].host = target_host;
	  receiver->targets[receiver->n_targets].inf = target_if;
	  receiver->n_targets++;
	  ast_log(LOG_DEBUG, "Added target %s#%s for link %s on host %s \n", target_host->name, target_if->name, link->name, host->name);
	  p = strsep(&spec, ",");
	}
      }
      else {
	ast_log(LOG_WARNING, "The link '%s' is not used by any host.\n", v->name);
      }
    }
    v = v->next;
  }
  if (!has_port) {
    ast_log(LOG_WARNING, "Missing port entry in cluster section");
    return -1;
  }
  return 0;
}

int load_config(int reload)
{
  struct ast_config *cfg;
  static const char conffile_name[] = "ss7.conf";
  char* prevcat = NULL;
  int i, j, k;

  cfg = ast_config_load(conffile_name);
  if(cfg == NULL) {
    ast_log(LOG_ERROR, "Unable to load config '%s'.\n", conffile_name);
    return -1;
  }


  n_linksets = 0;
  n_links = 0;
  n_hosts = 0;

  while ((prevcat = ast_category_browse(cfg, prevcat)) != NULL) {
    if (strncasecmp(prevcat, "linkset-", 8) == 0) {
      if (load_config_linkset(cfg, prevcat))
	goto fail;
    }
    else if (strncasecmp(prevcat, "link-", 5) == 0) {
      if (load_config_link(cfg, prevcat))
	goto fail;
    }
    else if (strncasecmp(prevcat, "host-", 5) == 0) {
      if (load_config_host(cfg, prevcat))
	goto fail;
    }
    else if (strcasecmp(prevcat, "cluster") == 0) {
      if (load_config_cluster(cfg))
	goto fail;
    }
    else if (strcasecmp(prevcat, "jitter") == 0) {
      if (load_config_jitter(cfg))
       goto fail;
    }
    else {
      ast_log(LOG_ERROR, "Error invalid config category '%s'.\n", prevcat);
      goto fail;
    }
  }
  if ((this_host = find_my_host()) == NULL)
    goto fail;
  for (i = 0; i < n_linksets; i++) {
    if (!linksets[i].enabled)
      continue;
    linksets[i].dpc = this_host->dpc[linksets[i].lsi];
    ast_log(LOG_NOTICE, "Configuring DPC %d for linkset '%s'.\n", linksets[i].dpc, linksets[i].name);
  }
  for (i = 0; i < n_linksets; i++) {
    int any = 0;
    if (!linksets[i].enabled)
      continue;
    for (j = 0; j < linksets[i].n_links; j++)
      for (k = 0; k < this_host->n_spans; k++)
	if (this_host->spans[k].link == linksets[i].links[j]) {
	  if (!linksets[i].dpc) {
	    ast_log(LOG_ERROR, "No DPC specified for linkset '%s'.\n", linksets[i].name);
	    goto fail;
	  }
	  any = any || linksets[i].links[j]->enabled;
	}
    linksets[i].enabled = any;
    ast_log(LOG_DEBUG, "Setting linkset %d '%s' enabled %d\n", i, linksets[i].name, any);
  }
  if (!this_host->enabled) {
    ast_log(LOG_ERROR, "Host '%s' not enabled, quitting!\n", this_host->name);
    goto fail;
  }
  if (this_host->default_linkset) {
    int haslinkset = 0;
    for (k = 0; k < this_host->n_spans; k++) {
      if (this_host->spans[k].link->enabled && this_host->spans[k].link->linkset->enabled &&
	  (this_host->spans[k].link->linkset == this_host->default_linkset))
	haslinkset = 1;
    }
    if (!haslinkset) {
      ast_log(LOG_ERROR, "Default linkset '%s' for host '%s' is not configured for this host!\n", this_host->default_linkset->name, this_host->name);
      goto fail;
    }
  }
  else {
    struct linkset* linkset = NULL;
    for (k = 0; k < this_host->n_spans; k++) {
      if (this_host->spans[k].link->linkset->enabled) {
	if (linkset && (linkset != this_host->spans[k].link->linkset)) {
	  ast_log(LOG_ERROR, "Host '%s' has multiple linksets, need to specify a default_linkset!\n", this_host->name);
	  goto fail;
	}
	linkset = this_host->spans[k].link->linkset;
      }
    }
    this_host->default_linkset = linkset;
  }
  if (make_host_schannels())
    goto fail;

  show_config();

  ast_config_destroy(cfg);
  return 0;

 fail:
  ast_config_destroy(cfg);
  return -1;
}

static void destroy_linksets(void)
{
  while (n_linksets-- > 0) {
    free(linksets[n_linksets].name);
    free(linksets[n_linksets].context);
    free(linksets[n_linksets].language);
    free(linksets[n_linksets].combined);
  }
}

static void destroy_links(void)
{
  while (n_links-- > 0) {
    free(links[n_links].name);
  }
}

static void destroy_hosts(void)
{
  while (n_hosts-- > 0) {
    free(hosts[n_hosts].name);
  }
}

void destroy_config(void)
{
  destroy_linksets();
  destroy_links();
  destroy_hosts();
}

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?