⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ztcfg.c

📁 This a SOFTWARE pbx DRIVER
💻 C
📖 第 1 页 / 共 2 页
字号:
/* * Configuration program for Zapata Telephony Interface * * Written by Mark Spencer <markster@linux-support.net> * Based on previous works, designs, and architectures conceived and * written by Jim Dixon <jim@lambdatel.com>. * * Copyright (C) 2001 Jim Dixon / Zapata Telephony. * Copyright (C) 2001 Linux Support Services, Inc. * * All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under thet erms 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. *  * This program 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 this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  * * Primary Author: Mark Spencer <markster@linux-support.net> * */#include <stdio.h> #include <getopt.h>#include <string.h>#include <stdarg.h>#include <stdlib.h>#include <unistd.h>#include <sys/ioctl.h>#include <fcntl.h>#include <errno.h>#include "ztcfg.h"#include "tonezone.h"#include "zaptel.h"#define NUM_SPANS ZT_MAX_SPANS/* Assume no more than 1024 dynamics */#define NUM_DYNAMIC	1024static int lineno=0;static FILE *cf;static char *filename=CONFIG_FILENAME;#define DEBUG_READER (1 << 0)#define DEBUG_PARSER (1 << 1)#define DEBUG_APPLY  (1 << 2)static int debug = 0;static int errcnt = 0;static int deftonezone = -1;static struct zt_lineconfig lc[ZT_MAX_SPANS];static struct zt_chanconfig cc[ZT_MAX_CHANNELS];static struct zt_dynamic_span zds[NUM_DYNAMIC];static char *sig[ZT_MAX_CHANNELS];		/* Signalling */static int slineno[ZT_MAX_CHANNELS];	/* Line number where signalling specified */static int spans=0;static int fo_real = 1;static int verbose = 0;static int stopmode = 0;static int numdynamic = 0;static char zonestoload[ZT_TONE_ZONE_MAX][10];static int numzones = 0;static char *lbostr[] = {"0 db (CSU)/0-133 feet (DSX-1)","133-266 feet (DSX-1)","266-399 feet (DSX-1)","399-533 feet (DSX-1)","533-655 feet (DSX-1)","-7.5db (CSU)","-15db (CSU)","-22.5db (CSU)"};static char *laws[] = {	"Default",	"Mu-law",	"A-law"};static int error(char *fmt, ...){	int res;	static int shown=0;	va_list ap;	if (!shown) {		fprintf(stderr, "Notice: Configuration file is %s\n", filename);		shown++;	}	res = fprintf(stderr, "line %d: ", lineno);	va_start(ap, fmt);	vfprintf(stderr, fmt, ap);	va_end(ap);	errcnt++;	return res;}static void trim(char *buf){	/* Trim off trailing spaces, tabs, etc */	while(strlen(buf) && (buf[strlen(buf) -1] < 33))		buf[strlen(buf) -1] = '\0';}static int parseargs(char *input, char *output[], int maxargs, char sep){	char *c;	int pos=0;	c = input;	output[pos++] = c;	while(*c) {		while(*c && (*c != sep)) c++;		if (*c) {			*c = '\0';			c++;			while(*c && (*c < 33)) c++;			if (*c)  {				if (pos >= maxargs)					return -1;				output[pos] = c;				trim(output[pos]);				pos++;				output[pos] = NULL;				/* Return error if we have too many */			} else				return pos;		}	}	return pos;}int dspanconfig(char *keyword, char *args){	static char *realargs[10];	int argc;	int res;	int chans;	int timing;	argc = res = parseargs(args, realargs, 4, ',');	if (res != 4) {		error("Incorrect number of arguments to 'dynamic' (should be <driver>,<address>,<num channels>, <timing>)\n");	}	res = sscanf(realargs[2], "%d", &chans);	if ((res == 1) && (chans < 1))		res = -1;	if (res != 1) {		error("Invalid number of channels '%s', should be a number > 0.\n", realargs[2]);	}	res = sscanf(realargs[3], "%d", &timing);	if ((res == 1) && (timing < 0))		res = -1;	if (res != 1) {		error("Invalid timing '%s', should be a number > 0.\n", realargs[3]);	}	strncpy(zds[numdynamic].driver, realargs[0], sizeof(zds[numdynamic].driver));	strncpy(zds[numdynamic].addr, realargs[1], sizeof(zds[numdynamic].addr));	zds[numdynamic].numchans = chans;	zds[numdynamic].timing = timing;		numdynamic++;	return 0;}int spanconfig(char *keyword, char *args){	static char *realargs[10];	int res;	int argc;	int span;	int timing;	argc = res = parseargs(args, realargs, 7, ',');	if ((res < 5) || (res > 7)) {		error("Incorrect number of arguments to 'span' (should be <spanno>,<timing>,<lbo>,<framing>,<coding>[, crc4 | yellow [, yellow]])\n");	}	res = sscanf(realargs[0], "%i", &span);	if (res != 1) {		error("Span number should be a valid span number, not '%s'\n", realargs[0]);		return -1;	}	res = sscanf(realargs[1], "%i", &timing);	if ((res != 1) || (timing < 0) || (timing > 15)) {		error("Timing should be a number from 0 to 15, not '%s'\n", realargs[1]);		return -1;	}	res = sscanf(realargs[2], "%i", &lc[spans].lbo);	if (res != 1) {		error("Line build-out (LBO) should be a number from 0 to 7 (usually 0) not '%s'\n", realargs[2]);		return -1;	}	if ((lc[spans].lbo < 0) || (lc[spans].lbo > 7)) {		error("Line build-out should be in the range 0 to 7, not %d\n", lc[spans].lbo);		return -1;	}	if (!strcasecmp(realargs[3], "d4")) {		lc[spans].lineconfig |= ZT_CONFIG_D4;		lc[spans].lineconfig &= ~ZT_CONFIG_ESF;		lc[spans].lineconfig &= ~ZT_CONFIG_CCS;	} else if (!strcasecmp(realargs[3], "esf")) {		lc[spans].lineconfig |= ZT_CONFIG_ESF;		lc[spans].lineconfig &= ~ZT_CONFIG_D4;		lc[spans].lineconfig &= ~ZT_CONFIG_CCS;	} else if (!strcasecmp(realargs[3], "ccs")) {		lc[spans].lineconfig |= ZT_CONFIG_CCS;		lc[spans].lineconfig &= ~(ZT_CONFIG_ESF | ZT_CONFIG_D4);	} else if (!strcasecmp(realargs[3], "cas")) {		lc[spans].lineconfig &= ~ZT_CONFIG_CCS;		lc[spans].lineconfig &= ~(ZT_CONFIG_ESF | ZT_CONFIG_D4);	} else {		error("Framing(T1)/Signalling(E1) must be one of 'd4', 'esf', 'cas' or 'ccs', not '%s'\n", realargs[3]);		return -1;	}	if (!strcasecmp(realargs[4], "ami")) {		lc[spans].lineconfig &= ~(ZT_CONFIG_B8ZS | ZT_CONFIG_HDB3);		lc[spans].lineconfig |= ZT_CONFIG_AMI;	} else if (!strcasecmp(realargs[4], "b8zs")) {		lc[spans].lineconfig |= ZT_CONFIG_B8ZS;		lc[spans].lineconfig &= ~(ZT_CONFIG_AMI | ZT_CONFIG_HDB3);	} else if (!strcasecmp(realargs[4], "hdb3")) {		lc[spans].lineconfig |= ZT_CONFIG_HDB3;		lc[spans].lineconfig &= ~(ZT_CONFIG_AMI | ZT_CONFIG_B8ZS);	} else {		error("Coding must be one of 'ami', 'b8zs' or 'hdb3', not '%s'\n", realargs[4]);		return -1;	}	if (argc > 5) {		if (!strcasecmp(realargs[5], "yellow"))			lc[spans].lineconfig |= ZT_CONFIG_NOTOPEN;		else if (!strcasecmp(realargs[5], "crc4")) {			lc[spans].lineconfig |= ZT_CONFIG_CRC4;		} else {			error("Only valid fifth arguments are 'yellow' or 'crc4', not '%s'\n", realargs[5]);			return -1;		}	}	if (argc > 6) {		if (!strcasecmp(realargs[6], "yellow"))			lc[spans].lineconfig |= ZT_CONFIG_NOTOPEN;		else {			error("Only valid sixth argument is 'yellow', not '%s'\n", realargs[6]);			return -1;		}	}	lc[spans].span = spans + 1;	lc[spans].sync = timing;	/* Valid span */	spans++;	return 0;}int apply_channels(int chans[], char *argstr){	char *args[ZT_MAX_CHANNELS+1];	char *range[3];	int res,x, res2,y;	int chan;	int start, finish;	char argcopy[256];	res = parseargs(argstr, args, ZT_MAX_CHANNELS, ',');	if (res < 0)		error("Too many arguments...  Max is %d\n", ZT_MAX_CHANNELS);	for (x=0;x<res;x++) {		if (strchr(args[x], '-')) {			/* It's a range */			strncpy(argcopy, args[x], sizeof(argcopy));			res2 = parseargs(argcopy, range, 2, '-');			if (res2 != 2) {				error("Syntax error in range '%s'.  Should be <val1>-<val2>.\n", args[x]);				return -1;			}			res2 =sscanf(range[0], "%i", &start);			if (res2 != 1) {				error("Syntax error.  Start of range '%s' should be a number from 1 to %d\n", args[x], ZT_MAX_CHANNELS - 1);				return -1;			} else if ((start < 1) || (start >= ZT_MAX_CHANNELS)) {				error("Start of range '%s' must be between 1 and %d (not '%d')\n", args[x], ZT_MAX_CHANNELS - 1, start);				return -1;			}			res2 =sscanf(range[1], "%i", &finish);			if (res2 != 1) {				error("Syntax error.  End of range '%s' should be a number from 1 to %d\n", args[x], ZT_MAX_CHANNELS - 1);				return -1;			} else if ((finish < 1) || (finish >= ZT_MAX_CHANNELS)) {				error("end of range '%s' must be between 1 and %d (not '%d')\n", args[x], ZT_MAX_CHANNELS - 1, finish);				return -1;			}			if (start > finish) {				error("Range '%s' should start before it ends\n", args[x]);				return -1;			}			for (y=start;y<=finish;y++)				chans[y]=1;		} else {			/* It's a single channel */			res2 =sscanf(args[x], "%i", &chan);			if (res2 != 1) {				error("Syntax error.  Channel should be a number from 1 to %d, not '%s'\n", ZT_MAX_CHANNELS - 1, args[x]);				return -1;			} else if ((chan < 1) || (chan >= ZT_MAX_CHANNELS)) {				error("Channel must be between 1 and %d (not '%d')\n", ZT_MAX_CHANNELS - 1, chan);				return -1;			}			chans[chan]=1;		}			}	return res;}int parse_idle(int *i, char *s){	char a,b,c,d;	if (s) {		if (sscanf(s, "%c%c%c%c", &a,&b,&c,&d) == 4) {			if (((a == '0') || (a == '1')) && ((b == '0') || (b == '1')) && ((c == '0') || (c == '1')) && ((d == '0') || (d == '1'))) {				*i = 0;				if (a == '1') 					*i |= ZT_ABIT;				if (b == '1')					*i |= ZT_BBIT;				if (c == '1')					*i |= ZT_CBIT;				if (d == '1')					*i |= ZT_DBIT;				return 0;			}		}	}	error("CAS Signalling requires idle definition in the form ':xxxx' at the end of the channel definition, where xxxx represent the a, b, c, and d bits\n");	return -1;}static int parse_channel(char *channel, int *startchan){	if (!channel || (sscanf(channel, "%i", startchan) != 1) || 		(*startchan < 1)) {		error("DACS requires a starting channel in the form ':x' where x is the channel\n");		return -1;	}	return 0;}static int chanconfig(char *keyword, char *args){	int chans[ZT_MAX_CHANNELS];	int res = 0;	int x;	int master=0;	int dacschan = 0;	char *idle;	bzero(chans, sizeof(chans));	strtok(args, ":");	idle = strtok(NULL, ":");	if (!strcasecmp(keyword, "dacs") || !strcasecmp(keyword, "dacsrbs")) {		res = parse_channel(idle, &dacschan);	}	if (!res)		res = apply_channels(chans, args);	if (res <= 0)		return -1;	for (x=1;x<ZT_MAX_CHANNELS;x++) 		if (chans[x]) {			if (slineno[x]) {				error("Channel %d already configured as '%s' at line %d\n", x, sig[x], slineno[x]);				continue;			}			if ((!strcasecmp(keyword, "dacs") || !strcasecmp(keyword, "dacsrbs")) && slineno[dacschan]) {				error("DACS Destination channel %d already configured as '%s' at line %d\n", dacschan, sig[dacschan], slineno[dacschan]);				continue;			} else {				cc[dacschan].chan = dacschan;				cc[dacschan].master = dacschan;				slineno[dacschan] = lineno;			}			cc[x].chan = x;			cc[x].master = x;			slineno[x] = lineno;			if (!strcasecmp(keyword, "e&m")) {				sig[x] = "E & M";				cc[x].sigtype = ZT_SIG_EM;			} else if (!strcasecmp(keyword, "e&me1")) {				sig[x] = "E & M E1";				cc[x].sigtype = ZT_SIG_EM_E1;			} else if (!strcasecmp(keyword, "fxsls")) {				sig[x] = "FXS Loopstart";				cc[x].sigtype = ZT_SIG_FXSLS;			} else if (!strcasecmp(keyword, "fxsgs")) {				sig[x] = "FXS Groundstart";				cc[x].sigtype = ZT_SIG_FXSGS;			} else if (!strcasecmp(keyword, "fxsks")) {				sig[x] = "FXS Kewlstart";				cc[x].sigtype = ZT_SIG_FXSKS;

⌨️ 快捷键说明

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