深入浅出asterisk(五):pbx.c代码分析

pbx.c主要实现了builtin applications,也就是内置的应用,比如最常见的Answer,Hangup, Background,Wait等等。

/main/asterisk.c中有一段代码调用load_pbx()负责加载builtin applications

02895    if (load_pbx()) {
   
   
02896       printf(term_quit());
   
   
02897       exit(1);
   
   
02898    }
   
   

这个load_pbx()函数就是实现在pbx.c中,它的主要任务是遍历全局数组builtins中每个application信息,调用ast_register_application()注册application的各自入口函数。

06046    /* Register builtin applications */
    
    
06047    for (x=0; x<sizeof(builtins) / sizeof(struct pbx_builtin); x++) {
   
   
06048       if (option_verbose)
   
   
06049          ast_verbose( VERBOSE_PREFIX_1 "[%s]/n", builtins[x].name);
   
   
06050       if (ast_register_application(builtins[x].name, builtins[x].execute, builtins[x].synopsis, builtins[x].description)) {
   
   
06051          ast_log(LOG_ERROR, "Unable to register builtin application '%s'/n", builtins[x].name);
   
   
06052          return -1;
   
   
06053       }
   
   
06054    }
   
   

比如Hangup应用的入口函数就是pbx_builtin_hangup()

00364    { "Hangup", pbx_builtin_hangup,
   
   
00365    "Hang up the calling channel",
   
   
00366    "  Hangup([causecode]): This application will hang up the calling channel./n"
    
    
00367    "If a causecode is given the channel's hangup cause will be set to the given/n"
    
    
00368    "value./n"
    
    
00369    },
   
   

 

 

下面我们分析一下pbx_builtin_hangup()函数,这个函数查看参数data调用ast_str2cause()获取挂断码,如果没有获取到,则设置chan->hangupcause

AST_CAUSE_NORMAL_CLEARING,也就是0

05448 /*!
    
    
05449  * /ingroup applications
    
    
05450  */
    
    
05451 static int pbx_builtin_hangup(struct ast_channel *chan, void *data)
   
   
05452 {
   
   
05453    if (!ast_strlen_zero(data)) {
   
   
05454       int cause;
   
   
05455       char *endptr;
   
   
05456 
   
   
05457       if ((cause = ast_str2cause(data)) > -1) {
   
   
05458          chan->hangupcause = cause;
   
   
05459          return -1;
   
   
05460       }
   
   
05461       
   
   
05462       cause = strtol((const char *) data, &endptr, 10);
   
   
05463       if (cause != 0 || (data != endptr)) {
   
   
05464          chan->hangupcause = cause;
   
   
05465          return -1;
   
   
05466       }
   
   
05467          
   
   
05468       ast_log(LOG_NOTICE, "Invalid cause given to Hangup(): /"%s/"/n", (char *) data);
   
   
05469    }
   
   
05470 
   
   
05471    if (!chan->hangupcause) {
   
   
05472       chan->hangupcause = AST_CAUSE_NORMAL_CLEARING;
   
   
05473    }
   
   
05474 
   
   
05475    return -1;
   
   
05476 }
   
   

看看pbx_exec()函数,这个函数是所有application被调用的入口处。它首先保存channel的两个变量,appldata,分别表示正在调用的application名和参数。然后调用app->execute(c, data)进入真正的处理,完后恢复appldata的值,有点像堆栈的管理

00507 /*
    
    
00508    /note This function is special. It saves the stack so that no matter
    
    
00509    how many times it is called, it returns to the same place */
    
    
00510 int pbx_exec(struct ast_channel *c,       /*!< Channel */
    
    
00511         struct ast_app *app,     /*!< Application */
    
    
00512         void *data)        /*!< Data for execution */
    
    
00513 {
   
   
00514    int res;
   
   
00515 
   
   
00516    const char *saved_c_appl;
   
   
00517    const char *saved_c_data;
   
   
00518 
   
   
00519    if (c->cdr &&  !ast_check_hangup(c))
   
   
00520       ast_cdr_setapp(c->cdr, app->name, data);
   
   
00521 
   
   
00522    /* save channel values */
    
    
00523    saved_c_appl= c->appl;
   
   
00524    saved_c_data= c->data;
   
   
00525 
   
   

  
  
   
   00526    c
  
  ->appl = app->name;
   
   

  
  
   
   00527    c
  
  ->data = data;
   
   
00528    /* XXX remember what to to when we have linked apps to modules */
    
    
00529    if (app->module) {
   
   
00530       /* XXX LOCAL_USER_ADD(app->module) */
    
    
00531    }
   
   
00532    res = app->execute(c, data);
   
   
00533    if (app->module) {
   
   
00534       /* XXX LOCAL_USER_REMOVE(app->module) */
    
    
00535    }
   
   
00536    /* restore channel values */
    
    

  
  
   
   00537    c
  
  ->appl = saved_c_appl;
   
   

  
  
   
   00538    c
  
  ->data = saved_c_data;
   
   
00539    return res;
   
   
00540 }
   
   
 
  • 0
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值