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

来源:互联网 发布:深圳java培训机构 编辑:程序博客网 时间:2024/05/15 11:21

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 }
 
原创粉丝点击