我是靠谱客的博主 懦弱海燕,最近开发中收集的这篇文章主要介绍dahdi_tools 分析(一)dahdi_scandahdi_tools 分析(一)dahdi_scan,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

dahdi_tools 分析(一)dahdi_scan

dahdi_scan 的使用

示例:

# dahdi_scan
[1]
active=yes
alarms=OK
description= XX WCTDM Board 1
name=WCTDM/0
manufacturer=xx
devicetype=xx
location=PCI Bus 00 Slot 00
basechan=1
totchans=4
irq=0
type=analog
port=1,FXS
port=2,FXS
port=3,FXS
port=4,FXS

dahdi_scan 用于显示板卡的一些信息。无参数时扫描所有板卡信息,加参数时扫描指定板卡,如 dahdi_scan 4 5 6 ;只扫描 4 5 6 号板卡。

源码分析

int main(int argc, char *argv[])
{
int ctl;
int x, y, z;
struct dahdi_params params;
unsigned int basechan = 1;
int direct_basechan;
struct dahdi_spaninfo s;
char buf[100];
char alarms[50];
// 打开 /dev/dahdi/ctl 
if ((ctl = open("/dev/dahdi/ctl", O_RDWR)) < 0) {
fprintf(stderr, "Unable to open /dev/dahdi/ctl: %sn", strerror(errno));
exit(1);
}
for (x = 1; x < DAHDI_MAX_SPANS; x++) {
memset(&s, 0, sizeof(s));
s.spanno = x;
if (ioctl(ctl, DAHDI_SPANSTAT, &s))
// 使用 ioctl DAHDI_SPANSTAT 获取板卡信息,struct dahdi_spaninfo
continue;
/* DAHDI-Linux 2.5.x exposes the base channel in sysfs. Let's
* try to look for it there in case there are holes in the span
* numbering. */
direct_basechan = get_basechan(x);
// get_basechan 后面分析
if (-1 != direct_basechan) {
basechan = direct_basechan;
}
fprintf(stdout, "[%d]n", x);
fprintf(stdout, "active=yesn");
fprintf(stdout, "alarms=%sn", alarms);
fprintf(stdout, "description=%sn", s.desc);
fprintf(stdout, "name=%sn", s.name);
fprintf(stdout, "manufacturer=%sn", s.manufacturer);
fprintf(stdout, "devicetype=%sn", s.devicetype);
fprintf(stdout, "location=%sn", s.location);
fprintf(stdout, "basechan=%dn", basechan);
fprintf(stdout, "totchans=%dn", s.totalchans);
fprintf(stdout, "irq=%dn", s.irq);
// 显示一些基本信息
y = basechan;
memset(&params, 0, sizeof(params));
params.channo = y;
if (ioctl(ctl, DAHDI_GET_PARAMS, &params)) {
// 看是否能获取其它信息
basechan += s.totalchans;
continue;
}
if (is_digital_span(&s)) {
// 判断是数字板卡还是模拟板卡
/* this is a digital span */
fprintf(stdout, "type=digital-%sn", s.spantype);
fprintf(stdout, "syncsrc=%dn", s.syncsrc);
fprintf(stdout, "lbo=%sn", s.lboname);
fprintf(stdout, "coding_opts=");
buf[0] = '';
if (s.linecompat & DAHDI_CONFIG_B8ZS) strcat(buf, "B8ZS,");
if (s.linecompat & DAHDI_CONFIG_AMI) strcat(buf, "AMI,");
if (s.linecompat & DAHDI_CONFIG_HDB3) strcat(buf, "HDB3,");
buf[strlen(buf) - 1] = '';
fprintf(stdout, "%sn", buf);
fprintf(stdout, "framing_opts=");
buf[0] = '';
if (s.linecompat & DAHDI_CONFIG_ESF) strcat(buf, "ESF,");
if (s.linecompat & DAHDI_CONFIG_D4) strcat(buf, "D4,");
if (s.linecompat & DAHDI_CONFIG_CCS) strcat(buf, "CCS,");
if (s.linecompat & DAHDI_CONFIG_CRC4) strcat(buf, "CRC4,");
buf[strlen(buf) - 1] = '';
fprintf(stdout, "%sn", buf);
fprintf(stdout, "coding=");
if (s.lineconfig & DAHDI_CONFIG_B8ZS) fprintf(stdout, "B8ZS");
else if (s.lineconfig & DAHDI_CONFIG_AMI) fprintf(stdout, "AMI");
else if (s.lineconfig & DAHDI_CONFIG_HDB3) fprintf(stdout, "HDB3");
fprintf(stdout, "n");
fprintf(stdout, "framing=");
if (s.lineconfig & DAHDI_CONFIG_ESF) fprintf(stdout, "ESF");
else if (s.lineconfig & DAHDI_CONFIG_D4) fprintf(stdout, "D4");
else if (s.lineconfig & DAHDI_CONFIG_CCS) fprintf(stdout, "CCS");
else fprintf(stdout, "CAS");
if (s.lineconfig & DAHDI_CONFIG_CRC4) fprintf(stdout, "/CRC4");
fprintf(stdout, "n");
} else {
/* this is an analog span */
fprintf(stdout, "type=analogn");
for (y = basechan; y < (basechan + s.totalchans); y++) {
memset(&params, 0, sizeof(params));
params.channo = y;
if (ioctl(ctl, DAHDI_GET_PARAMS, &params)) {
// 获取params参数
fprintf(stdout, "port=%d,unknownn", y);
continue;
};
fprintf(stdout, "port=%d,", y);
switch (params.sigcap & (__DAHDI_SIG_FXO | __DAHDI_SIG_FXS)) {
// 根据 params.sigcap 区分是FXS还是FXO
case __DAHDI_SIG_FXO:
fprintf(stdout, "FXS");
break;
case __DAHDI_SIG_FXS:
fprintf(stdout, "FXO");
break;
default:
fprintf(stdout, "none");
}
if (params.sigcap & DAHDI_SIG_BROKEN)
fprintf(stdout, " FAILED");
fprintf(stdout, "n");
}
}
basechan += s.totalchans;
}
}

