BLOB 传输模型
二进制大型对象(BLOB)传输模型实现了蓝牙 Mesh 二进制大对象传输模型规范1.0版,并提供了通过 Bluetooth Mesh 网络将大型二进制对象从单个源发送到多个目标节点的功能。 它是 设备固件更新(DFU) 的底层传输方法,但可以用于其他对象传输目的。该实现处于实验状态。
BLOB 传输模型支持高达 4 GB(2 32 bytes)的连续二进制对象的传输。BLOB 传输协议具有内置的数据包丢失恢复过程,并设置检查点以确保所有目标在继续操作之前接收到所有数据。数据传输顺序不受保证。
BLOB 传输受到底层网状网络的传输速度和可靠性的限制。在理想条件下, BLOB 可以以高达 1 kbps 的速率传输,允许在 10-15 分钟内传输 100 kB 的 BLOB。 然而,网络条件、传输能力和其他限制因素可以容易地将数据速率降低几个数量级。 根据应用程序和网络配置调整传输的参数,并将其调度到网络流量较低的时段, 将显著提高协议的速度和可靠性。然而,在实际部署中,实现接近理想速率的传输速率是不可能的。
有两种 BLOB 传输模型:
BLOB Transfer Client 在发送方节点上实例化,BLOB 传输服务器在接收方节点上实例化。
概念
BLOB 传输协议引入了几个新的概念来实现 BLOB 传送。
BLOBs
BLOB 是大小高达 4 GB 的二进制对象,可以包含应用程序希望通过网状网络传输的任何数据。 BLOB 为连续数据对象,分为块和块,以使传输可靠且易于处理。BLOB 的内容或结构没有任何限制, 应用程序可以自由地对数据本身定义他们想要的任何编码或压缩。
BLOB 传输协议不提供 BLOB 数据的任何内置完整性检查、加密或身份验证。然而, Bluetooth Mesh 协议的底层加密提供了数据完整性检查,并使用网络和应用程序级加密保护 BLOB 的内容免受第三方的攻击。
阻碍
二进制对象被划分为块,通常大小从几百字节到几千字节。
每个块都是单独传输的,BLOB 传输客户机确保所有 BLOB 转移服务器在转移到下一个块之前都已收到完整的块。
块大小由传输的 block_size_log
参数确定,并且对于传输中的所有块都相同,但最后一个块除外,
后者可能更小。对于存储在闪存中的 BLOB,块大小通常是目标设备的闪存页面大小的倍数。
块结构
每个块被划分为块。区块是 BLOB 传输中的最小数据单元,并且必须适合单个 Bluetooth Mesh 访问消息(操作码除外)(379字节或更少)。传输块的机制取决于传输模式。
在推送 BLOB 传输模式下操作时,区块将作为未确认的数据包从 BLOB Transfer Client 发送到所有目标 BLOB 转移服务器。 一旦发送了块中的所有块,BLOB 传输客户端就会询问每个 BLOB Transfer Server 是否缺少任何块, 然后重新发送它们。重复此操作,直到所有 BLOB 传输服务器都接收到所有区块,或者 BLOB 转移客户端放弃。
在 Pull BLOB 传输模式下操作时,BLOB Transfer Server 将一次从 BLOB 转移客户端请求少量块,并等待 BLOB 传送客户端发送它们, 然后再请求更多块。重复此操作,直到所有区块都已传输,或者 BLOB 传输服务器放弃。
在 传输模式 部分中阅读有关传输模式的更多信息。
BLOB 流
在 BLOB 传输模型的 API 中,BLOB 数据处理与高级传输处理分离。这种拆分允许为不同的应用程序重用不同的 BLOB 存储和传输策略。虽然高级传输直接由应用程序控制,但 BLOB 数据本身是通过 BLOB 流访问的。
BLOB 流与标准库文件流相当。通过打开、关闭、读取和写入,BLOB 传输模型可以完全访问 BLOB 数据, 无论它保存在闪存、RAM 还是外围设备上。BLOB 流在使用之前以访问模式(读或写)打开, BLOB 传输模型将在 BLOB 的数据中以块和块的形式移动,使用 BLOB 数据流作为接口。
相互作用
在读取或写入 BLOB 之前,通过调用其 open
回调。当与 BLOB 传输服务器一起使用时,BLOB 流始终以写入模式打开,当与 BLIB 传输客户端一起使用时则始终以读取模式打开。
对于 BLOB 中的每个块,BLOB 传输模型通过调用 block_start
。然后,根据访问模式,
重复调用 BLOB 流的 wr
或 rd
回调以将数据移动到 BLOB 或从 BLOB 移动。
当模型完成处理块时,它调用 block_end
。
传输完成后,通过调用 close
关闭 BLOB 流。
启动位置
应用程序可以实现自己的 BLOB 流,或使用 WM IoT SDK 提供的实现:
传输能力
每个 BLOB 传输服务器可能具有不同的传输功能。通过以下配置选项控制每个设备的传输能力:
CONFIG_BT_MESH_BLOB_SIZE_MAX
CONFIG_BT_MESH_BLOB_BLOCK_SIZE_MIN
CONFIG_BT_MESH_BLOB_BLOCK_SIZE_MAX
CONFIG_BT_MESH_BLOB_CHUNK_COUNT_MAX
CONFIG_BT_MESH_BLOB_CHUNK_COUNT_MAX
选项也由 BLOB 传输客户端使用,并影响 BLOB 转移客户端模型结构的内存消耗。
为了确保传输可以被尽可能多的服务器接收,BLOB 传输客户端可以在开始传输之前检索每个 BLOB transfer Server 的功能。客户端将传输具有最大可能块和区块大小的 BLOB。
传输模式
BLOB 可以使用两种传输模式进行传输,即 Push BLOB 传输模式和 Pull BLOB 转换模式。在大多数情况下,传输应在 Push BLOB 传输模式下进行。
在 Push-BLOB 传输模式下,发送速率由 BLOB 传输客户端控制,该客户端将在没有任何高级流控制的情况下推送每个块的所有块。推送 BLOB 传输模式支持任意数量的目标节点,并且应该是默认传输模式。
在 Pull BLOB 传输模式下,BLOB Transfer Server 将以自己的速率从 BLOB 转移客户端“拉取”区块。 Pull BLOB 传输模式可以与多个 Target 节点一起执行,用于将 BLOB 传送到充当 低功耗节点 . 在 Pull BLOB 传输模式下操作时,BLOB Transfer Server 将小批量地从 BLOB 转移客户端请求区块, 并等待它们全部到达,然后再请求更多区块。重复此过程,直到 BLOB 传输服务器接收到块中的所有块。 然后,BLOB Transfer Client 启动下一个块,而 BLOB 传输服务器请求该块的所有块。
传输超时时间
BLOB 传输的超时基于 timeout Base 值。客户端和服务器都使用相同的 Timeout Base 值,但它们计算超时的方式不同。
BLOB 传输服务器使用以下公式来计算 BLOB 传送超时:
10 * (Timeout Base + 1) seconds
对于 BLOB 传输客户端,使用以下公式:
(10000 * (Timeout Base + 2)) + (100 * TTL) milliseconds
其中 TTL 是传输中设置的生存时间值。
API 参考
本节包含 BLOB 传输模型通用的类型和定义。
- group bt_mesh_blob
Defines
-
CONFIG_BT_MESH_BLOB_CHUNK_COUNT_MAX
Enums
-
enum bt_mesh_blob_xfer_mode
BLOB transfer mode.
Values:
-
enumerator BT_MESH_BLOB_XFER_MODE_NONE
No valid transfer mode.
-
enumerator BT_MESH_BLOB_XFER_MODE_PUSH
Push mode (Push BLOB Transfer Mode).
-
enumerator BT_MESH_BLOB_XFER_MODE_PULL
Pull mode (Pull BLOB Transfer Mode).
-
enumerator BT_MESH_BLOB_XFER_MODE_ALL
Both modes are valid.
-
enumerator BT_MESH_BLOB_XFER_MODE_NONE
-
enum bt_mesh_blob_xfer_phase
Transfer phase.
Values:
-
enumerator BT_MESH_BLOB_XFER_PHASE_INACTIVE
The BLOB Transfer Server is awaiting configuration.
-
enumerator BT_MESH_BLOB_XFER_PHASE_WAITING_FOR_START
The BLOB Transfer Server is ready to receive a BLOB transfer.
-
enumerator BT_MESH_BLOB_XFER_PHASE_WAITING_FOR_BLOCK
The BLOB Transfer Server is waiting for the next block of data.
-
enumerator BT_MESH_BLOB_XFER_PHASE_WAITING_FOR_CHUNK
The BLOB Transfer Server is waiting for the next chunk of data.
-
enumerator BT_MESH_BLOB_XFER_PHASE_COMPLETE
The BLOB was transferred successfully.
-
enumerator BT_MESH_BLOB_XFER_PHASE_SUSPENDED
The BLOB transfer is paused.
-
enumerator BT_MESH_BLOB_XFER_PHASE_INACTIVE
-
enum bt_mesh_blob_status
BLOB model status codes.
Values:
-
enumerator BT_MESH_BLOB_SUCCESS
The message was processed successfully.
-
enumerator BT_MESH_BLOB_ERR_INVALID_BLOCK_NUM
The Block Number field value is not within the range of blocks being transferred.
-
enumerator BT_MESH_BLOB_ERR_INVALID_BLOCK_SIZE
The block size is smaller than the size indicated by the Min Block Size Log state or is larger than the size indicated by the Max Block Size Log state.
-
enumerator BT_MESH_BLOB_ERR_INVALID_CHUNK_SIZE
The chunk size exceeds the size indicated by the Max Chunk Size state, or the number of chunks exceeds the number specified by the Max Total Chunks state.
-
enumerator BT_MESH_BLOB_ERR_WRONG_PHASE
The operation cannot be performed while the server is in the current phase.
-
enumerator BT_MESH_BLOB_ERR_INVALID_PARAM
A parameter value in the message cannot be accepted.
-
enumerator BT_MESH_BLOB_ERR_WRONG_BLOB_ID
The message contains a BLOB ID value that is not expected.
-
enumerator BT_MESH_BLOB_ERR_BLOB_TOO_LARGE
There is not enough space available in memory to receive the BLOB.
-
enumerator BT_MESH_BLOB_ERR_UNSUPPORTED_MODE
The transfer mode is not supported by the BLOB Transfer Server model.
-
enumerator BT_MESH_BLOB_ERR_INTERNAL
An internal error occurred on the node.
-
enumerator BT_MESH_BLOB_ERR_INFO_UNAVAILABLE
The requested information cannot be provided while the server is in the current phase.
-
enumerator BT_MESH_BLOB_SUCCESS
-
struct bt_mesh_blob_block
BLOB transfer data block.
-
struct bt_mesh_blob_chunk
BLOB data chunk.
-
struct bt_mesh_blob_xfer
BLOB transfer.
Public Members
-
uint64_t id
BLOB ID.
-
size_t size
Total BLOB size in bytes.
-
enum bt_mesh_blob_xfer_mode mode
BLOB transfer mode.
-
uint16_t chunk_size
Base chunk size. May be smaller for the last chunk.
-
uint64_t id
-
struct bt_mesh_blob_io
BLOB stream.
Public Members
-
int (*open)(const struct bt_mesh_blob_io *io, const struct bt_mesh_blob_xfer *xfer, enum bt_mesh_blob_io_mode mode)
Open callback.
Called when the reader is opened for reading.
- Param io:
BLOB stream.
- Param xfer:
BLOB transfer.
- Param mode:
Direction of the stream (read/write).
- Return:
0 on success, or (negative) error code otherwise.
-
void (*close)(const struct bt_mesh_blob_io *io, const struct bt_mesh_blob_xfer *xfer)
Close callback.
Called when the reader is closed.
- Param io:
BLOB stream.
- Param xfer:
BLOB transfer.
-
int (*block_start)(const struct bt_mesh_blob_io *io, const struct bt_mesh_blob_xfer *xfer, const struct bt_mesh_blob_block *block)
Block start callback.
Called when a new block is opened for sending. Each block is only sent once, and are always sent in increasing order. The data chunks inside a single block may be requested out of order and multiple times.
- Param io:
BLOB stream.
- Param xfer:
BLOB transfer.
- Param block:
Block that was started.
-
void (*block_end)(const struct bt_mesh_blob_io *io, const struct bt_mesh_blob_xfer *xfer, const struct bt_mesh_blob_block *block)
Block end callback.
Called when the current block has been transmitted in full. No data from this block will be requested again, and the application data associated with this block may be discarded.
- Param io:
BLOB stream.
- Param xfer:
BLOB transfer.
- Param block:
Block that finished sending.
-
int (*wr)(const struct bt_mesh_blob_io *io, const struct bt_mesh_blob_xfer *xfer, const struct bt_mesh_blob_block *block, const struct bt_mesh_blob_chunk *chunk)
Chunk data write callback.
Used by the BLOB Transfer Server on incoming data.
Each block is divided into chunks of data. This callback is called when a new chunk of data is received. Chunks may be received in any order within their block.
If the callback returns successfully, this chunk will be marked as received, and will not be received again unless the block is restarted due to a transfer suspension. If the callback returns a non-zero value, the chunk remains unreceived, and the BLOB Transfer Client will attempt to resend it later.
Note that the Client will only perform a limited number of attempts at delivering a chunk before dropping a Target node from the transfer. The number of retries performed by the Client is implementation specific.
- Param io:
BLOB stream.
- Param xfer:
BLOB transfer.
- Param block:
Block the chunk is part of.
- Param chunk:
Received chunk.
- Return:
0 on success, or (negative) error code otherwise.
-
int (*rd)(const struct bt_mesh_blob_io *io, const struct bt_mesh_blob_xfer *xfer, const struct bt_mesh_blob_block *block, const struct bt_mesh_blob_chunk *chunk)
Chunk data read callback.
Used by the BLOB Transfer Client to fetch outgoing data.
The Client calls the chunk data request callback to populate a chunk message going out to the Target nodes. The data request callback may be called out of order and multiple times for each offset, and cannot be used as an indication of progress.
Returning a non-zero status code on the chunk data request callback results in termination of the transfer.
- Param io:
BLOB stream.
- Param xfer:
BLOB transfer.
- Param block:
Block the chunk is part of.
- Param chunk:
Chunk to get the data of. The buffer pointer to by the
data
member should be filled by the callback.- Return:
0 on success, or (negative) error code otherwise.
-
int (*open)(const struct bt_mesh_blob_io *io, const struct bt_mesh_blob_xfer *xfer, enum bt_mesh_blob_io_mode mode)
-
CONFIG_BT_MESH_BLOB_CHUNK_COUNT_MAX