Bluetooth: 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.

Fixes #11731

Signed-off-by: Johan Hedberg <johan.hedberg@intel.com>
This commit is contained in:
Johan Hedberg 2018-11-29 14:18:13 +02:00 committed by Johan Hedberg
commit bec74121f6
2 changed files with 18 additions and 6 deletions

View file

@ -110,6 +110,15 @@ static struct net_buf *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)
{
@ -132,7 +141,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;
}
}
@ -821,6 +830,11 @@ int bt_mesh_friend_req(struct bt_mesh_net_rx *rx, struct net_buf_simple *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;
@ -863,6 +877,7 @@ int bt_mesh_friend_req(struct bt_mesh_net_rx *rx, struct net_buf_simple *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;
@ -1190,11 +1205,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++) {

View file

@ -95,6 +95,7 @@ struct bt_mesh_friend {
valid:1,
established:1;
s32_t poll_to;
u8_t num_elem;
u16_t lpn_counter;
u16_t counter;