环境:gcc (Ubuntu 11.4.0-1ubuntu1~22.04) 11.4.0
代码地址:https://github.com/BroadbandForum/obuspa
必选项:
$ sudo apt-get install libssl-dev libcurl4-openssl-dev libsqlite3-dev libz-dev autoconf automake libtool pkg-config
可选项:
$ sudo apt-get install libmosquitto-dev libwebsockets-dev
$ cd obuspa
$ autoreconf --force --install
$ ./configure
$ make
$ sudo make install
编译选项
--disable-coap
- 移除 CoAP MTP--disable-mqtt
- 移除 MQTT MTP--disable-websockets
- 移除 WebSockets MTP--disable-stomp
- 移除 STOMP MTP$ cd obuspa
$ cmake -B build_folder -S .
$ cmake --build build_folder
$ cmake --install build_folder
编译选项
-DENABLE_STOMP=[ON|OFF]
- 启用/禁用 STOMP MTP (默认启用)-DENABLE_MQTT=[ON|OFF]
- 启用/禁用 MQTT MTP (默认启用)-DENABLE_COAP=[ON|OFF]
- 启用/禁用 CoAP MTP (默认启用)-DENABLE_WEBSOCKETS=[ON|OFF]
- 启用/禁用 WebSockets MTP (默认启用)$ obuspa -p -v 4 -r factory_reset_example.txt -i eth0
-p : 输出协议交互数据
-v : 日志等级
-f : 指定一个要使用的数据库,跟 -r 一起使用时,-f 优先
-r : 指定一个默认数据库(当 -f 指定的数据库文件不存在时会自动生成 -f 指定的文件)详细格式见代码根目录 *_factory_reset_example.txt 等文件
-i : 指定使用的网卡
通常我们的开发目录为 src/vendor,在这里我们可以添加数据模型
初始化所有实现的实例参数和回调函数
int VENDOR_Init(void)
示例
int VENDOR_Init(void)
{
int err = USP_ERR_OK;
err |= VENDOR_DEVICEINFO_Init();
return err;
}
int VENDOR_DEVICEINFO_Init(void)
{
int err = USP_ERR_OK;
vendor_hook_cb_t core_callbacks;
memset(&core_callbacks, 0, sizeof(core_callbacks));
#ifndef REMOVE_DEVICE_INFO
core_callbacks.get_hardware_version_cb = xxxx;
core_callbacks.get_active_software_version_cb = xxxx;
#endif
err |= USP_REGISTER_CoreVendorHooks(&core_callbacks);
err |= USP_REGISTER_VendorParam_ReadOnly("Device.DeviceInfo.ModelNumber", xxxx, DM_STRING);
return err;
}
在注册数据模型并从USP数据库读取实例号之后调用
通常,此函数用于使用实例号为数据模型提供种子,或初始化需要运行数据模型以访问参数的内部数据结构
int VENDOR_Start(void)
正常停止 USP 代理时调用,以释放内存并关闭任何供应商进程等
int VENDOR_Stop(void)
有关 API 函数的用途和参数的信息,请参阅定义函数的函数标头注释(通常 src/core/usp_register.c
为 或 src/core/usp_api.c
)
OB-USP-AGENT 的核心实现在许多功能方面都有默认值。某些方面被设计为由集成商使用回调覆盖。要覆盖默认实现,请通过调用 USP_REGISTER_CoreVendorHooks()
注册核心代理可以回调的核心供应商挂钩函数
注意:该函数可能会被多次调用。
如果要覆盖当前存储的回调,请在结构中将回调设置为非 NULL
callbacks - 指向包含要注册的回调的结构的指针
int USP_REGISTER_CoreVendorHooks(vendor_hook_cb_t *callbacks)
示例:
int VENDOR_Init(void)
{
vendor_hook_cb_t core_callbacks;
memset(&core_callbacks, 0, sizeof(core_callbacks));
core_callbacks.get_mtp_password_cb = GetStompPassword;
return USP_REGISTER_CoreVendorHooks(&core_callbacks);
}
int GetStompPassword(char *buf, int len)
{
strncpy(buf, "MyPassword", len);
return USP_ERR_OK;
}
可以覆盖的参数如下
typedef struct
{
dm_vendor_get_agent_serial_number_cb_t get_agent_serial_number_cb;
dm_vendor_get_agent_endpoint_id_cb_t get_agent_endpoint_id_cb;
dm_vendor_reboot_cb_t reboot_cb;
dm_vendor_factory_reset_cb_t factory_reset_cb;
// Vendor hooks associated with vendor database transactions
dm_vendor_start_trans_cb_t start_trans_cb;
dm_vendor_commit_trans_cb_t commit_trans_cb;
dm_vendor_abort_trans_cb_t abort_trans_cb;
// Vendor hooks associated with certificates and controller trust
register_controller_trust_cb_t register_controller_trust_cb;
is_system_time_reliable_cb_t is_system_time_reliable_cb;
get_trust_store_cb_t get_trust_store_cb;
get_agent_cert_cb_t get_agent_cert_cb;
// Miscellaneous vendor hooks
#ifndef REMOVE_DEVICE_INFO
get_active_software_version_cb_t get_active_software_version_cb;
get_hardware_version_cb_t get_hardware_version_cb;
#endif
dm_vendor_get_mtp_username_cb_t get_mtp_username_cb;
dm_vendor_get_mtp_password_cb_t get_mtp_password_cb;
load_agent_cert_cb_t load_agent_cert_cb;
log_message_cb_t log_message_cb;
modify_firmware_updated_cb_t modify_firmware_updated_cb;
} vendor_hook_cb;
注册一个永远不会改变的参数
这对于仅说明代理支持哪些选项的参数以及版本号等很有用
path - 参数的完整数据模型路径
value - 参数的常量值
type_flags - 参数的类型
int USP_REGISTER_Param_Constant(char *path, char *value, unsigned type_flags)
用于注册包含逗号分隔的枚举值列表的参数的便捷函数
此函数通常用于说明支持选项的固定列表的参数
path - 参数的完整数据模型路径
enums - 指向转换表的指针,枚举列表及其关联的字符串表示形式
num_enums - 表中的枚举数
int USP_REGISTER_Param_SupportedList(char *path, const enum_entry_t *enums, int num_enums)
注册一个参数,该参数表示数据模型表中的条目数
读取参数时,USP Agent 会自动计算指定表中的条目数
此函数可用于数据库和供应商控制表
path - 参数的完整数据模型路径
table_path - 该参数代表的表的数据模型路径
int USP_REGISTER_Param_NumEntries(char *path, char *table_path)
注册一个参数,该参数保留在数据库中并且是只读的
这对于代理可以更改的配置参数很有用,例如在其 GUI 中,但控制器不能更改
注意:对于这种类型的参数,可以使用 USP_REGISTER_VendorParam_ReadOnly(),该函数只是使供应商实现更容易
path - 参数的完整数据模型路径
value - 参数的默认值
type_flags - 参数的类型
int USP_REGISTER_DBParam_ReadOnly(char *path, char *value, unsigned type_flags)
注册一个可以写入的参数,但读回时始终返回一个空字符串
该函数用于注册所有参数,即密码
path - 参数的完整数据模型路径
value - 参数的默认值
validator_cb - 在允许设置值之前调用回调来验证值
notification_set_cb - 值更改后调用的回调
int USP_REGISTER_DBParam_SecureWithType(char *path, char *value, dm_validate_value_cb_t validator_cb, dm_notify_set_cb_t notify_set_cb, unsigned type_flags)
注册一个将保存在数据库中的参数
这对于控制代理配置的参数很有用
path - 参数的完整数据模型路径
value - 参数的默认值
validator_cb - 在允许设置值之前调用回调来验证值
notification_set_cb - 值更改后调用的回调
type_flags - 参数的类型
int USP_REGISTER_DBParam_ReadWrite(char *path, char *value, dm_validate_value_cb_t validator_cb, dm_notify_set_cb_t notify_set_cb, unsigned type_flags)
注册一个参数,该参数不保存在数据库中,并且是只读的
这对于用于监视代理的当前(瞬时)状态的参数很有用
path - 参数的完整数据模型路径
get_cb - 调用回调以获取参数值
type_flags - 参数的类型
int USP_REGISTER_VendorParam_ReadOnly(char *path, dm_get_value_cb_t get_cb, unsigned type_flags)
注册由供应商实施且不保留在 USP 代理数据库中的读写参数
path - 参数的完整数据模型路径
get_cb - 调用回调以获取参数值
set_cb - 调用回调来设置参数的值
notification_set_cb - 值更改后调用的回调
type_flags - 参数的类型
int USP_REGISTER_VendorParam_ReadWrite(char *path, dm_get_value_cb_t get_cb, dm_set_value_cb_t set_cb, dm_notify_set_cb_t notify_set_cb, unsigned type_flags)
注册一个参数,该参数是表的一部分,其(只读)值在创建时动态初始化
path - 参数的完整数据模型路径
get_cb - 仅调用一次回调,以获取参数的自动分配值
type_flags - 参数的类型
int USP_REGISTER_DBParam_ReadOnlyAuto(char *path, dm_get_value_cb_t get_cb, unsigned type_flags)
注册一个参数,该参数是表的一部分,其(读写)值在创建时动态初始化
path - 参数的完整数据模型路径
get_cb - 仅调用一次回调,以获取参数的自动分配值
validator_cb - 在允许设置值之前调用回调来验证值
notification_set_cb - 值更改后调用的回调
type_flags - 参数的类型
int USP_REGISTER_DBParam_ReadWriteAuto(char *path, dm_get_value_cb_t get_cb, dm_validate_value_cb_t validator_cb, dm_notify_set_cb_t notify_set_cb, unsigned type_flags)
控制器可以添加和删除对象实例(存储在数据库中)的寄存器
这对于控制代理配置的参数很有用
path - 对象的完整数据模型路径
validate_add_cb - 调用回调来验证控制器是否可以添加实例。
如果设置为 NULL,则始终可以添加实例。
如果设置为 USP_HOOK_DenyAddInstance(),则无法将实例添加到表中
add_cb - 供应商通常使用回调在供应商数据库中创建实例,并设置默认供应商参数
notification_add_cb - 添加实例后调用的回调
validate_del_cb - 调用回调来验证控制器是否可以删除指定的实例。
如果设置为 NULL,则可以删除任何实例。
如果设置为 USP_HOOK_DenyDeleteInstance,则无法从表中删除实例
del_cb - 供应商通常使用回调从供应商数据库中删除实例
notification_del_cb - 删除实例后调用的回调
int USP_REGISTER_Object(char *path, dm_validate_add_cb_t validate_add_cb, dm_add_cb_t add_cb, dm_notify_add_cb_t notify_add_cb, dm_validate_del_cb_t validate_del_cb, dm_del_cb_t del_cb, dm_notify_del_cb_t notify_del_cb)
注册哪些参数形成多实例对象的唯一键(或复合唯一键)
每个表可以注册多个唯一键/复合唯一键
注意:必须在密钥中的所有参数都已注册到数据模型后调用此函数
path - 多实例对象的完整数据模型路径
params - 指向字符串数组的指针。 每个字符串都是唯一键中的参数名称
num_params - 形成唯一键的参数数量。 如果大于 1,则唯一键是复合键
int USP_REGISTER_Object_UniqueKey(char *path, char **params, int num_params)
注册一个函数来调用以获取顶级多实例对象的实例(及其数据模型树中的所有后代)
path - 顶级多实例对象的完整数据模型路径
refresh_instances_cb - 调用回调以获取指定对象的所有实例(以及所有子对象的实例)
int USP_REGISTER_Object_RefreshInstances(char *path, dm_refresh_instances_cb_t refresh_instances_cb)
示例:
int VENDOR_Init(void)
{
int err = USP_ERR_OK;
err |= USP_REGISTER_Object("Device.IP.Interface.{i}", NULL, NULL, NULL, NULL, NULL, NULL);
err |= USP_REGISTER_Object_RefreshInstances("Device.IP.Interface.{i}", RefreshIPInterfaceInstances);
if (err != USP_ERR_OK)
{
return USP_ERR_INTERNAL_ERROR;
}
return USP_ERR_OK;
}
int RefreshIPInterfaceInstances(int group_id, char *path, int *expiry_period)
{
// 注册该对象和所有子对象的当前有效实例
USP_DM_RefreshInstance("Device.IP.Interface.1");
USP_DM_RefreshInstance("Device.IP.Interface.1.IPv4Address.1");
// 缓存对象实例编号 30 秒
*expiry_period = 30;
return USP_ERR_OK;
}
使用数据模型注册对象上的同步操作
path - 操作的完整数据模型路径
sync_oper_cb - 调用回调以对对象执行此操作
int USP_REGISTER_SyncOperation(char *path, dm_sync_oper_cb_t sync_oper_cb)
使用数据模型注册对象的异步操作
path - 操作的完整数据模型路径
async_oper_cb - 调用回调以在对象上启动此操作
restart_cb - 调用以确定是否重新启动操作(如果操作被电源周期中断)
int USP_REGISTER_AsyncOperation(char *path, dm_async_oper_cb_t async_oper_cb, dm_async_restart_cb_t restart_cb)
注册该类型并发运行操作的最大数量
path - 操作的完整数据模型路径
max_concurrency - 在对象上启动此操作时调用的并发回调的最大数量
int USP_REGISTER_AsyncOperation_MaxConcurrency(char *path, int max_concurrency)
注册操作的输入和输出参数的名称
该函数注册的信息在 GetSupportedDM Response 中返回
path - 操作的完整数据模型路径
input_arg_names - 指向包含输入参数名称的字符串数组的指针
num_input_arg_names - 输入参数的数量
output_arg_names - 指向包含输出参数名称的字符串数组的指针
num_output_arg_names - 输出参数的数量
int USP_REGISTER_OperationArguments(char *path, char **input_arg_names, int num_input_arg_names, char **output_arg_names, int num_output_arg_names)
注册一个使用组添加和删除供应商挂钩的对象
group_id - 用于注册对象的 group_id,默认值范围 [0,9]
由宏 MAX_VENDOR_PARAM_GROUPS 限制
path - 顶级多实例对象的完整数据模型路径
is_writable - 设置是否可以添加/删除实例,如果实例不受 USP 控制器控制则清除
int USP_REGISTER_GroupedObject(int group_id, char *path, bool is_writable)
示例
int VENDOR_Init(void)
{
int err = USP_ERR_OK;
#define MY_GROUP 1
err |= USP_REGISTER_GroupedObject(MY_GROUP, "Device.MyObject.{i}", true);
err |= USP_REGISTER_GroupedVendorParam_ReadWrite(MY_GROUP, "Device.MyObject.{i}.MyParam", DM_BOOL);
err |= USP_REGISTER_GroupVendorHooks(MY_GROUP, GetMyParams, SetMyParams, AddMyObject, DelMyObject);
if (err != USP_ERR_OK)
{
return USP_ERR_INTERNAL_ERROR;
}
return USP_ERR_OK;
}
注册一组供应商参数的 get/set/add/del 回调函数
group_id - 该参数所属的参数组的标识符
get_group_cb - 调用回调获取各种参数的值
set_group_cb - 调用回调设置各种参数的值
add_group_cb - 调用回调增加组中参数
del_group_cb - 调用回调删除组中参数
int USP_REGISTER_GroupVendorHooks(int group_id, dm_get_group_cb_t get_group_cb, dm_set_group_cb_t set_group_cb, dm_add_group_cb_t add_group_cb, dm_del_group_cb_t del_group_cb)
注册一个分组参数,该参数不保存在数据库中并且是只读的
这对于用于监视代理的当前(瞬时)状态的参数很有用
该参数是一组参数的一部分(具有相同的group_id),可以使用组获取值供应商挂钩更有效地获取该参数
group_id - 该参数所属的参数组的标识符
path - 参数的完整数据模型路径
type_flags - 参数的类型
int USP_REGISTER_GroupedVendorParam_ReadOnly(int group_id, char *path, unsigned type_flags)
注册由供应商实现的读写参数,不会保留在 USP 代理数据库中
该参数是一组参数(具有相同的 group_id)的一部分,可以使用组获取/设置值供应商挂钩更有效地获取/设置
group_id - 该参数所属的参数组的标识符
path - 参数的完整数据模型路径
type_flags - 参数的类型
int USP_REGISTER_GroupedVendorParam_ReadWrite(int group_id, char *path, unsigned type_flags)
include $(TOPDIR)/rules.mk
PKG_NAME:=obuspa
PKG_VERSION=7.0.5
include $(INCLUDE_DIR)/package.mk
include $(INCLUDE_DIR)/cmake.mk
define Package/obuspa
SECTION:=net
CATEGORY:=public
DEPENDS:=+libzip-openssl +libopenssl +libsqlite3 +libmosquitto-ssl +libcurl +libcap +libwebsockets
TITLE:=OB-USP-AGENT
endef
define Package/obuspa/description
Open Broadband-User Services Platform-Agent
endef
define Build/Prepare
mkdir -p $(PKG_BUILD_DIR)
$(CP) ./obuspa/* $(PKG_BUILD_DIR)
endef
define Package/obuspa/install
$(INSTALL_DIR) $(1)/usr/bin
$(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/bin/obuspa $(1)/usr/bin/
endef
$(eval $(call BuildPackage,obuspa))