7.7 DBoT 分布式物联总线
7.7 DBoT 分布式物联总线
📚 本节导读
学习时长:约 35 分钟
难度级别:⭐⭐⭐⭐☆
前置知识:第 7.2 节网络协议栈基础、Socket 编程
🎯 学习目标
- 理解 DBoT(分布式物联总线)的设计理念和架构
- 掌握能力发布与能力发现的编程模型
- 学会在设备间进行服务调用
- 了解 DTP 数据流转机制
- 掌握 DBoT 的 Kconfig 配置和 Shell 调试命令
一、DBoT 概述
1.1 什么是 DBoT
DBoT(Distributed Bus of Things,分布式物联总线) 是 OneOS 提供的分布式设备互联框架。源码位于 components/DBoT/,README.md 提供了完整的架构说明,Kconfig 配置位于 Kconfig。核心子模块:auth/(认证)、coap/(CoAP 协议)、discovery/(设备发现)、group/(组管理)、session/(会话管理)。它基于设备组建的网络构建一条虚拟的"总线",将设备分解为多个子应用连接到总线上,呈现给用户一个大的虚拟设备。
1.2 核心概念
| 概念 | 说明 |
|---|---|
| 能力发布 | 设备将自身功能提炼为"能力"(如灯、摄像头、麦克风),发布到 DBoT 网络 |
| 能力发现 | 设备搜索 DBoT 网络中其他设备发布的能力 |
| 服务调用 | 发现能力后,远程调用其他设备的能力属性 |
| 数据流转(DTP) | 设备间建立点对点连接传输音视频等大数据流 |
1.3 应用场景示例
智能家居场景:
┌─────────────┐ ┌──────────────┐ ┌─────────────┐
│ 智能门锁 │ │ 智能灯具 │ │ 智能音箱 │
│ 能力: 门锁 │ │ 能力: 灯 │ │ 能力: 喇叭 │
│ 属性: 开锁/关锁│ │ 属性: 开关/调光 │ │ 属性: 播放/停止 │
└──────┬──────┘ └──────┬───────┘ └──────┬──────┘
│ │ │
└──────────────────┼───────────────────┘
│
┌───────────┴───────────┐
│ DBoT 总线 │
│ (分布式发现与调用) │
└───────────────────────┘二、架构设计
2.1 协议栈架构
┌─────────────────────────────────────────────┐
│ 应用层 (能力发布/发现/调用) │
├─────────────────────────────────────────────┤
│ DBoT 服务层 (DBOT_SERVICE) │
│ ┌──────────┐ ┌──────────┐ ┌────────────┐ │
│ │ 发布模块 │ │ 发现模块 │ │ 会话管理 │ │
│ │ publish │ │discovery │ │ session │ │
│ └──────────┘ └──────────┘ └────────────┘ │
├─────────────────────────────────────────────┤
│ DDP (设备发现协议) / DTCP (设备调用协议) │
├─────────────────────────────────────────────┤
│ DTP (数据流转协议) — UDP/TCP 传输 │
├─────────────────────────────────────────────┤
│ 网络层 (UDP/TCP/BLE) │
└─────────────────────────────────────────────┘2.2 能力类型定义
DBoT 预定义了常用的设备能力类型:
typedef enum
{
CAPABILITY_TYPE_LIGHT = 0, /* 灯 */
CAPABILITY_TYPE_TEMP = 1, /* 温度 */
CAPABILITY_TYPE_HUMI = 2, /* 湿度 */
CAPABILITY_TYPE_LCD = 3, /* 屏 */
CAPABILITY_TYPE_ILLU = 4, /* 光照强度 */
CAPABILITY_TYPE_CAMERA = 5, /* 摄像头 */
CAPABILITY_TYPE_MICROPHONE = 6, /* 麦克风 */
CAPABILITY_TYPE_SPEAKER = 7, /* 喇叭 */
CAPABILITY_TYPE_SWITCH = 8, /* 开关 */
CAPABILITY_TYPE_FILESYSTEM, /* 文件系统 */
CAPABILITY_TYPE_UNKNOWN = 31, /* 未知设备 */
} capability_list_t;三、核心数据结构
3.1 DBoT 服务上下文
typedef struct dbot_service_context_s
{
DDP_SERVICE_CONTEXT_S *ddp;
DTCP_CLIENT_CONTEXT_S *dtcp_client;
DTCP_SERVER_CONTEXT_S *dtcp_server;
PUBLISH_MODULE_S *publish;
DISCOVERY_MODULE_S *discovery;
device_info_local_t *profile;
}DBOT_SERVICE_CONTEXT_S;3.2 DTP 数据流转上下文
typedef struct dtp_service_context_s
{
DTP_SERVICE_TYPE_E type;
union
{
UDP_CLIENT_S udp_client;
UDP_SERVER_S udp_server;
TCP_CLIENT_S tcp_client;
TCP_SERVER_S tcp_server;
}dtp_service;
uint16_t port;
DTP_SEND_FUNC dtp_send;
DTP_RECV_FUNC dtp_recv;
void *dbot_ctx;
}DTP_SERVICE_CONTEXT_S;四、核心 API
4.1 服务生命周期
| API | 说明 |
|---|---|
dbot_service_init() | 初始化 DBoT 设备相关信息 |
dbot_service_start() | 启动 DBoT 服务 |
dbot_service_stop() | 停止 DBoT 服务 |
dbot_service_started() | 检查 DBoT 是否已启动成功 |
dbot_service_get_ctx() | 获取 DBoT 服务上下文 |
4.2 能力发布与发现
/* 添加设备能力(注册到本地服务列表) */
int dbot_service_add_service(
uint32_t service, // 能力 ID
uint32_t attr_num, // 属性数目
ATTR_INFO_S *attrs // 属性内容数组
);
/* 发布已添加的能力到 DBoT 网络(无参,广播全部已添加服务) */
int dbot_service_publish_service(void);
/* 发现网络中的设备及能力 */
int dbot_service_discovery_service(void);
/* 调用其他设备的能力 */
int dbot_service_call_service(
int device_id, // 被调用设备 ID
uint32_t service, // 被调用能力 ID
char *func, // 被调用属性名
char *param, // 调用参数
DTCP_CALL_RESULT_CB cb // 回调函数
);关键理解(易错点):能力发布分两步——先用
dbot_service_add_service(service, attr_num, attrs)把能力(含属性数组)注册到本地,再用dbot_service_publish_service(void)(无参)广播发布。不存在dbot_service_publish_service(service, attr_num, attrs)(3 参数版本)。
4.3 消息与资源
/* 注册监听的消息资源 */
int dbot_service_add_resource(
const char *res_name, // 消息资源名
DDP_REQUEST_PROC func // 消息回调函数
);
/* 向 DBoT 网络广播消息 */
int dbot_service_send_broadcast(
char *res_name, // 消息资源名
char *buf, // 消息内容
int len // 消息长度
);4.4 会话管理
/* 与设备建立会话 */
int dbot_service_create_session(int device_id);
/* 与设备断开会话 */
int dbot_service_remove_session(int device_id);4.5 数据流转(DTP)
/* 初始化 DTP 服务(用于音视频数据流转) */
DTP_SERVICE_CONTEXT_S *dbot_service_init_dtp(
DTP_SERVICE_TYPE_E type, // 流转服务类型
char *ip, // 目标 IP 地址
uint16_t port // 端口号
);
/* 销毁 DTP 服务 */
int dbot_service_destory_dtp(DTP_SERVICE_CONTEXT_S *ctx);五、使用示例
5.1 智能灯设备 — 能力发布端
先看真实的属性结构体
ATTR_INFO_S(discovery/include/publish_service.h):
typedef int(*ATTR_FUNC)(int len, char *req, char **resp);
typedef struct _attr_info_t
{
char func_name[MAX_SERVICE_ATTR_FUNC_NAME_LEN];
char func_param[MAX_SERVICE_ATTR_FUNC_PARAM_LEN];
ATTR_FUNC func;
}ATTR_INFO_S;关键理解:能力的一个属性就是一条 ATTR_INFO_S——func_name(属性名)、func_param(参数说明)、func(处理函数,签名 int(*)(int len, char *req, char **resp))。没有 name/type 字段,也没有 ATTR_TYPE_BOOL/INT/STRING 这些类型。
#include <dbot_service.h>
#include <string.h>
/* 灯开关属性处理函数(ATTR_FUNC 签名) */
static int light_power(int len, char *req, char **resp)
{
bool power = (req != NULL) && (strncmp(req, "on", 2) == 0);
if (power) {
os_kprintf("Light turned ON\r\n");
/* 实际控制硬件:GPIO 输出高电平 */
} else {
os_kprintf("Light turned OFF\r\n");
/* 实际控制硬件:GPIO 输出低电平 */
}
return 0;
}
/* 灯能力属性数组(真实 ATTR_INFO_S 字段) */
ATTR_INFO_S light_attrs[] = {
{"power_ctrl", "", light_power}, /* 开关属性 */
};
void light_device_init(void)
{
/* 1. 初始化 DBoT 服务 */
dbot_service_init();
/* 2. 添加灯能力(注册到本地服务列表) */
dbot_service_add_service(
CAPABILITY_TYPE_LIGHT,
1, /* 1 个属性 */
light_attrs
);
/* 3. 发布已添加的能力到 DBoT 网络(无参) */
dbot_service_publish_service();
/* 4. 启动 DBoT 服务 */
dbot_service_start();
os_kprintf("Light device is online on DBoT bus\r\n");
}5.2 灯控面板 — 能力发现与调用
#include <dbot_service.h>
/* 设备发现回调 */
static void on_device_found(int device_id, capability_list_t cap)
{
os_kprintf("Found device %d with capability %d\r\n", device_id, cap);
if (cap == CAPABILITY_TYPE_LIGHT) {
/* 发现灯设备,调用开灯 */
bool power_on = true;
dbot_service_call_service(
device_id,
CAPABILITY_TYPE_LIGHT,
"power_ctrl", /* 调用开关属性 */
(char *)&power_on,
call_result_cb /* 调用结果回调 */
);
}
}
static int call_result_cb(char *resp, int len)
{
if (resp != NULL) {
os_kprintf("Service call result: %.*s\r\n", len, resp);
return 0;
}
return -1;
}
void panel_device_init(void)
{
dbot_service_init();
dbot_service_start();
/* 发现网络中的设备 */
dbot_service_discovery_service();
}5.3 音视频数据流转
/* 启动音频流转(从麦克风设备到喇叭设备) */
void start_audio_flow(void)
{
DTP_SERVICE_CONTEXT_S *dtp_ctx;
/* 初始化 DTP 客户端 */
dtp_ctx = dbot_service_init_dtp(
DTP_SERVICE_UDP_CLIENT,
"192.168.1.100", /* 目标设备 IP */
8888 /* 端口号 */
);
if (dtp_ctx) {
/* 使用 dtp_send 发送音频数据(签名:int (*)(void *ctx, uint8_t *data, int len)) */
dtp_ctx->dtp_send(dtp_ctx, audio_buffer, audio_len);
}
}六、Kconfig 配置
6.1 配置菜单
(Top) → Components → DBoT
[*] Enable DBoT
[*] Enable DBoT publish module # 能力发布模块
[*] Enable DBoT discover module # 能力发现模块
(5) Configure DBoT heartbeat interval # 心跳间隔(秒)
Configure DBoT network --->
(X) ethernet # 以太网
( ) wifi # WiFi
( ) ble # 蓝牙
[*] Enable DBoT example
[*] Enable light example
[ ] Enable lcd example
[*] Enable camera example
[*] Enable DBoT example auto start
[*] Enable DBoT example shell cmd6.2 配置项说明
| 配置项 | 类型 | 默认值 | 说明 |
|---|---|---|---|
OS_USING_DBOT | bool | n | 启用 DBoT 组件 |
DBOT_PUBLISH | bool | y | 启用能力发布模块 |
DBOT_DISCOVERY | bool | y | 启用能力发现模块 |
DBOT_HB_INTERVAL | int | 5 | 心跳间隔(秒) |
DBOT_NETWORK_USE_ETH | choice | y | 使用以太网 |
DBOT_NETWORK_USE_WIFI | choice | n | 使用 WiFi |
DBOT_NETWORK_USE_BLE | choice | n | 使用蓝牙 |
6.3 依赖关系
OS_USING_DBOT
├── PKG_USING_CJSON (JSON 解析)
├── OS_USING_PTHREADS (POSIX 线程)
├── NET_USING_BSD (BSD Socket)
└── OS_USING_RTC (实时时钟)七、Shell 调试命令
DBoT 提供了丰富的 Shell 命令用于调试:
| 命令 | 说明 |
|---|---|
dbot_device_info | 查询设备基本信息 |
dbot_show_service | 查询已发现的设备及能力 |
dbot_call_service | 调用设备能力(简易) |
dbot_create_session | 与设备建立会话 |
dbot_remove_session | 与设备断开会话 |
dbot_discovery_service | 发现设备及能力 |
dbot_show_directory | 查询对端设备目录结构 |
dbot_write_file | 向对端传输文件 |
dbot_audio_dataflow | 启动音频流转 |
dbot_audio_dataflow_stop | 停止音频流转 |
dbot_video_dataflow | 启动视频流转 |
dbot_video_dataflow_stop | 停止视频流转 |
Shell 交互示例:
$ dbot_device_info
Device ID: 0x0012
Device Name: smart_light_01
Capabilities: Light, Temperature
$ dbot_show_service
Service ID: 0x0001 - Light (Device: 0x0012)
Service ID: 0x0002 - Camera (Device: 0x0015)
$ dbot_call_service 0x0012 Light power_ctrl 1
Service call result: OK八、内置示例能力
DBoT 组件内置了 7 种能力示例,可直接用于学习和验证:
| 能力示例 | 配置宏 | 说明 |
|---|---|---|
| 灯 | LIGHT_EXAMPLE | 开关、亮度、颜色控制 |
| 屏幕 | LCD_EXAMPLE | 图片/视频显示 |
| 光照传感器 | ILLUMINATION_EXAMPLE | 光照强度读取 |
| 摄像头 | CAMERA_EXAMPLE | 视频采集与流转 |
| 录音 | RECORDER_EXAMPLE | 音频录制 |
| 喇叭 | SPEAKER_EXAMPLE | 音频播放 |
| 文件系统 | FILESYSTEM_EXAMPLE | 目录浏览、文件传输 |
📝 本节小结
核心要点回顾
- 定位:DBoT(Distributed Bus of Things)是 OneOS 分布式物联总线,把设备分解为多个子应用连到虚拟总线上,呈现为一个大虚拟设备;源码位于
components/DBoT/。 - 分层协议:DDP(设备发现)→ DTCP(设备调用)→ DTP(数据流转,UDP/TCP);子模块含 auth/coap/discovery/group/session。
- 能力模型:
capability_list_t预定义 LIGHT/TEMP/HUMI/LCD/CAMERA/MICROPHONE/SPEAKER/SWITCH/FILESYSTEM 等能力(源码注释为中文,逐字一致)。 - 属性结构:
ATTR_INFO_S含func_name/func_param/func(ATTR_FUNC处理函数int(*)(int len, char *req, char **resp)),没有 name/type 字段。 - 核心 API:
dbot_service_init/start/stop/started/get_ctx(生命周期)、add_service+publish_service(发布)、discovery_service(发现)、call_service(调用)、add_resource/send_broadcast(消息)、create_session/remove_session(会话)、init_dtp/destory_dtp(数据流转)。 - 发布流程:
dbot_service_add_service(service, attr_num, attrs)(添加)→dbot_service_publish_service(void)(无参发布)。 - Kconfig:
OS_USING_DBOT(默认 n,select cJSON/PTHREADS/BSD/RTC)+DBOT_PUBLISH/DBOT_DISCOVERY/DBOT_HB_INTERVAL(默认 5s)+ 网络 choice(ETH/WIFI/BLE)+ 各能力示例开关。 - 调试:12 个 Shell 命令覆盖设备信息、服务调用、会话、数据流转。
关键易错点速查
| 易错点 | 正确做法 |
|---|---|
用 dbot_service_publish_service(service, attr_num, attrs)(3 参) | 不存在 → 先 dbot_service_add_service(service, attr_num, attrs),再 dbot_service_publish_service(void) |
ATTR_INFO_S 用 .name/.type | 没有 name/type 字段 → 用 {"func_name", "func_param", func}(func 为 ATTR_FUNC 处理函数) |
用 ATTR_TYPE_BOOL/INT/STRING 类型 | 不存在 → 无属性类型字段,属性就是 ATTR_INFO_S |
能力属性回调用 DDP_REQUEST_PROC 签名 | 属性处理函数是 ATTR_FUNC int(*)(int len, char *req, char **resp) → 用 ATTR_FUNC |
DTP_SERVICE_TYPE_UDP_CLIENT | 枚举是 DTP_SERVICE_UDP_CLIENT(无 _TYPE_)→ 用 DTP_SERVICE_UDP_CLIENT/SERVER/TCP_CLIENT/SERVER |
dtp_send(data, len) 只传 2 参 | DTP_SEND_FUNC 签名是 int(*)(void *ctx, uint8_t *data, int len) → 传 3 参(首参 dtp_ctx) |
call_result_cb(int result) 回调签名 | DTCP_CALL_RESULT_CB 是 int(*)(char *resp, int len) → 签名含 resp/len |
服务调用 func 参数乱传 | call_service 的 func 对应属性 func_name → 传 "power_ctrl" 等属性名 |
忘开 OS_USING_DBOT 及依赖 | 组件被裁剪 → 开 OS_USING_DBOT(自动 select cJSON/PTHREADS/BSD/RTC) |
忘 dbot_service_start() | 只 init 不 start 无法服务 → 发布后调用 dbot_service_start() |
数据结构 dbot_service_context_s 加 // 中文注释 | 违反"逐字一致"规范 → 保留源码原样(无注释),中文解释写正文 |
下一步
- 7.8 OTA 远程升级组件:DBoT 已覆盖设备互联,下一节学习 OneOS OTA 远程升级组件,掌握固件分包、升级流程与安全校验,为产品提供远程固件更新能力。