asterisk核心框架.docx
- 文档编号:7179513
- 上传时间:2023-01-21
- 格式:DOCX
- 页数:27
- 大小:32.49KB
asterisk核心框架.docx
《asterisk核心框架.docx》由会员分享,可在线阅读,更多相关《asterisk核心框架.docx(27页珍藏版)》请在冰豆网上搜索。
asterisk核心框架
Asterisk是一个开源的pbx系统,在公开的资料中,很难找到asterisk内核系统的详细描述。
因此,很有必要写一篇内核框架的描述文档,作为内部培训文档,相互学习提高。
本文主要从三个层面来描述asterisk内核,即asterisk内核模块、内核启动过程、基本呼叫流程。
一、asterisk内核模块
Asterisk由内部核心和外围动态可加载模块组成。
内部核心由以下六个部分组成:
PBX交换核心模块(PBXSwitchingCore)、调度和I/O管理模块(SchedulerandI/OManager)、应用调用模块(ApplicationLauncher)、编解码转换模块(CodecTranslator)、动态模块加载器模块(DynamicModuleLoader)和CDR生成模块(CDRCore)。
外围动态可加载模块包括以App_开始的Applications、以Func_开始的Functions、以Res_开始的Resources、以Chan_开始的channels、以Codec_开始的codec编解码模块等。
1.内核模块
1)PBX交换核心模块(PBXSwitchingCore):
lpbx.c
pbx.c是asterisk的核心模块,每路呼叫都需要经过它调度。
pbx实现了builtinapplications,也就是内置的应用,比如最常见的Answer,Hangup,Background,Wait等等。
structast_app是一个关键数据结构,它定义了注册builtinapplications的结构。
load_pbx函数用来注册builtinapplications和一些命令行CLI命令(每个模块都有些CLI命令)。
该函数在系统启动时被调用。
pbx_exec是Answer/BackGround/Busy/Goto/GotoIf/Hangup/Set等builtinapplications的执行入口函数,它被pbx_extension_helper调用。
ast_pbx_start函数是每路呼叫的起点。
2)调度和I/O管理模块(SchedulerandI/OManager):
lChannel.c:
Channel.c/channel.h定义了channel操作的结构体和接口函数。
structast_channel_tech结构体是所有channel都要用到的关键结构体,它定义channel操作的一系列回调函数指针,如call、hangup、answer等。
每个channel模块都会定义ast_channel_tech的实体,并将各自的回调函数赋值给它。
例如chan_sip.c中定义如下:
/*!
\briefDefinitionofthischannelforPBXchannelregistration*/
staticconststructast_channel_techsip_tech={
.type="SIP",
.description="SessionInitiationProtocol(SIP)",
.capabilities=((AST_FORMAT_MAX_AUDIO<<1)-1),
.properties=AST_CHAN_TP_WANTSJITTER|AST_CHAN_TP_CREATESJITTER,
.requester=sip_request_call,
.devicestate=sip_devicestate,
.call=sip_call,
.hangup=sip_hangup,
.answer=sip_answer,
.read=sip_read,
.write=sip_write,
.write_video=sip_write,
.indicate=sip_indicate,
.transfer=sip_transfer,
.fixup=sip_fixup,
.send_digit_begin=sip_senddigit_begin,
.send_digit_end=sip_senddigit_end,
.bridge=ast_rtp_bridge,
.send_text=sip_sendtext,
.func_channel_read=acf_channel_read,
};
ast_call、ast_hangup、ast_answer等函数分别实现ast_channel_tech中的call、hangup、answer等回调函数的调用。
structast_channel结构体定义了channel的上下文参数,它是每个参与呼叫的channel必不可少的,都会调用ast_channel_alloc来申请ast_channel。
lio.c
io.c实现了asterisk跟外部交互时的I/O管理,如chan_sip为了从外部接收SIP信令,调用ast_io_add添加IO接口,并调用ast_io_wait实现外部消息接收。
3)应用调用模块(ApplicationLauncher):
在pbx.c中定义了一系列的应用调用接口。
applications模块定义了application回调函数并注册后,在pbx.c中通过应用调用接口回调执行。
应用调用接口的关键函数是pbx_extension_helper,它执行dialplan,在cli上打印“Executing……”,并抛出amievent事件,同时调用pbx_exec执行application回调函数。
4)编解码转换模块(CodecTranslator):
Translate.c:
structast_translator:
编码转换描述结构体,它定义了编码转换的名称、回调函数、运行时选项。
structast_trans_pvt:
编码转换上下文描述结构体。
ast_register_translator:
编码转换注册接口函数,供各编码模块调用,注册structast_translator类型的结构体变量。
ast_unregister_translator:
编码转换注销函数
ast_translate:
编码转换的执行函数。
codec_gsm.c/codec_...:
对应各种编码的编解码执行模块,如g.711alaw/g.711ulaw/gsm等。
5)动态模块加载器模块(DynamicModuleLoader):
该模块主要是Module.h。
Module.h中定义了structast_module_info结构,用来保存各模块的注册、注销回调函数,以及模块描述信息。
load_module、unload_module,每个应用模块的注册、注销函数,由各个模块自行定义为static函数。
AST_MODULE_INFO_STANDARD:
注册接口、注销接口、模块描述信息等模块信息的登记接口。
它是一个宏定义,动态模块调用它时,首先定义类型为ast_module_info的__mod_info静态结构变量,保存模块信息,并定义__attribute__((constructor))__reg_module和__attribute__((destructor))__unreg_module,在程序启动和退出时调用。
6)CDR生成模块(CDRCore):
Cdr.c:
ast_cdr_register:
cdrdriver注册,供cdr_mysql等调用,注册话单保存的回调函数。
ast_cdr_engine_init:
CDR模块初始化,注册cdrstatus、加载cdr.conf、启动CDR线程。
ast_cdr_detach:
产生话单的接口函数,呼叫结束时被调用。
2.外围可加载模块:
1)Applications
以app_开始的模块,如app_dial.c、app_db.c、app_queue.c、app_record.c、app_meetme.c等,代码保存在apps目录中。
每个application模块都定义了load_module函数和unload_module函数,分别用来注册和注销application。
load_module函数调用ast_register_application函数,注册application命令,例如app_dial模块注册Dial:
res=ast_register_application(app,dial_exec,synopsis,descrip)。
unload_module函数调用ast_unregister_application函数,注销application命令。
每个application模块都会使用AST_MODULE_INFO_STANDARD宏来登记模块信息__mod_info。
AST_MODULE_INFO_STANDARD将load_module和unload_module注册为回调函数,供moduleload/unload/reload调用。
2)Channel
以chan_开始的模块,如chan_sip.c、chan_h323.c、chan_mgcp.c、chan_iax2.c、chan_zap.c等,对应代码保存在channels目录中。
channel注册、注销过程和application基本类似。
由于每个channel需要和外部交互,都会在load_module中启用do_monitor线程来侦听外部tcp/udp端口,接收外部消息。
每个channel也定义了各自的cli命令和Function命令,例如chan_sip定义了sipdebug/history/no/notify/prune/reload/set/show等cli命令和SIP_HEADER、CHECKSIPDOMAIN、SIPPEER、SIPCHANINFO等Function命令。
3)Functions
以Fun_开始的模块,例如Fun_db.c、func_moh.c、func_cdr.c等,对应代码保存在funcs目录中。
Function注册、注销过程也和application类似。
每个Function模块也定义了各自的Function命令,例如Fun_db.c就定义了DB、DB_EXISTS、DB_DELETE等Function命令。
二、asterisk启动过程
主要就main函数讲解asterisk的启动过程:
1intmain(intargc,char*argv[])
2
3{
4
5intc;
6
7charfilename[80]="";
8
9charhostname[MAXHOSTNAMELEN]="";
10
11chartmp[80];
12
13char*xarg=NULL;
14
15intx;
16
17FILE*f;
18
19sigset_tsigs;
20
21intnum;
22
23intisroot=1;
24
25char*buf;
26
27char*runuser=NULL,*rungroup=NULL;
28
29/*保存命令行参数(argv[]->_argv[]),以便程序重启时使用*/
30
31/*Rememberoriginalargsforrestart*/
32
33if(argc>sizeof(_argv)/sizeof(_argv[0])-1){
34
35fprintf(stderr,"Truncatingargumentsizeto%d\n",(int)(sizeof(_argv)/sizeof(_argv[0]))-1);
36
37argc=sizeof(_argv)/sizeof(_argv[0])-1;
38
39}
40
41for(x=0;x 42 43_argv[x]=argv[x]; 44 45_argv[x]=NULL; 46 47if(geteuid()! =0) 48 49isroot=0; 50 51/*命令如果是rasterisk,设置AST_OPT_FLAG_NO_FORK和AST_OPT_FLAG_REMOTE标志位*/ 52 53/*iftheprognameisrasteriskconsideritaremoteconsole*/ 54 55if(argv[0]&&(strstr(argv[0],"rasterisk"))! =NULL){ 56 57ast_set_flag(&ast_options,AST_OPT_FLAG_NO_FORK|AST_OPT_FLAG_REMOTE); 58 59} 60 61/*得到当前主机名,在启动时打印出来*/ 62 63if(gethostname(hostname,sizeof(hostname)-1)) 64 65ast_copy_string(hostname," 66 67/*获取当前的进程标识*/ 68 69ast_mainpid=getpid(); 70 71/*建立mu-law和a-law转换表*/ 72 73ast_ulaw_init(); 74 75ast_alaw_init(); 76 77/*为FFT逆变换(傅立叶逆变换)做一些初始化,用于在zaptel里进行callerid的DTMF检测*/ 78 79callerid_init(); 80 81/*初始化内置命令的_full_cmd字符串,并注册常用命令,ast_builtins_init()->ast_cli_register_multiple()->ast_cli_register()->__ast_cli_register()*/ 82 83ast_builtins_init(); 84 85/*初始化base64转换*/ 86 87ast_utils_init(); 88 89/*tty/tdd初始化*/ 90 91tdd_init(); 92 93/*设置用户历史命令的保存路径*/ 94 95if(getenv("HOME")) 96 97snprintf(filename,sizeof(filename),"%s/.asterisk_history",getenv("HOME")); 98 99/*Checkforoptions*/ 100 101/*检查命令行的输入参数,匹配参数范围是“mtThfFdvVqprRgciInx: U: G: C: L: M: ”,不同的参数输入走到不同的case分支处理。 有几个v,verbose级别就增加几*/ 102 103while((c=getopt(argc,argv,"mtThfFdvVqprRgciInx: U: G: C: L: M: "))! =-1){ 104 105switch(c){ 106 107#ifHAVE_WORKING_FORK 108 109case'F': 110 111ast_set_flag(&ast_options,AST_OPT_FLAG_ALWAYS_FORK); 112 113break; 114 115case'f': 116 117ast_set_flag(&ast_options,AST_OPT_FLAG_NO_FORK); 118 119break; 120 121#endif 122 123case'd': 124 125option_debug++; 126 127ast_set_flag(&ast_options,AST_OPT_FLAG_NO_FORK); 128 129break; 130 131case'c': 132 133ast_set_flag(&ast_options,AST_OPT_FLAG_NO_FORK|AST_OPT_FLAG_CONSOLE); 134 135break; 136 137case'n': 138 139ast_set_flag(&ast_options,AST_OPT_FLAG_NO_COLOR); 140 141break; 142 143case'r': 144 145ast_set_flag(&ast_options,AST_OPT_FLAG_NO_FORK|AST_OPT_FLAG_REMOTE); 146 147break; 148 149case'R': 150 151ast_set_flag(&ast_options,AST_OPT_FLAG_NO_FORK|AST_OPT_FLAG_REMOTE|AST_OPT_FLAG_RECONNECT); 152 153break; 154 155case'p': 156 157ast_set_flag(&ast_options,AST_OPT_FLAG_HIGH_PRIORITY); 158 159break; 160 161case'v': 162 163option_verbose++; 164 165ast_set_flag(&ast_options,AST_OPT_FLAG_NO_FORK); 166 167break; 168 169case'm': 170 171ast_set_flag(&ast_options,AST_OPT_FLAG_MUTE); 172 173break; 174 175case'M': 176 177if((sscanf(optarg,"%d",&option_maxcalls)! =1)||(option_maxcalls<0)) 178 179option_maxcalls=0; 180 181break; 182 183case'L': 184 185if((sscanf(optarg,"%lf",&option_maxload)! =1)||(option_maxload<0.0)) 186 187option_maxload=0.0; 188 189break; 190 191case'q': 192 193ast_set_flag(&ast_options,AST_OPT_FLAG_QUIET); 194 195break; 196 197case't': 198 199ast_set_flag(&ast_options,AST_OPT_FLAG_CACHE_RECORD_FILES); 200 201break; 202 203case'T': 204 205ast_set_flag(&ast_options,AST_OPT_FLAG_TIMESTAMP); 206 207break; 208 209case'x': 210 211ast_set_flag(&ast_options,AST_OPT_FLAG_EXEC); 212 213xarg=ast_strdupa(optarg); 214 215break; 216 217case'C': 218 219ast_copy_string(ast_config_AST_CONFIG_FILE,optarg,sizeof(ast_config_AST_CONFIG_FILE)); 220 221ast_set_flag(&ast_options,AST_OPT_FLAG_OVERRIDE_CONFIG); 222 223break; 224 225case'I': 226 227ast_set_flag(&ast_options,AST_OPT_FLAG_INTERNAL_TIMING); 228 229break; 230 231case'i': 232 233ast_set_flag(&ast_options,AST_OPT_FLAG_INIT_KEYS); 234 235break; 236 237case'g': 238 239ast_set_flag(&ast_options,AST_OPT_FLAG_DUMP_CORE); 240 241break; 242 243case'h': 244 245show_cli_help(); 246 247exit(0); 248 249case'V': 250 251show_version(); 252 253exit(0); 254 255case'U': 256 257runuser=ast_strdupa(optarg); 258 259break; 260 261case'G': 262 263rungroup=ast_strdupa(optarg); 264 265break; 266 267case'? ': 268 269exit (1); 270 271} 272 273} 274 275/
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- asterisk 核心 框架
![提示](https://static.bdocx.com/images/bang_tan.gif)