Bluetooth: Mesh: Transport: Fix calculating SeqAuth

This patch fixes case where Mesh is receiving segmented data with
SEQ and SeqZero as in logs below:

bt_mesh_trans_recv: src 0x07FF dst 0x0001 seq 0x00031FFF friend_match 0
bt_mesh_trans_recv: Payload dd7ffc016e5c7f861272e5f7577a6644
trans_seg: ASZMIC 0 AKF 1 AID 0x1D
trans_seg: SeqZero 0x1FFF SegO 0 SegN 1
trans_seg: ######## seq_auth=204799

bt_mesh_trans_recv: src 0x07FF dst 0x0001 seq 0x00032000 friend_match 0
bt_mesh_trans_recv: Payload dd7ffc21abb5a7
trans_seg: ASZMIC 0 AKF 1 AID 0x1D
trans_seg: SeqZero 0x1FFF SegO 1 SegN 1
trans_seg: ######## seq_auth=212991

Original-patch-by: Łukasz Rymanowski <lukasz.rymanowski@codecoup.pl>
Signed-off-by: Johan Hedberg <johan.hedberg@intel.com>
This commit is contained in:
Johan Hedberg 2018-08-16 14:51:19 +03:00 committed by Johan Hedberg
commit e4908119f1

View file

@ -1190,8 +1190,23 @@ static int trans_seg(struct net_buf_simple *buf, struct bt_mesh_net_rx *net_rx,
return -EINVAL;
}
/* According to Mesh 1.0 specification:
* "The SeqAuth is composed of the IV Index and the sequence number
* (SEQ) of the first segment"
*
* Therefore we need to calculate very first SEQ in order to find
* seqAuth. We can calculate as below:
*
* SEQ(0) = SEQ(n) - (delta between seqZero and SEQ(n) by looking into
* 14 least significant bits of SEQ(n))
*
* Mentioned delta shall be >= 0, if it is not then seq_auth will
* be broken and it will be verified by the code below.
*/
*seq_auth = SEQ_AUTH(BT_MESH_NET_IVI_RX(net_rx),
(net_rx->seq & 0xffffe000) | seq_zero);
(net_rx->seq -
((((net_rx->seq & BIT_MASK(14)) - seq_zero)) &
BIT_MASK(13))));
/* Look for old RX sessions */
rx = seg_rx_find(net_rx, seq_auth);