Asterisk dahdi 介绍:
DAHDI是Digium Asterisk Hardware Device Interface的简称。
原文出自:http://downloads.asterisk.org/pub/telephony/dahdi-linux/releases/README-2.2.1-rc2
1、DAHDI支持的硬件
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
数字卡:
- wct4xxp:
* Digium TE205P/TE207P/TE210P/TE212P/TE405P/TE407P/TE410P/TE412P/TE220/TE420
- wcte12xp:
* Digium TE120P/TE121/TE122
- wcte11xp:
* Digium TE110P
- wct1xxp:
* Digium T100P/ E100P
- wcb4xxp:
* Digium B410
- tor2
模拟卡:
- wctdm24xxp:
* Digium TDM2400P/AEX2400/TDM800P/AEX800/TDM410P/AEX410
- wctdm:
* Digium TDM400P
- xpp: Xorcom Astribank: a USB connected unit of up to 32 ports
(including the digital BRI and E1/T1 modules)
- wcfxo: X100P, similar and clones. A simple single-port FXO card
其他驱动:
- pciradio: Zapata Telephony PCI Quad Radio Interface
- wctc4xxp: Digium hardware transcoder cards (also need dahdi_transcode)
- dahdi_dynamic_eth: TDM over Ethernet (TDMoE) driver. Requires dahdi_dynamic
- dahdi_dynamic_loc: Mirror a local span. Requires dahdi_dynamic
- dahdi_dummy: A dummy driver that only provides a DAHDI timing source.
2、模块的参数(Module Parameters)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
内核模块可以通过模块参数来配置,通常在/etc/modprobe.d/或者是在文件/etc/modprobe.conf中用一行来配置。
如下:
options dahdi debug=1
同样,模块参数可以在系统运行时通过sys系统调用来更改
#cat /sys/module/dahdi/parameters/debug
0
#echo 1 > /sys/module/dahdi/parameters/debug
#cat /sys/module/dahdi/parameters/debug
1
有用的参数:
debug:
设置debug模式和debug级别,大多数模块可以被设置成0(禁止debug)和其他的数值(使能debug)
大多数模块有称作debugging flags的bit位,用来控制不同的调试信息,具体如下:
- dahdi_dummy:
* 1: DEBUG_GENERAL - general error messages.
* 2: DEBUG_TICKS - Show that the module is alive :-)
- wctdm24xxp:
* 1: DEBUG_CARD
* 2: DEBUG_ECHOCAN
- wct4xxp:
* 1: DEBUG_MAIN
* 2: DEBUG_DTMF
* 4: DEBUG_REGS
* 8: DEBUG_TSI
* 16: DEBUG_ECHOCAN
* 32: DEBUG_RBS
* 64: DEBUG_FRAMER
- xpp: See also README.Astribank:
* 1: GENERAL - General debug comments.
* 2: PCM - PCM-related messages. Tend to flood logs.
* 4: LEDS - Anything related to the LEDs status control. The driver
produces a lot of messages when the option is enabled.
* 8: SYNC - Synchronization related messages.
* 16: SIGNAL - DAHDI signalling related messages.
* 32: PROC - Messages related to the procfs interface.
* 64: REGS - Reading and writing to chip registers. Tends to flood
logs.
* 128: DEVICES - Device instantiation, destruction and such.
* 256 - COMMANDS - Protocol commands. Tends to flood logs.
deftabs:
回音消除的默认级别。
注意:asterisk的chan_dahdi总会试着传递它自己的值,可能是另一个默认值。因此如果只在这里更改,有可能会不起作用。
得到一个模块支持的参数的列表,使用下面的命令:
modinfo modname
或者是你刚刚编译的模块
modinfo ./modname
对xpp模块来说,你还可以得到参数的描述和默认值。另外,还可以在README.astribank中看到关于xpp的有用参数的列表。
3、DAHDI的设备文件
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
用户空间的程序通常通过位于/dev/dahdi目录下的设备文件和DAHDI交互。设备文件可以静态的或动态的产生。具体描述如下:
* /dev/dahdi/ctl (196:0) - a general device file for various information and
control operations on the DAHDI channels.
* /dev/dahdi/NNN (196:NNN) - for NNN in the range 1-249. A device file for
DAHDI channel NNN. It can be used to read data from the channel
and write data to the channel.
* /dev/dahdi/transcode (196:250) - Used to connect to a DAHDI transcoding
device.
* /dev/dahdi/timer (196:253) - Allows setting timers. Used anywhere?
* /dev/dahdi/channel (196:254) - Can be used to open an arbitrary DAHDI
channel. This is an alternative to /dev/dahdi/NNN that is not limited to
249 channels.
* /dev/dahdi/pseudo (196:255) - A timing-only device. Every time you open
it, a new DAHDI channel is created. That DAHDI channel is "pseudo" -
DAHDI receives no data in it, and only sends garbage data with the
same timing as the DAHDI timing master device.
4、DAHDI Timing
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
PBX系统通常需要单一的时钟,假如你通过数字接口(T1或E1)连接到电话供应商,通常是由电话供应商提供(由接口提供时钟)。因此,对asterisk来说,一个重要的任务是向PBX提供时钟。
DAHDI每个tick为1ms,在一个tick中,从每一个活动的DAHDI通道上读取1byte的数据。Asterisk通过一个打开的pseudo通道,可以把tick作为时钟。
不过,并不是所有的PBX系统都连接到T1以及类似的接口。使用模拟接口的话,并不需要和其他的部分同步。再说,其他的系统可能连DAHDI硬件都没有。就算是一个数字卡,也有可能不连接到供应商接口而作为其他功能使用。DAHDI系统同样具备通过卡上的clock提供时钟。
如果以上都不能使用,你可以通过dahdi_dummy单独的提供时钟,而不需要任何的DAHDI硬件设备。这在大多数的系统和内核上都能工作。
5、spans和channels
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
DAHDI向用户空间程序提供电话channel,这和DAHDI中逻辑上的定义span相关。
对数字电话适配器(T1或E1)来说,一个span代表一个单个的端口。对模拟系统来说,一个span代表一个PCI适配器或者一个相似的逻辑单元。
channel和span都是通过enum结构表示(从1开始),当生常channel或者span号时,从最小没有使用的那个号开始。
6、PROCFS接口:/proc/dahdi
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
从/proc/dahdi可以得到当前spans的列表,以及一个sapn中的channel数目。如下所示:
Span 1: XBUS-00/XPD-00 "Xorcom XPD #0/0: FXS"
2 XPP_FXS/0/0/1 FXOLS (In use)
其中标题行包括span的名称、span号以及任何的alarm标识(可选)
channel行包括channel号、名称以及实际分配的信号,同时还包括是否正在使用等。
7、ABI接口
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
向应用层提供的接口,这里暂不了解
8、alarm类型
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
alarm用来指示由于某种原因,该端口无法工作。暂不具体说明了。
接下来看下面的链接以了解CID的资料:
http://www.ainslie.org.uk/callerid/cli_faq.htm
再看下面的链接以了解Digiumu关于DTMF的BUG:
https://issues.asterisk.org/view.php?id=9096
Caller id signaling in Denmark, Brazil and other places is done through DTMF tones before the first ring
https://issues.asterisk.org/view.php?id=16460
来电显示CID主要分为DTMF和FSK两大类,中国为定义标准为FSK为在第一声响铃和第二声响铃中间传送(美规)
但也有在第一声之前传送的,如果遇到后一种就麻烦了。
DTMF有第一声响铃之前及第一声和第二声之音传送的
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
工作前的准备:
增加拨号脚本:/etc/asterisk/extensions_custom.conf
[test_pstn] exten => s,1,Noop(CID is ${CALLERID(all)})
修改:dahdi_channels.conf 指定卡上的第一端口的 context=test_psn
打开dahdi的debug级别: echo 1 > /sys/module/dahdi/parameters/debug
查看第一端口连接状态:CLI> dahdi show channel 1 内的:InAlarm: 0 此端口UP
查看卡类型:dahdi_hardware pci:0000:04:00.0 wctdm24xxp+ d161:8005 Wildcard TDM410P
拨测一个呼入:
asterisk –cvvvvgr -d
Executing [s@test_pstn:1] NoOp("DAHDI/1-1", "CID is "" <>") in new stack 没有取到CallerID
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
对第一口进行录音并查看波型如下:
dahdi_monitor 1 -f channel_1.raw
振铃前送DTMF信号
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
这是一台8口的GSM平台的呼入波型,此为第一声和第二声之间传送的DTMF
dahdi_monitor 2 -f a.raw
针对第二口进行录音,raw音频格式为: 8000,单声道,16位,在cooledit里选16bit Inter PCM格式
格式为:DTMF 在第一次响铃后发送 DTMF
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
查看Dahdi版本:dahdi_cfg -vv 显示为:DAHDI Version: 2.1.0.4
下载Dahdi源代码以便进行修改:dahdi-linux-2.1.0.4.tar.gz
主要注意chan_dahdi.conf文件里的关于CID的配置:
sendcalleridafter= ('0' or '1' or '2')
cidsignalling=('dtmf', 'dtmf_astart' or 'dtmf_dk'. This may or may not be combined with one of either 'bell' or 'v23')cidstart= (' ring' and/or 'polarity' )以振铃还是反极开始发送CID
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
问题分析:
如果配置为:cidstart=polarity,cidsignalling=dtmf,这样asterisk认为需要收到polarity才有 cid。但实际上这个cid是在第一声ring之后发送的,此时asterisk没看到polarity,因此就不再检测cid,只是看到有振铃,就摘机了,这就造成了cid不全。
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
解决方法:
修改dahdi代码并重新编绎:
TDM800P、TDM410P卡对应的是wctdm24xxp.c,TDM400P卡对应的是wctdm.c,X100P的卡对应的是wcfxo.c
下载Dahdi源代码以便进行修改:dahdi-linux-2.1.0.4.tar.gz
放本公司提供的wctdm24xxp.c wctdm.c wcfxo.c放入代码目录进行编绎并安装
make, make install. 之后重启,修改chan_dahdi.conf文件进行配置
cidsignalling=dtmf
cidstart=polarity
cidbeforering=1
修改:/etc/dahdi/system.conf 及 indication.conf 里的国家代码为 cn
重新载入模块
modprobe dahdi
修改asterisk源代码里的chan_dahdi.c 里的代码为4000或更高
if (res <= 0) { ast_log(LOG_WARNING, "DTMFCID timed out waiting for ring. " "Exiting simple switch\n"; ast_hangup(chan); return NULL; }
f = ast_read(chan);
if (!f) break;
if (f->frametype == AST_FRAME_DTMF)
{ dtmfbuf[i++] = f->subclass;
ast_log(LOG_DEBUG, "CID got digit '%c'\n", f->subclass);
res = 4000; // at line 6156, change 2000 to 4000
}
ast_frfree(f);
if (chan->_state == AST_STATE_RING
|| chan->_state == AST_STATE_RINGING) break; /* Got ring */ }
重新编绎asterisk: make and make install
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
配置参数:
加载驱动参数 modprobe wctdm cidbeforering=1 cidbuflen=1 (or wctdm24xxp )
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
其它波型示例:
DTMF格式的波形(第一声响铃前送):
FSK格式(dahdi系统默认可收到CID)波形:
加上DTMF转FSK转接盒(可收到CID)的波型: