📄 nos_dev_ctrl.h
字号:
/***********************************************************
nos_dev_ctrl_main.h
-------------------
description : normal dev control func define for mn_main call
begin : Thu Mar 7 2002
copyright : (C) 2001 Dragon Co.
email : martin@dragon.com
*************************************************************/
#ifdef _cplusplus
extern"C"{
#endif
#include <nos.h>
#include <msgQLib.h>
/***********************************
函数 nos_dev_ctrl_call 的返回结果
*************************************/
typedef enum _nos_dev_ctrl_op_result
{
NOS_DEV_CTRL_OP_SUCESS, /* operate success */
NOS_DEV_CTRL_OP_REQ_MODID_OUTOFRANGE, /* module id outof range */
NOS_DEV_CTRL_OP_REQ_VAR_TOOLONG, /* var data len beyong max dev_ctrl msg len */
NOS_DEV_CTRL_OP_REQ_SEMTAKE_FAIL, /* semTake fail, */
NOS_DEV_CTRL_OP_NOMEMROY, /* no memory for dev_ctrl_op */
NOS_DEV_CTRL_OP_REQ_SEND_FAIL, /* send msg fail, too much nos_dev_control running */
NOS_DEV_CTRL_OP_MSG_TRANS_LOST, /* msg send fail or discard because of error in transmit */
NOS_DEV_CTRL_OP_MSG_DISCARD_BY_DEV_TASK,
NOS_DEV_CTRL_OP_MSG_TRANS_TIMEOUT, /* msg track state not change in timeout time period */
NOS_DEV_CTRL_OP_RES_MSG_TOO_SHORT, /* got msg_len < sizeof(nos_dev_ctrl_msg) */
NOS_DEV_CTRL_OP_RES_MSG_TYPE_WRONG, /* (msg_type != NOS_MSG_DEV_CTRL_RESPONSE) */
NOS_DEV_CTRL_OP_RES_MANAGE_MOD_NOTMATCH, /* recv->manage_module_id != send->manage_module_id */
NOS_DEV_CTRL_OP_RES_MSG_LEN_NOT_MATCH, /* msg_len != msg->data_len + sizeof(nos_dev_ctrl_msg) */
NOS_DEV_CTRL_OP_RES_DATA_NULL, /* (result_len > 0)&&(ptr_res_data == NULL) */
NOS_DEV_CTRL_OP_RES_DATA_TOOLONG, /* result_len > max_result_len */
NOS_DEV_CTRL_OP_MANAGE_TASKID_NULL,
NOS_DEV_CTRL_OP_DEV_TASKID_NULL,
NOS_DEV_CTRL_OP_MAX_RESULT
}nos_dev_ctrl_op_result;
/***********************************
函数 nos_dev_ctrl_call 的返回结果的描述字符串
nos_dev_ctrl_call 的调用者可以使用这个字符串数组打印执行结果,以便于调试
*************************************/
extern char nos_dev_ctrl_op_result_descstr[NOS_DEV_CTRL_OP_MAX_RESULT][50];
/*****************************************************
函数名 : nos_dev_ctrl_register_manager_module;
描述 : 管理模块(CLI,SNMP,WEB等)注册函数, 由管理模块调用
在dev_ctrl任务中注册管理模块
如果管理模块想使用dev_ctrl这个通用的管理接口,
必须向 dev_ctrl 注册
参数说明:
manage_module_id: 调用者,管理模块的模块ID, 在nos.h中定义
task_id : 调用者, 管理模块的taskID
****************************************************/
int nos_dev_ctrl_register_manager_module(nos_module_id module_id,int task_id);
/*****************************************************
函数名 : nos_dev_ctrl_unregister_manager_module;
描述 : 管理模块(CLI,SNMP,WEB等)注册函数, 由管理模块调用
在dev_ctrl任务中注销管理模块
如果管理模块中止任务,在中止前必须
调用这个函数必须向 dev_ctrl 注销
参数说明:
manage_module_id: 调用者,管理模块的模块ID, 在nos.h中定义
task_id : 调用者, 管理模块的taskID
****************************************************/
int nos_dev_ctrl_unregister_manager_module(nos_module_id module_id);
/***********************************************
操作码检查函数
由设备模块定义,主要用于检查管理模块调用的操作码是否越界
参数说明:
op_code : 操作码,由管理模块传进来
返回值:
如果操作码非法,没有该操作码对应的操作函数,就返回ERROR
如果操作码合法,有该操作码对应的操作函数,就返回OK
**************************************************/
typedef int (*nos_dev_ctrl_op_code_check_func)(long op_code);
/************************************
设备管理操作函数
由设备模块定义
设备模块需要定义一个以操作码为下标的函数指针数组
具体的设别管理功能就由这一组操作函数实现
以供nos_dev_ctrl_execute (见下边的定义) 调用
参数说明:
var_data : 参数指针, 带进操作所需要的参数数据,无须申请内存,直接使用
var_len : 参数长度, 带进参数的数据长度
res_data : 存放操作结果的指针,无须申请内存,直接使用
res_len : 返回操作结果数据长度的指针,
请注意 : 一定要给这个指针赋值,否则设备管理不知道返回值
有多长的数据,
不推荐没有返回值的函数定义,
即使没有返回值,也一定要把这个指针指向的值设成0
max_res_len : 最大返回值长度,表示res_data 这个指针指向的数据区域的长度
一般为 (_NOS_DEV_CTRL_MAX_MSG_LEN_) - sizeof(nos_dev_ctrl_msg)
大概 1000 个字节不到
***************************************/
typedef void (*nos_dev_ctrl_op_func)(void *var_data,int var_len,void *res_data,int *res_len,int max_res_len);
/*****************************************************
函数名 : nos_dev_ctrl_register_manager_module;
描述 : 被管理设备模块(BR,ROUTE,FDB等)注册函数, 由被管理设备模块调用
在dev_ctrl任务中注册设备模块
如果设备模块
参数说明:
module_id : 调用者,被管理设备模块的模块ID, 在nos.h中定义
task_id : 被管理模块(设备模块)的taskID
dev_msg_id : 设备模块的接收来自dev_ctrl任务消息的MSG_Q_ID
dev_sem_id : 设备模块的信号量锁,在设备管理操作时,会把该信号量锁上
op_func_group : 操作函数组,一组以操作码为下标的具体实现设备管理功能的函数
op_check_func : 用于检查传该设备模块的操作码是否合法的函数
请注意 :
该设备模块的消息格式,最开始一个消息成员必须设置成nos_module_msg_type数据类型
每收到消息后都取前 sizeof(nos_module_msg_type) 位判断消息类型
如果 消息类型 == NOS_MSG_DEV_CTRL_REQUEST
那么直接调用 nos_dev_ctrl_execute 处理该设备管理请求
****************************************************/
int nos_dev_ctrl_register_device_module(nos_module_id module_id,int task_id,
MSG_Q_ID dev_msg_id,SEM_ID dev_sem_id,nos_dev_ctrl_op_func *op_func_group,
nos_dev_ctrl_op_code_check_func op_check_func);
/*********************************************
函数名 : nos_dev_ctrl_unregister_device_module
函数描述 : 注销设备模块
参数说明 :
module_id : 设备模块的模块ID 在nos.h 中定义
请注意 :
推荐设备模块使用任务常在的模式,即使该功能被关掉,
也应该能被配置该任务的一些参数,这样功能启动时这些
配置还能立即生效
*************************************************/
int nos_dev_ctrl_unregister_device_module(nos_module_id module_id);
/*****************************************************
函数名 : nos_dev_ctrl_call;
描述 : 设备管理函数API,由管理模块(CLI,SNMP,WEB等)调用
参数说明:
manage_module_id: 调用者,管理模块的模块ID, 在nos.h中定义
device_module_id: 被调用者,被管理设备管理模块的模块ID,在nos.h中定义
operate_code: 操作码,具体的操作定义,每个被管理设备模块可以有自己的操作码定义
var_data : 操作参数指针,内存由调用者申请和释放
var_len : 操作参数长度,
res_data : 操作返回结果指针,内存由调用者申请和释放
res_len : 操作返回结果长度指针,返回结果长度
max_res_len : 操作返回结果缓存长度,返回结果不能超过这个长度
返回结果:
nos_dev_ctrl_op_result:
见上边的数据结构定义
****************************************************/
nos_dev_ctrl_op_result
nos_dev_ctrl_call(nos_module_id manage_module_id,nos_module_id device_module_id,long operate_code,char *var_data,int var_len,char *res_data,int *res_len,int max_res_len);
/******************************************************
函数名 nos_dev_ctrl_execute
函数描述 :
由设备模块调用,当设备模块收到
消息的类型 == NOS_MSG_DEV_CTRL_REQUEST
可以直接调用这个函数处理设备管理请求
参数说明 :
msg : 指向收到的消息的指针,内存由调用者申请和释放
msg_len : 收到的消息长度
dev_module_id : 设备模块的模块ID, 在nos.h 中定义
*****************************************************/
void nos_dev_ctrl_execute(char *msg,int msg_len,int dev_module_id);
/*********************************************
简要使用说明:
I:
初始化顺序
1. nos_dev_ctrl_init
2. mn_main_init
3. 设备模块注册管理功能
包括 a. 注册 dev_ctrl 调用 nos_dev_ctrl_register_device_module
b. 注册命令行
4. mn_main_start
注意: 所有管理模块必须一启动,得到taskID 后就
调用 nos_dev_ctrl_register_manager_module
向 dev_ctrl 注册
尤其命令行启动,必须先注册管理模块,后load startup config
因为dev_ctrl作为一个任务,它的主要流程仅仅是消息转发,特别简单
而且为了避免管理模块调用nos_dev_ctrl_call挂起时间过长,所以设置的优先级为5
仅低于 nos_timer, WDBTask 等.
II:
管理模块的使用
管理模块向dev_ctrl 注册过之后,就可以使用nos_dev_ctrl_call来执行设备管理了.
注意事项 :
1. 需要注意申请和释放存放操作参数和存放返回结果的内存
2. 管理模块需要注意检查
函数 nos_dev_ctrl_call 的返回值
以及检查返回结果的长度是否是预期的返回数据类型长度
如有必要可以打印 nos_dev_ctrl_op_result_descstr
增强输出信息的可读性,便于调试
3. 从返回结果中判断由设备模块传出操作结果,并根据
不同的管理模块需要来组织输出文字
III:
设备模块的使用
1. 设备模块启动后,得到taskID后,需要向 dev_ctrl 注册自己模块
2. 设备模块的消息格式必须第一个成员是nos_module_msg_type
该数据类型在nos.h中定义
3. 每个设备管理操作函数中应尽量避免使用可能
挂起的函数,nos_dev_ctrl_call 会超时
4. 每个设备模块可以各自定义自己的操作码和返回结果,
只要同一模块内部不冲突就行,不需要考虑跨模块定义冲突
5. 每个设备模块定义的使用 nos_dev_ctrl_call 所需要
的 操作码, 数据结构, 返回值定义最好统一放在
nos_modulename_ctl.h 文件中,放在Include 目录下的dev_ctl目录中.
这个nos_modulename_ctl.h文件的定义最好不要包含太多
bluelightOS中的别的头文件,和复杂的数据结构,
尽量保持该头文件的独立性,以便于移植
ssh 实现以后可以直接把 nos_modulename_ctl.h 移植
到ssh client的实现中
再把以后的ssh server 的代码稍加改动,就可以同时
支持基于ssh通信的CLI 和
基于ssh 通信的远程函数调用了.
IV:
调试命令
在隐含命令节点下有 config devctrl-debug [on|off]命令
打开这个debug开关可以把nos_dev_ctrl_call超时时间增长3600倍
缺省值是60 个tick, 1 秒钟
同时会把设备管理消息的传递过程打印输出
debug 关掉的时候只有消息被丢弃或者传递失败才会打印错误信息
dev_ctrl任务打印不使用syslog和vty_out打印到vty中,而是直接把
所有打印信息直接打印到串口
V:
参考实现:
Manage 模块下的syslog 目录中,有syslog_cli.c和syslog_ctl.c
分别实现了调用nos_dev_ctrl_call的命令定义
和被nos_dev_ctrl_execute调用的操作函数数组
syslog_main.c中实现了向dev_ctrl 任务注册.
*******************************************/
#ifdef _cplusplus
}
#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -