Commit cad1f4ce authored by Johan Hedberg's avatar Johan Hedberg Committed by Johan Hedberg
Browse files

Bluetooth: Mesh: Fix transport layer heartbeat subscription matching

parent 95d34e05
Loading
Loading
Loading
Loading
+3 −0
Original line number Diff line number Diff line
@@ -2902,6 +2902,9 @@ static void heartbeat_sub_set(struct bt_mesh_model *model,
		period_ms = hb_pwr2(sub_period, 1) * 1000;
	}

	/* Let the transport layer know it needs to handle this address */
	bt_mesh_set_hb_sub_dst(cfg->hb_sub.dst);

	BT_DBG("period_ms %u", period_ms);

	if (period_ms) {
+2 −0
Original line number Diff line number Diff line
@@ -105,6 +105,8 @@ void bt_mesh_reset(void)
	bt_mesh.last_update = 0;
	bt_mesh.ivu_initiator = 0;

	bt_mesh_set_hb_sub_dst(BT_MESH_ADDR_UNASSIGNED);

	k_delayed_work_cancel(&bt_mesh.ivu_complete);

	if (IS_ENABLED(CONFIG_BT_MESH_LOW_POWER)) {
+32 −17
Original line number Diff line number Diff line
@@ -90,6 +90,13 @@ static struct seg_rx {
	},
};

static u16_t hb_sub_dst = BT_MESH_ADDR_UNASSIGNED;

void bt_mesh_set_hb_sub_dst(u16_t addr)
{
	hb_sub_dst = addr;
}

static int send_unseg(struct bt_mesh_net_tx *tx, u8_t aid,
		      struct net_buf_simple *sdu)
{
@@ -687,6 +694,11 @@ static int trans_heartbeat(struct bt_mesh_net_rx *rx,
		return -EINVAL;
	}

	if (rx->dst != hb_sub_dst) {
		BT_WARN("Ignoring heartbeat to non-subscribed destination");
		return 0;
	}

	init_ttl = (net_buf_simple_pull_u8(buf) & 0x7f);
	feat = net_buf_simple_pull_be16(buf);

@@ -711,18 +723,15 @@ static int ctl_recv(struct bt_mesh_net_rx *rx, u8_t hdr,
	switch (ctl_op) {
	case TRANS_CTL_OP_ACK:
		return trans_ack(rx, hdr, buf, seq_auth);
	case TRANS_CTL_OP_HEARTBEAT:
		return trans_heartbeat(rx, buf);
	}

	/* Only acks need processing for Friend behavior */
	if (IS_ENABLED(CONFIG_BT_MESH_FRIEND) && !rx->local_match) {
	/* Only acks and heartbeats may need processing without local_match */
	if (!rx->local_match) {
		return 0;
	}

	switch (ctl_op) {
	case TRANS_CTL_OP_HEARTBEAT:
		return trans_heartbeat(rx, buf);
	}

	if (IS_ENABLED(CONFIG_BT_MESH_FRIEND)) {
		switch (ctl_op) {
		case TRANS_CTL_OP_FRIEND_POLL:
@@ -784,6 +793,11 @@ static int trans_unseg(struct net_buf_simple *buf, struct bt_mesh_net_rx *rx,
	if (rx->ctl) {
		return ctl_recv(rx, hdr, buf, seq_auth);
	} else {
		/* SDUs must match a local element or an LPN of this Friend. */
		if (!rx->local_match && !rx->friend_match) {
			return 0;
		}

		return sdu_recv(rx, hdr, 4, 0, buf);
	}
}
@@ -1197,12 +1211,8 @@ int bt_mesh_trans_recv(struct net_buf_simple *buf, struct bt_mesh_net_rx *rx)
		rx->friend_match = false;
	}

	if (!rx->local_match && !rx->friend_match) {
		return 0;
	}

	BT_DBG("src 0x%04x dst 0x%04x seq 0x%08x", rx->ctx.addr, rx->dst,
	       rx->seq);
	BT_DBG("src 0x%04x dst 0x%04x seq 0x%08x friend_match %u",
	       rx->ctx.addr, rx->dst, rx->seq, rx->friend_match);

	/* Remove network headers */
	net_buf_simple_pull(buf, BT_MESH_NET_HDR_LEN);
@@ -1217,8 +1227,7 @@ int bt_mesh_trans_recv(struct net_buf_simple *buf, struct bt_mesh_net_rx *rx)
	    bt_mesh_lpn_established() &&
	    (!bt_mesh_lpn_waiting_update() || !rx->ctx.friend_cred)) {
		BT_WARN("Ignoring unexpected message in Low Power mode");
		err = -EAGAIN;
		goto done;
		return -EAGAIN;
	}

	/* Save the parsing state so the buffer can later be relayed or
@@ -1227,6 +1236,13 @@ int bt_mesh_trans_recv(struct net_buf_simple *buf, struct bt_mesh_net_rx *rx)
	net_buf_simple_save(buf, &state);

	if (SEG(buf->data)) {
		/* Segmented messages must match a local element or an
		 * LPN of this Friend.
		 */
		if (!rx->local_match && !rx->friend_match) {
			return 0;
		}

		err = trans_seg(buf, rx, &pdu_type, &seq_auth);
	} else {
		err = trans_unseg(buf, rx, &seq_auth);
@@ -1244,10 +1260,9 @@ int bt_mesh_trans_recv(struct net_buf_simple *buf, struct bt_mesh_net_rx *rx)
		bt_mesh_lpn_msg_received(rx);
	}

done:
	net_buf_simple_restore(buf, &state);

	if (IS_ENABLED(CONFIG_BT_MESH_FRIEND) && !err) {
	if (IS_ENABLED(CONFIG_BT_MESH_FRIEND) && rx->friend_match && !err) {
		if (seq_auth == TRANS_SEQ_AUTH_NVAL) {
			bt_mesh_friend_enqueue_rx(rx, pdu_type, NULL, buf);
		} else {
+2 −0
Original line number Diff line number Diff line
@@ -74,6 +74,8 @@ struct bt_mesh_ctl_friend_sub_confirm {
	u8_t xact;
} __packed;

void bt_mesh_set_hb_sub_dst(u16_t addr);

struct bt_mesh_app_key *bt_mesh_app_key_find(u16_t app_idx);

bool bt_mesh_tx_in_progress(void);