dahdi_cfg -h
DAHDI Tools Version - 2.11.1
Usage: dahdi_cfg [options]
Valid options are:
-c -- Use instead of /etc/dahdi/system.conf
-d [level] -- Generate debugging output. (Default level is 1.)
-f -- Always reconfigure every channel
-h -- Generate this help statement
-s -- Shutdown spans only
-t -- Test mode only, do not apply
-C -- Only configure specified channels
-S -- Only configure specified span
-v -- Verbose (more -v's means more verbose)
用于对dahdi 驱动进行相关参数配置。默认从 /etc/dahdi/system.conf 中读取配置。
/etc/dahdi/system.conf 示例
loadzone=cn
defaultzone=cn
fxsks=1
echocanceller=OSLEC,1
#define CONFIG_FILENAME "/etc/dahdi/system.conf"
#define MASTER_DEVICE "/dev/dahdi/ctl"
static FILE *cf;
static char *filename=CONFIG_FILENAME;
int main(int argc, char *argv[])
{
if (fd == -1) fd = open(MASTER_DEVICE, O_RDWR); // 打开 /dev/dahdi/ctl
if (strcmp(filename, "-") == 0)
cf = fdopen(STDIN_FILENO, "r");
else
cf = fopen(filename, "r"); // 打开 /etc/dahdi/system.conf
if (cf) {
while((buf = readline())) { // 按行读取
if (*buf == 10) /* skip new line */
continue;
if ((value = strchr(buf, '='))) {
*value++ = '\0';
value = trim(value);
key = trim(buf);
}
if (!value || !*value || !*key) {
error("Syntax error. Should be =\n" );
continue;
}
found = 0;
for (x = 0; x < sizeof(handlers) / sizeof(handlers[0]); x++) { // 遍历 handlers 数组
if (!strcasecmp(key, handlers[x].keyword)) { // 匹配 key
found++;
handlers[x].func(key, value); // 执行相应 func
break;
}
}
}
}
来看 handlers 的定义
static struct handler {
char *keyword;
int (*func)(char *keyword, char *args);
} handlers[] = {
{ "span", spanconfig },
{ "dynamic", dspanconfig },
{ "loadzone", registerzone },
{ "defaultzone", defaultzone },
{ "e&m", chanconfig },
{ "e&me1", chanconfig },
{ "fxsls", chanconfig },
{ "fxsgs", chanconfig },
{ "fxsks", chanconfig },
{ "fxols", chanconfig },
{ "fxogs", chanconfig },
{ "fxoks", chanconfig },
{ "rawhdlc", chanconfig },
{ "nethdlc", chanconfig },
{ "fcshdlc", chanconfig },
{ "hardhdlc", chanconfig },
{ "mtp2", chanconfig },
{ "dchan", chanconfig },
{ "bchan", chanconfig },
{ "indclear", chanconfig },
{ "clear", chanconfig },
{ "unused", chanconfig },
{ "cas", chanconfig },
{ "dacs", chanconfig },
{ "dacsrbs", chanconfig },
{ "user", chanconfig },
{ "alaw", setlaw },
{ "mulaw", setlaw },
{ "deflaw", setlaw },
{ "ctcss", ctcss },
{ "dcsrx", dcsrx },
{ "rxdcs", dcsrx },
{ "tx", tx },
{ "debouncetime", debounce_time },
{ "bursttime", burst_time },
{ "exttone", ext_tone },
{ "invertcor", invert_cor },
{ "corthresh", cor_thresh },
{ "rxgain", rx_gain },
{ "txgain", tx_gain },
{ "deemp", de_emp },
{ "preemp", pre_emp },
{ "channel", rad_chanconfig },
{ "channels", rad_chanconfig },
{ "echocanceller", setechocan },
{ "56k", setfiftysixkhdlc },
};
就是一个 keyword :func 一一对应的一张表。
以 loadzone=cn 为例跟踪一下代码
{ “loadzone”, registerzone },
static int registerzone(char *keyword, char *args)
{
if (numzones >= DAHDI_TONE_ZONE_MAX) {
error("Too many tone zones specified\n");
return 0;
}
dahdi_copy_string(zonestoload[numzones++], args, sizeof(zonestoload[0]));
return 0;
}
for (x=0;x<numzones;x++) {
if (tone_zone_register(fd, zonestoload[x])) {
if (errno != EBUSY)
error("Unable to register tone zone '%s'\n", zonestoload[x]);
}
}
int tone_zone_register(int fd, char *country)
{
struct tone_zone *z;
z = tone_zone_find(country);
if (z) {
return tone_zone_register_zone(-1, z);
} else {
return -1;
}
}
int tone_zone_register_zone(int fd, struct tone_zone *z)
{
...
if ((res = ioctl(fd, DAHDI_FREEZONE, &x))) {
if (errno != EBUSY)
fprintf(stderr, "ioctl(DAHDI_FREEZONE) failed: %s\n", strerror(errno));
return res;
}
if ((res = ioctl(fd, DAHDI_LOADZONE, h)))
{
}
}
可以看出其最终是使用 ioctl 向驱动里面设置一些参数,其它的也都类似。不逐一分析。