1 /*  Bluetooth Mesh */
2 
3 /*
4  * Copyright (c) 2017 Intel Corporation
5  *
6  * SPDX-License-Identifier: Apache-2.0
7  */
8 
9 #include <stdint.h>
10 #include <ble_os.h>
11 #include <misc/byteorder.h>
12 
13 #include <net/buf.h>
14 #include <bluetooth/bluetooth.h>
15 #include <api/mesh.h>
16 
17 #ifdef CONFIG_BT_MESH_LOW_POWER
18 #define BT_DBG_ENABLED IS_ENABLED(CONFIG_BT_MESH_DEBUG_LOW_POWER)
19 #include "common/log.h"
20 
21 #include "crypto.h"
22 #include "adv.h"
23 #include "mesh.h"
24 #include "net.h"
25 #include "ble_transport.h"
26 #include "access.h"
27 #include "beacon.h"
28 #include "foundation.h"
29 #include "lpn.h"
30 #include "bt_errno.h"
31 
32 #if defined(CONFIG_BT_MESH_LPN_AUTO)
33 #define LPN_AUTO_TIMEOUT          K_SECONDS(CONFIG_BT_MESH_LPN_AUTO_TIMEOUT)
34 #else
35 #define LPN_AUTO_TIMEOUT          0
36 #endif
37 
38 #define LPN_RECV_DELAY            CONFIG_BT_MESH_LPN_RECV_DELAY
39 #define SCAN_LATENCY              MIN(CONFIG_BT_MESH_LPN_SCAN_LATENCY, \
40 				      LPN_RECV_DELAY)
41 
42 #define FRIEND_REQ_RETRY_TIMEOUT  K_SECONDS(CONFIG_BT_MESH_LPN_RETRY_TIMEOUT)
43 
44 #define FRIEND_REQ_WAIT           K_MSEC(100)
45 #define FRIEND_REQ_SCAN           K_SECONDS(1)
46 #define FRIEND_REQ_TIMEOUT        (FRIEND_REQ_WAIT + FRIEND_REQ_SCAN)
47 
48 #define POLL_RETRY_TIMEOUT        K_MSEC(100)
49 
50 #define REQ_RETRY_DURATION(lpn)  (4 * (LPN_RECV_DELAY + (lpn)->adv_duration + \
51 				       (lpn)->recv_win + POLL_RETRY_TIMEOUT))
52 
53 #define POLL_TIMEOUT_INIT     (CONFIG_BT_MESH_LPN_INIT_POLL_TIMEOUT * 100)
54 #define POLL_TIMEOUT_MAX(lpn) ((CONFIG_BT_MESH_LPN_POLL_TIMEOUT * 100) - \
55 			       REQ_RETRY_DURATION(lpn))
56 #ifndef CONFIG_BT_BQB
57 #define REQ_ATTEMPTS(lpn)     (POLL_TIMEOUT_MAX(lpn) < K_SECONDS(3) ? 2 : 4)
58 #else
59 #define REQ_ATTEMPTS(lpn)     (POLL_TIMEOUT_MAX(lpn) < K_SECONDS(3) ? 2 : 16)
60 #endif
61 #define CLEAR_ATTEMPTS        2
62 
63 #define LPN_CRITERIA ((CONFIG_BT_MESH_LPN_MIN_QUEUE_SIZE) | \
64 		      (CONFIG_BT_MESH_LPN_RSSI_FACTOR << 3) | \
65 		      (CONFIG_BT_MESH_LPN_RECV_WIN_FACTOR << 5))
66 
67 #define POLL_TO(to) { (u8_t)((to) >> 16), (u8_t)((to) >> 8), (u8_t)(to) }
68 #define LPN_POLL_TO POLL_TO(CONFIG_BT_MESH_LPN_POLL_TIMEOUT)
69 
70 /* 2 transmissions, 20ms interval */
71 #define POLL_XMIT BT_MESH_TRANSMIT(1, 20)
72 
73 static void (*lpn_cb)(u16_t friend_addr, bool established);
74 
75 extern void lpn_hb_send();
76 
77 #if defined(CONFIG_BT_MESH_DEBUG_LOW_POWER)
state2str(int state)78 static const char *state2str(int state)
79 {
80 	switch (state) {
81 	case BT_MESH_LPN_DISABLED:
82 		return "disabled";
83 	case BT_MESH_LPN_CLEAR:
84 		return "clear";
85 	case BT_MESH_LPN_TIMER:
86 		return "timer";
87 	case BT_MESH_LPN_ENABLED:
88 		return "enabled";
89 	case BT_MESH_LPN_REQ_WAIT:
90 		return "req wait";
91 	case BT_MESH_LPN_WAIT_OFFER:
92 		return "wait offer";
93 	case BT_MESH_LPN_ESTABLISHED:
94 		return "established";
95 	case BT_MESH_LPN_RECV_DELAY:
96 		return "recv delay";
97 	case BT_MESH_LPN_WAIT_UPDATE:
98 		return "wait update";
99 	default:
100 		return "(unknown)";
101 	}
102 }
103 #endif /* CONFIG_BT_MESH_DEBUG_LOW_POWER */
104 
lpn_set_state(int state)105 static inline void lpn_set_state(int state)
106 {
107 #if defined(CONFIG_BT_MESH_DEBUG_LOW_POWER)
108 	BT_DBG("%s -> %s", state2str(bt_mesh.lpn.state), state2str(state));
109 #endif
110 	bt_mesh.lpn.state = state;
111 }
112 
group_zero(atomic_t * target)113 static inline void group_zero(atomic_t *target)
114 {
115 #if CONFIG_BT_MESH_LPN_GROUPS > 32
116 	int i;
117 
118 	for (i = 0; i < ARRAY_SIZE(bt_mesh.lpn.added); i++) {
119 		atomic_set(&target[i], 0);
120 	}
121 #else
122 	atomic_set(target, 0);
123 #endif
124 }
125 
group_set(atomic_t * target,atomic_t * source)126 static inline void group_set(atomic_t *target, atomic_t *source)
127 {
128 #if CONFIG_BT_MESH_LPN_GROUPS > 32
129 	int i;
130 
131 	for (i = 0; i < ARRAY_SIZE(bt_mesh.lpn.added); i++) {
132 		atomic_or(&target[i], atomic_get(&source[i]));
133 	}
134 #else
135 	atomic_or(target, atomic_get(source));
136 #endif
137 }
138 
group_clear(atomic_t * target,atomic_t * source)139 static inline void group_clear(atomic_t *target, atomic_t *source)
140 {
141 #if CONFIG_BT_MESH_LPN_GROUPS > 32
142 	int i;
143 
144 	for (i = 0; i < ARRAY_SIZE(bt_mesh.lpn.added); i++) {
145 		atomic_and(&target[i], ~atomic_get(&source[i]));
146 	}
147 #else
148 	atomic_and(target, ~atomic_get(source));
149 #endif
150 }
151 
152 static void clear_friendship(bool force, bool disable);
153 
friend_clear_sent(int err,void * user_data)154 static void friend_clear_sent(int err, void *user_data)
155 {
156 	struct bt_mesh_lpn *lpn = &bt_mesh.lpn;
157 
158 	/* We're switching away from Low Power behavior, so permanently
159 	 * enable scanning.
160 	 */
161 	bt_mesh_scan_enable();
162 
163 	lpn->req_attempts++;
164 
165 	if (err) {
166 		BT_ERR("Sending Friend Request failed (err %d)", err);
167 		lpn_set_state(BT_MESH_LPN_ENABLED);
168 		clear_friendship(false, lpn->disable);
169 		return;
170 	}
171 
172 	lpn_set_state(BT_MESH_LPN_CLEAR);
173 	k_delayed_work_submit(&lpn->timer, FRIEND_REQ_TIMEOUT);
174 }
175 
176 static const struct bt_mesh_send_cb clear_sent_cb = {
177 	.end = friend_clear_sent,
178 };
179 
send_friend_clear(void)180 static int send_friend_clear(void)
181 {
182 	struct bt_mesh_msg_ctx ctx = {
183 		.net_idx     = bt_mesh.sub[0].net_idx,
184 		.app_idx     = BT_MESH_KEY_UNUSED,
185 		.addr        = bt_mesh.lpn.frnd,
186 		.send_ttl    = 0,
187 	};
188 	struct bt_mesh_net_tx tx = {
189 		.sub = &bt_mesh.sub[0],
190 		.ctx = &ctx,
191 		.src = bt_mesh_primary_addr(),
192 		.xmit = bt_mesh_net_transmit_get(),
193 	};
194 	struct bt_mesh_ctl_friend_clear req = {
195 		.lpn_addr    = sys_cpu_to_be16(tx.src),
196 		.lpn_counter = sys_cpu_to_be16(bt_mesh.lpn.counter),
197 	};
198 
199 	BT_DBG("");
200 
201 	return bt_mesh_ctl_send(&tx, TRANS_CTL_OP_FRIEND_CLEAR, &req,
202 				sizeof(req), NULL, &clear_sent_cb, NULL);
203 }
204 
clear_friendship(bool force,bool disable)205 static void clear_friendship(bool force, bool disable)
206 {
207 	struct bt_mesh_lpn *lpn = &bt_mesh.lpn;
208 
209 	BT_DBG("force %u disable %u", force, disable);
210 
211 	if (!force && lpn->established && !lpn->clear_success &&
212 	    lpn->req_attempts < CLEAR_ATTEMPTS) {
213 		send_friend_clear();
214 		lpn->disable = disable;
215 		return;
216 	}
217 
218 	bt_mesh_rx_reset();
219 
220 	k_delayed_work_cancel(&lpn->timer);
221 
222 	friend_cred_del(bt_mesh.sub[0].net_idx, lpn->frnd);
223 
224 	if (lpn->clear_success) {
225 		lpn->old_friend = BT_MESH_ADDR_UNASSIGNED;
226 	} else {
227 		lpn->old_friend = lpn->frnd;
228 	}
229 
230 	if (lpn_cb && lpn->frnd != BT_MESH_ADDR_UNASSIGNED) {
231 		lpn_cb(lpn->frnd, false);
232 	}
233 
234 	lpn->frnd = BT_MESH_ADDR_UNASSIGNED;
235 	lpn->fsn = 0;
236 	lpn->req_attempts = 0;
237 	lpn->recv_win = 0;
238 	lpn->queue_size = 0;
239 	lpn->disable = 0;
240 	lpn->sent_req = 0;
241 	lpn->established = 0;
242 	lpn->clear_success = 0;
243 
244 	group_zero(lpn->added);
245 	group_zero(lpn->pending);
246 	group_zero(lpn->to_remove);
247 
248 	/* Set this to 1 to force group subscription when the next
249 	 * Friendship is created, in case lpn->groups doesn't get
250 	 * modified meanwhile.
251 	 */
252 	lpn->groups_changed = 1;
253 
254 	if (disable) {
255 		lpn_set_state(BT_MESH_LPN_DISABLED);
256 		lpn_hb_send();
257 		return;
258 	}
259 
260 	lpn_set_state(BT_MESH_LPN_ENABLED);
261 	lpn_hb_send();
262 	k_delayed_work_submit(&lpn->timer, FRIEND_REQ_RETRY_TIMEOUT);
263 }
264 
friend_req_sent(u16_t duration,int err,void * user_data)265 static void friend_req_sent(u16_t duration, int err, void *user_data)
266 {
267 	struct bt_mesh_lpn *lpn = &bt_mesh.lpn;
268 
269 	if (err) {
270 		BT_ERR("Sending Friend Request failed (err %d)", err);
271 		return;
272 	}
273 
274 	lpn->adv_duration = duration;
275 
276 	if (IS_ENABLED(CONFIG_BT_MESH_LPN_ESTABLISHMENT)) {
277 		k_delayed_work_submit(&lpn->timer, FRIEND_REQ_WAIT);
278 		lpn_set_state(BT_MESH_LPN_REQ_WAIT);
279 	} else {
280 		k_delayed_work_submit(&lpn->timer,
281 				      duration + FRIEND_REQ_TIMEOUT);
282 		lpn_set_state(BT_MESH_LPN_WAIT_OFFER);
283 	}
284 }
285 
286 static const struct bt_mesh_send_cb friend_req_sent_cb = {
287 	.start = friend_req_sent,
288 };
289 
send_friend_req(struct bt_mesh_lpn * lpn)290 static int send_friend_req(struct bt_mesh_lpn *lpn)
291 {
292 	const struct bt_mesh_comp *comp = bt_mesh_comp_get();
293 	struct bt_mesh_msg_ctx ctx = {
294 		.net_idx  = bt_mesh.sub[0].net_idx,
295 		.app_idx  = BT_MESH_KEY_UNUSED,
296 		.addr     = BT_MESH_ADDR_FRIENDS,
297 		.send_ttl = 0,
298 	};
299 	struct bt_mesh_net_tx tx = {
300 		.sub = &bt_mesh.sub[0],
301 		.ctx = &ctx,
302 		.src = bt_mesh_primary_addr(),
303 		.xmit = POLL_XMIT,
304 	};
305 	struct bt_mesh_ctl_friend_req req = {
306 		.criteria    = LPN_CRITERIA,
307 		.recv_delay  = LPN_RECV_DELAY,
308 		.poll_to     = LPN_POLL_TO,
309 		.prev_addr   = sys_cpu_to_be16(lpn->old_friend),
310 		.num_elem    = comp->elem_count,
311 		.lpn_counter = sys_cpu_to_be16(lpn->counter),
312 	};
313 
314 	BT_DBG("");
315 
316 	return bt_mesh_ctl_send(&tx, TRANS_CTL_OP_FRIEND_REQ, &req,
317 				sizeof(req), NULL, &friend_req_sent_cb, NULL);
318 }
319 
req_sent(u16_t duration,int err,void * user_data)320 static void req_sent(u16_t duration, int err, void *user_data)
321 {
322 	struct bt_mesh_lpn *lpn = &bt_mesh.lpn;
323 
324 #if defined(CONFIG_BT_MESH_DEBUG_LOW_POWER)
325 	BT_DBG("req 0x%02x duration %u err %d state %s",
326 	       lpn->sent_req, duration, err, state2str(lpn->state));
327 #endif
328 
329 	if (err) {
330 		BT_ERR("Sending request failed (err %d)", err);
331 		lpn->sent_req = 0;
332 		group_zero(lpn->pending);
333 		return;
334 	}
335 
336 	lpn->req_attempts++;
337 	lpn->adv_duration = duration;
338 
339 	if (lpn->established || IS_ENABLED(CONFIG_BT_MESH_LPN_ESTABLISHMENT)) {
340 		lpn_set_state(BT_MESH_LPN_RECV_DELAY);
341 		/* We start scanning a bit early to elimitate risk of missing
342 		 * response data due to HCI and other latencies.
343 		 */
344 		k_delayed_work_submit(&lpn->timer,
345 				      LPN_RECV_DELAY - SCAN_LATENCY);
346 	} else {
347 		k_delayed_work_submit(&lpn->timer,
348 				      LPN_RECV_DELAY + duration +
349 				      lpn->recv_win);
350 	}
351 }
352 
353 static const struct bt_mesh_send_cb req_sent_cb = {
354 	.start = req_sent,
355 };
356 
send_friend_poll(void)357 static int send_friend_poll(void)
358 {
359 	struct bt_mesh_msg_ctx ctx = {
360 		.net_idx     = bt_mesh.sub[0].net_idx,
361 		.app_idx     = BT_MESH_KEY_UNUSED,
362 		.addr        = bt_mesh.lpn.frnd,
363 		.send_ttl    = 0,
364 	};
365 	struct bt_mesh_net_tx tx = {
366 		.sub = &bt_mesh.sub[0],
367 		.ctx = &ctx,
368 		.src = bt_mesh_primary_addr(),
369 		.xmit = POLL_XMIT,
370 		.friend_cred = true,
371 	};
372 	struct bt_mesh_lpn *lpn = &bt_mesh.lpn;
373 	u8_t fsn = lpn->fsn;
374 	int err;
375 
376 	BT_DBG("lpn->sent_req 0x%02x", lpn->sent_req);
377 
378 	if (lpn->sent_req) {
379 		if (lpn->sent_req != TRANS_CTL_OP_FRIEND_POLL) {
380 			lpn->pending_poll = 1;
381 		}
382 
383 		return 0;
384 	}
385 
386 	err = bt_mesh_ctl_send(&tx, TRANS_CTL_OP_FRIEND_POLL, &fsn, 1,
387 			       NULL, &req_sent_cb, NULL);
388 	if (err == 0) {
389 		lpn->pending_poll = 0;
390 		lpn->sent_req = TRANS_CTL_OP_FRIEND_POLL;
391 	}
392 
393 	return err;
394 }
395 
bt_mesh_lpn_disable(bool force)396 void bt_mesh_lpn_disable(bool force)
397 {
398 	if (bt_mesh.lpn.state == BT_MESH_LPN_DISABLED) {
399 		return;
400 	}
401 
402 	clear_friendship(force, true);
403 }
404 
bt_mesh_lpn_set(bool enable)405 int bt_mesh_lpn_set(bool enable)
406 {
407 	struct bt_mesh_lpn *lpn = &bt_mesh.lpn;
408 
409 	if (enable) {
410 		if (lpn->state != BT_MESH_LPN_DISABLED) {
411 			return 0;
412 		}
413 	} else {
414 		if (lpn->state == BT_MESH_LPN_DISABLED) {
415 			return 0;
416 		}
417 	}
418 
419 	if (!bt_mesh_is_provisioned()) {
420 		if (enable) {
421 			lpn_set_state(BT_MESH_LPN_ENABLED);
422 		} else {
423 			lpn_set_state(BT_MESH_LPN_DISABLED);
424 		}
425 
426 		return 0;
427 	}
428 
429 	if (enable) {
430 		lpn_set_state(BT_MESH_LPN_ENABLED);
431 
432 		if (IS_ENABLED(CONFIG_BT_MESH_LPN_ESTABLISHMENT)) {
433 			bt_mesh_scan_disable();
434 		}
435 
436 		send_friend_req(lpn);
437 	} else {
438 		if (IS_ENABLED(CONFIG_BT_MESH_LPN_AUTO) &&
439 		    lpn->state == BT_MESH_LPN_TIMER) {
440 			k_delayed_work_cancel(&lpn->timer);
441 			lpn_set_state(BT_MESH_LPN_DISABLED);
442 		} else {
443 			bt_mesh_lpn_disable(false);
444 		}
445 	}
446 
447 	return 0;
448 }
449 
friend_response_received(struct bt_mesh_lpn * lpn)450 static void friend_response_received(struct bt_mesh_lpn *lpn)
451 {
452 	BT_DBG("lpn->sent_req 0x%02x", lpn->sent_req);
453 
454 	if (lpn->sent_req == TRANS_CTL_OP_FRIEND_POLL) {
455 		lpn->fsn++;
456 	}
457 
458 	k_delayed_work_cancel(&lpn->timer);
459 	bt_mesh_scan_disable();
460 	lpn_set_state(BT_MESH_LPN_ESTABLISHED);
461 	lpn->req_attempts = 0;
462 	lpn->sent_req = 0;
463 }
464 
bt_mesh_lpn_msg_received(struct bt_mesh_net_rx * rx)465 void bt_mesh_lpn_msg_received(struct bt_mesh_net_rx *rx)
466 {
467 	struct bt_mesh_lpn *lpn = &bt_mesh.lpn;
468 
469 	if (lpn->state == BT_MESH_LPN_TIMER) {
470 		BT_DBG("Restarting establishment timer");
471 		k_delayed_work_submit(&lpn->timer, LPN_AUTO_TIMEOUT);
472 		return;
473 	}
474 
475 	if (lpn->sent_req != TRANS_CTL_OP_FRIEND_POLL) {
476 		BT_WARN("Unexpected message withouth a preceding Poll");
477 		return;
478 	}
479 
480 	friend_response_received(lpn);
481 
482 	BT_DBG("Requesting more messages from Friend");
483 
484 	send_friend_poll();
485 }
486 
bt_mesh_lpn_friend_offer(struct bt_mesh_net_rx * rx,struct net_buf_simple * buf)487 int bt_mesh_lpn_friend_offer(struct bt_mesh_net_rx *rx,
488 			     struct net_buf_simple *buf)
489 {
490 	struct bt_mesh_ctl_friend_offer *msg = (void *)buf->data;
491 	struct bt_mesh_lpn *lpn = &bt_mesh.lpn;
492 	struct bt_mesh_subnet *sub = rx->sub;
493 	struct friend_cred *cred;
494 	u16_t frnd_counter;
495 	int err;
496 
497 	if (buf->len < sizeof(*msg)) {
498 		BT_WARN("Too short Friend Offer");
499 		return -EINVAL;
500 	}
501 
502 	if (lpn->state != BT_MESH_LPN_WAIT_OFFER) {
503 		BT_WARN("Ignoring unexpected Friend Offer");
504 		return 0;
505 	}
506 
507 	if (!msg->recv_win) {
508 		BT_WARN("Prohibited ReceiveWindow value");
509 		return -EINVAL;
510 	}
511 
512 	frnd_counter = sys_be16_to_cpu(msg->frnd_counter);
513 
514 	BT_DBG("recv_win %u queue_size %u sub_list_size %u rssi %d counter %u",
515 	       msg->recv_win, msg->queue_size, msg->sub_list_size, msg->rssi,
516 	       frnd_counter);
517 
518 	lpn->frnd = rx->ctx.addr;
519 
520 	cred = friend_cred_create(sub, lpn->frnd, lpn->counter, frnd_counter);
521 	if (!cred) {
522 		lpn->frnd = BT_MESH_ADDR_UNASSIGNED;
523 		return -ENOMEM;
524 	}
525 
526 	/* TODO: Add offer acceptance criteria check */
527 
528 	k_delayed_work_cancel(&lpn->timer);
529 
530 	lpn->recv_win = msg->recv_win;
531 	lpn->queue_size = msg->queue_size;
532 
533 	err = send_friend_poll();
534 	if (err) {
535 		friend_cred_clear(cred);
536 		lpn->frnd = BT_MESH_ADDR_UNASSIGNED;
537 		lpn->recv_win = 0;
538 		lpn->queue_size = 0;
539 		return err;
540 	}
541 
542 	lpn->counter++;
543 
544 	return 0;
545 }
546 
bt_mesh_lpn_friend_clear_cfm(struct bt_mesh_net_rx * rx,struct net_buf_simple * buf)547 int bt_mesh_lpn_friend_clear_cfm(struct bt_mesh_net_rx *rx,
548 				 struct net_buf_simple *buf)
549 {
550 	struct bt_mesh_ctl_friend_clear_confirm *msg = (void *)buf->data;
551 	struct bt_mesh_lpn *lpn = &bt_mesh.lpn;
552 	u16_t addr, counter;
553 
554 	if (buf->len < sizeof(*msg)) {
555 		BT_WARN("Too short Friend Clear Confirm");
556 		return -EINVAL;
557 	}
558 
559 	if (lpn->state != BT_MESH_LPN_CLEAR) {
560 		BT_WARN("Ignoring unexpected Friend Clear Confirm");
561 		return 0;
562 	}
563 
564 	addr = sys_be16_to_cpu(msg->lpn_addr);
565 	counter = sys_be16_to_cpu(msg->lpn_counter);
566 
567 	BT_DBG("LPNAddress 0x%04x LPNCounter 0x%04x", addr, counter);
568 
569 	if (addr != bt_mesh_primary_addr() || counter != lpn->counter) {
570 		BT_WARN("Invalid parameters in Friend Clear Confirm");
571 		return 0;
572 	}
573 
574 	lpn->clear_success = 1;
575 	clear_friendship(false, lpn->disable);
576 
577 	return 0;
578 }
579 
lpn_group_add(u16_t group)580 static void lpn_group_add(u16_t group)
581 {
582 	struct bt_mesh_lpn *lpn = &bt_mesh.lpn;
583 	u16_t *free_slot = NULL;
584 	int i;
585 
586 	for (i = 0; i < ARRAY_SIZE(lpn->groups); i++) {
587 		if (lpn->groups[i] == group) {
588 			atomic_clear_bit(lpn->to_remove, i);
589 			return;
590 		}
591 
592 		if (!free_slot && lpn->groups[i] == BT_MESH_ADDR_UNASSIGNED) {
593 			free_slot = &lpn->groups[i];
594 		}
595 	}
596 
597 	if (!free_slot) {
598 		BT_WARN("Friend Subscription List exceeded!");
599 		return;
600 	}
601 
602 	*free_slot = group;
603 	lpn->groups_changed = 1;
604 }
605 
lpn_group_del(u16_t group)606 static void lpn_group_del(u16_t group)
607 {
608 	struct bt_mesh_lpn *lpn = &bt_mesh.lpn;
609 	int i;
610 
611 	for (i = 0; i < ARRAY_SIZE(lpn->groups); i++) {
612 		if (lpn->groups[i] == group) {
613 			if (atomic_test_bit(lpn->added, i) ||
614 			    atomic_test_bit(lpn->pending, i)) {
615 				atomic_set_bit(lpn->to_remove, i);
616 				lpn->groups_changed = 1;
617 			} else {
618 				lpn->groups[i] = BT_MESH_ADDR_UNASSIGNED;
619 			}
620 		}
621 	}
622 }
623 
group_popcount(atomic_t * target)624 static inline int group_popcount(atomic_t *target)
625 {
626 #if CONFIG_BT_MESH_LPN_GROUPS > 32
627 	int i, count = 0;
628 
629 	for (i = 0; i < ARRAY_SIZE(bt_mesh.lpn.added); i++) {
630 		count += popcount(atomic_get(&target[i]));
631 	}
632 #else
633 	return popcount(atomic_get(target));
634 #endif
635 }
636 
sub_update(u8_t op)637 static bool sub_update(u8_t op)
638 {
639 	struct bt_mesh_lpn *lpn = &bt_mesh.lpn;
640 	int added_count = group_popcount(lpn->added);
641 	struct bt_mesh_msg_ctx ctx = {
642 		.net_idx     = bt_mesh.sub[0].net_idx,
643 		.app_idx     = BT_MESH_KEY_UNUSED,
644 		.addr        = lpn->frnd,
645 		.send_ttl    = 0,
646 	};
647 	struct bt_mesh_net_tx tx = {
648 		.sub = &bt_mesh.sub[0],
649 		.ctx = &ctx,
650 		.src = bt_mesh_primary_addr(),
651 		.xmit = POLL_XMIT,
652 		.friend_cred = true,
653 	};
654 	struct bt_mesh_ctl_friend_sub req;
655 	size_t i, g;
656 
657 	BT_DBG("op 0x%02x sent_req 0x%02x", op, lpn->sent_req);
658 
659 	if (lpn->sent_req) {
660 		return false;
661 	}
662 
663 	for (i = 0, g = 0; i < ARRAY_SIZE(lpn->groups); i++) {
664 		if (lpn->groups[i] == BT_MESH_ADDR_UNASSIGNED) {
665 			continue;
666 		}
667 
668 		if (op == TRANS_CTL_OP_FRIEND_SUB_ADD) {
669 			if (atomic_test_bit(lpn->added, i)) {
670 				continue;
671 			}
672 		} else {
673 			if (!atomic_test_bit(lpn->to_remove, i)) {
674 				continue;
675 			}
676 		}
677 
678 		if (added_count + g >= lpn->queue_size) {
679 			BT_WARN("Friend Queue Size exceeded");
680 			break;
681 		}
682 
683 		req.addr_list[g++] = sys_cpu_to_be16(lpn->groups[i]);
684 		atomic_set_bit(lpn->pending, i);
685 
686 		if (g == ARRAY_SIZE(req.addr_list)) {
687 			break;
688 		}
689 	}
690 
691 	if (g == 0) {
692 		group_zero(lpn->pending);
693 		return false;
694 	}
695 
696 	req.xact = lpn->xact_next++;
697 
698 	if (bt_mesh_ctl_send(&tx, op, &req, 1 + g * 2, NULL,
699 			     &req_sent_cb, NULL) < 0) {
700 		group_zero(lpn->pending);
701 		return false;
702 	}
703 
704 	lpn->xact_pending = req.xact;
705 	lpn->sent_req = op;
706 	return true;
707 }
708 
update_timeout(struct bt_mesh_lpn * lpn)709 static void update_timeout(struct bt_mesh_lpn *lpn)
710 {
711 	if (lpn->established) {
712 		BT_WARN("No response from Friend during ReceiveWindow");
713 		bt_mesh_scan_disable();
714 		lpn_set_state(BT_MESH_LPN_ESTABLISHED);
715 		k_delayed_work_submit(&lpn->timer, POLL_RETRY_TIMEOUT);
716 	} else {
717 		if (IS_ENABLED(CONFIG_BT_MESH_LPN_ESTABLISHMENT)) {
718 			bt_mesh_scan_disable();
719 		}
720 
721 		if (lpn->req_attempts < 6) {
722 			BT_WARN("Retrying first Friend Poll");
723 			lpn->sent_req = 0;
724 			if (send_friend_poll() == 0) {
725 				return;
726 			}
727 		}
728 
729 		BT_ERR("Timed out waiting for first Friend Update");
730 		clear_friendship(false, false);
731 	}
732 }
733 
lpn_timeout(struct k_work * work)734 static void lpn_timeout(struct k_work *work)
735 {
736 	struct bt_mesh_lpn *lpn = &bt_mesh.lpn;
737 
738 #if defined(CONFIG_BT_MESH_DEBUG_LOW_POWER)
739 	BT_DBG("state: %s", state2str(lpn->state));
740 #endif
741 
742 	switch (lpn->state) {
743 	case BT_MESH_LPN_DISABLED:
744 		break;
745 	case BT_MESH_LPN_CLEAR:
746 		clear_friendship(false, bt_mesh.lpn.disable);
747 		break;
748 	case BT_MESH_LPN_TIMER:
749 		BT_DBG("Starting to look for Friend nodes");
750 		lpn_set_state(BT_MESH_LPN_ENABLED);
751 		if (IS_ENABLED(CONFIG_BT_MESH_LPN_ESTABLISHMENT)) {
752 			bt_mesh_scan_disable();
753 		}
754 		/* fall through */
755 	case BT_MESH_LPN_ENABLED:
756 		send_friend_req(lpn);
757 		break;
758 	case BT_MESH_LPN_REQ_WAIT:
759 		bt_mesh_scan_enable();
760 		k_delayed_work_submit(&lpn->timer,
761 				      lpn->adv_duration + FRIEND_REQ_SCAN);
762 		lpn_set_state(BT_MESH_LPN_WAIT_OFFER);
763 		break;
764 	case BT_MESH_LPN_WAIT_OFFER:
765 		BT_WARN("No acceptable Friend Offers received");
766 		if (IS_ENABLED(CONFIG_BT_MESH_LPN_ESTABLISHMENT)) {
767 			bt_mesh_scan_disable();
768 		}
769 		lpn->counter++;
770 		lpn_set_state(BT_MESH_LPN_ENABLED);
771 		k_delayed_work_submit(&lpn->timer, FRIEND_REQ_RETRY_TIMEOUT);
772 		break;
773 	case BT_MESH_LPN_ESTABLISHED:
774 		if (lpn->req_attempts < REQ_ATTEMPTS(lpn)) {
775 			u8_t req = lpn->sent_req;
776 
777 			lpn->sent_req = 0;
778 
779 			if (!req || req == TRANS_CTL_OP_FRIEND_POLL) {
780 				send_friend_poll();
781 			} else {
782 				sub_update(req);
783 			}
784 
785 			break;
786 		}
787 
788 		BT_ERR("No response from Friend after %u retries",
789 		       lpn->req_attempts);
790 		lpn->req_attempts = 0;
791 		clear_friendship(false, false);
792 		break;
793 	case BT_MESH_LPN_RECV_DELAY:
794 		k_delayed_work_submit(&lpn->timer,
795 				      lpn->adv_duration + SCAN_LATENCY +
796 				      lpn->recv_win);
797 		bt_mesh_scan_enable();
798 		lpn_set_state(BT_MESH_LPN_WAIT_UPDATE);
799 		break;
800 	case BT_MESH_LPN_WAIT_UPDATE:
801 		update_timeout(lpn);
802 		break;
803 	default:
804 		__ASSERT(0, "Unhandled LPN state");
805 		break;
806 	}
807 }
808 
bt_mesh_lpn_group_add(u16_t group)809 void bt_mesh_lpn_group_add(u16_t group)
810 {
811 	BT_DBG("group 0x%04x", group);
812 
813 	lpn_group_add(group);
814 
815 	if (!bt_mesh_lpn_established() || bt_mesh.lpn.sent_req) {
816 		return;
817 	}
818 
819 	sub_update(TRANS_CTL_OP_FRIEND_SUB_ADD);
820 }
821 
bt_mesh_lpn_group_del(u16_t * groups,size_t group_count)822 void bt_mesh_lpn_group_del(u16_t *groups, size_t group_count)
823 {
824 	int i;
825 
826 	for (i = 0; i < group_count; i++) {
827 		if (groups[i] != BT_MESH_ADDR_UNASSIGNED) {
828 			BT_DBG("group 0x%04x", groups[i]);
829 			lpn_group_del(groups[i]);
830 		}
831 	}
832 
833 	if (!bt_mesh_lpn_established() || bt_mesh.lpn.sent_req) {
834 		return;
835 	}
836 
837 	sub_update(TRANS_CTL_OP_FRIEND_SUB_REM);
838 }
839 
poll_timeout(struct bt_mesh_lpn * lpn)840 static bt_s32_t poll_timeout(struct bt_mesh_lpn *lpn)
841 {
842 	/* If we're waiting for segment acks keep polling at high freq */
843 	if (bt_mesh_tx_in_progress()) {
844 		return MIN(POLL_TIMEOUT_MAX(lpn), K_SECONDS(1));
845 	}
846 
847 	if (lpn->poll_timeout < POLL_TIMEOUT_MAX(lpn)) {
848 		lpn->poll_timeout *= 2;
849 		lpn->poll_timeout = MIN(lpn->poll_timeout,
850 					POLL_TIMEOUT_MAX(lpn));
851 	}
852 
853 	BT_DBG("Poll Timeout is %ums", lpn->poll_timeout);
854 
855 	return lpn->poll_timeout;
856 }
857 
bt_mesh_lpn_friend_sub_cfm(struct bt_mesh_net_rx * rx,struct net_buf_simple * buf)858 int bt_mesh_lpn_friend_sub_cfm(struct bt_mesh_net_rx *rx,
859 			       struct net_buf_simple *buf)
860 {
861 	struct bt_mesh_ctl_friend_sub_confirm *msg = (void *)buf->data;
862 	struct bt_mesh_lpn *lpn = &bt_mesh.lpn;
863 
864 	if (buf->len < sizeof(*msg)) {
865 		BT_WARN("Too short Friend Subscription Confirm");
866 		return -EINVAL;
867 	}
868 
869 	BT_DBG("xact 0x%02x", msg->xact);
870 
871 	if (!lpn->sent_req) {
872 		BT_WARN("No pending subscription list message");
873 		return 0;
874 	}
875 
876 	if (msg->xact != lpn->xact_pending) {
877 		BT_WARN("Transaction mismatch (0x%02x != 0x%02x)",
878 			msg->xact, lpn->xact_pending);
879 		return 0;
880 	}
881 
882 	if (lpn->sent_req == TRANS_CTL_OP_FRIEND_SUB_ADD) {
883 		group_set(lpn->added, lpn->pending);
884 		group_zero(lpn->pending);
885 	} else if (lpn->sent_req == TRANS_CTL_OP_FRIEND_SUB_REM) {
886 		int i;
887 
888 		group_clear(lpn->added, lpn->pending);
889 
890 		for (i = 0; i < ARRAY_SIZE(lpn->groups); i++) {
891 			if (atomic_test_and_clear_bit(lpn->pending, i) &&
892 			    atomic_test_and_clear_bit(lpn->to_remove, i)) {
893 				lpn->groups[i] = BT_MESH_ADDR_UNASSIGNED;
894 			}
895 		}
896 	} else {
897 		BT_WARN("Unexpected Friend Subscription Confirm");
898 		return 0;
899 	}
900 
901 	friend_response_received(lpn);
902 
903 	if (lpn->groups_changed) {
904 		sub_update(TRANS_CTL_OP_FRIEND_SUB_ADD);
905 		sub_update(TRANS_CTL_OP_FRIEND_SUB_REM);
906 
907 		if (!lpn->sent_req) {
908 			lpn->groups_changed = 0;
909 		}
910 	}
911 
912 	if (lpn->pending_poll) {
913 		send_friend_poll();
914 	}
915 
916 	if (!lpn->sent_req) {
917 		k_delayed_work_submit(&lpn->timer, poll_timeout(lpn));
918 	}
919 
920 	return 0;
921 }
922 
bt_mesh_lpn_friend_update(struct bt_mesh_net_rx * rx,struct net_buf_simple * buf)923 int bt_mesh_lpn_friend_update(struct bt_mesh_net_rx *rx,
924 			      struct net_buf_simple *buf)
925 {
926 	struct bt_mesh_ctl_friend_update *msg = (void *)buf->data;
927 	struct bt_mesh_lpn *lpn = &bt_mesh.lpn;
928 	struct bt_mesh_subnet *sub = rx->sub;
929 	bt_u32_t iv_index;
930 
931 	if (buf->len < sizeof(*msg)) {
932 		BT_WARN("Too short Friend Update");
933 		return -EINVAL;
934 	}
935 
936 	if (lpn->sent_req != TRANS_CTL_OP_FRIEND_POLL) {
937 		BT_WARN("Unexpected friend update");
938 		return 0;
939 	}
940 
941 	if (sub->kr_phase == BT_MESH_KR_PHASE_2 && !rx->new_key) {
942 		BT_WARN("Ignoring Phase 2 KR Update secured using old key");
943 		return 0;
944 	}
945 
946 	if (atomic_test_bit(bt_mesh.flags, BT_MESH_IVU_INITIATOR) &&
947 	    (atomic_test_bit(bt_mesh.flags, BT_MESH_IVU_IN_PROGRESS) ==
948 	     BT_MESH_IV_UPDATE(msg->flags))) {
949 		bt_mesh_beacon_ivu_initiator(false);
950 	}
951 
952 	if (!lpn->established) {
953 		/* This is normally checked on the transport layer, however
954 		 * in this state we're also still accepting master
955 		 * credentials so we need to ensure the right ones (Friend
956 		 * Credentials) were used for this message.
957 		 */
958 		if (!rx->friend_cred) {
959 			BT_WARN("Friend Update with wrong credentials");
960 			return -EINVAL;
961 		}
962 
963 		lpn->established = 1;
964 
965 		BT_INFO("Friendship established with 0x%04x", lpn->frnd);
966 
967 		if (lpn_cb) {
968 			lpn_cb(lpn->frnd, true);
969 		}
970 
971 		lpn_hb_send();
972 
973 		/* Set initial poll timeout */
974 		lpn->poll_timeout = MIN(POLL_TIMEOUT_MAX(lpn),
975 					POLL_TIMEOUT_INIT);
976 	}
977 
978 	friend_response_received(lpn);
979 
980 	iv_index = sys_be32_to_cpu(msg->iv_index);
981 
982 	BT_DBG("flags 0x%02x iv_index 0x%08x md %u", msg->flags, iv_index,
983 	       msg->md);
984 
985 	if (bt_mesh_kr_update(sub, BT_MESH_KEY_REFRESH(msg->flags),
986 			      rx->new_key)) {
987 		bt_mesh_net_beacon_update(sub);
988 	}
989 
990 	bt_mesh_net_iv_update(iv_index, BT_MESH_IV_UPDATE(msg->flags));
991 
992 	if (lpn->groups_changed) {
993 		sub_update(TRANS_CTL_OP_FRIEND_SUB_ADD);
994 		sub_update(TRANS_CTL_OP_FRIEND_SUB_REM);
995 
996 		if (!lpn->sent_req) {
997 			lpn->groups_changed = 0;
998 		}
999 	}
1000 
1001 	if (msg->md) {
1002 		BT_DBG("Requesting for more messages");
1003 		send_friend_poll();
1004 	}
1005 
1006 	if (!lpn->sent_req) {
1007 		k_delayed_work_submit(&lpn->timer, poll_timeout(lpn));
1008 	}
1009 
1010 	return 0;
1011 }
1012 
bt_mesh_lpn_poll(void)1013 int bt_mesh_lpn_poll(void)
1014 {
1015 	if (!bt_mesh.lpn.established) {
1016 		return -EAGAIN;
1017 	}
1018 
1019 	BT_DBG("Requesting more messages");
1020 
1021 	return send_friend_poll();
1022 }
1023 
bt_mesh_lpn_set_cb(void (* cb)(u16_t friend_addr,bool established))1024 void bt_mesh_lpn_set_cb(void (*cb)(u16_t friend_addr, bool established))
1025 {
1026 	lpn_cb = cb;
1027 }
1028 
bt_mesh_lpn_init(void)1029 int bt_mesh_lpn_init(void)
1030 {
1031 	struct bt_mesh_lpn *lpn = &bt_mesh.lpn;
1032 
1033 	BT_DBG("");
1034 
1035 	k_delayed_work_init(&lpn->timer, lpn_timeout);
1036 
1037 	if (lpn->state == BT_MESH_LPN_ENABLED) {
1038 		if (IS_ENABLED(CONFIG_BT_MESH_LPN_ESTABLISHMENT)) {
1039 			bt_mesh_scan_disable();
1040 		} else {
1041 			bt_mesh_scan_enable();
1042 		}
1043 
1044 		send_friend_req(lpn);
1045 	} else {
1046 		bt_mesh_scan_enable();
1047 
1048 		if (IS_ENABLED(CONFIG_BT_MESH_LPN_AUTO)) {
1049 			BT_DBG("Waiting %u ms for messages", LPN_AUTO_TIMEOUT);
1050 			lpn_set_state(BT_MESH_LPN_TIMER);
1051 			k_delayed_work_submit(&lpn->timer, LPN_AUTO_TIMEOUT);
1052 		}
1053 	}
1054 
1055 	return 0;
1056 }
1057 #endif
1058