Lines Matching full:lpn
27 #include "lpn.h"
47 #define REQ_RETRY_DURATION(lpn) (4 * (LPN_RECV_DELAY + (lpn)->adv_duration + \ argument
48 (lpn)->recv_win + POLL_RETRY_TIMEOUT))
51 #define POLL_TIMEOUT_MAX(lpn) ((MYNEWT_VAL(BLE_MESH_LPN_POLL_TIMEOUT) * 100) - \ argument
52 REQ_RETRY_DURATION(lpn))
53 #define REQ_ATTEMPTS(lpn) (POLL_TIMEOUT_MAX(lpn) < K_SECONDS(3) ? 2 : 4) argument
100 BT_DBG("%s -> %s", state2str(bt_mesh.lpn.state), state2str(state)); in lpn_set_state()
102 bt_mesh.lpn.state = state; in lpn_set_state()
110 for (i = 0; i < ARRAY_SIZE(bt_mesh.lpn.added); i++) { in group_zero()
123 for (i = 0; i < ARRAY_SIZE(bt_mesh.lpn.added); i++) { in group_set()
136 for (i = 0; i < ARRAY_SIZE(bt_mesh.lpn.added); i++) { in group_clear()
148 struct bt_mesh_lpn *lpn = &bt_mesh.lpn; in friend_clear_sent() local
155 lpn->req_attempts++; in friend_clear_sent()
160 clear_friendship(false, lpn->disable); in friend_clear_sent()
165 k_delayed_work_submit(&lpn->timer, FRIEND_REQ_TIMEOUT); in friend_clear_sent()
177 .addr = bt_mesh.lpn.frnd, in send_friend_clear()
188 .lpn_counter = sys_cpu_to_be16(bt_mesh.lpn.counter), in send_friend_clear()
199 struct bt_mesh_lpn *lpn = &bt_mesh.lpn; in clear_friendship() local
203 if (!force && lpn->established && !lpn->clear_success && in clear_friendship()
204 lpn->req_attempts < CLEAR_ATTEMPTS) { in clear_friendship()
206 lpn->disable = disable; in clear_friendship()
212 k_delayed_work_cancel(&lpn->timer); in clear_friendship()
214 friend_cred_del(bt_mesh.sub[0].net_idx, lpn->frnd); in clear_friendship()
216 if (lpn->clear_success) { in clear_friendship()
217 lpn->old_friend = BT_MESH_ADDR_UNASSIGNED; in clear_friendship()
219 lpn->old_friend = lpn->frnd; in clear_friendship()
222 if (lpn_cb && lpn->frnd != BT_MESH_ADDR_UNASSIGNED) { in clear_friendship()
223 lpn_cb(lpn->frnd, false); in clear_friendship()
226 lpn->frnd = BT_MESH_ADDR_UNASSIGNED; in clear_friendship()
227 lpn->fsn = 0; in clear_friendship()
228 lpn->req_attempts = 0; in clear_friendship()
229 lpn->recv_win = 0; in clear_friendship()
230 lpn->queue_size = 0; in clear_friendship()
231 lpn->disable = 0; in clear_friendship()
232 lpn->sent_req = 0; in clear_friendship()
233 lpn->established = 0; in clear_friendship()
234 lpn->clear_success = 0; in clear_friendship()
236 group_zero(lpn->added); in clear_friendship()
237 group_zero(lpn->pending); in clear_friendship()
238 group_zero(lpn->to_remove); in clear_friendship()
241 * Friendship is created, in case lpn->groups doesn't get in clear_friendship()
244 lpn->groups_changed = 1; in clear_friendship()
252 k_delayed_work_submit(&lpn->timer, FRIEND_REQ_RETRY_TIMEOUT); in clear_friendship()
257 struct bt_mesh_lpn *lpn = &bt_mesh.lpn; in friend_req_sent() local
264 lpn->adv_duration = duration; in friend_req_sent()
267 k_delayed_work_submit(&lpn->timer, FRIEND_REQ_WAIT); in friend_req_sent()
270 k_delayed_work_submit(&lpn->timer, in friend_req_sent()
280 static int send_friend_req(struct bt_mesh_lpn *lpn) in send_friend_req() argument
299 .prev_addr = lpn->old_friend, in send_friend_req()
301 .lpn_counter = sys_cpu_to_be16(lpn->counter), in send_friend_req()
312 struct bt_mesh_lpn *lpn = &bt_mesh.lpn; in req_sent() local
316 lpn->sent_req, duration, err, state2str(lpn->state)); in req_sent()
321 lpn->sent_req = 0; in req_sent()
322 group_zero(lpn->pending); in req_sent()
326 lpn->req_attempts++; in req_sent()
327 lpn->adv_duration = duration; in req_sent()
329 if (lpn->established || IS_ENABLED(CONFIG_BT_MESH_LPN_ESTABLISHMENT)) { in req_sent()
334 k_delayed_work_submit(&lpn->timer, in req_sent()
337 k_delayed_work_submit(&lpn->timer, in req_sent()
339 lpn->recv_win); in req_sent()
352 .addr = bt_mesh.lpn.frnd, in send_friend_poll()
362 struct bt_mesh_lpn *lpn = &bt_mesh.lpn; in send_friend_poll() local
363 u8_t fsn = lpn->fsn; in send_friend_poll()
366 BT_DBG("lpn->sent_req 0x%02x", lpn->sent_req); in send_friend_poll()
368 if (lpn->sent_req) { in send_friend_poll()
369 if (lpn->sent_req != TRANS_CTL_OP_FRIEND_POLL) { in send_friend_poll()
370 lpn->pending_poll = 1; in send_friend_poll()
379 lpn->pending_poll = 0; in send_friend_poll()
380 lpn->sent_req = TRANS_CTL_OP_FRIEND_POLL; in send_friend_poll()
388 if (bt_mesh.lpn.state == BT_MESH_LPN_DISABLED) { in bt_mesh_lpn_disable()
397 struct bt_mesh_lpn *lpn = &bt_mesh.lpn; in bt_mesh_lpn_set() local
400 if (lpn->state != BT_MESH_LPN_DISABLED) { in bt_mesh_lpn_set()
404 if (lpn->state == BT_MESH_LPN_DISABLED) { in bt_mesh_lpn_set()
426 send_friend_req(lpn); in bt_mesh_lpn_set()
429 lpn->state == BT_MESH_LPN_TIMER) { in bt_mesh_lpn_set()
430 k_delayed_work_cancel(&lpn->timer); in bt_mesh_lpn_set()
440 static void friend_response_received(struct bt_mesh_lpn *lpn) in friend_response_received() argument
442 BT_DBG("lpn->sent_req 0x%02x", lpn->sent_req); in friend_response_received()
444 if (lpn->sent_req == TRANS_CTL_OP_FRIEND_POLL) { in friend_response_received()
445 lpn->fsn++; in friend_response_received()
448 k_delayed_work_cancel(&lpn->timer); in friend_response_received()
451 lpn->req_attempts = 0; in friend_response_received()
452 lpn->sent_req = 0; in friend_response_received()
457 struct bt_mesh_lpn *lpn = &bt_mesh.lpn; in bt_mesh_lpn_msg_received() local
459 if (lpn->state == BT_MESH_LPN_TIMER) { in bt_mesh_lpn_msg_received()
461 k_delayed_work_submit(&lpn->timer, LPN_AUTO_TIMEOUT); in bt_mesh_lpn_msg_received()
465 if (lpn->sent_req != TRANS_CTL_OP_FRIEND_POLL) { in bt_mesh_lpn_msg_received()
470 friend_response_received(lpn); in bt_mesh_lpn_msg_received()
481 struct bt_mesh_lpn *lpn = &bt_mesh.lpn; in bt_mesh_lpn_friend_offer() local
492 if (lpn->state != BT_MESH_LPN_WAIT_OFFER) { in bt_mesh_lpn_friend_offer()
508 lpn->frnd = rx->ctx.addr; in bt_mesh_lpn_friend_offer()
510 cred = friend_cred_create(sub, lpn->frnd, lpn->counter, frnd_counter); in bt_mesh_lpn_friend_offer()
512 lpn->frnd = BT_MESH_ADDR_UNASSIGNED; in bt_mesh_lpn_friend_offer()
518 k_delayed_work_cancel(&lpn->timer); in bt_mesh_lpn_friend_offer()
520 lpn->recv_win = msg->recv_win; in bt_mesh_lpn_friend_offer()
521 lpn->queue_size = msg->queue_size; in bt_mesh_lpn_friend_offer()
526 lpn->frnd = BT_MESH_ADDR_UNASSIGNED; in bt_mesh_lpn_friend_offer()
527 lpn->recv_win = 0; in bt_mesh_lpn_friend_offer()
528 lpn->queue_size = 0; in bt_mesh_lpn_friend_offer()
532 lpn->counter++; in bt_mesh_lpn_friend_offer()
541 struct bt_mesh_lpn *lpn = &bt_mesh.lpn; in bt_mesh_lpn_friend_clear_cfm() local
549 if (lpn->state != BT_MESH_LPN_CLEAR) { in bt_mesh_lpn_friend_clear_cfm()
559 if (addr != bt_mesh_primary_addr() || counter != lpn->counter) { in bt_mesh_lpn_friend_clear_cfm()
564 lpn->clear_success = 1; in bt_mesh_lpn_friend_clear_cfm()
565 clear_friendship(false, lpn->disable); in bt_mesh_lpn_friend_clear_cfm()
572 struct bt_mesh_lpn *lpn = &bt_mesh.lpn; in lpn_group_add() local
576 for (i = 0; i < ARRAY_SIZE(lpn->groups); i++) { in lpn_group_add()
577 if (lpn->groups[i] == group) { in lpn_group_add()
578 atomic_clear_bit(lpn->to_remove, i); in lpn_group_add()
582 if (!free_slot && lpn->groups[i] == BT_MESH_ADDR_UNASSIGNED) { in lpn_group_add()
583 free_slot = &lpn->groups[i]; in lpn_group_add()
593 lpn->groups_changed = 1; in lpn_group_add()
598 struct bt_mesh_lpn *lpn = &bt_mesh.lpn; in lpn_group_del() local
601 for (i = 0; i < ARRAY_SIZE(lpn->groups); i++) { in lpn_group_del()
602 if (lpn->groups[i] == group) { in lpn_group_del()
603 if (atomic_test_bit(lpn->added, i) || in lpn_group_del()
604 atomic_test_bit(lpn->pending, i)) { in lpn_group_del()
605 atomic_set_bit(lpn->to_remove, i); in lpn_group_del()
606 lpn->groups_changed = 1; in lpn_group_del()
608 lpn->groups[i] = BT_MESH_ADDR_UNASSIGNED; in lpn_group_del()
619 for (i = 0; i < ARRAY_SIZE(bt_mesh.lpn.added); i++) { in group_popcount()
629 struct bt_mesh_lpn *lpn = &bt_mesh.lpn; in sub_update() local
630 int added_count = group_popcount(lpn->added); in sub_update()
634 .addr = lpn->frnd, in sub_update()
647 BT_DBG("op 0x%02x sent_req 0x%02x", op, lpn->sent_req); in sub_update()
649 if (lpn->sent_req) { in sub_update()
653 for (i = 0, g = 0; i < ARRAY_SIZE(lpn->groups); i++) { in sub_update()
654 if (lpn->groups[i] == BT_MESH_ADDR_UNASSIGNED) { in sub_update()
659 if (atomic_test_bit(lpn->added, i)) { in sub_update()
663 if (!atomic_test_bit(lpn->to_remove, i)) { in sub_update()
668 if (added_count + g >= lpn->queue_size) { in sub_update()
673 req.addr_list[g++] = sys_cpu_to_be16(lpn->groups[i]); in sub_update()
674 atomic_set_bit(lpn->pending, i); in sub_update()
682 group_zero(lpn->pending); in sub_update()
686 req.xact = lpn->xact_next++; in sub_update()
690 group_zero(lpn->pending); in sub_update()
694 lpn->xact_pending = req.xact; in sub_update()
695 lpn->sent_req = op; in sub_update()
699 static void update_timeout(struct bt_mesh_lpn *lpn) in update_timeout() argument
701 if (lpn->established) { in update_timeout()
705 k_delayed_work_submit(&lpn->timer, POLL_RETRY_TIMEOUT); in update_timeout()
711 if (lpn->req_attempts < 6) { in update_timeout()
713 lpn->sent_req = 0; in update_timeout()
726 struct bt_mesh_lpn *lpn = &bt_mesh.lpn; in lpn_timeout() local
729 BT_DBG("state: %s", state2str(lpn->state)); in lpn_timeout()
732 switch (lpn->state) { in lpn_timeout()
736 clear_friendship(false, bt_mesh.lpn.disable); in lpn_timeout()
746 send_friend_req(lpn); in lpn_timeout()
750 k_delayed_work_submit(&lpn->timer, in lpn_timeout()
751 lpn->adv_duration + FRIEND_REQ_SCAN); in lpn_timeout()
759 lpn->counter++; in lpn_timeout()
761 k_delayed_work_submit(&lpn->timer, FRIEND_REQ_RETRY_TIMEOUT); in lpn_timeout()
764 if (lpn->req_attempts < REQ_ATTEMPTS(lpn)) { in lpn_timeout()
765 u8_t req = lpn->sent_req; in lpn_timeout()
767 lpn->sent_req = 0; in lpn_timeout()
779 lpn->req_attempts); in lpn_timeout()
780 lpn->req_attempts = 0; in lpn_timeout()
784 k_delayed_work_submit(&lpn->timer, in lpn_timeout()
785 lpn->adv_duration + SCAN_LATENCY + in lpn_timeout()
786 lpn->recv_win); in lpn_timeout()
791 update_timeout(lpn); in lpn_timeout()
794 __ASSERT(0, "Unhandled LPN state"); in lpn_timeout()
805 if (!bt_mesh_lpn_established() || bt_mesh.lpn.sent_req) { in bt_mesh_lpn_group_add()
823 if (!bt_mesh_lpn_established() || bt_mesh.lpn.sent_req) { in bt_mesh_lpn_group_del()
830 static s32_t poll_timeout(struct bt_mesh_lpn *lpn) in poll_timeout() argument
834 return min(POLL_TIMEOUT_MAX(lpn), K_SECONDS(1)); in poll_timeout()
837 if (lpn->poll_timeout < POLL_TIMEOUT_MAX(lpn)) { in poll_timeout()
838 lpn->poll_timeout *= 2; in poll_timeout()
839 lpn->poll_timeout = min(lpn->poll_timeout, in poll_timeout()
840 POLL_TIMEOUT_MAX(lpn)); in poll_timeout()
843 BT_DBG("Poll Timeout is %ums", lpn->poll_timeout); in poll_timeout()
845 return lpn->poll_timeout; in poll_timeout()
852 struct bt_mesh_lpn *lpn = &bt_mesh.lpn; in bt_mesh_lpn_friend_sub_cfm() local
861 if (!lpn->sent_req) { in bt_mesh_lpn_friend_sub_cfm()
866 if (msg->xact != lpn->xact_pending) { in bt_mesh_lpn_friend_sub_cfm()
868 msg->xact, lpn->xact_pending); in bt_mesh_lpn_friend_sub_cfm()
872 if (lpn->sent_req == TRANS_CTL_OP_FRIEND_SUB_ADD) { in bt_mesh_lpn_friend_sub_cfm()
873 group_set(lpn->added, lpn->pending); in bt_mesh_lpn_friend_sub_cfm()
874 group_zero(lpn->pending); in bt_mesh_lpn_friend_sub_cfm()
875 } else if (lpn->sent_req == TRANS_CTL_OP_FRIEND_SUB_REM) { in bt_mesh_lpn_friend_sub_cfm()
878 group_clear(lpn->added, lpn->pending); in bt_mesh_lpn_friend_sub_cfm()
880 for (i = 0; i < ARRAY_SIZE(lpn->groups); i++) { in bt_mesh_lpn_friend_sub_cfm()
881 if (atomic_test_and_clear_bit(lpn->pending, i) && in bt_mesh_lpn_friend_sub_cfm()
882 atomic_test_and_clear_bit(lpn->to_remove, i)) { in bt_mesh_lpn_friend_sub_cfm()
883 lpn->groups[i] = BT_MESH_ADDR_UNASSIGNED; in bt_mesh_lpn_friend_sub_cfm()
891 friend_response_received(lpn); in bt_mesh_lpn_friend_sub_cfm()
893 if (lpn->groups_changed) { in bt_mesh_lpn_friend_sub_cfm()
897 if (!lpn->sent_req) { in bt_mesh_lpn_friend_sub_cfm()
898 lpn->groups_changed = 0; in bt_mesh_lpn_friend_sub_cfm()
902 if (lpn->pending_poll) { in bt_mesh_lpn_friend_sub_cfm()
906 if (!lpn->sent_req) { in bt_mesh_lpn_friend_sub_cfm()
907 k_delayed_work_submit(&lpn->timer, poll_timeout(lpn)); in bt_mesh_lpn_friend_sub_cfm()
917 struct bt_mesh_lpn *lpn = &bt_mesh.lpn; in bt_mesh_lpn_friend_update() local
926 if (lpn->sent_req != TRANS_CTL_OP_FRIEND_POLL) { in bt_mesh_lpn_friend_update()
941 if (!lpn->established) { in bt_mesh_lpn_friend_update()
952 lpn->established = 1; in bt_mesh_lpn_friend_update()
954 BT_INFO("Friendship established with 0x%04x", lpn->frnd); in bt_mesh_lpn_friend_update()
957 lpn_cb(lpn->frnd, true); in bt_mesh_lpn_friend_update()
961 lpn->poll_timeout = min(POLL_TIMEOUT_MAX(lpn), in bt_mesh_lpn_friend_update()
965 friend_response_received(lpn); in bt_mesh_lpn_friend_update()
979 if (lpn->groups_changed) { in bt_mesh_lpn_friend_update()
983 if (!lpn->sent_req) { in bt_mesh_lpn_friend_update()
984 lpn->groups_changed = 0; in bt_mesh_lpn_friend_update()
993 if (!lpn->sent_req) { in bt_mesh_lpn_friend_update()
994 k_delayed_work_submit(&lpn->timer, poll_timeout(lpn)); in bt_mesh_lpn_friend_update()
1002 if (!bt_mesh.lpn.established) { in bt_mesh_lpn_poll()
1018 struct bt_mesh_lpn *lpn = &bt_mesh.lpn; in bt_mesh_lpn_init() local
1022 k_delayed_work_init(&lpn->timer, lpn_timeout); in bt_mesh_lpn_init()
1024 if (lpn->state == BT_MESH_LPN_ENABLED) { in bt_mesh_lpn_init()
1031 send_friend_req(lpn); in bt_mesh_lpn_init()
1038 k_delayed_work_submit(&lpn->timer, LPN_AUTO_TIMEOUT); in bt_mesh_lpn_init()