分享

Asterisk模块编写3

 昵称7719523 2011-09-15
面是通过基本接口来为Asterisk提供更多功能系列文章的第三篇--Asterisk模块编写3--高级。 L=W8Q8 hf  
第一篇《Asterisk模块编写1--入门-gZI^EII  
第二篇《Asterisk模块编写2--进阶]i\C4*  
      在本文里,你将看到如何实现一个Asterisk CLI命令。CLI命令对于显示配置信息、统计信息和其它调试目的来说都是非常有用的。我们继续编辑上一篇文章中的那个res_helloworld2.c。 I9GRSm;0<  
      第一步是加载定义CLI命令接口的头文件: !e*BQ3  
#include "asterisk/cli.h" cX'&J_T+  
      下面是实现CLI命令“echo”的代码,简单地打印了CLI命令的第一个参数,后面会解释这个功能。 86(8p_&zC  
复制代码
  1. static char *handle_cli_echo(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
  2. {
  3.     switch (cmd) {
  4.     case CLI_INIT:
  5.         e->command = "echo";
  6.         e->usage =
  7.             "Usage: echo <stuff>\n"
  8.             "       Print back the first argument.\n"
  9.             "Examples:\n"
  10.             "       echo foo\n"
  11.             "       echo \"multiple words\"\n"
  12.             "";
  13.         return NULL;
  14.     case CLI_GENERATE:
  15.         return NULL;
  16.     }
  17.     if (a->argc == e->args) {
  18.         ast_cli(a->fd, "You did not provide an argument to echo\n\n");
  19.         return CLI_SHOWUSAGE;
  20.     }
  21.     ast_cli(a->fd, "%s\n", a->argv[1]);
  22.     return CLI_SUCCESS;
  23. }
|ho|Kl `=  
        这个CLI处理程序相匹配的CLI命令处理程序定义的函数原型。ast_cli_entry参数包括有关CLI命令正在执行的静态信息。当CLI命令非正常执行其他调用的时候,会设置cmd参数。该ast_cli_args参数包含这一命令一次执行的特定信息,如同命令参数。 sG{hUsPa  
                static char *handle_cli_echo(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) "Xq.b"N{*  
J}IHQZS  
        在函数的开头switch语句是用来处理cmd参数,以指示调用什么功能。有两种情况需要处理: NIn#  
  • CLI_INIT. 每个CLI命令处理程序都要执行一次 CLI_INIT. 用来要求函数说明命令是什么,用法是什么等。
  • CLI_GENERATE. This cmd is used for implementing tab completion. CLI commands that provide tab completion of arguments must add code here. Implementing tab completion may be explained in a later tutorial. For now, there are many examples throughout the code.
        下面这小段代码表示至少给函数提供了一个参数。值得注意的是,这里的ast_cli_entry参数用于检索多少命令本身定义的参数和ast_cli_args参数用于检索多少参数,实际上是在CLI命令行下执行此命令时指定的。如果它们相等,那么就能提供简单的“echo”。 H%c:f  
        if (a->argc == e->args) { r@;n \  
                ast_cli(a->fd, "You did not provide an argument to echo\n\n"); W| S{v7[l  
                return CLI_SHOWUSAGE; a!ao{8#  
        }  #P8R  
        最后,我们打印一个参数到CLI,返回 CLI命令成功执行的结果。 &HdzbKO=  
        ast_cli(a->fd, "%s\n", a->argv[1]); JY 4sB8  
        return CLI_SUCCESS;
1^<R2x  
        下一步增加包含在这个模块里的CLI命令表。我们将使用 AST_CLI_DEFINE() 为表增加单个入口。 AST_CLI_DEFINE 包含了CLI 命令处理函数的指针,以及这个命令时用来做什么的总结。 0'ha!4h3Z  
        static struct ast_cli_entry cli_helloworld[] = { |fYr*8rH  
                AST_CLI_DEFINE(handle_cli_echo, "Echo to the CLI"), Kt Wn08D!  
        }; wm> I;|gA)  
}[a  
        最后,就像我们在前面文章中提到的那样,我们要修改 load_module 和unload_module来把CLI命令表注册到Asterisk内核里。  [o]^\a y  
        卸载模块unload_module,加入: <[9{Lg*D  
                ast_cli_unregister_multiple(cli_helloworld, ARRAY_LEN(cli_helloworld)); }%z {tn  
        加载模块load_module,加入: U&W{; myt  
                ast_cli_register_multiple(cli_helloworld, ARRAY_LEN(cli_helloworld)); S%ULGX:@ga  
        就这样,重新编译安装这个模块,完整的代码请参见这个文件 res_helloworld3.c 。 l(;~9u0sa  
        然后您可以试试这个模块了: b(<#n6a}\  
复制代码
  1. *CLI> help echo
  2. Usage: echo
  3.        Print back the first argument.
  4. Examples:
  5.        echo foo
  6.        echo "multiple words"
  7. *CLI> echo
  8. You did not provide an argument to echo
  9. Usage: echo
  10.        Print back the first argument.
  11. Examples:
  12.        echo foo
  13.        echo "multiple words"
  14. *CLI> echo foo
  15. foo
  16. *CLI> echo hello world
  17. hello
  18. *CLI> echo "hello world"
  19. hello world
f|eUpf%)  
翻译的比较拗口,勉强看吧,为方便对照,下面是英文全文。 nt$V H  
7A!E~/nSC  
How-to: Write an Asterisk Module, Part 3 tYE\tbCO'  
作者/ Russell Bryant      摘自 http://www./blog/ !RX7TYf  
In this section, you will see how to implement an Asterisk CLI command. CLI commands are extremely useful for showing configuration, statistics, and other debugging purposes. D[d+lq#p  
We are going to continue editing the module from part 2, res_helloworld2.c. 5X2&hG*  
The first step is to include the header file which defines the CLI command interface. tPD d~fOk  
yXg #<H6V  
#include "asterisk/cli.h" !U}dYB:O  
!PpooYK  
Here is the code for a CLI command, “echo”. It simply prints back the first argument to the CLI command. The individual parts of this function will be described later. aZK%?c  
static char *handle_cli_echo(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) Q};g~b3  
{ &~ =q1?  
    switch (cmd) { p-p]dV  
    case CLI_INIT: Aqi9@BH  
        e->command = "echo"; G5JZpB#o  
        e->usage = 9rO,h|L   
            "Usage: echo <stuff>\n" $kc*~V~   
            "       Print back the first argument.\n" s@Q, wa(  
            "Examples:\n" (QARle(i  
            "       echo foo\n" r-Nv<oH;  
            "       echo \"multiple words\"\n" &f 2'cR  
            ""; =LP,+z  
        return NULL; /hx|KC&:e  
    case CLI_GENERATE: zOV.cI6fZz  
        return NULL; znNJ ?  
    } 9DAk|K   
82mKI+9&"  
    if (a->argc == e->args) { Sqt '}  
        ast_cli(a->fd, "You did not provide an argument to echo\n\n"); .Xq 4QR .  
        return CLI_SHOWUSAGE; 0N" VOEvG  
    } #osP"~{  
X4- _l$j  
    ast_cli(a->fd, "%s\n", a->argv[1]); @Ido6Z 7  
@raw8w\Zj+  
    return CLI_SUCCESS; ~E]ct F  
} S 5 4N  
fj/sN HU  
The first line of this CLI handler matches the defined function prototype for CLI command handlers. The ast_cli_entry argument includes static information about the CLI command being executed. The cmd argument is set when the CLI command is being invoked for a reason other than normal execution from the CLI, which will be explained more later. The ast_cli_args argument contains information specific to this one time execution of the command, like the arguments to the command. F|rJ{=x  
f{} zqCK  
static char *handle_cli_echo(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) H(MCY3t  
s,tZi6Z=%E  
The switch statement at the beginning of the function handles when the cmd argument is set to indicate that the function is being called for a reason other than normal execution. There are two cases handled. *{ =5AW}o  
  • CLI_INIT. Every CLI command handler is called one time with a cmd of CLI_INIT. This asks the function to fill in the documentation on what the command is, as well as usage documentation.
  • CLI_GENERATE. This cmd is used for implementing tab completion. CLI commands that provide tab completion of arguments must add code here. Implementing tab completion may be explained in a later tutorial. For now, there are many examples throughout the code.
The next code snippet ensures that at least one argument has been provided to the function. It is worth noting here that the ast_cli_entry argument is used to retrieve how many arguments define the command itself and the ast_cli_args argument is used to retrieve how many arguments were actually specified at the CLI when executing this command. If they are equal, then simply “echo” was provided. |=dmxfj@  
5W T^;J9V  
if (a->argc == e->args) { ,b&-o?.{  
ast_cli(a->fd, "You did not provide an argument to echo\n\n"); $. ;j4%%  
return CLI_SHOWUSAGE; wRc=;f  
} #Cwzk{p(  
;AFF7N> &  
Finally, we print a single argument to the CLI, and return that the execution of the CLI command was successful. C*S%aR  
NXwlRMbo  
ast_cli(a->fd, "%s\n", a->argv[1]);  qep<7 QO  
return CLI_SUCCESS; jslfq@5v  
n*4N%yI^m5  
The next thing that we have to add is the table of CLI commands included in this module. We will use AST_CLI_DEFINE() to add a single entry to this table. AST_CLI_DEFINE includes the pointer to the CLI command handling function, as well as a brief summary of what the command does. `kx+Kc  
/K#t$O4  
static struct ast_cli_entry cli_helloworld[] = { HxC_n h  
AST_CLI_DEFINE(handle_cli_echo, "Echo to the CLI"), lS`hJ:  
}; x*)@:W!  
2 |f N*Wm  
Finally, as discussed in part 2, we have to modify load_module and unload_module to register and unregister the CLI command table with the Asterisk core. K1P3 FfG  
In unload_module, we add this: Q( WE.ux)<  
0FDfB;  
ast_cli_unregister_multiple(cli_helloworld, ARRAY_LEN(cli_helloworld)); [*-DtbE k  
&ZjQa.-U>  
In load_module, we add this: 5"f')MKUV9  
\7 8w1Rkl  
ast_cli_register_multiple(cli_helloworld, ARRAY_LEN(cli_helloworld)); zc<C %t[~y  
>L#HE  
That’s it! Recompile and reinstall the module. Take a look at res_helloworld3.c, for the completed code. =] R_6#  
You can then try it out. bDLPA27  
*CLI> help echo #+2|ZfCn%  
Usage: echo l \=M'D  
       Print back the first argument. _)q,:g~fu  
Examples: fP41 B  
       echo foo G)A5;u\P9  
       echo "multiple words" 0K -jF5i$`  
Y4PB&pZ$O2  
*CLI> echo 3|/<Pk  
You did not provide an argument to echo lGa'Y  
;>o}/h  
Usage: echo hP4*S^l  
       Print back the first argument. J 4 yT|  
Examples: s)q;{wz  
       echo foo pq`Bg`c  
       echo "multiple words" F=C8U$'S  
Z6<vLc  
*CLI> echo foo uy~KJn?Tu  
foo pb~&gliW  
pPcn F`A  
*CLI> echo hello world <$s G]l!\  
hello Q E7 r{  
ET4 C/nb   
*CLI> echo "hello world" B$b'bw.  
hello world =R)9_D6I  

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多