面是通过基本接口来为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
这个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#
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}\
翻译的比较拗口,勉强看吧,为方便对照,下面是英文全文。 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
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 |
|