From 1630de1a67d9f2c824f363016f31236a7e37fe3f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Narajowski?= Date: Wed, 30 Jan 2019 14:55:31 +0100 Subject: [PATCH] mesh: Fix matching for all elements of an LPN When we're acting as a Friend for an LPN, we need to consider all elements of the LPN. The information of how many elements the LPN has is provided in the Friend Request message, however until now the code did not do anything with this information. Fix the issue by tracking the number of elements for each LPN and update the unicast address matching code to take this into account. --- nimble/host/mesh/src/friend.c | 23 +++++++++++++++++------ nimble/host/mesh/src/net.h | 1 + 2 files changed, 18 insertions(+), 6 deletions(-) diff --git a/nimble/host/mesh/src/friend.c b/nimble/host/mesh/src/friend.c index 561f5b287..18cb3c1f0 100644 --- a/nimble/host/mesh/src/friend.c +++ b/nimble/host/mesh/src/friend.c @@ -111,6 +111,15 @@ static struct os_mbuf *friend_buf_alloc(u16_t src) return buf; } +static bool is_lpn_unicast(struct bt_mesh_friend *frnd, u16_t addr) +{ + if (frnd->lpn == BT_MESH_ADDR_UNASSIGNED) { + return false; + } + + return (addr >= frnd->lpn && addr < (frnd->lpn + frnd->num_elem)); +} + struct bt_mesh_friend *bt_mesh_friend_find(u16_t net_idx, u16_t lpn_addr, bool valid, bool established) { @@ -133,7 +142,7 @@ struct bt_mesh_friend *bt_mesh_friend_find(u16_t net_idx, u16_t lpn_addr, continue; } - if (frnd->lpn == lpn_addr) { + if (is_lpn_unicast(frnd, lpn_addr)) { return frnd; } } @@ -831,6 +840,11 @@ int bt_mesh_friend_req(struct bt_mesh_net_rx *rx, struct os_mbuf *buf) return -EINVAL; } + if (!BT_MESH_ADDR_IS_UNICAST(rx->ctx.addr + msg->num_elem - 1)) { + BT_WARN("LPN elements stretch outside of unicast range"); + return -EINVAL; + } + if (!MIN_QUEUE_SIZE_LOG(msg->criteria)) { BT_WARN("Prohibited Minimum Queue Size in Friend Request"); return -EINVAL; @@ -873,6 +887,7 @@ int bt_mesh_friend_req(struct bt_mesh_net_rx *rx, struct os_mbuf *buf) init_friend: frnd->lpn = rx->ctx.addr; + frnd->num_elem = msg->num_elem; frnd->net_idx = rx->sub->net_idx; frnd->recv_delay = msg->recv_delay; frnd->poll_to = poll_to * 100; @@ -1216,11 +1231,7 @@ static bool friend_lpn_matches(struct bt_mesh_friend *frnd, u16_t net_idx, } if (BT_MESH_ADDR_IS_UNICAST(addr)) { - if (addr == frnd->lpn) { - return true; - } - - return false; + return is_lpn_unicast(frnd, addr); } for (i = 0; i < ARRAY_SIZE(frnd->sub_list); i++) { diff --git a/nimble/host/mesh/src/net.h b/nimble/host/mesh/src/net.h index 8b1557ab6..fc309594c 100644 --- a/nimble/host/mesh/src/net.h +++ b/nimble/host/mesh/src/net.h @@ -103,6 +103,7 @@ struct bt_mesh_friend { valid:1, established:1; s32_t poll_to; + u8_t num_elem; u16_t lpn_counter; u16_t counter;