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:
parent
ab748e3afb
commit
bec74121f6
2 changed files with 18 additions and 6 deletions
|
@ -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++) {
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue