Lines Matching +full:poll +full:- +full:timeout +full:- +full:ms

4  * SPDX-License-Identifier: Apache-2.0
36 #warning Frienship feature may work unstable when non-deferred log mode is selected. Use the \
41 #define RX_DELAY_CORRECTION(lpn) ((lpn)->adv_duration)
64 #define REQ_RETRY_DURATION(lpn) (LPN_RECV_DELAY + (lpn)->adv_duration + \
65 (lpn)->recv_win + POLL_RETRY_TIMEOUT)
75 #define POLL_TIMEOUT_MAX(lpn) (POLL_TIMEOUT - \
87 /* 1 transmission, 20ms interval */
126 if (lpn->poll_timeout < POLL_TIMEOUT_MAX(lpn)) { in poll_timeout()
127 lpn->poll_timeout *= 2; in poll_timeout()
128 lpn->poll_timeout = in poll_timeout()
129 MIN(lpn->poll_timeout, POLL_TIMEOUT_MAX(lpn)); in poll_timeout()
132 LOG_DBG("Poll Timeout is %ums", lpn->poll_timeout); in poll_timeout()
134 return lpn->poll_timeout; in poll_timeout()
140 LOG_DBG("%s -> %s", state2str(bt_mesh.lpn.state), state2str(state)); in lpn_set_state()
192 lpn->req_attempts++; in friend_clear_sent()
197 clear_friendship(false, lpn->disable); in friend_clear_sent()
202 k_work_reschedule(&lpn->timer, K_MSEC(FRIEND_REQ_TIMEOUT)); in friend_clear_sent()
212 .net_idx = bt_mesh.lpn.sub->net_idx, in send_friend_clear()
237 bool was_established = lpn->established; in clear_friendship()
238 uint16_t frnd = lpn->frnd; in clear_friendship()
239 uint16_t net_idx = lpn->sub->net_idx; in clear_friendship()
243 if (!force && lpn->established && !lpn->clear_success && in clear_friendship()
244 lpn->req_attempts < CLEAR_ATTEMPTS) { in clear_friendship()
246 lpn->disable = disable; in clear_friendship()
255 (void)k_work_cancel_delayable(&lpn->timer); in clear_friendship()
261 if (lpn->clear_success) { in clear_friendship()
262 lpn->old_friend = BT_MESH_ADDR_UNASSIGNED; in clear_friendship()
264 lpn->old_friend = lpn->frnd; in clear_friendship()
267 for (int i = 0; i < ARRAY_SIZE(lpn->cred); i++) { in clear_friendship()
268 if (lpn->sub->keys[i].valid) { in clear_friendship()
269 bt_mesh_friend_cred_destroy(&lpn->cred[i]); in clear_friendship()
273 lpn->frnd = BT_MESH_ADDR_UNASSIGNED; in clear_friendship()
274 lpn->fsn = 0U; in clear_friendship()
275 lpn->req_attempts = 0U; in clear_friendship()
276 lpn->recv_win = 0U; in clear_friendship()
277 lpn->queue_size = 0U; in clear_friendship()
278 lpn->disable = 0U; in clear_friendship()
279 lpn->sent_req = 0U; in clear_friendship()
280 lpn->established = 0U; in clear_friendship()
281 lpn->clear_success = 0U; in clear_friendship()
282 lpn->sub = NULL; in clear_friendship()
284 group_zero(lpn->added); in clear_friendship()
285 group_zero(lpn->pending); in clear_friendship()
286 group_zero(lpn->to_remove); in clear_friendship()
289 * Friendship is created, in case lpn->groups doesn't get in clear_friendship()
292 lpn->groups_changed = 1U; in clear_friendship()
299 k_work_reschedule(&lpn->timer, FRIEND_REQ_RETRY_TIMEOUT); in clear_friendship()
308 if (cb->terminated) { in clear_friendship()
309 cb->terminated(net_idx, frnd); in clear_friendship()
319 if (lpn->state != BT_MESH_LPN_ENABLED) { in friend_req_send_end()
328 lpn->adv_duration = k_uptime_get_32() - lpn->adv_start_time; in friend_req_send_end()
331 k_work_reschedule(&lpn->timer, in friend_req_send_end()
332 K_MSEC(FRIEND_REQ_WAIT - (int32_t)lpn->adv_duration)); in friend_req_send_end()
335 k_work_reschedule(&lpn->timer, K_MSEC(FRIEND_REQ_TIMEOUT)); in friend_req_send_end()
344 lpn->adv_start_time = k_uptime_get_32(); in friend_req_send_start()
370 lpn->lpn_counter++; in send_friend_req()
376 .prev_addr = sys_cpu_to_be16(lpn->old_friend), in send_friend_req()
377 .num_elem = comp->elem_count, in send_friend_req()
378 .lpn_counter = sys_cpu_to_be16(lpn->lpn_counter), in send_friend_req()
383 lpn->sub = bt_mesh_subnet_next(NULL); in send_friend_req()
384 if (!lpn->sub) { in send_friend_req()
386 return -ENOENT; in send_friend_req()
389 ctx.net_idx = lpn->sub->net_idx; in send_friend_req()
390 tx.sub = lpn->sub; in send_friend_req()
401 if (lpn->state == BT_MESH_LPN_DISABLED) { in req_send_end()
405 lpn->adv_duration = k_uptime_get_32() - lpn->adv_start_time; in req_send_end()
408 LOG_DBG("req 0x%02x duration %u err %d state %s", lpn->sent_req, lpn->adv_duration, err, in req_send_end()
409 state2str(lpn->state)); in req_send_end()
414 lpn->sent_req = 0U; in req_send_end()
415 group_zero(lpn->pending); in req_send_end()
419 retry = (lpn->req_attempts > 0); in req_send_end()
421 lpn->req_attempts++; in req_send_end()
423 if (lpn->established || IS_ENABLED(CONFIG_BT_MESH_LPN_ESTABLISHMENT)) { in req_send_end()
428 k_work_reschedule(&lpn->timer, in req_send_end()
429 K_MSEC(LPN_RECV_DELAY - SCAN_LATENCY - RX_DELAY_CORRECTION(lpn))); in req_send_end()
432 k_work_reschedule(&lpn->timer, K_MSEC(LPN_RECV_DELAY + lpn->recv_win)); in req_send_end()
436 if (cb->polled) { in req_send_end()
437 cb->polled(lpn->sub->net_idx, lpn->frnd, retry); in req_send_end()
446 lpn->adv_start_time = k_uptime_get_32(); in req_send_start()
461 .net_idx = bt_mesh.lpn.sub->net_idx, in send_friend_poll()
474 uint8_t fsn = lpn->fsn; in send_friend_poll()
477 LOG_DBG("lpn->sent_req 0x%02x", lpn->sent_req); in send_friend_poll()
479 if (lpn->sent_req) { in send_friend_poll()
480 if (lpn->sent_req != TRANS_CTL_OP_FRIEND_POLL) { in send_friend_poll()
481 lpn->pending_poll = 1U; in send_friend_poll()
490 lpn->pending_poll = 0U; in send_friend_poll()
491 lpn->sent_req = TRANS_CTL_OP_FRIEND_POLL; in send_friend_poll()
511 if (lpn->state != BT_MESH_LPN_DISABLED) { in bt_mesh_lpn_set()
515 if (lpn->state == BT_MESH_LPN_DISABLED) { in bt_mesh_lpn_set()
540 lpn->state == BT_MESH_LPN_TIMER) { in bt_mesh_lpn_set()
542 * next timeout. in bt_mesh_lpn_set()
544 (void)k_work_cancel_delayable(&lpn->timer); in bt_mesh_lpn_set()
558 if (!lpn->established) { in bt_mesh_lpn_friendship_end()
567 LOG_DBG("lpn->sent_req 0x%02x", lpn->sent_req); in friend_response_received()
569 if (lpn->sent_req == TRANS_CTL_OP_FRIEND_POLL) { in friend_response_received()
570 lpn->fsn++; in friend_response_received()
574 lpn->req_attempts = 0U; in friend_response_received()
575 lpn->sent_req = 0U; in friend_response_received()
577 /* Schedule the next poll. This may be overridden by additional in friend_response_received()
580 int32_t timeout = poll_timeout(lpn); in friend_response_received() local
582 k_work_reschedule(&lpn->timer, K_MSEC(timeout)); in friend_response_received()
590 if (lpn->state == BT_MESH_LPN_TIMER) { in bt_mesh_lpn_msg_received()
592 k_work_reschedule(&lpn->timer, K_MSEC(LPN_AUTO_TIMEOUT)); in bt_mesh_lpn_msg_received()
597 * Poll was already queued for sending. In this case, we're already in in bt_mesh_lpn_msg_received()
600 if (lpn->state != BT_MESH_LPN_WAIT_UPDATE) { in bt_mesh_lpn_msg_received()
604 if (lpn->sent_req != TRANS_CTL_OP_FRIEND_POLL) { in bt_mesh_lpn_msg_received()
605 LOG_WRN("Unexpected message without a preceding Poll"); in bt_mesh_lpn_msg_received()
621 lpn->frnd, lpn->lpn_counter, in friend_cred_create()
622 lpn->frnd_counter, key); in friend_cred_create()
628 struct bt_mesh_ctl_friend_offer *msg = (void *)buf->data; in bt_mesh_lpn_friend_offer()
633 if (buf->len < sizeof(*msg)) { in bt_mesh_lpn_friend_offer()
635 return -EBADMSG; in bt_mesh_lpn_friend_offer()
638 if (lpn->state != BT_MESH_LPN_WAIT_OFFER) { in bt_mesh_lpn_friend_offer()
643 if (!msg->recv_win) { in bt_mesh_lpn_friend_offer()
645 return -EBADMSG; in bt_mesh_lpn_friend_offer()
648 frnd_counter = sys_be16_to_cpu(msg->frnd_counter); in bt_mesh_lpn_friend_offer()
650 LOG_DBG("recv_win %u queue_size %u sub_list_size %u rssi %d counter %u", msg->recv_win, in bt_mesh_lpn_friend_offer()
651 msg->queue_size, msg->sub_list_size, msg->rssi, frnd_counter); in bt_mesh_lpn_friend_offer()
653 lpn->frnd_counter = frnd_counter; in bt_mesh_lpn_friend_offer()
654 lpn->frnd = rx->ctx.addr; in bt_mesh_lpn_friend_offer()
659 for (int i = 0; i < ARRAY_SIZE(lpn->cred); i++) { in bt_mesh_lpn_friend_offer()
660 if (!lpn->sub->keys[i].valid) { in bt_mesh_lpn_friend_offer()
664 err = friend_cred_create(&lpn->cred[i], &lpn->sub->keys[i].net); in bt_mesh_lpn_friend_offer()
666 lpn->frnd = BT_MESH_ADDR_UNASSIGNED; in bt_mesh_lpn_friend_offer()
673 lpn->recv_win = msg->recv_win; in bt_mesh_lpn_friend_offer()
674 lpn->queue_size = msg->queue_size; in bt_mesh_lpn_friend_offer()
678 LOG_WRN("LPN didn't succeed poll sending (err %d)", err); in bt_mesh_lpn_friend_offer()
679 for (int i = 0; i < ARRAY_SIZE(lpn->cred); i++) { in bt_mesh_lpn_friend_offer()
680 if (lpn->sub->keys[i].valid) { in bt_mesh_lpn_friend_offer()
681 bt_mesh_friend_cred_destroy(&lpn->cred[i]); in bt_mesh_lpn_friend_offer()
685 lpn->sub = NULL; in bt_mesh_lpn_friend_offer()
686 lpn->frnd = BT_MESH_ADDR_UNASSIGNED; in bt_mesh_lpn_friend_offer()
687 lpn->recv_win = 0U; in bt_mesh_lpn_friend_offer()
688 lpn->queue_size = 0U; in bt_mesh_lpn_friend_offer()
697 struct bt_mesh_ctl_friend_clear_confirm *msg = (void *)buf->data; in bt_mesh_lpn_friend_clear_cfm()
701 if (buf->len < sizeof(*msg)) { in bt_mesh_lpn_friend_clear_cfm()
703 return -EBADMSG; in bt_mesh_lpn_friend_clear_cfm()
706 if (lpn->state != BT_MESH_LPN_CLEAR) { in bt_mesh_lpn_friend_clear_cfm()
711 addr = sys_be16_to_cpu(msg->lpn_addr); in bt_mesh_lpn_friend_clear_cfm()
712 counter = sys_be16_to_cpu(msg->lpn_counter); in bt_mesh_lpn_friend_clear_cfm()
716 if (addr != bt_mesh_primary_addr() || counter != lpn->lpn_counter) { in bt_mesh_lpn_friend_clear_cfm()
721 lpn->clear_success = 1U; in bt_mesh_lpn_friend_clear_cfm()
722 clear_friendship(false, lpn->disable); in bt_mesh_lpn_friend_clear_cfm()
733 for (i = 0; i < ARRAY_SIZE(lpn->groups); i++) { in lpn_group_add()
734 if (lpn->groups[i] == group) { in lpn_group_add()
735 atomic_clear_bit(lpn->to_remove, i); in lpn_group_add()
739 if (!free_slot && lpn->groups[i] == BT_MESH_ADDR_UNASSIGNED) { in lpn_group_add()
740 free_slot = &lpn->groups[i]; in lpn_group_add()
750 lpn->groups_changed = 1U; in lpn_group_add()
758 for (i = 0; i < ARRAY_SIZE(lpn->groups); i++) { in lpn_group_del()
759 if (lpn->groups[i] == group) { in lpn_group_del()
760 if (atomic_test_bit(lpn->added, i) || in lpn_group_del()
761 atomic_test_bit(lpn->pending, i)) { in lpn_group_del()
762 atomic_set_bit(lpn->to_remove, i); in lpn_group_del()
763 lpn->groups_changed = 1U; in lpn_group_del()
765 lpn->groups[i] = BT_MESH_ADDR_UNASSIGNED; in lpn_group_del()
787 int added_count = group_popcount(lpn->added); in sub_update()
789 .net_idx = lpn->sub->net_idx, in sub_update()
791 .addr = lpn->frnd, in sub_update()
795 .sub = lpn->sub, in sub_update()
804 LOG_DBG("op 0x%02x sent_req 0x%02x", op, lpn->sent_req); in sub_update()
806 if (lpn->sent_req) { in sub_update()
810 for (i = 0, g = 0; i < ARRAY_SIZE(lpn->groups); i++) { in sub_update()
811 if (lpn->groups[i] == BT_MESH_ADDR_UNASSIGNED) { in sub_update()
816 if (atomic_test_bit(lpn->added, i)) { in sub_update()
820 if (!atomic_test_bit(lpn->to_remove, i)) { in sub_update()
825 if (added_count + g >= lpn->queue_size) { in sub_update()
830 req.addr_list[g++] = sys_cpu_to_be16(lpn->groups[i]); in sub_update()
831 atomic_set_bit(lpn->pending, i); in sub_update()
839 group_zero(lpn->pending); in sub_update()
843 req.xact = lpn->xact_next++; in sub_update()
847 group_zero(lpn->pending); in sub_update()
851 lpn->xact_pending = req.xact; in sub_update()
852 lpn->sent_req = op; in sub_update()
858 if (lpn->established) { in update_timeout()
861 k_work_reschedule(&lpn->timer, K_MSEC(POLL_RETRY_TIMEOUT)); in update_timeout()
868 if (lpn->req_attempts < REQ_ATTEMPTS(lpn)) { in update_timeout()
869 LOG_WRN("Retrying first Friend Poll"); in update_timeout()
870 lpn->sent_req = 0U; in update_timeout()
886 LOG_DBG("state: %s", state2str(lpn->state)); in lpn_timeout()
889 switch (lpn->state) { in lpn_timeout()
906 k_work_reschedule(&lpn->timer, K_MSEC(lpn->adv_duration + FRIEND_REQ_SCAN)); in lpn_timeout()
913 lpn->sent_req = 0U; in lpn_timeout()
914 k_work_reschedule(&lpn->timer, FRIEND_REQ_RETRY_TIMEOUT); in lpn_timeout()
921 if (lpn->req_attempts < REQ_ATTEMPTS(lpn)) { in lpn_timeout()
922 uint8_t req = lpn->sent_req; in lpn_timeout()
924 lpn->sent_req = 0U; in lpn_timeout()
935 LOG_ERR("No response from Friend after %u retries", lpn->req_attempts); in lpn_timeout()
936 lpn->req_attempts = 0U; in lpn_timeout()
940 k_work_reschedule(&lpn->timer, in lpn_timeout()
941 K_MSEC(SCAN_LATENCY + lpn->recv_win + RX_DELAY_CORRECTION(lpn))); in lpn_timeout()
988 struct bt_mesh_ctl_friend_sub_confirm *msg = (void *)buf->data; in bt_mesh_lpn_friend_sub_cfm()
991 if (buf->len < sizeof(*msg)) { in bt_mesh_lpn_friend_sub_cfm()
993 return -EBADMSG; in bt_mesh_lpn_friend_sub_cfm()
996 LOG_DBG("xact 0x%02x", msg->xact); in bt_mesh_lpn_friend_sub_cfm()
998 if (!lpn->sent_req) { in bt_mesh_lpn_friend_sub_cfm()
1003 if (msg->xact != lpn->xact_pending) { in bt_mesh_lpn_friend_sub_cfm()
1004 LOG_WRN("Transaction mismatch (0x%02x != 0x%02x)", msg->xact, lpn->xact_pending); in bt_mesh_lpn_friend_sub_cfm()
1008 if (lpn->sent_req == TRANS_CTL_OP_FRIEND_SUB_ADD) { in bt_mesh_lpn_friend_sub_cfm()
1009 group_set(lpn->added, lpn->pending); in bt_mesh_lpn_friend_sub_cfm()
1010 group_zero(lpn->pending); in bt_mesh_lpn_friend_sub_cfm()
1011 } else if (lpn->sent_req == TRANS_CTL_OP_FRIEND_SUB_REM) { in bt_mesh_lpn_friend_sub_cfm()
1014 group_clear(lpn->added, lpn->pending); in bt_mesh_lpn_friend_sub_cfm()
1016 for (i = 0; i < ARRAY_SIZE(lpn->groups); i++) { in bt_mesh_lpn_friend_sub_cfm()
1017 if (atomic_test_and_clear_bit(lpn->pending, i) && in bt_mesh_lpn_friend_sub_cfm()
1018 atomic_test_and_clear_bit(lpn->to_remove, i)) { in bt_mesh_lpn_friend_sub_cfm()
1019 lpn->groups[i] = BT_MESH_ADDR_UNASSIGNED; in bt_mesh_lpn_friend_sub_cfm()
1029 if (lpn->groups_changed) { in bt_mesh_lpn_friend_sub_cfm()
1033 if (!lpn->sent_req) { in bt_mesh_lpn_friend_sub_cfm()
1034 lpn->groups_changed = 0U; in bt_mesh_lpn_friend_sub_cfm()
1038 if (lpn->pending_poll) { in bt_mesh_lpn_friend_sub_cfm()
1048 struct bt_mesh_ctl_friend_update *msg = (void *)buf->data; in bt_mesh_lpn_friend_update()
1050 struct bt_mesh_subnet *sub = rx->sub; in bt_mesh_lpn_friend_update()
1054 if (buf->len < sizeof(*msg)) { in bt_mesh_lpn_friend_update()
1056 return -EBADMSG; in bt_mesh_lpn_friend_update()
1059 if (lpn->sent_req != TRANS_CTL_OP_FRIEND_POLL) { in bt_mesh_lpn_friend_update()
1064 if (sub->kr_phase == BT_MESH_KR_PHASE_2 && !rx->new_key) { in bt_mesh_lpn_friend_update()
1071 BT_MESH_IV_UPDATE(msg->flags))) { in bt_mesh_lpn_friend_update()
1075 if (!lpn->established) { in bt_mesh_lpn_friend_update()
1081 if (!rx->friend_cred) { in bt_mesh_lpn_friend_update()
1083 return -EINVAL; in bt_mesh_lpn_friend_update()
1086 lpn->established = 1U; in bt_mesh_lpn_friend_update()
1088 LOG_INF("Friendship established with 0x%04x", lpn->frnd); in bt_mesh_lpn_friend_update()
1092 /* Set initial poll timeout */ in bt_mesh_lpn_friend_update()
1093 lpn->poll_timeout = MIN(POLL_TIMEOUT_MAX(lpn), in bt_mesh_lpn_friend_update()
1101 iv_index = sys_be32_to_cpu(msg->iv_index); in bt_mesh_lpn_friend_update()
1103 LOG_DBG("flags 0x%02x iv_index 0x%08x md %u", msg->flags, iv_index, msg->md); in bt_mesh_lpn_friend_update()
1105 bt_mesh_kr_update(sub, BT_MESH_KEY_REFRESH(msg->flags), rx->new_key); in bt_mesh_lpn_friend_update()
1106 bt_mesh_net_iv_update(iv_index, BT_MESH_IV_UPDATE(msg->flags)); in bt_mesh_lpn_friend_update()
1108 if (lpn->groups_changed) { in bt_mesh_lpn_friend_update()
1112 if (!lpn->sent_req) { in bt_mesh_lpn_friend_update()
1113 lpn->groups_changed = 0U; in bt_mesh_lpn_friend_update()
1117 if (msg->md) { in bt_mesh_lpn_friend_update()
1124 if (cb->established) { in bt_mesh_lpn_friend_update()
1125 cb->established(lpn->sub->net_idx, lpn->frnd, lpn->queue_size, in bt_mesh_lpn_friend_update()
1126 lpn->recv_win); in bt_mesh_lpn_friend_update()
1137 return -EAGAIN; in bt_mesh_lpn_poll()
1156 friend_cred_create(&bt_mesh.lpn.cred[1], &sub->keys[1].net); in subnet_evt()
1173 k_work_init_delayable(&lpn->timer, lpn_timeout); in bt_mesh_lpn_init()
1175 if (lpn->state == BT_MESH_LPN_ENABLED) { in bt_mesh_lpn_init()
1187 LOG_DBG("Waiting %u ms for messages", LPN_AUTO_TIMEOUT); in bt_mesh_lpn_init()
1189 k_work_reschedule(&lpn->timer, in bt_mesh_lpn_init()