这是最新(主)开发分支的文档。如果您正在查找以前版本的文档,使用左侧的下拉菜单选择所需的版本。

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 流的 wrrd 回调以将数据移动到 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.

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.

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.

enum bt_mesh_blob_io_mode

BLOB stream interaction mode.

Values:

enumerator BT_MESH_BLOB_READ

Read data from the stream.

enumerator BT_MESH_BLOB_WRITE

Write data to the stream.

struct bt_mesh_blob_block

BLOB transfer data block.

Public Members

size_t size

Block size in bytes

off_t offset

Offset in bytes from the start of the BLOB.

uint16_t number

Block number

uint16_t chunk_count

Number of chunks in block.

uint8_t missing[DIV_ROUND_UP(0, 8)]

Bitmap of missing chunks.

struct bt_mesh_blob_chunk

BLOB data chunk.

Public Members

off_t offset

Offset of the chunk data from the start of the block.

size_t size

Chunk data size.

uint8_t *data

Chunk data.

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.

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.