Asterisk cli模块分析

    最近写一些工具库,需要远程命令行调试(cli)功能,原有的一个cli模块是将接收处理的命令具体实现在cli模块中,其他模块需要修改添加自己的cli命令都需要去修改cli模块代码,觉得模块间耦合度太高,在看asterisk源码时记得它的cli模块是一种注册机制,cli模块主要对外提供注册和反注册接口,其他模块实现一组特定的cli entry,再调用注册和反注册函数进行操作。可以动态的控制远程可操作的cli命令,觉得比较好,分析了一下。并参照它的思想简化的实现了一个满足自己需求的cli模块。

    以下文章原是写在trac的wiki与代码结合使用的,所以部分超链接在此网页中无法使用。

 

 Asterisk cli模块分析

 

 

asterisk cli结构分析图
   

整体流程分析图

关键结构体ast_cli_entry:include/asterisk/cli.h

 

具体ast_cli_entry例子

具体例子: chan_sip.c

模块中如何使用见 .外围模块中cli机制

cli_sipsip通道模块注册的cli命令集合。其中每一个是具体的一个命令。以"sip show users"为例,{ "sip", "show", "users", NULL }cmdasip_show_usershandler(函数),"List defined SIP users"是命令概述,show_users_usage是命令使用范围(一个字符串)。

sip_show_users分析handler的结构,位于: chan_sip.c,成功返回RESULT_SUCCESS,失败返回RESULT_SHOWUSAGE,显示使用范围。具体代码:

.核心文件中cli机制,main函数调用cli流程

1.cli.ccli.h分析

·       1. ast_cli:用于在cli界面上显示信息。 源码

void ast_cli(int fd, char *fmt, ...)

fd为文件句柄,fmt和后面的参数是要显示的信息。

·       2. ast_cli_command:用于具体处理cli上输入的命令,选择对应的handler处理。源码
int ast_cli_command(int fd, const char *s)

fd为文件句柄,sarg,但是s是将所有argv拼起来的一个字符串,在函数内部调用 parse_args将其分离还原。

·       3. ast_cli_command_multiple循环调用 ast_cli_command执行命令,源码

2.asterisk.c分析

·       4. netconsole,main/asterisk.c中,它为线程函数,调用了ast_cli_command_multiple

static void *netconsole(void *vconsole)
vconsole
是一个struct console结构,是一个console的结构,
ast_cli_command_multiple(con->fd, res, tmp);
res
是要处理的命令的数目,tmp是命令字符串(多条命令在一起,以'/0'分隔)。 它结构中的fd即为传递给最终ast_clifd

·       5. listener,它调用了netconsole,在main/asterisk.c中,为线程函数,按照consoles的数目,启动多个netconsole的线程,传递参数为console

·       6.ast_makesocket,在main/asterisk.c,它启动了 listener线程

它又被main函数调用

.核心文件中cli机制,向外提供的cli注册接口

·       1.ast_cli_register__ast_cli_register!__ast_cli_register源码ast_cli_register源码 不知为什么有ast_cli_register调用__ast_cli_register这一层,未看出有什么作用,而且在unregister中没有这 样一层调用。__ast_cli_register具体处理将一个struct ast_cli_entry *e注册到helpers上,它调用find_cli寻找是否已经注册。没有注册使用 AST_LIST_INSERT_TAIL(&helpers, e, list)或者AST_LIST_INSERT_BEFORE_CURRENT(&helpers, e, list)将其注册到helpers上。

·       2.ast_cli_unregister。反注册一个struct ast_cli_entry *e

·       3.find_cli,在链表buildinshelpers上寻找一个符合条件的struct ast_cli_entry *e。具体调用cli_next遍历这两个链表。在这里还有匹配度的选择,可以进行最优匹配或者最先匹配。

.外围模块中cli机制

    外围模块需要使用cli机制:

·       1.首先声明一个struct ast_cli_entry cli_sip[],将自己具有的可cli调用的函数写在其中,包括相应的说明等,如#具体ast_cli_entry例子

·       2.load_module中调用ast_cli_register_multiple注册cli_sip[]helpers。如:

 四.参照其思想简化实现

    在实现中根据自身的需求和时间决定暂时先简化实现一个cli,主要需要其动态注册功能,但是对于其中一些具体实现进行简化,如命令cmd暂时只接受一个字符串,只使用最快查找等。但对于开发接口都尽量保留,以便后期开发。对于其运用到其他运行支撑模块如lock.h,linkedlist.h 等进行实现,但对于io模块暂时未实现。

    测试代码,功能达到要求。

  • 2
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值