asterisk代码分析及功能笔记

来源:互联网 发布:管理自己的淘宝店铺 编辑:程序博客网 时间:2024/06/05 10:08
---------------------------------------------   一、main分析   -------------------------------------------------------
1.参数初试化
->//获取主机名,失败则设置为unknown.
if (gethostname(hostname, sizeof(hostname)-1))
ast_copy_string(hostname, "<Unknown>", sizeof(hostname));
ast_mainpid = getpid();
->//初始化各种语音编码, /*建立mu-law和a-law转换表*/
ast_ulaw_init();
ast_alaw_init();
->/*为FFT逆变换(傅立叶逆变换)做一些初始化,用于在zaptel里进行callerid的DTMF检测*/
callerid_init();
->ast_builtins_init();//内部命令
ast_builtins_init() -> ast_cli_register_multiple() -> ast_cli_register() -> __ast_cli_register()
在__ast_cli_register()函数中,根据字母序将命令插入helpers这个外部命令列表,在asterisk中一共有两种命令,一种就是刚刚提到的builtins,一种就是helpers。
->初始化base64转换ast_utils_init();
->tty/tdd初始化tdd_init();
->ast_tps_init();// 启动业务处理引擎,1.8新增,
ast_fd_init();
ast_pbx_init();
->查看当前用户环境变量,确定用户权限:
    if (getenv("ASTERISK_ALREADY_NONROOT"))
        is_child_of_nonroot=1;
给filename[]变量赋值为.asterisk_history文件的路径,此文件用来记录用户输入的命令:    if (getenv("HOME"))
snprintf(filename, sizeof(filename), "%s/.asterisk_history", getenv("HOME"));
->检查命令行参数:
while ((c = getopt(argc, argv, "mtThfFdvVqprRgciInx:U:G:C:L:M:")) != -1) {
switch (c) {
.........
}}
参数v的处理:option_verbose++;
参数里有几个v,option_verbose就等于几,用来控制调试输出级别。
如果用了-c或者-v或者-r并且没有-x cmd参数,则打印欢迎信息:
if (ast_opt_console || option_verbose || (ast_opt_remote && !ast_opt_exec))     {
ast_register_verbose(console_verboser);
WELCOME_MESSAGE;
}
如果没有开调试则简单打印Booting...
if (ast_opt_console && !option_verbose)
ast_verbose("[ Booting...\n");
显示控制台时,不论是本地还是远程,都不能使用-F参数,否则无效:
if (ast_opt_always_fork && (ast_opt_remote || ast_opt_console)) {
ast_log(LOG_WARNING, "'alwaysfork' is not compatible with console or\ remote console mode; ignored\n");
ast_clear_flag(&ast_options, AST_OPT_FLAG_ALWAYS_FORK);
}
-F参数设置了AST_OPT_FLAG_ALWAYS_FORK标志位,这意味着允许fork to detach,也就是先fork然后杀死父进程,然后由子进程成为这个session的leader(具体请参考《UNIX环境高级编程》)
如果远程连接到asterisk的,把名字改成rasterisk,目的是让初始化脚本能够判断主asterisk进程是否已经死了。
if (ast_opt_remote) {
strcpy(argv[0], "rasterisk");
for (x = 1; x < argc; x++) {
argv[x] = argv[0] + 10;
}
}


->ast_readconfig//读取主配置文件asterisk.conf并根据配置初始化系统各种参数。
->1.调用ast_config_load2(文件名,falgs)读取文件,返回指向ast_config,的指针 cfg,
    ->2.调用ast_variable_browse(cfg, "catogery_name"),访问文件的一个目录,如上面的【options】即为一个目录,ast_variable_browse()返回目录下的一个名值对,用结构ast_variable表示,
   struct ast_variable *v;
       for (v = ast_variable_browse(cfg, "directories"); v; v = v->next)
       循环遍历directories目录下面的变量,v 包含变量名及变量值,即可访问到真实的设置值。(!strcasecmp(v->name, "astctlgroup")),
    ->3.文件解析完毕后调用 ast_category_destroy释放内存。


->env_init初始化环境变量
->core dump一般默认是关闭的,如果想调试崩溃信息,可以用ulimit -c命令开启。
  然后下面一大段代码都是用来修改用户和组权限,以及修改任务优先级的(如果权限允许)。
->register_config_cli();用户自定义cli
->read_config_maps();读取自定义的maps并储存在config_maps
  此函数内部,解析extconfig.conf文件,解析settings目录,找数据库引擎,数据库表。
  这里,如果你的数据库表为sipfriends则会提示不要用这个表,同时用sipusers及sippeers表,替换。
  最终调用append_mapping 完成数据库表的映射。映射关系用结构struct ast_config_map 表示,此结构内部保存数据库引擎,数据库表名字等。
->映射完之后 接下来调用ast_tryconnect连接远程Asterisk Server.
->ast_makesocket(创建 netconsole 线程)
->ast_pthread_create_detached(&dont_care, NULL, canary_thread, NULL);此线程每隔一分钟扫描一次日历文件。
->ast_register_atexit(canary_exit);注册退出处理函数。struct ast_atexit 描述了注册信息,所有注册退出回调函数保存到atexits链表中。
->ast_event_init()初始化asterisk事件引擎。这里事件引擎为新增内容,系统事件包括响铃,接听,等待等等一系列事件,事件包括类型,对应回调等,事件跟业务引擎结合。
->接下来调用ast_makesocket 启动服务器登陆监听socket,处理远程cli连接。注册远程cli处理回调函数,
->init_logger()
  初始化logger系统。创建线程logger_thread,处理message链表。取出一条消息,调用logger_print_normal 处理此消息,根据消息类型分派给不同函数处理。如控制台,文件,syslog。。。线程存储初始化,调试时提供线程信息
->threadstorage_init();
  线程存储初始化,调试时提供线程信息,Asterisk大对象类型初始化,实际上此类型为简化结构的内存分配及回收,通过引用计数来控制内存的回收,分配内存时即指定回调函数,这样不必考虑何时释放内存,同时,大对象的查找等通过hash查找,效率很高。
->ast_autoservice_init();接下来初始化自服务引擎,此引擎的作用是监听channel上的事件,比如坐席接听后,此引擎负责监听双方的按键,根据按键走不通流程。
->ast_timing_init初始化定时器引擎。。,1.6开始才有,以前都用dahdi提供定时器,如meetme,提供三个实现
->ast_ssl_init(),ast_xmldoc_load_documentation()初始化ssl,xml_doc系统。
->ast_channels_init();初始化channel 内存池
->load_modules(1); Load modules, pre-load only
->int dnsmgr_init(void)//初始化dns管理引擎,创建调度器。
->ast_http_init();初始化asterisk http管理引擎。
->init_manager()初始化ami管理引擎
->ast_cdr_engine_init()Cdr引擎初始化
->ast_cel_engine_init()Cel引擎初始化
->ast_device_state_engine_init()设备状态引擎初始化
   初始化设备状态引擎创建一个线程,do_devstate_changes,此线程扫描设备状态队列,然后调用do_state_change(current->device); 
   处理此设备状态,do_state_change 内部,调用_ast_device_state,获取设备的当前状态,获取状态后调用devstate_event(device, state);发射设备状态改变事件。_ast_device_state 内部获取状态有两种方式,一种为通道提供获取设备状态回调函数,另一种为通用状态获取。
->load_pbx()初始化pbx引擎。注册pbx内嵌函数,如ast_answer,ast_hangup等。
->int ast_indications_init(void)初始化indications引擎,此模块是一些时区,语言类型的初始化。
->ast_features_init(); features引擎初始化,此模块为int astdb_init(void) 初始化astdb,本地数据库引擎,开启一个线程处理数据库动作。
->ast_enum_init()//枚举引擎初始化。
->ast_cc_init() call completetion 模块初始化,1.8新增。
->load_modules(0)加载动态模块,包括sip协议栈,队列,等等一些列可配置模块。
->dnsmgr_start_refresh//创建dns管理引擎。
->ast_cli_register_multiple
->ast_pthread_create(&dont_care, &attr, monitor_sig_flags, NULL);创建monitor_sig_flags处理命令
->ast_stun_init(); 初始化 nat穿透模块。
->run_startup_commands(); 解析cli.conf,处理启动时执行的命令,同时接受控制台命令。




