USP-Agent

用户服务平台(USP)中的代理(Agent)

本文介绍用户服务平台(USP)中的代理(Agent)

BroadbandForum(宽带论坛 BBF)

宽带论坛是一个非营利性的行业联盟,致力于发展宽带网络规范。宽带论坛一直在研究自己的技术标准,称之为技术报告(TR)

宽带论坛的标准命名由两部分组成标准代号与序号,之间用“-”分割,代号为TR,序号由三位数组成,目前已经发布超400个TR,如TR-069、TR-181等。TR-369也是其中之一

obuspa

obuspa是宽带论坛发布的一个提供用户服务平台(USP)代理的开源程序,主页为obuspa

可以通过此链接下载代码,最新版本为7.0,建议使用6.0版本进行测试开发:

1
$git clone --branch v6.0.0-master https://github.com/BroadbandForum/obuspa.git

数据模型加载流程

数据模型核心加载流程如下:

data_model

  1. DATABASE_Init:数据库初始化
  2. DATA_MODEL_Init:初始化数据模型,在这里创建数据模型,初始化资源
  3. DATA_MODEL_Start:根据数据模型实例化对象,分配使用资源等
  4. DATA_MODEL_Stop:回收资源

vendor目录

建议vendor目录做为开发目录,添加的数据模型代码都放到这个目录中,并在vendor.c中调用

工程文件添加

  1. 在Vendor目录中创建文件(如device_wifi.c/device_wifi.h 实现WIFI相关的数据模型)
  2. 根据流程创建三个函数(Init,Start,Stop)
  3. 在vendor中一一对应调用三个函数如下:
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    int VENDOR_Init(void)
    {
    int err;
    //WIFI
    err = DEVICE_WIFI_Init();
    return err;
    }

    int VENDOR_Start(void)
    {
    int err;
    //WIFI
    err = DEVICE_WIFI_Start();
    return err;
    }

    int VENDOR_Stop(void)
    {
    int err;
    //WIFI
    err = DEVICE_WIFI_Stop();
    return err;
    }
  4. 在vendor.am中加入工程文件及其依赖:
    1
    2
    3
    4
    5
    6
    7
    # Source files in vendor
    SOURCES += src/vendor/vendor.c \
    src/vendor/vendor_factory_reset_example.c \
    src/vendor/device_wifi.c

    # Add extra vendor specific CPP or LD flags below

数据模型添加

在init函数中添加数据模型,接口函数及其说明参考REGISTER_FUNC

例如创建一个SSID多实例的对象:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
#define DEVICE_WIFI_SSID_ROOT "Device.WiFi.SSID"
#define SSID_MAX_PROFILES 5

typedef struct
{
int instance; // instance of this connection in the Device.WIFI.SSID.{i} table. Set to INVALID, if this entry is not used.
bool enable;
} device_wifi_ssid_params_t;

static device_wifi_ssid_params_t ssid_profiles[SSID_MAX_PROFILES];

int DEVICE_WIFI_Init(void)
{
int err = USP_ERR_OK;
device_wifi_ssid_params_t *device_ssid_params;
// Initialise all profiles
memset(ssid_profiles, 0, sizeof(ssid_profiles));
for (int i=0; i<SSID_MAX_PROFILES; i++)
{
device_ssid_params = &ssid_profiles[i];
device_ssid_params->instance = INVALID;
}

err |= USP_REGISTER_Object(DEVICE_WIFI_SSID_ROOT ".{i}", Validate_AddWIFISSID, NULL, Notify_ProcessWifiSSidAdded,Validate_DelWIFISSID, NULL, Notify_ProcessWifiSSidDeleted);
err |= USP_REGISTER_DBParam_Alias(DEVICE_WIFI_SSID_ROOT ".{i}.Alias", NULL);
err |= USP_REGISTER_DBParam_ReadWrite(DEVICE_WIFI_SSID_ROOT ".{i}.Enable", "false", NULL, NotifyChange_WIFISSIDEnable, DM_BOOL);
err |= USP_REGISTER_VendorParam_ReadOnly(DEVICE_WIFI_SSID_ROOT ".{i}.Status", Get_SSIDProfileStatus, DM_STRING);
err |= USP_REGISTER_VendorParam_ReadWrite(DEVICE_WIFI_SSID_ROOT ".{i}.SSID", Get_WIFISSID, Set_WIFISSID, NULL, DM_STRING);
err |= USP_REGISTER_VendorParam_ReadOnly(DEVICE_WIFI_SSID_ROOT ".{i}.BSSID", Get_BSSIDProfileStatus, DM_STRING);

if (err != USP_ERR_OK)
{
return USP_ERR_INTERNAL_ERROR;
}

// If the code gets here, then registration was successful
return USP_ERR_OK;
}

