dahdi_tools 分析(四) dahdi_cfg

dahdi_tools 分析(四) dahdi_cfg

dahdi_cfg 的使用

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 向驱动里面设置一些参数,其它的也都类似。不逐一分析。

你可能感兴趣的:(VOIP)