登录  
 加关注
   显示下一条  |  关闭
温馨提示!由于新浪微博认证机制调整,您的新浪微博帐号绑定已过期,请重新绑定!立即重新绑定新浪微博》  |  关闭

baikgd的博客

技术是工具,生活是目的,更好的生活是目标!

 
 
 

日志

 
 

Asterisk Internal Architecture Overview   

2008-10-07 14:40:14|  分类: Asterisk |  标签: |举报 |字号 订阅

  下载LOFTER 我的照片书  |
This page tries to present an overview of the Asterisk core.

The information here is based on my study of the Asterisk source at a point (May 2005) where I was a relative newcomer to Asterisk, and needed this information in order to program a new channel driver. Corrections and additions welcome!

Channels


Call processing in Asterisk is centered around channel drivers. Many channel drivers are included with Asterisk in the channels/ subdirectory; other channel drivers are available separately. Channel drivers handle all the protocol-specific details of ISDN, SIP, and other telephony protocols and interface them to Asterisk.
Some channel drivers (like chan_local and chan_agent) work as "proxy channels" and do not directly interface to real protocols or hardware.

A channel driver is a shared object (.so) file that is loaded dynamically into Asterisk as a module. Modules are usually loaded automatically from modules.conf, but may also be loaded/unloaded explicitly from the CLI with the load and unload commands. Use show channeltypes to list all loaded channel drivers.

A channel driver must export the functions load_module(), unload_module(), usecount(), description(), and key(). Since Asterisk applications are also modules, the example skeleton application in apps/app_skel.c may be useful to get started with channel drivers.

The main task of the module part of the channel driver is to have the load_module() entry point call ast_channel_register() with a pointer to its struct ast_channel_tech. This is what makes the channel driver available in Asterisk.

Channel Technology Descriptor


The struct ast_channel_tech is the channel technology descriptor and defines the complete behaviour of the channel driver. It includes

  • The type name used to reference the channel (eg. `SIP'); this is used as the part before the slash in Dial(SIP/xxx).
  • Textual description.
  • Set of audio formats supported (ULAW, GSM, ...).
  • Callback functions called by Asterisk to initiate and manage calls to and from the channel.

The requester callback is used to reserve a single channel from the driver (some channels like an E1 PRI interface has a limited number of channels available). It calls ast_channel_alloc() to allocate a new struct ast_channel and returns it. It also fills in the tech_pvt field with a pointer to a channel private structure that holds driver-specific data. All other operations on the channel reference the struct ast_channel. The requester callback does not block waiting for I/O. Called by ast_request().

The call callback initiates outgoing calls on the channel. It may block on I/O waiting to get the call established, but it does not wait for the remote end to answer (that is indicated by returning an AST_CONTROL_ANSWER control frame from the read callback). Called by ast_call().

The main call processing happens in the read and write callbacks. A channel does not have a specific OS thread associated with it (though a driver is free to create one for it if necessary). Instead the driver registers one or more file descriptors in the fds field of struct ast_channel. When data becomes available on any of the file descriptors, the read callback is called (via ast_read() to read the data and return an appropriate frame. This includes incoming audio data, but also control frames indicating things like remote answer or hangup; see frame.h for possible frame types. The driver may also inject frames outside of the read callback using ast_queue_frame() or ast_queue_control() (this may require calling ast_channel_alloc(1) to reserve an "alert pipe" if not using zaptel(?)). The write callback is called periodically by Asterisk (via ast_write()) to pass outgoing voice frames to the channel.

Getting things moving


The is no central "main loop" or kernel thread in Asterisk. Instead, processing is distributed among a number of threads, mainly of two kinds:

  • Dialplan threads, started by ast_pbx_start() to run a single instance/session of the dial plan. Such a thread may control multiple active channels at once, for example when forwarding a call with the Dial or Queue applications.
  • Channel driver monitor threads. Most channel drivers have a single monitor thread that listens for incoming calls. When a call arrives it is passed to ast_pbx_start() to start executing the dialplan.

When a thread is in control of one or more active channels, it must continously call ast_read() and ast_write() on these channels to keep the voice and control frames flowing. Again, there is no central loop in the code where this happens, instead custom read/write loops are used in each instance as appropriate. For example wait_for_answer() in the Dial application, ast_generic_bridge in channel.c to connect two channels during a conversation, and ast_waitstream() in file.c. The ast_waitfor*() family of functions are used in these loops to wait until input is available on a channel, at which point ast_read() is called on that channel (maybe passing the data on to ast_write() on another channel).

Conclusion


The overall flow of control in Asterisk is as follows:

  • Channel drivers monitor threads listen for incoming calls and starts dialplan threads for each new call with ast_pbx_start().
  • Dialplan threads run applications as specified by the dialplan.
  • Application commands process voice and control frames in processing loops alternating calls to ast_waitfor*() and ast_read()/ast_write(); and initiate new outgoing calls with ast_request() and ast_call().
  评论这张
 
阅读(510)| 评论(0)

历史上的今天

评论

<#--最新日志,群博日志--> <#--推荐日志--> <#--引用记录--> <#--博主推荐--> <#--随机阅读--> <#--首页推荐--> <#--历史上的今天--> <#--被推荐日志--> <#--上一篇,下一篇--> <#-- 热度 --> <#-- 网易新闻广告 --> <#--右边模块结构--> <#--评论模块结构--> <#--引用模块结构--> <#--博主发起的投票-->
 
 
 
 
 
 
 
 
 
 
 
 
 
 

页脚

网易公司版权所有 ©1997-2018