You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@mynewt.apache.org by GitBox <gi...@apache.org> on 2017/11/16 09:22:21 UTC

[GitHub] michal-narajowski closed pull request #651: mesh: Preparation for Friend support

michal-narajowski closed pull request #651: mesh: Preparation for Friend support
URL: https://github.com/apache/mynewt-core/pull/651
 
 
   

This is a PR merged from a forked repository.
As GitHub hides the original diff on merge, it is displayed below for
the sake of provenance:

As this is a foreign pull request (from a fork), the diff is supplied
below (as it won't show otherwise due to GitHub magic):

diff --git a/net/nimble/host/mesh/src/adv.c b/net/nimble/host/mesh/src/adv.c
index a05333819..8c30f4406 100644
--- a/net/nimble/host/mesh/src/adv.c
+++ b/net/nimble/host/mesh/src/adv.c
@@ -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,
diff --git a/net/nimble/host/mesh/src/adv.h b/net/nimble/host/mesh/src/adv.h
index 2f9f94b54..31d68296f 100644
--- a/net/nimble/host/mesh/src/adv.h
+++ b/net/nimble/host/mesh/src/adv.h
@@ -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);
diff --git a/net/nimble/host/mesh/src/beacon.c b/net/nimble/host/mesh/src/beacon.c
index 69d47cc8a..9558ae58f 100644
--- a/net/nimble/host/mesh/src/beacon.c
+++ b/net/nimble/host/mesh/src/beacon.c
@@ -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 */
diff --git a/net/nimble/host/mesh/src/cfg.c b/net/nimble/host/mesh/src/cfg.c
index a55f53138..5c6779908 100644
--- a/net/nimble/host/mesh/src/cfg.c
+++ b/net/nimble/host/mesh/src/cfg.c
@@ -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) {
diff --git a/net/nimble/host/mesh/src/net.c b/net/nimble/host/mesh/src/net.c
index 032abed83..861271a74 100644
--- a/net/nimble/host/mesh/src/net.c
+++ b/net/nimble/host/mesh/src/net.c
@@ -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))
@@ -136,13 +141,6 @@ static bool msg_is_known(u64_t hash)
 	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;
@@ -354,8 +352,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;
 
@@ -390,33 +388,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 */
 
+u8_t bt_mesh_net_flags(struct bt_mesh_subnet *sub)
+{
+	u8_t flags = 0x00;
+
+	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;
-	u8_t flags;
 
 	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 (bt_mesh.iv_update) {
-		flags |= BT_MESH_NET_FLAG_IVU;
-	}
-
 	BT_DBG("flags 0x%02x, IVI 0x%08x", flags, bt_mesh.iv_index);
 
 	return bt_mesh_beacon_auth(keys->beacon, flags, keys->net_id,
@@ -552,7 +558,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;
 
@@ -562,13 +568,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 */
@@ -577,7 +583,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) {
@@ -591,19 +597,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;
 		}
 	}
 
@@ -612,7 +618,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;
 		}
 	}
 
@@ -620,7 +626,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:
@@ -649,6 +655,8 @@ void bt_mesh_iv_update(u32_t iv_index, bool iv_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,
@@ -660,8 +668,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;
 		}
@@ -756,9 +765,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;
 			}
@@ -769,9 +778,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;
 			}
@@ -914,15 +923,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;
 		}
 
@@ -949,7 +958,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;
@@ -1038,9 +1047,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;
 			}
@@ -1051,9 +1060,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;
 			}
@@ -1113,8 +1122,7 @@ static void bt_mesh_net_relay(struct os_mbuf *sbuf,
 }
 
 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);
@@ -1144,11 +1152,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 */
@@ -1159,10 +1162,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));
@@ -1209,7 +1210,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;
 	}
 
@@ -1218,6 +1219,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);
 
diff --git a/net/nimble/host/mesh/src/net.h b/net/nimble/host/mesh/src/net.h
index 77923c5e2..2fd12b05c 100644
--- a/net/nimble/host/mesh/src/net.h
+++ b/net/nimble/host/mesh/src/net.h
@@ -239,12 +239,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]);
@@ -272,7 +279,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 *
@@ -297,8 +304,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);
diff --git a/net/nimble/host/mesh/src/proxy.c b/net/nimble/host/mesh/src/proxy.c
index c9f0d80f2..c4e6d8929 100644
--- a/net/nimble/host/mesh/src/proxy.c
+++ b/net/nimble/host/mesh/src/proxy.c
@@ -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) {
diff --git a/net/nimble/host/mesh/src/transport.c b/net/nimble/host/mesh/src/transport.c
index 85a2be8c3..ebc2d72ec 100644
--- a/net/nimble/host/mesh/src/transport.c
+++ b/net/nimble/host/mesh/src/transport.c
@@ -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 @@ static int sdu_recv(struct bt_mesh_net_rx *rx, u8_t hdr, u8_t mic_size,
     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
diff --git a/net/nimble/host/mesh/src/transport.h b/net/nimble/host/mesh/src/transport.h
index b6cb00115..072085e61 100644
--- a/net/nimble/host/mesh/src/transport.h
+++ b/net/nimble/host/mesh/src/transport.h
@@ -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


 

----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on GitHub and use the
URL above to go to the specific comment.
 
For queries about this service, please contact Infrastructure at:
users@infra.apache.org


With regards,
Apache Git Services