目录
一、什么是BLE Mesh Access Layer访问层?
二、Access payload
2.1 Opcode
三、Access layer behavior
3.1 Access layer发送消息的流程
3.2 Access layer接收消息的流程
3.3 Unacknowledged and acknowledged messages
3.3.1 Unacknowledged message
3.3.2 Acknowledged message
3.4 Example message sequence charts
3.4.1 Acknowledged Get
3.4.2 Acknowledged Set
3.4.3 Unacknowledged Set
3.4.4 Acknowledged set with periodic publishing
四、资料获取
BLE Mesh Access Layer是蓝牙Mesh协议栈的一部分,它主要负责以下几个方面的功能:
Field Name |
Size (octets) |
Notes |
Opcode |
1, 2, or 3 |
Operation Code |
Parameters |
0 to 379 |
Application Parameters |
一个access payload最多可以发送32个片段,每个片段12字节。这意味着最大值 包括TransMIC在内的字节数是384个。
对于4字节的TransMIC,access payload最大大小是380字节,因此对于单个字节的操作码,参数字段最多可以达到379字节。对于2字节的操作码,参数字段最多可以有378个字节。对于一个3字节的操作码,parameters字段最多可以有377个字节。
下传输层可以将消息分割成多段PDU,以便在网络层上传输。下表显示了根据包的数量和TransMIC的大小而定的最大有用的应用层包大小。
Number of Packets |
Maximum useful access payload size (octets) |
|
32 bit TransMIC |
64 bit TransMIC |
|
1 |
11 (unsegmented) |
n/a |
1 |
8 (segmented) |
4 (segmented) |
2 |
20 |
16 |
3 |
32 |
28 |
n |
(n×12)-4 |
(n×12)-8 |
32 |
380 |
376 |
Opcode Format |
Notes |
0xxxxxxx (excluding 01111111) |
1-octet Opcodes |
01111111 |
Reserved for Future Use |
10xxxxxx xxxxxxxx |
2-octet Opcodes |
11xxxxxx zzzzzzzz zzzzzzzz |
3-octet Opcodes |
/*源自开源协议栈NimBLE*/
static int model_send(struct bt_mesh_model *model,
struct bt_mesh_net_tx *tx, bool implicit_bind,
struct os_mbuf *msg,
const struct bt_mesh_send_cb *cb, void *cb_data)
{
BT_DBG("net_idx 0x%04x app_idx 0x%04x dst 0x%04x", tx->ctx->net_idx,
tx->ctx->app_idx, tx->ctx->addr);
BT_DBG("len %u: %s", msg->om_len, bt_hex(msg->om_data, msg->om_len));
if (!bt_mesh_is_provisioned()) {
BT_ERR("Local node is not yet provisioned");
return -EAGAIN;
}
if (net_buf_simple_tailroom(msg) < 4) {
BT_ERR("Not enough tailroom for TransMIC");
return -EINVAL;
}
if (msg->om_len > BT_MESH_TX_SDU_MAX - 4) {
BT_ERR("Too big message");
return -EMSGSIZE;
}
if (!implicit_bind && !model_has_key(model, tx->ctx->app_idx)) {
BT_ERR("Model not bound to AppKey 0x%04x", tx->ctx->app_idx);
return -EINVAL;
}
return bt_mesh_trans_send(tx, msg, cb, cb_data);
}
int bt_mesh_model_send(struct bt_mesh_model *model,
struct bt_mesh_msg_ctx *ctx,
struct os_mbuf *msg,
const struct bt_mesh_send_cb *cb, void *cb_data)
{
struct bt_mesh_net_tx tx = {
.sub = bt_mesh_subnet_get(ctx->net_idx),
.ctx = ctx,
.src = bt_mesh_model_elem(model)->addr,
.xmit = bt_mesh_net_transmit_get(),
.friend_cred = 0,
};
return model_send(model, &tx, false, msg, cb, cb_data);
}
/*BLE Mesh访问层接收数据子函数*/
/*源自开源协议栈NimBLE*/
void bt_mesh_model_recv(struct bt_mesh_net_rx *rx, struct os_mbuf *buf)
{
struct bt_mesh_model *models, *model;
const struct bt_mesh_model_op *op;
u32_t opcode;
u8_t count;
int i;
BT_DBG("app_idx 0x%04x src 0x%04x dst 0x%04x", rx->ctx.app_idx,
rx->ctx.addr, rx->ctx.recv_dst);
BT_DBG("len %u: %s", buf->om_len, bt_hex(buf->om_data, buf->om_len));
if (get_opcode(buf, &opcode) < 0) {
BT_WARN("Unable to decode OpCode");
return;
}
BT_DBG("OpCode 0x%08x", (unsigned) opcode);
for (i = 0; i < dev_comp->elem_count; i++) {
struct bt_mesh_elem *elem = &dev_comp->elem[i];
struct net_buf_simple_state state;
/* SIG models cannot contain 3-byte (vendor) OpCodes, and
* vendor models cannot contain SIG (1- or 2-byte) OpCodes, so
* we only need to do the lookup in one of the model lists.
*/
if (BT_MESH_MODEL_OP_LEN(opcode) < 3) {
models = elem->models;
count = elem->model_count;
} else {
models = elem->vnd_models;
count = elem->vnd_model_count;
}
op = find_op(models, count, opcode, &model);
if (!op) {
BT_DBG("No OpCode 0x%08x for elem %d", opcode, i);
continue;
}
if (!model_has_key(model, rx->ctx.app_idx)) {
continue;
}
if (!model_has_dst(model, rx->ctx.recv_dst)) {
continue;
}
if (buf->om_len < op->min_len) {
BT_ERR("Too short message for OpCode 0x%08x", opcode);
continue;
}
/* The callback will likely parse the buffer, so
* store the parsing state in case multiple models
* receive the message.
*/
net_buf_simple_save(buf, &state);
op->func(model, &rx->ctx, buf);
net_buf_simple_restore(buf, &state);
}
}
unAcknowledged Message是一种不需要接收端回复应答的消息。它的定义如下:
Acknowledged Message是一种需要接收端回复一个状态消息作为应答的消息。它的定义如下:
Acknowledged Get是一种用于从服务器端请求状态信息的消息类型。它属于Acknowledged MSG的一种,也就是说,当服务器端收到这个消息后,需要回复一个对应的Status消息,告诉客户端当前的状态值。这样可以保证客户端和服务器端的状态同步,也可以避免消息丢失或重复的问题。
例如,如果客户端想要知道一个灯的亮度,它可以发送一个Generic Level Get消息,这是一种Acknowledged Get消息,它的Opcode是0x8205。服务器端收到这个消息后,会回复一个Generic Level Status消息,它的Opcode是0x8206,它的Payload包含了当前的亮度值。
Acknowledged Set是一种用于向服务器端发送状态设置请求的消息类型。它也属于Acknowledged MSG的一种,也就是说,当服务器端收到这个消息后,需要回复一个对应的Status消息,告诉客户端状态是否设置成功。这样可以保证客户端和服务器端的状态同步,也可以避免消息丢失或重复的问题。
例如,如果客户端想要设置一个灯的亮度,它可以发送一个Generic Level Set消息,这是一种Acknowledged Set消息,它的Opcode是0x8207。它的Payload包含了要设置的亮度值和一个可选的Transition Time和Delay参数,用于控制灯的渐变效果。服务器端收到这个消息后,会回复一个Generic Level Status消息,它的Opcode是0x8206,它的Payload包含了当前的亮度值。
Unacknowledged Set是一种用于向服务器端发送状态设置请求的消息类型。它不属于Acknowledged MSG,也就是说,当服务器端收到这个消息后,不需要回复一个对应的Status消息,也不会把当前状态的改变后的结果通过Publish地址向四周广播。这样可以减少网络层的负载,提高传输效率,但也可能导致客户端和服务器端的状态不同步,或者消息丢失或重复的问题。
例如,如果客户端想要设置一个灯的亮度,它可以发送一个Generic Level Set Unacknowledged消息,这是一种Unacknowledged Set消息,它的Opcode是0x8208。它的Payload包含了要设置的亮度值和一个可选的Transition Time和Delay参数,用于控制灯的渐变效果。服务器端收到这个消息后,不会回复任何消息,也不会广播当前的亮度值。
Acknowledged set with periodic publishing是一种用于向服务器端发送状态设置请求并启用周期性状态发布的消息类型。它属于Acknowledged MSG的一种,也就是说,当服务器端收到这个消息后,需要回复一个对应的Status消息,告诉客户端状态是否设置成功,并且按照设定的时间间隔和发布地址,定期广播当前的状态值。这样可以保证客户端和服务器端的状态同步,也可以让其他订阅了发布地址的节点获取服务器端的状态信息。
例如,如果客户端想要设置一个灯的亮度,并且让灯每隔5秒钟发布一次当前的亮度值,它可以发送一个Generic Level Set消息,这是一种Acknowledged Set消息,它的Opcode是0x8207。它的Payload包含了要设置的亮度值和一个可选的Transition Time和Delay参数,用于控制灯的渐变效果。它还需要配置灯的发布地址和发布周期,比如发布地址为0xC000(所有节点的组播地址),发布周期为5秒。服务器端收到这个消息后,会回复一个Generic Level Status消息,它的Opcode是0x8206,它的Payload包含了当前的亮度值。同时,服务器端会每隔5秒钟向0xC000地址发送一个Generic Level Status消息,让其他节点知道当前的亮度值
通过点击以下链接,您可以获取BLE Mesh模块原理图、源代码以及开发资料。链接地址将为您提供详细的文件资料,以供您进行参考和使用。
如果您在使用过程中遇到任何问题或疑虑,欢迎加我QQ ,一起探讨技术问题,我的QQ号是986571840,加的时候请注明CSDN。
BLE Mesh蓝牙组网模块 - 硬创社 (jlc.com)https://x.jlc.com/platform/detail/001d23cba7b64b0d9df5b9b69720fadb
感谢各位用户点赞、分享、在看,这些行为让知识得以更加广泛地传播,从而让更多人受益。
请在转载作品时注明出处,严禁抄袭行为。