注:device_wifi_ssid_params_t模拟节点所需要的资源

数据模型实例化

在start函数中进行实例化,主要调用USP_DM_InformInstance(char *path)方法实例化对象,如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
int DEVICE_WIFI_Start(void)
{
int err;
int instance;
char *device_wifi_ssid_root = DEVICE_WIFI_SSID_ROOT;
char path[MAX_DM_PATH];

//get vendor instance
instance = GET_SSID_INSTANCE();
for (int i = 1; i <= instance; i++)
{
//Device.WiFi.SSID.I I=1,2,3...
USP_SNPRINTF(path, sizeof(path), "%s.%d", DEVICE_WIFI_SSID_ROOT, i);
err = USP_DM_InformInstance(path);
if (err != USP_ERR_OK)
{
goto exit;
}

//set device_wifi_ssid_params_t
err = ProcessWifiSSidAdded(i);
if (err != USP_ERR_OK)
{
goto exit;

}
}
err = USP_ERR_OK;

exit:
return err;
}

ProcessWifiSSidAdded是自定义的使用资源的函数,这里是为ssid_profiles赋值

释放资源

在stop函数中释放资源,如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
int DEVICE_WIFI_Stop(void)
{
int i;
device_wifi_ssid_params_t *ssid;

// Iterate over all profiles, deleting them (this stops them, and frees dynamic memory associated with them)
for (i=0; i < SSID_MAX_PROFILES; i++)
{
ssid = &ssid_profiles[i];
if (ssid->instance != INVALID)
{
ProcessWifiSSidDeleted(ssid);
}
}
return USP_ERR_OK;
}

这里模拟释放资源:ssid_profiles

core vendor hooks

OB-USP-AGENT的核心功能的实现许多都有默认值。但是其中有一些通过调用USP_REGISTER_CoreVendorHooks()函数在VENDOR_Init()中注册(src/vendor/vendor.c)。

例如:

1
2
3
4
5
6
7
8
9
10
11
12
13
int VENDOR_Reboot(void);

int VENDOR_Init(void)
{
int err;
vendor_hook_cb_t core_callbacks;
memset(&core_callbacks, 0, sizeof(core_callbacks));

//register core vendor hooks
core_callbacks.reboot_cb = VENDOR_Reboot;
err |= USP_REGISTER_CoreVendorHooks(&core_callbacks);
return err;
}

这个例子是注册了reboot的回调函数,其他函数也可以在调用USP_REGISTER_CoreVendorHooks()前进行赋值,支持的回调函数如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
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;

} vendor_hook_cb_t;

注:如果有需要,此结构体可以按照需求进行扩充

编译

1
2
3
4
5
$ cd obuspa
$ autoreconf --force --install
$ ./configure
$ make
$ sudo make install

启动

1
obuspa -p -v 4 -r factory_reset_example.txt -i eth0
  • -r 配置文件

  • -f 数据库

  • -i 网络接口

  • -p 打开log

  • -v log等级

    其余参数请使用-h查看帮助


USP-Agent
https://carl-5535.github.io/2023/11/10/tr369/USP-Agent/
作者
Carl Chen
发布于
2023年11月10日
许可协议