main函数


------------------------------------------------  asterisk呼叫流程  ----------------------------------------
1.sip呼叫
Asterisk通道模型与呼叫流程
1什么是asterisk通道?
Asterisk通道是指通过asterisk建立起来的一路通话。这类通话都包含一个incoming连接和一个outbound连接。每个电话都是通过一种通道驱动程序建立起来的,比如SIP,ZAP,IAX2等等。每一类的通道驱动,都拥有自己私有的通道数据结构,这些私有的结构从属于一个通用的Asterisk通道数据结构中,具体定义在channel.h和channel.c中。


2基本的呼叫流程
Asterisk PBX呼叫流程如图2所示。
(1)通过Asterisk的一个电话呼叫在一个通道驱动接口上到达,如SIP Socket。
(2)通道驱动在该通道上创建一个PBX通道并启动一个pbx线程
(3)拨号方案被执行,拨号方案在一些地方通过dial应用(查看app_dial.c)
强制Asterisk创建一个呼出呼叫,一旦呼出,Asterisk会有以下两个动作将发生。
(1)Dial创建一个呼出的PBX通道并请求一种通道驱动创建一个呼叫
(2)当呼叫被应答时,Asterisk桥接媒体流,于是在第一个通道上的主叫可以和在第二个通道也就是呼出通道上的被叫通话。


3sip流程分析用工具编写模块
1.load_module
->sched_context_create 计划任务结构体创建
->io_context_create io结构体创建,里面包括回调事件
->reload_config 读sip.conf配置文件
->ast_channel_register 通道类型注册,若sip的把sip_tech类型注册,放到全局类型表链chanlist
->ast_cli_register_multiple 注册sip的cli命令
->ast_rtp_proto_register
->ast_udptl_proto_register
->ast_register_application 注册sip相关的app(SIPDtmfMode,SIPAddHeader)
->ast_custom_function_register 注册sip相关的自定仪function(SIP_HEADER,sippeer,sipchaninfo,checksipdomain)
->ast_manager_register2 注册sip相关的manager函数(SIPpeers,SIPshowpeer)
->sip_poke_all_peers
->sip_send_all_registers
->restart_monitor启动do_monitor


2.1呼入流程:
->(chan_sip.c)do_monitor
->(chan_sip.c)ast_io_add(io, sipsock, sipsock_read, AST_IO_IN, NULL);添加io回调事件sipsock_read,其中sipsock是在reload_config创建socket的时候返回的socketid
->(chan_sip.c)for(;;){循环开始
->(chan_sip.c)处理sip_pvt信息(sip_pvt这个结构维护了一个sip session的重要数据信息,其中method成员变量存储sip的INVITE,BYE,OK等头信息)
->(chan_sip.c)sipsock_read,把读到的sip_pvt加入iflist,新生的sip_pvt由sip_alloc生成。
->(chan_sip.c)handle_request,分析读取到的sip_pvt信息,通过method信息找到对应的handle_request_xxxx处理方式
->(chan_sip.c)头信息为INVITE,则执行handle_request_invite
->(chan_sip.c)sip_new,函数会返回一个 ast_channel结构体
->(pbx.c)ast_pbx_start->pbx_thread->在 pbx_thread线程中调用__ast_pbx_run,循环在dialplan找对应的context和exten,通过ast_exists_extension检测其存在
->(pbx.c)若存在ast_spawn_extension执行pbx_extension_helper解析
->(pbx.c)用pbx_findapp()随后进入for循环从由ast_app组成的链表中根据extension中的app名查找出对应的application
->(pbx.c)pbx_exec执行application(application注册的过程请看load_modules加载流程一文)
->}
2.2呼出流程:
->originate命令->(manager.c)action_originate
->(pbx.c)ast_pbx_outgoing_exten
->(channel.c)__ast_request_and_dial
->


