mirror of
https://github.com/espressif/esp-nimble.git
synced 2026-09-17 06:29:54 +00:00
Merge pull request #651 from michal-narajowski/friend_preparation
mesh: Preparation for Friend support X-Original-Commit: 92956057369204bd50d7f5f64c73076fbbf4588d
This commit is contained in:
@@ -175,13 +175,15 @@ void bt_mesh_adv_update(void)
|
||||
os_eventq_put(&adv_queue, &ev);
|
||||
}
|
||||
|
||||
struct os_mbuf *bt_mesh_adv_create(enum bt_mesh_adv_type type, u8_t xmit_count,
|
||||
u8_t xmit_int, s32_t timeout)
|
||||
struct os_mbuf *bt_mesh_adv_create_from_pool(struct os_mbuf_pool *pool,
|
||||
enum bt_mesh_adv_type type,
|
||||
u8_t xmit_count, u8_t xmit_int,
|
||||
s32_t timeout)
|
||||
{
|
||||
struct os_mbuf *adv_data;
|
||||
struct bt_mesh_adv *adv;
|
||||
|
||||
adv_data = os_mbuf_get_pkthdr(&adv_os_mbuf_pool, sizeof(struct bt_mesh_adv));
|
||||
adv_data = os_mbuf_get_pkthdr(pool, sizeof(struct bt_mesh_adv));
|
||||
if (!adv_data) {
|
||||
return NULL;
|
||||
}
|
||||
@@ -197,6 +199,14 @@ struct os_mbuf *bt_mesh_adv_create(enum bt_mesh_adv_type type, u8_t xmit_count,
|
||||
return adv_data;
|
||||
}
|
||||
|
||||
struct os_mbuf *bt_mesh_adv_create(enum bt_mesh_adv_type type, u8_t xmit_count,
|
||||
u8_t xmit_int, s32_t timeout)
|
||||
{
|
||||
return bt_mesh_adv_create_from_pool(&adv_os_mbuf_pool,
|
||||
type, xmit_count,
|
||||
xmit_int, timeout);
|
||||
}
|
||||
|
||||
void bt_mesh_adv_send(struct os_mbuf *buf, bt_mesh_adv_func_t sent)
|
||||
{
|
||||
BT_DBG("buf %p, type 0x%02x len %u: %s", buf, BT_MESH_ADV(buf)->type, buf->om_len,
|
||||
|
||||
@@ -37,6 +37,9 @@ struct bt_mesh_adv
|
||||
/* Generic User Data */
|
||||
u8_t user_data[2];
|
||||
|
||||
/* Address, used e.g. for Friend Queue messages */
|
||||
u16_t addr;
|
||||
|
||||
/* For transport layer segment sending */
|
||||
struct
|
||||
{
|
||||
@@ -53,6 +56,11 @@ struct bt_mesh_adv
|
||||
struct os_mbuf * bt_mesh_adv_create(enum bt_mesh_adv_type type, u8_t xmit_count,
|
||||
u8_t xmit_int, s32_t timeout);
|
||||
|
||||
struct os_mbuf *bt_mesh_adv_create_from_pool(struct os_mbuf_pool *pool,
|
||||
enum bt_mesh_adv_type type,
|
||||
u8_t xmit_count, u8_t xmit_int,
|
||||
s32_t timeout);
|
||||
|
||||
void bt_mesh_adv_send(struct os_mbuf *buf, bt_mesh_adv_func_t sent);
|
||||
|
||||
void bt_mesh_adv_update(void);
|
||||
|
||||
@@ -84,23 +84,17 @@ static void beacon_complete(struct os_mbuf *buf, int err)
|
||||
void bt_mesh_beacon_create(struct bt_mesh_subnet *sub,
|
||||
struct os_mbuf *buf)
|
||||
{
|
||||
u8_t flags = bt_mesh_net_flags(sub);
|
||||
struct bt_mesh_subnet_keys *keys;
|
||||
u8_t flags;
|
||||
|
||||
net_buf_simple_add_u8(buf, BEACON_TYPE_SECURE);
|
||||
|
||||
if (sub->kr_flag) {
|
||||
flags = BT_MESH_NET_FLAG_KR;
|
||||
keys = &sub->keys[1];
|
||||
} else {
|
||||
flags = 0x00;
|
||||
keys = &sub->keys[0];
|
||||
}
|
||||
|
||||
if (bt_mesh.iv_update) {
|
||||
flags |= BT_MESH_NET_FLAG_IVU;
|
||||
}
|
||||
|
||||
net_buf_simple_add_u8(buf, flags);
|
||||
|
||||
/* Network ID */
|
||||
|
||||
@@ -2536,7 +2536,9 @@ static void friend_set(struct bt_mesh_model *model,
|
||||
goto send_status;
|
||||
}
|
||||
|
||||
cfg->frnd = buf->om_data[0];
|
||||
if (MYNEWT_VAL(BLE_MESH_FRIEND)) {
|
||||
cfg->frnd = buf->om_data[0];
|
||||
}
|
||||
|
||||
sub = bt_mesh_subnet_get(cfg->hb_pub.net_idx);
|
||||
if ((cfg->hb_pub.feat & BT_MESH_FEAT_FRIEND) && sub) {
|
||||
|
||||
+66
-62
@@ -44,6 +44,11 @@
|
||||
#define NID(pdu) ((pdu)[0] & 0x7f)
|
||||
#define CTL(pdu) ((pdu)[1] >> 7)
|
||||
#define TTL(pdu) ((pdu)[1] & 0x7f)
|
||||
#define SEQ(pdu) (((u32_t)(pdu)[2] << 16) | \
|
||||
((u32_t)(pdu)[3] << 8) | (u32_t)(pdu)[4]);
|
||||
#define SRC(pdu) (sys_get_be16(&(pdu)[5]))
|
||||
#define DST(pdu) (sys_get_be16(&(pdu)[7]))
|
||||
|
||||
|
||||
/* Determine how many friendship credentials we need */
|
||||
#if (MYNEWT_VAL(BLE_MESH_FRIEND))
|
||||
@@ -131,13 +136,6 @@ static bool msg_cache_match(struct bt_mesh_net_rx *rx,
|
||||
return false;
|
||||
}
|
||||
|
||||
static inline u32_t net_seq(struct os_mbuf *buf)
|
||||
{
|
||||
return ((net_buf_simple_pull_u8(buf) << 16) & 0xff0000) |
|
||||
((net_buf_simple_pull_u8(buf) << 8) & 0xff00) |
|
||||
net_buf_simple_pull_u8(buf);
|
||||
}
|
||||
|
||||
struct bt_mesh_subnet *bt_mesh_subnet_get(u16_t net_idx)
|
||||
{
|
||||
int i;
|
||||
@@ -349,8 +347,8 @@ int bt_mesh_friend_cred_del(u16_t net_idx, u16_t addr)
|
||||
return -ENOENT;
|
||||
}
|
||||
|
||||
static int friend_cred_get(u16_t net_idx, u16_t addr, u8_t idx,
|
||||
u8_t *nid, const u8_t **enc, const u8_t **priv)
|
||||
int bt_mesh_friend_cred_get(u16_t net_idx, u16_t addr, u8_t idx,
|
||||
u8_t *nid, const u8_t **enc, const u8_t **priv)
|
||||
{
|
||||
int i;
|
||||
|
||||
@@ -385,33 +383,41 @@ static int friend_cred_get(u16_t net_idx, u16_t addr, u8_t idx,
|
||||
return -ENOENT;
|
||||
}
|
||||
#else
|
||||
static inline int friend_cred_get(u16_t net_idx, u16_t addr, u8_t idx,
|
||||
u8_t *nid, const u8_t **enc,
|
||||
const u8_t **priv)
|
||||
int bt_mesh_friend_cred_get(u16_t net_idx, u16_t addr, u8_t idx,
|
||||
u8_t *nid, const u8_t **enc, const u8_t **priv)
|
||||
{
|
||||
return -ENOENT;
|
||||
}
|
||||
#endif /* FRIEND || LOW_POWER */
|
||||
|
||||
int bt_mesh_net_beacon_update(struct bt_mesh_subnet *sub)
|
||||
u8_t bt_mesh_net_flags(struct bt_mesh_subnet *sub)
|
||||
{
|
||||
struct bt_mesh_subnet_keys *keys;
|
||||
u8_t flags;
|
||||
u8_t flags = 0x00;
|
||||
|
||||
if (sub->kr_flag) {
|
||||
BT_DBG("NetIndex %u Using new key", sub->net_idx);
|
||||
flags = BT_MESH_NET_FLAG_KR;
|
||||
keys = &sub->keys[1];
|
||||
} else {
|
||||
BT_DBG("NetIndex %u Using current key", sub->net_idx);
|
||||
flags = 0x00;
|
||||
keys = &sub->keys[0];
|
||||
if (sub && sub->kr_flag) {
|
||||
flags |= BT_MESH_NET_FLAG_KR;
|
||||
}
|
||||
|
||||
if (bt_mesh.iv_update) {
|
||||
flags |= BT_MESH_NET_FLAG_IVU;
|
||||
}
|
||||
|
||||
return flags;
|
||||
}
|
||||
|
||||
int bt_mesh_net_beacon_update(struct bt_mesh_subnet *sub)
|
||||
{
|
||||
u8_t flags = bt_mesh_net_flags(sub);
|
||||
struct bt_mesh_subnet_keys *keys;
|
||||
|
||||
if (sub->kr_flag) {
|
||||
BT_DBG("NetIndex %u Using new key", sub->net_idx);
|
||||
keys = &sub->keys[1];
|
||||
} else {
|
||||
BT_DBG("NetIndex %u Using current key", sub->net_idx);
|
||||
keys = &sub->keys[0];
|
||||
}
|
||||
|
||||
BT_DBG("flags 0x%02x, IVI 0x%08x", flags, bt_mesh.iv_index);
|
||||
|
||||
return bt_mesh_beacon_auth(keys->beacon, flags, keys->net_id,
|
||||
@@ -547,7 +553,7 @@ void bt_mesh_rpl_reset(void)
|
||||
}
|
||||
}
|
||||
|
||||
void bt_mesh_iv_update(u32_t iv_index, bool iv_update)
|
||||
bool bt_mesh_iv_update(u32_t iv_index, bool iv_update)
|
||||
{
|
||||
int i;
|
||||
|
||||
@@ -557,13 +563,13 @@ void bt_mesh_iv_update(u32_t iv_index, bool iv_update)
|
||||
if (iv_index != bt_mesh.iv_index) {
|
||||
BT_WARN("IV Index mismatch: 0x%08x != 0x%08x",
|
||||
iv_index, bt_mesh.iv_index);
|
||||
return;
|
||||
return false;
|
||||
}
|
||||
|
||||
if (iv_update) {
|
||||
/* Nothing to do */
|
||||
BT_DBG("Already in IV Update in Progress state");
|
||||
return;
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
/* We're currently in Normal mode */
|
||||
@@ -572,7 +578,7 @@ void bt_mesh_iv_update(u32_t iv_index, bool iv_update)
|
||||
iv_index > bt_mesh.iv_index + 42) {
|
||||
BT_ERR("IV Index out of sync: " "0x%08x != 0x%08x",
|
||||
iv_index, bt_mesh.iv_index);
|
||||
return;
|
||||
return false;
|
||||
}
|
||||
|
||||
if (iv_index > bt_mesh.iv_index + 1) {
|
||||
@@ -586,19 +592,19 @@ void bt_mesh_iv_update(u32_t iv_index, bool iv_update)
|
||||
if (iv_index == bt_mesh.iv_index + 1 && !iv_update) {
|
||||
BT_WARN("Ignoring new index in normal mode",
|
||||
iv_index, bt_mesh.iv_index);
|
||||
return;
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!iv_update) {
|
||||
/* Nothing to do */
|
||||
BT_DBG("Already in Normal mode");
|
||||
return;
|
||||
return false;
|
||||
}
|
||||
|
||||
if (iv_index != bt_mesh.iv_index + 1) {
|
||||
BT_WARN("Wrong new IV Index: 0x%08x != 0x%08x + 1",
|
||||
iv_index, bt_mesh.iv_index);
|
||||
return;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -607,7 +613,7 @@ void bt_mesh_iv_update(u32_t iv_index, bool iv_update)
|
||||
|
||||
if (delta < K_HOURS(96)) {
|
||||
BT_WARN("IV Update before minimum duration");
|
||||
return;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -615,7 +621,7 @@ void bt_mesh_iv_update(u32_t iv_index, bool iv_update)
|
||||
if (!iv_update && bt_mesh_tx_in_progress()) {
|
||||
BT_WARN("IV Update deferred because of pending transfer");
|
||||
bt_mesh.pending_update = 1;
|
||||
return;
|
||||
return false;
|
||||
}
|
||||
|
||||
do_update:
|
||||
@@ -644,6 +650,8 @@ do_update:
|
||||
bt_mesh_net_beacon_update(&bt_mesh.sub[i]);
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
int bt_mesh_net_resend(struct bt_mesh_subnet *sub, struct os_mbuf *buf,
|
||||
@@ -655,8 +663,9 @@ int bt_mesh_net_resend(struct bt_mesh_subnet *sub, struct os_mbuf *buf,
|
||||
BT_DBG("net_idx 0x%04x, len %u", sub->net_idx, buf->om_len);
|
||||
|
||||
if (friend_cred) {
|
||||
err = friend_cred_get(sub->net_idx, BT_MESH_ADDR_UNASSIGNED,
|
||||
new_key, NULL, &enc, &priv);
|
||||
err = bt_mesh_friend_cred_get(sub->net_idx,
|
||||
BT_MESH_ADDR_UNASSIGNED,
|
||||
new_key, NULL, &enc, &priv);
|
||||
if (err) {
|
||||
return err;
|
||||
}
|
||||
@@ -751,9 +760,9 @@ int bt_mesh_net_encode(struct bt_mesh_net_tx *tx, struct os_mbuf *buf,
|
||||
|
||||
if (tx->sub->kr_phase == BT_MESH_KR_PHASE_2) {
|
||||
if (tx->ctx->friend_cred) {
|
||||
err = friend_cred_get(tx->sub->net_idx,
|
||||
BT_MESH_ADDR_UNASSIGNED,
|
||||
1, &nid, &enc, &priv);
|
||||
err = bt_mesh_friend_cred_get(tx->sub->net_idx,
|
||||
BT_MESH_ADDR_UNASSIGNED,
|
||||
1, &nid, &enc, &priv);
|
||||
if (err) {
|
||||
return err;
|
||||
}
|
||||
@@ -764,9 +773,9 @@ int bt_mesh_net_encode(struct bt_mesh_net_tx *tx, struct os_mbuf *buf,
|
||||
}
|
||||
} else {
|
||||
if (tx->ctx->friend_cred) {
|
||||
err = friend_cred_get(tx->sub->net_idx,
|
||||
BT_MESH_ADDR_UNASSIGNED,
|
||||
0, &nid, &enc, &priv);
|
||||
err = bt_mesh_friend_cred_get(tx->sub->net_idx,
|
||||
BT_MESH_ADDR_UNASSIGNED,
|
||||
0, &nid, &enc, &priv);
|
||||
if (err) {
|
||||
return err;
|
||||
}
|
||||
@@ -909,15 +918,15 @@ static int net_decrypt(struct bt_mesh_subnet *sub, u8_t idx, const u8_t *data,
|
||||
sub->keys[idx].nid, NID(data), sub->net_idx, idx);
|
||||
|
||||
if (NID(data) == sub->keys[idx].nid) {
|
||||
rx->ctx.friend_cred = false;
|
||||
enc = sub->keys[idx].enc;
|
||||
priv = sub->keys[idx].privacy;
|
||||
rx->ctx.friend_cred = 0;
|
||||
} else {
|
||||
u8_t nid;
|
||||
|
||||
if (friend_cred_get(sub->net_idx, BT_MESH_ADDR_UNASSIGNED, idx,
|
||||
&nid, &enc, &priv)) {
|
||||
if (bt_mesh_friend_cred_get(sub->net_idx,
|
||||
BT_MESH_ADDR_UNASSIGNED, idx,
|
||||
&nid, &enc, &priv)) {
|
||||
return -ENOENT;
|
||||
}
|
||||
|
||||
@@ -944,7 +953,7 @@ static int net_decrypt(struct bt_mesh_subnet *sub, u8_t idx, const u8_t *data,
|
||||
return -EALREADY;
|
||||
}
|
||||
|
||||
rx->ctx.addr = sys_get_be16(&buf->om_data[5]);
|
||||
rx->ctx.addr = SRC(buf->om_data);
|
||||
if (!BT_MESH_ADDR_IS_UNICAST(rx->ctx.addr)) {
|
||||
BT_WARN("Ignoring non-unicast src addr 0x%04x", rx->ctx.addr);
|
||||
return -EINVAL;
|
||||
@@ -1033,9 +1042,9 @@ static void bt_mesh_net_relay(struct os_mbuf *sbuf,
|
||||
|
||||
if (rx->sub->kr_phase == BT_MESH_KR_PHASE_2) {
|
||||
if (bt_mesh_friend_dst_is_lpn(rx->dst)) {
|
||||
if (friend_cred_get(rx->sub->net_idx,
|
||||
BT_MESH_ADDR_UNASSIGNED,
|
||||
1, &nid, &enc, &priv)) {
|
||||
if (bt_mesh_friend_cred_get(rx->sub->net_idx,
|
||||
BT_MESH_ADDR_UNASSIGNED,
|
||||
1, &nid, &enc, &priv)) {
|
||||
BT_ERR("friend_cred_get failed");
|
||||
goto done;
|
||||
}
|
||||
@@ -1046,9 +1055,9 @@ static void bt_mesh_net_relay(struct os_mbuf *sbuf,
|
||||
}
|
||||
} else {
|
||||
if (bt_mesh_friend_dst_is_lpn(rx->dst)) {
|
||||
if (friend_cred_get(rx->sub->net_idx,
|
||||
BT_MESH_ADDR_UNASSIGNED,
|
||||
0, &nid, &enc, &priv)) {
|
||||
if (bt_mesh_friend_cred_get(rx->sub->net_idx,
|
||||
BT_MESH_ADDR_UNASSIGNED,
|
||||
0, &nid, &enc, &priv)) {
|
||||
BT_ERR("friend_cred_get failed");
|
||||
goto done;
|
||||
}
|
||||
@@ -1108,8 +1117,7 @@ done:
|
||||
}
|
||||
|
||||
int bt_mesh_net_decode(struct os_mbuf *data, enum bt_mesh_net_if net_if,
|
||||
struct bt_mesh_net_rx *rx, struct os_mbuf *buf,
|
||||
struct net_buf_simple_state *state)
|
||||
struct bt_mesh_net_rx *rx, struct os_mbuf *buf)
|
||||
{
|
||||
if (data->om_len < 18) {
|
||||
BT_WARN("Dropping too short mesh packet (len %u)", data->om_len);
|
||||
@@ -1135,11 +1143,6 @@ int bt_mesh_net_decode(struct os_mbuf *data, enum bt_mesh_net_if net_if,
|
||||
/* Initialize AppIdx to a sane value */
|
||||
rx->ctx.app_idx = BT_MESH_KEY_UNUSED;
|
||||
|
||||
/* Save parsing state so the buffer can later be relayed */
|
||||
if (state) {
|
||||
net_buf_simple_save(buf, state);
|
||||
}
|
||||
|
||||
rx->ctx.recv_ttl = TTL(buf->om_data);
|
||||
|
||||
/* Default to responding with TTL 0 for non-routed messages */
|
||||
@@ -1150,10 +1153,8 @@ int bt_mesh_net_decode(struct os_mbuf *data, enum bt_mesh_net_if net_if,
|
||||
}
|
||||
|
||||
rx->ctl = CTL(buf->om_data);
|
||||
net_buf_simple_pull(buf, 2); /* SRC, already parsed by net_decrypt() */
|
||||
rx->seq = net_seq(buf);
|
||||
net_buf_simple_pull(buf, 2);
|
||||
rx->dst = net_buf_simple_pull_be16(buf);
|
||||
rx->seq = SEQ(buf->om_data);
|
||||
rx->dst = DST(buf->om_data);
|
||||
|
||||
BT_DBG("Decryption successful. Payload len %u: %s", buf->om_len,
|
||||
bt_hex(buf->om_data, buf->om_len));
|
||||
@@ -1195,7 +1196,7 @@ void bt_mesh_net_recv(struct os_mbuf *data, s8_t rssi,
|
||||
goto done;
|
||||
}
|
||||
|
||||
if (bt_mesh_net_decode(data, net_if, &rx, buf, &state)) {
|
||||
if (bt_mesh_net_decode(data, net_if, &rx, buf)) {
|
||||
goto done;
|
||||
}
|
||||
|
||||
@@ -1204,6 +1205,9 @@ void bt_mesh_net_recv(struct os_mbuf *data, s8_t rssi,
|
||||
bt_mesh_proxy_addr_add(data, rx.ctx.addr);
|
||||
}
|
||||
|
||||
/* Save parsing state so the buffer can later be relayed */
|
||||
net_buf_simple_save(buf, &state);
|
||||
|
||||
if (bt_mesh_fixed_group_match(rx.dst) || bt_mesh_elem_find(rx.dst)) {
|
||||
bt_mesh_trans_recv(buf, &rx);
|
||||
|
||||
|
||||
@@ -238,12 +238,19 @@ extern struct bt_mesh_net bt_mesh;
|
||||
#define BT_MESH_NET_IVI_TX (bt_mesh.iv_index - bt_mesh.iv_update)
|
||||
#define BT_MESH_NET_IVI_RX(rx) (bt_mesh.iv_index - (rx)->old_iv)
|
||||
|
||||
#define BT_MESH_NET_HDR_LEN 9
|
||||
|
||||
int
|
||||
bt_mesh_net_keys_create(struct bt_mesh_subnet_keys *keys, const u8_t key[16]);
|
||||
|
||||
int
|
||||
bt_mesh_net_create(u16_t idx, u8_t flags, const u8_t key[16], u32_t iv_index);
|
||||
|
||||
u8_t
|
||||
bt_mesh_net_flags(struct bt_mesh_subnet *sub);
|
||||
|
||||
int bt_mesh_friend_cred_get(u16_t net_idx, u16_t addr, u8_t idx,
|
||||
u8_t *nid, const u8_t **enc, const u8_t **priv);
|
||||
int
|
||||
bt_mesh_friend_cred_set(struct bt_mesh_friend_cred *cred, u8_t idx,
|
||||
const u8_t net_key[16]);
|
||||
@@ -271,7 +278,7 @@ bt_mesh_net_beacon_update(struct bt_mesh_subnet *sub);
|
||||
void
|
||||
bt_mesh_rpl_reset(void);
|
||||
|
||||
void
|
||||
bool
|
||||
bt_mesh_iv_update(u32_t iv_index, bool iv_update);
|
||||
|
||||
struct bt_mesh_subnet *
|
||||
@@ -296,8 +303,7 @@ bool new_key,
|
||||
|
||||
int
|
||||
bt_mesh_net_decode(struct os_mbuf *data, enum bt_mesh_net_if net_if,
|
||||
struct bt_mesh_net_rx *rx, struct os_mbuf *buf,
|
||||
struct net_buf_simple_state *state);
|
||||
struct bt_mesh_net_rx *rx, struct os_mbuf *buf);
|
||||
|
||||
void
|
||||
bt_mesh_net_recv(struct os_mbuf *data, s8_t rssi, enum bt_mesh_net_if net_if);
|
||||
|
||||
@@ -315,12 +315,15 @@ static void proxy_cfg(struct bt_mesh_proxy_client *client)
|
||||
int err;
|
||||
|
||||
err = bt_mesh_net_decode(client->buf, BT_MESH_NET_IF_PROXY_CFG,
|
||||
&rx, buf, NULL);
|
||||
&rx, buf);
|
||||
if (err) {
|
||||
BT_ERR("Failed to decode Proxy Configuration (err %d)", err);
|
||||
goto done;
|
||||
}
|
||||
|
||||
/* Remove network headers */
|
||||
net_buf_simple_pull(buf, BT_MESH_NET_HDR_LEN);
|
||||
|
||||
BT_DBG("%u bytes: %s", buf->om_len, bt_hex(buf->om_data, buf->om_len));
|
||||
|
||||
if (buf->om_len < 1) {
|
||||
|
||||
@@ -27,16 +27,12 @@
|
||||
#include "transport.h"
|
||||
|
||||
#define AID_MASK ((u8_t)(BIT_MASK(6)))
|
||||
#define OP_MASK ((u8_t)(BIT_MASK(7)))
|
||||
|
||||
#define SEG(data) ((data)[0] >> 7)
|
||||
#define AKF(data) (((data)[0] >> 6) & 0x01)
|
||||
#define AID(data) ((data)[0] & AID_MASK)
|
||||
#define MIC_SIZE(data) (((data)[1] & 0x80) ? 8 : 4)
|
||||
|
||||
#define CTL_OP(data) ((data)[0] & OP_MASK)
|
||||
#define CTL_HDR(op, seg) ((op & OP_MASK) | (seg << 7))
|
||||
|
||||
#define SZMIC(mic_len) (mic_len == 8 ? 1 : 0)
|
||||
|
||||
#define UNSEG_HDR(akf, aid) ((akf << 6) | (aid & AID_MASK))
|
||||
@@ -59,6 +55,7 @@ static struct seg_tx {
|
||||
struct bt_mesh_subnet *sub;
|
||||
struct os_mbuf *seg[BT_MESH_TX_SEG_COUNT];
|
||||
u64_t seq_auth;
|
||||
u16_t dst;
|
||||
u8_t seg_n; /* Last segment index */
|
||||
u8_t nack_count; /* Number of not acked segments */
|
||||
bt_mesh_cb_t cb;
|
||||
@@ -101,7 +98,7 @@ static int send_unseg(struct bt_mesh_net_tx *tx, u8_t aid,
|
||||
return -ENOBUFS;
|
||||
}
|
||||
|
||||
net_buf_reserve(buf, 9);
|
||||
net_buf_reserve(buf, BT_MESH_NET_HDR_LEN);
|
||||
|
||||
if (tx->ctx->app_idx == BT_MESH_KEY_DEV) {
|
||||
net_buf_simple_add_u8(buf, UNSEG_HDR(0, 0));
|
||||
@@ -137,6 +134,7 @@ static void seg_tx_reset(struct seg_tx *tx)
|
||||
tx->cb_data = NULL;
|
||||
tx->seq_auth = 0;
|
||||
tx->sub = NULL;
|
||||
tx->dst = BT_MESH_ADDR_UNASSIGNED;
|
||||
|
||||
if (!tx->nack_count) {
|
||||
return;
|
||||
@@ -263,6 +261,7 @@ static int send_seg(struct bt_mesh_net_tx *net_tx, u8_t aid,
|
||||
}
|
||||
|
||||
seg_o = 0;
|
||||
tx->dst = net_tx->ctx->addr;
|
||||
tx->seg_n = (sdu->om_len - 1) / 12;
|
||||
tx->nack_count = tx->seg_n + 1;
|
||||
tx->seq_auth = SEQ_AUTH(BT_MESH_NET_IVI_TX, bt_mesh.seq);
|
||||
@@ -292,7 +291,7 @@ static int send_seg(struct bt_mesh_net_tx *net_tx, u8_t aid,
|
||||
BT_MESH_ADV(seg)->seg.new_key = net_tx->sub->kr_flag;
|
||||
BT_MESH_ADV(seg)->seg.friend_cred = net_tx->ctx->friend_cred;
|
||||
|
||||
net_buf_reserve(seg, 9);
|
||||
net_buf_reserve(seg, BT_MESH_NET_HDR_LEN);
|
||||
|
||||
net_buf_simple_add_u8(seg, seg_hdr);
|
||||
net_buf_simple_add_u8(seg, (SZMIC(mic_len) << 7) | seq_zero >> 6);
|
||||
@@ -534,6 +533,36 @@ done:
|
||||
return err;
|
||||
}
|
||||
|
||||
static struct seg_tx *seg_tx_lookup(u16_t seq_zero, u8_t obo, u16_t addr)
|
||||
{
|
||||
struct seg_tx *tx;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(seg_tx); i++) {
|
||||
tx = &seg_tx[i];
|
||||
|
||||
if ((tx->seq_auth & 0x1fff) != seq_zero) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (tx->dst == addr) {
|
||||
return tx;
|
||||
}
|
||||
|
||||
/* If the expected remote address doesn't match,
|
||||
* but the OBO flag is set and this is the first
|
||||
* acknowledgement, assume it's a Friend that's
|
||||
* responding and therefore accept the message.
|
||||
*/
|
||||
if (obo && tx->nack_count == tx->seg_n + 1) {
|
||||
tx->dst = addr;
|
||||
return tx;
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static int trans_ack(struct bt_mesh_net_rx *rx, u8_t hdr,
|
||||
struct os_mbuf *buf)
|
||||
{
|
||||
@@ -542,7 +571,6 @@ static int trans_ack(struct bt_mesh_net_rx *rx, u8_t hdr,
|
||||
u32_t ack;
|
||||
u16_t seq_zero;
|
||||
u8_t obo;
|
||||
int i;
|
||||
|
||||
if (buf->om_len < 6) {
|
||||
BT_ERR("Too short ack message");
|
||||
@@ -557,15 +585,9 @@ static int trans_ack(struct bt_mesh_net_rx *rx, u8_t hdr,
|
||||
|
||||
BT_DBG("OBO %u seq_zero 0x%04x ack 0x%08x", obo, seq_zero, ack);
|
||||
|
||||
for (tx = NULL, i = 0; i < ARRAY_SIZE(seg_tx); i++) {
|
||||
if ((seg_tx[i].seq_auth & 0x1fff) == seq_zero) {
|
||||
tx = &seg_tx[i];
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
tx = seg_tx_lookup(seq_zero, obo, rx->ctx.addr);
|
||||
if (!tx) {
|
||||
BT_WARN("Unknown SeqZero for ack");
|
||||
BT_WARN("No matching TX context for ack");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
@@ -631,7 +653,7 @@ static int trans_heartbeat(struct bt_mesh_net_rx *rx,
|
||||
static int ctl_recv(struct bt_mesh_net_rx *rx, u8_t hdr,
|
||||
struct os_mbuf *buf)
|
||||
{
|
||||
u8_t ctl_op = CTL_OP(&hdr);
|
||||
u8_t ctl_op = TRANS_CTL_OP(&hdr);
|
||||
|
||||
BT_DBG("OpCode 0x%02x len %u", ctl_op, buf->om_len);
|
||||
|
||||
@@ -731,10 +753,9 @@ int bt_mesh_ctl_send(struct bt_mesh_net_tx *tx, u8_t ctl_op, void *data,
|
||||
return -ENOBUFS;
|
||||
}
|
||||
|
||||
/* Reserve space for Network headers */
|
||||
net_buf_reserve(buf, 9);
|
||||
net_buf_reserve(buf, BT_MESH_NET_HDR_LEN);
|
||||
|
||||
net_buf_simple_add_u8(buf, CTL_HDR(ctl_op, 0));
|
||||
net_buf_simple_add_u8(buf, TRANS_CTL_HDR(ctl_op, 0));
|
||||
|
||||
net_buf_add_mem(buf, data, data_len);
|
||||
|
||||
@@ -1072,6 +1093,10 @@ int bt_mesh_trans_recv(struct os_mbuf *buf, struct bt_mesh_net_rx *rx)
|
||||
|
||||
BT_DBG("src 0x%04x dst 0x%04x seq 0x%08x", rx->ctx.addr, rx->dst,
|
||||
rx->seq);
|
||||
|
||||
/* Remove network headers */
|
||||
net_buf_simple_pull(buf, BT_MESH_NET_HDR_LEN);
|
||||
|
||||
BT_DBG("Payload %s", bt_hex(buf->om_data, buf->om_len));
|
||||
|
||||
/* If LPN mode is enabled messages are only accepted when we've
|
||||
|
||||
@@ -12,6 +12,10 @@
|
||||
#define BT_MESH_TX_SEG_COUNT (MYNEWT_VAL(BLE_MESH_ADV_BUF_COUNT) - 3)
|
||||
#define BT_MESH_TX_SDU_MAX (BT_MESH_TX_SEG_COUNT * 12)
|
||||
|
||||
#define TRANS_CTL_OP_MASK ((u8_t)BIT_MASK(7))
|
||||
#define TRANS_CTL_OP(data) ((data)[0] & TRANS_CTL_OP_MASK)
|
||||
#define TRANS_CTL_HDR(op, seg) ((op & TRANS_CTL_OP_MASK) | (seg << 7))
|
||||
|
||||
#define TRANS_CTL_OP_ACK 0x00
|
||||
#define TRANS_CTL_OP_FRIEND_POLL 0x01
|
||||
#define TRANS_CTL_OP_FRIEND_UPDATE 0x02
|
||||
|
||||
Reference in New Issue
Block a user