代码里面核心的部分就是 ioctl DAHDI_SPANSTAT 获取板卡信息,即 struct dahdi_spaninfo ,然后打印出来。然后根据是数字板卡还是模拟板卡打印不同的信息。

有两个函数这里分析一下

  • get_basechan
  • is_digital_span

get_basechan

static int get_basechan(unsigned int spanno)
{
int res;
int basechan;
char filename[256];
FILE *fp;
snprintf(filename, sizeof(filename),
"/sys/bus/dahdi_spans/devices/span-%u/basechan", spanno);
fp = fopen(filename, "r");
if (NULL == fp) {
return -1;
}
res = fscanf(fp, "%d", &basechan);
fclose(fp);
if (EOF == res) {
return -1;
}
return basechan;
}

通过读取 /sys/bus/dahdi_spans/devices/span-x/basechan , 来获取 basechan ,即该板卡 的第一个通道的号码。

当一个系统上存在多个板卡时。ls /sys/bus/dahdi_spans/devices 可以看的到

# ls /sys/bus/dahdi_spans/devices
span-1
span-2
span-3
span-4
span-5
span-6
span-7
span-8
span-9

进去可以看到:

span-1]# ls -1
alarms
basechan
channels
dahdi!chan!001!001
...
...
ddev
desc
driver
is_digital
is_sync_master
lbo
linecompat
lineconfig
local_spanno
name
power
spantype
subsystem
syncsrc
uevent

is_digital_span

static inline int is_digital_span(struct dahdi_spaninfo *s)
{
return (s->linecompat > 0);
}

s->linecompat > 0 时表示数字板卡。

struct dahdi_spaninfo

数据结构定义如下:

struct dahdi_spaninfo {
int	spanno;
/* span number */
char	name[20];	/* Name */
char	desc[40];	/* Description */
int	alarms;
/* alarms status */
int	txlevel;	/* what TX level is set to */
int	rxlevel;	/* current RX level */
int	bpvcount;	/* current BPV count */
int	crc4count;	/* current CRC4 error count */
int	ebitcount;	/* current E-bit error count */
int	fascount;	/* current FAS error count */
__u32	fecount;	/* Framing error counter */
__u32	cvcount;	/* Coding violations counter */
__u32	becount;	/* current bit error count */
__u32	prbs;
/* current PRBS detected pattern */
__u32	errsec;
/* errored seconds */
int	irqmisses;	/* current IRQ misses */
int	syncsrc;	/* span # of current sync source,
or 0 for free run */
int	numchans;	/* number of configured channels on this span */
int	totalchans;	/* total number of channels on the span */
int	totalspans;	/* total number of spans in entire system */
int	lbo;
/* line build out */
int	lineconfig;	/* framing/coding */
char
lboname[40];	/* line build out in text form */
char	location[40];	/* span's device location in system */
char	manufacturer[40]; /* manufacturer of span's device */
char	devicetype[40];	/* span's device type */
int	irq;
/* span's device IRQ */
int	linecompat;	/* span global signaling or 0 for
analog spans.*/
char	spantype[6];	/* type of span in text form */
}

最后

以上就是懦弱海燕为你收集整理的dahdi_tools 分析(一)dahdi_scandahdi_tools 分析(一)dahdi_scan的全部内容,希望文章能够帮你解决dahdi_tools 分析(一)dahdi_scandahdi_tools 分析(一)dahdi_scan所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(40)

评论列表共有 0 条评论

立即
投稿
返回
顶部