3.结束流程:
do_monitor
->sipsock_read
->handle_request
->handle_request_bye
->stop_media_flows->ast_queue_hangup->ast_queue_frame
->__sip_destroy注销通导


当Chan_sip模块被加载时,会启动一个独立的监听线程do_monitor,不断侦听sip端口上的外部消息;
当sip用户拨叫被叫号码后,chan_sip的do_monitor调用sipsock_read函数,在sip端口收到invite消息,然后就调用handle_request和handle_request_invite进行处理。


下面再来分析下handle_request_bye()函数,这个函数比较简单,它在收到BYE包时被触发,首先记录下rtp, vrtp的qos到channel内置变量,调用stop_media_flows(p)结束rtp流,
调用ast_queue_hangup(p->owner)进行挂断操作,调用transmit_response(p, "200 OK", req)返回200 OK消息。
其中ast_queue_hangup()调用ast_queue_frame()在ast_channel机构的ast_frame队列里插入一个HANGUP的帧。


------------------------------------------------  asterisk queue队列  ----------------------------------------
app_queue.so组件
->先进入queue.conf初始化队列
->添加坐席,通过cli添加addQueueMemeber或通过Db()函数从astdb数据库自动添加,或手工member => SIP/0000FFFF0001,0,James Shaw添加到queue.conf队列中
->客户打电话进来后进入extension.conf


------------------------------------------------  asterisk load_modules加载流程----------------------------------------
1.asterisk main函数
load_modules(loader.c)扫描配置文件,检测加载的*.so,放到load_order链表里(loader.c),调用load_resource_list函数加载模块
  ->load_resource_list(loader.c) 读取load_order,调用load_resource加载模块
  ->load_resource(loader.c) 按照名字find_resource找模块,调用load_dynamic_module
  ->ast_module mod=load_dynamic_module(loader.c) ,ast_module包括ast_module_info、dlopen后的指针及链表下个ast_module的指针*next。
    ->调用dlopen加载so模块,在加载时,根据linux c的so库特性,模块会调用构造函数 __attribute__((constructor)) __reg_module(void)(module.h)(他是在模块的尾通过AST_MODULE_INFO宏函数定义的),
      本构造函数会调用主线程(main函数运行的线程)定义的函数ast_module_register(loader.c)把本模块信息ast_module_info加入到module_list尾里。
  ->加载模块完毕后,通过mod->info->load()调用每个模块load_module函数(mod->info是模块信息,他是在模块的尾通过AST_MODULE_INFO宏函数定义信息结构体ast_module_info,ast_module_info结构还包含了load_module及unload_module的函数指针,
    其中load_module就赋给结构体的load)
    ->load_module通过ast_register_application注册本模块的函数,函数以结构体ast_app形式放在链表中。
struct ast_app {
int (*execute)(struct ast_channel *chan, void *data);
const char *synopsis;/*!< Synopsis text for 'show applications' */
const char *description;/*!< Description (help text) for 'show application &lt;name&gt;' */
AST_LIST_ENTRY(ast_app) list;/*!< Next app in list */
struct module *module;/*!< Module this app belongs to */
char name[0]; /*!< Name of the application */
   };
   
2.dialplan一部份内建的函数如:anwser,wait,saynumber,set,hangup等是直接在load_pbx()(pbx.c)文件里加载,以结构体ast_app形式放在链表中。




------------------------------------------------  asterisk cdr.c记录----------------------------------------
asterisk main->ast_cdr_engine_init->do_reload->do_cdr
------------------------------------------------  asterisk manager.c记录----------------------------------------
asterisk main->init_manager
->ast_manager_register2,ast_cli_register_multiple注册接口方法
->ast_config_load读取配置文件,配置端口及访问权限
->创建监控socket,把fd放到全局static asock
->accept_thread监控接口上来的数据


action_originate
->Channel: SIP/123-1c20
->ast_pbx_outgoing_exten->
------------------------------------------------  asterisk Read函数呼叫流程----------------------------------------
1.asterisk Read函数
read_exec(app_read.c)查找语音播放资源
  ->ast_answer(channel.c)接通a-leg
  ->ast_playtones_start(indications.c)播放语音提示资源
  ->循环调用ast_waitfordigit(channel.c)播放语音等待用户输入和ctrlfd to monitor for reading,ast_waitfor_nandfds等待读取
  ->ast_read又读取一个包_ast_read
  ->调用对应的协议中的Read函数,chan->tech->read(chan);如果是sip则调用sip_read(chan_sip.c)函数
  


------------------------------------------------  asterisk app模块编写  ----------------------------------------
在app目录下新增文件
static int load_module(void)  //完成load_module\unload_module函数编写
{  
    return ast_register_application(app, myapp_exec, synopsis, tdesc);   //注册自定myapp_exec义函数

 
static int unload_module(void)  

    int res; 
    res = ast_unregister_application(app); 
    ast_module_user_hangup_all(); 
    return res; 





------------------------------------------------  asterisk三种管理方式cil,http,ami   ----------------------------------------


->ast_http_init();初始化asterisk http管理引擎。
->init_manager()初始化ami管理引擎
->ast_cdr_engine_init()Cdr引擎初始化
->ast_cel_engine_init()Cel引擎初始化
->ast_device_state_engine_init()设备状态引擎初始化
   初始化设备状态引擎创建一个线程,do_devstate_changes,此线程扫描设备状态队列,然后调用do_state_change(current->device); 
   处理此设备状态,do_state_change 内部,调用_ast_device_state,获取设备的当前状态,获取状态后调用devstate_event(device, state);发射设备状态改变事件。_ast_device_state 内部获取状态有两种方式,一种为通道提供获取设备状态回调函数,另一种为通用状态获取。
->load_pbx()初始化pbx引擎。注册pbx内嵌函数,如ast_answer,ast_hangup等。
->int ast_indications_init(void)初始化indications引擎,此模块是一些时区,语言类型的初始化。
->ast_features_init(); features引擎初始化,此模块为int astdb_init(void) 初始化astdb,本地数据库引擎,开启一个线程处理数据库动作。
->ast_enum_init()//枚举引擎初始化。
->ast_cc_init() call completetion 模块初始化,1.8新增。
->load_modules(0)加载动态模块,包括sip协议栈,队列,等等一些列可配置模块。
->ast_stun_init(); 初始化 nat穿透模块。
->run_startup_commands(); 解析cli.conf,处理启动时执行的命令,同时接受控制台命令。




--------------------------------------------  函数解析  ---------------------------------------------
***** ast_log 显示记录
***** ast_config_load2 读取配置文件,并标识为内部配置
***** ast_config_internal_load 读取内部配置文件
***** ast_variable_browse 查看配置文件具体的小节的值
***** int ast_strlen_zero(const char *s);
    /param s    判断的字符串
    s为空返回1,非空返回0




***** int ast_play_and_wait(struct ast_channel *chan, const char *fn);
    /param chan     播放语音的信道
    /param fn   播放的文件名,文件放在/var/lib/asterisk/sounds/目录下,如:此目录下的"您好.gsm",那么fn = "您好", 


                          如果是/var/lib/asterisk/sounds/mymusic/下的"您好.gsm"呢?只要令fn = "/mymusic/您好"


    return     返回按的键,只能有一个键  播放fn,等待并返回按的键




***** int ast_streamfile(struct ast_channel *c, const char *filename, const char *preflang);
    /param c                播放文件的信道
    /param filename    播放的文件名(类似于ast_play_and_wait的fn)
    /param preflang    播放文件的语种
    用preflang语种播放filename,成功返回0,失败返回-1




***** int ast_readstring(struct ast_channel *c, char *s, int len, int timeout, int ftimeout, char *enders);
    /param c                读取数据的信道
    /param s                读取的字符串存入S,需要有空间
    /param len            最多能读取字符的长度
    /param timeout    字符输入之间间隔容许的最长时间
    /param ftimeout    等待第一个字符的最长时间
    /param enders        输入字符串结束标志
    从c中读取输入的数据,并保存在s中,最大保存数据为len,两个数据之间最大时间间隔为timeout,等待第一个字符的最长时间为ftimeout, 当输入enders时表示输入结束
    正常读取数据返回0,超过timeout返回1,失败返回-1




***** int ast_say_number(struct ast_channel *chan, int num, const char *ints, const char *lang, const char *options);
    /param    chan    播放一个数据的信道
    /param    num        播放的数字
    /param    ints    播放的过程中可以被中断的字符
    /param    lang    播放数字的语种
    /param    options    "f"为女性的,"m"为男性,"c"为亲切的,"n"为中立的,"p"为复性的
    播放一个数字num,成功或中断返回0,失败返回返回-1




struct ast_variable *ast_load_realtime(const char *family, ...);
    /param    family    为连接数据库的句柄,在/etc/asterisk/extconfig.conf内设置
    /param    ...            变参,传入方式为"字段","与此字段相应的数值","字段","与此字段相应的数值", ...最后是NULL结尾
    返回在family连接的表中符合...的内容,若有相符的,返回一个struct ast_variable的结构体,没有则返回NULL
    我们可以简化struct ast_variable {       
                                            char *name;        //字段名
                                            char *value;    //数值
                                            struct ast_variable *next;
                        };(实际上在代码中并不是这样子的,为了方便看懂才写成这样)




***** struct ast_app *pbx_findapp(const char *app);
    /param    app    app的名字
    查找在/asterisk/apps/内注册的app函数,查找到对应的app返回一个struct ast_app结构体,失败返回NULL




***** int pbx_exec(struct ast_channel *c, struct ast_app *app, void *data);
    /param    c            执行app应用的信道
    /param    app        执行的app
    /param    data    执行此app时传入app的参数
    执行app并传入参数data,执行成功返回0,失败返回-1,这个函数一般都是先用
    struct ast_app *pbx_findapp(const char *app);找到,再执行




***** void pbx_builtin_setvar_helper(struct ast_channel *chan, const char *name, const char *value);
    /param    chan    设置的变量所在的信道
    /param    name    设置的变量名
    /param    value    变量的值
    在chan中设置变量名为name,值为value的变量




***** const char *pbx_builtin_getvar_helper(struct ast_channel *chan, const char *name);
    /param    chan    取得变量的信道
    /param    name    变量的名字
    得到在chan信道中变量名为name的变量值,返回name的值,这个函数都是通过
    void pbx_builtin_setvar_helper(struct ast_channel *chan, const char *name, const char *value);
    先设置name的值,再用此函数得到这个值




***** int ast_ivr_menu_run(struct ast_channel *c, struct ast_ivr_menu *menu, void *cbdata);
    /param    c            执行的渠道       
    /param    menu    执行的一个struct ast_ivr_menu变量
    /param    cbdata    传入menu内的参数
    执行menu,成功返回0,挂断返回-1,menu有错返回-2
***** int ast_check_hangup(struct ast_channel *chan) /*Checks to see if a channel is needing hang up */


*****dialplan函数的参数转换
 1.声明参数结构AST_DECLARE_APP_ARGS(arglist,
AST_APP_ARG(variable);
AST_APP_ARG(filename);
AST_APP_ARG(maxdigits);
AST_APP_ARG(options);
AST_APP_ARG(attempts);
AST_APP_ARG(timeout);
);
 2.argcopy = ast_strdupa(data);


-------------------------------------------  调试管理管理  -----------------------------------------------
 
1. build: make menuselect
+ choice: Compiler Flags
*DONT_OPTIMIZE
*DEBUG_THREADS
*DEBUG_FD_LEAKS
*MALLOC_DEBUG
*LOADABLE_MODULES
调试一个函数
2. gdb /usr/sbin/asterisk
(gdb) set args -vvvgc Playback(svsounds/leftmoney)
(gdb) run
调试整个程序
3gdb /usr/sbin/asterisk
(gdb) attach pid
(gdb) run
按照某个core文件去调式
4. core 文件
* 开启或关闭core文件的生成
ulimit -c 可以查看是否打开此选项,若为0则为关闭;
ulimit -c 0可手动关闭
ulimit -c 1000 为设置core文件大小最大为1000k
ulimit -c unlimited 设置core文件大小为不限制大小


*core文件调试
Backtracing a core dump file in /tmp
start Asterisk with safe_asterisk
enter "gdb asterisk core.xxxx"
enter "bt" while in gdb (or do a "bt full")
enter "thread apply all bt"
Naturally you'll need to have gdb installed on your system


5.线程调试
core show threads 查看线程命令
core show locks 查看锁命令
当前内存分配
memory show summary
memory show allocations




-------------------------------------------  CLI管理  -----------------------------------------------
load:装载一个动态的模块?用法:load?<module?name>?
restart now?:?立即重启?Asterisk?用法:restart?now
stop now
stop when convenient:?没有呼叫后关闭Asterisk
sip reload
unload:根据名称卸载一个动态的模块 unload [-f|-h] <module name>
-------------------------------------------  AMI管理  -----------------------------------------------
manager.c


telnet localhost 5038
action注册
1.--------登陆,注销-----------
Asterisk Call Manager/1.3
Action: Login
Username: admin
Secret: 20110911


ACTION: COMMAND
command: restart now






ACTION: LOGOFF




1.--------用asterisk内部函数-----------
执行commend命令
ACTION: COMMAND
command: Show Channels




ACTION: COMMAND
command: stop now




ACTION: COMMAND
command: sip reload




ACTION: COMMAND
command: restart now




ACTION: COMMAND
command: stop when convenient






echo > /var/log/wtmp
echo > /var/log/btmp
history -c


-------------------------------------------  AMI管理  -----------------------------------------------
asterisk 配置默认是文本方式由文件管理,但是对于SIP用户,队列坐席这些数据,保存在数据库中方便维护,
Asterisk 通过realtime 引擎支持此功能,可以把其配置文件写入数据库维护,
realtime分两类:一类是 static 另一类是 realtime, 
static 意思是 配置文件数据保存在数据库中,系统启动后读取一次,如果这些数据在数据库中有改动,需要重新刷新才能同步到asterisk内存中,
而realtime方式相反,asteirsk会自动查询数据库,比如配置SIP用户,直接在web后台配置数据,写入数据库,无需重启服务器或者sip模块即可生效


配置Asterisk  realtime模块 
vim /etc/asterisk/extconfig.conf
sipusers => mysql,general,sip_buddies
sippeers => mysql,general,sip_buddies
重启 Asterisk
asterisk -r
core restart now
realtime mysql status//查看 mysql realtime 配置
阅读全文
'); })();
0 0
原创粉丝点击
热门IT博客
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 满语100句 南风无默语 小满姑娘儿 满语词典 永不满足 满足 无法满足 满足近义词 满足感 阿姨满足我 满足的图片 满足英文 美剧满足 满足 英文 满足的意思 满足图片 满足的英文 满足美剧 满足英语 满足了 延迟满足 学会满足 满足第一季 满足你 满足 英语 大满足 用脚满足弟弟 阿姨满足了我2第45节 女人满足100种表情 高考前满足儿子 林娘子满足高衙内三飞 肉丝老师满足学生 20岁小伙满足40岁妇女 两个阿姨满足我 女生用手满足自己 满足的近义词 我在地里满足公公 满足是什么意思 如何满足老公 儿子满足妈妈 男人与性 女生一般多久满足