@@ -75,10 +75,9 @@ static void discard_buffer(void)
7575 }
7676 }
7777
78- BT_WARN ("Discarding buffer for LPN 0x%04x" , frnd -> lpn );
79-
8078 buf = net_buf_slist_get (& frnd -> queue );
8179 __ASSERT_NO_MSG (buf != NULL );
80+ BT_WARN ("Discarding buffer %p for LPN 0x%04x" , buf , frnd -> lpn );
8281 net_buf_unref (buf );
8382}
8483
@@ -163,6 +162,11 @@ static void friend_clear(struct bt_mesh_friend *frnd)
163162 friend_cred_del (frnd -> net_idx , frnd -> lpn );
164163
165164 if (frnd -> last ) {
165+ /* Cancel the sending if necessary */
166+ if (frnd -> pending_buf ) {
167+ BT_MESH_ADV (frnd -> last )-> busy = 0 ;
168+ }
169+
166170 net_buf_unref (frnd -> last );
167171 frnd -> last = NULL ;
168172 }
@@ -184,6 +188,7 @@ static void friend_clear(struct bt_mesh_friend *frnd)
184188 frnd -> pending_buf = 0 ;
185189 frnd -> fsn = 0 ;
186190 frnd -> queue_size = 0 ;
191+ frnd -> pending_req = 0 ;
187192 memset (frnd -> sub_list , 0 , sizeof (frnd -> sub_list ));
188193}
189194
@@ -440,6 +445,13 @@ static void enqueue_sub_cfm(struct bt_mesh_friend *frnd, u8_t xact)
440445 frnd -> send_last = 1 ;
441446}
442447
448+ static void friend_recv_delay (struct bt_mesh_friend * frnd )
449+ {
450+ frnd -> pending_req = 1 ;
451+ k_delayed_work_submit (& frnd -> timer , recv_delay (frnd ));
452+ BT_DBG ("Waiting RecvDelay of %d ms" , recv_delay (frnd ));
453+ }
454+
443455int bt_mesh_friend_sub_add (struct bt_mesh_net_rx * rx ,
444456 struct net_buf_simple * buf )
445457{
@@ -462,7 +474,7 @@ int bt_mesh_friend_sub_add(struct bt_mesh_net_rx *rx,
462474 return 0 ;
463475 }
464476
465- k_delayed_work_submit ( & frnd -> timer , recv_delay ( frnd ) );
477+ friend_recv_delay ( frnd );
466478
467479 xact = net_buf_simple_pull_u8 (buf );
468480
@@ -472,8 +484,6 @@ int bt_mesh_friend_sub_add(struct bt_mesh_net_rx *rx,
472484
473485 enqueue_sub_cfm (frnd , xact );
474486
475- BT_DBG ("Waiting RecvDelay of %d ms" , recv_delay (frnd ));
476-
477487 return 0 ;
478488}
479489
@@ -499,7 +509,7 @@ int bt_mesh_friend_sub_rem(struct bt_mesh_net_rx *rx,
499509 return 0 ;
500510 }
501511
502- k_delayed_work_submit ( & frnd -> timer , recv_delay ( frnd ) );
512+ friend_recv_delay ( frnd );
503513
504514 xact = net_buf_simple_pull_u8 (buf );
505515
@@ -509,8 +519,6 @@ int bt_mesh_friend_sub_rem(struct bt_mesh_net_rx *rx,
509519
510520 enqueue_sub_cfm (frnd , xact );
511521
512- BT_DBG ("Waiting RecvDelay of %d ms" , recv_delay (frnd ));
513-
514522 return 0 ;
515523}
516524
@@ -560,19 +568,24 @@ int bt_mesh_friend_poll(struct bt_mesh_net_rx *rx, struct net_buf_simple *buf)
560568 return 0 ;
561569 }
562570
563- k_delayed_work_submit (& frnd -> timer , recv_delay (frnd ));
571+ BT_DBG ("msg->fsn %u frnd->fsn %u" , (msg -> fsn & 1 ), frnd -> fsn );
572+
573+ friend_recv_delay (frnd );
564574
565575 if (!frnd -> established ) {
566576 BT_DBG ("Friendship established with 0x%04x" , frnd -> lpn );
567577 frnd -> established = 1 ;
568578 }
569579
570- BT_DBG ("msg->fsn %u frnd->fsn %u" , (msg -> fsn & 1 ), frnd -> fsn );
571-
572580 if (msg -> fsn == frnd -> fsn && frnd -> last ) {
573581 BT_DBG ("Re-sending last PDU" );
574582 frnd -> send_last = 1 ;
575583 } else {
584+ if (frnd -> last ) {
585+ net_buf_unref (frnd -> last );
586+ frnd -> last = NULL ;
587+ }
588+
576589 frnd -> fsn = msg -> fsn ;
577590
578591 if (sys_slist_is_empty (& frnd -> queue )) {
@@ -581,8 +594,6 @@ int bt_mesh_friend_poll(struct bt_mesh_net_rx *rx, struct net_buf_simple *buf)
581594 }
582595 }
583596
584- BT_DBG ("Waiting RecvDelay of %d ms" , recv_delay (frnd ));
585-
586597 return 0 ;
587598}
588599
@@ -733,7 +744,12 @@ static void enqueue_offer(struct bt_mesh_friend *frnd, s8_t rssi)
733744
734745 frnd -> counter ++ ;
735746
736- enqueue_buf (frnd , buf );
747+ if (frnd -> last ) {
748+ net_buf_unref (frnd -> last );
749+ }
750+
751+ frnd -> last = buf ;
752+ frnd -> send_last = 1 ;
737753}
738754
739755#define RECV_WIN CONFIG_BT_MESH_FRIEND_RECV_WIN
@@ -944,6 +960,12 @@ static void buf_send_start(u16_t duration, int err, void *user_data)
944960 BT_DBG ("err %d" , err );
945961
946962 frnd -> pending_buf = 0 ;
963+
964+ /* Friend Offer doesn't follow the re-sending semantics */
965+ if (!frnd -> established ) {
966+ net_buf_unref (frnd -> last );
967+ frnd -> last = NULL ;
968+ }
947969}
948970
949971static void buf_send_end (int err , void * user_data )
@@ -952,17 +974,18 @@ static void buf_send_end(int err, void *user_data)
952974
953975 BT_DBG ("err %d" , err );
954976
977+ if (frnd -> pending_req ) {
978+ BT_WARN ("Another request before previous completed sending" );
979+ return ;
980+ }
981+
955982 if (frnd -> established ) {
956983 k_delayed_work_submit (& frnd -> timer , frnd -> poll_to );
957984 BT_DBG ("Waiting %u ms for next poll" , frnd -> poll_to );
958985 } else {
959986 /* Friend offer timeout is 1 second */
960987 k_delayed_work_submit (& frnd -> timer , K_SECONDS (1 ));
961988 BT_DBG ("Waiting for first poll" );
962-
963- /* Friend Offer doesn't follow the re-sending semantics */
964- net_buf_unref (frnd -> last );
965- frnd -> last = NULL ;
966989 }
967990}
968991
@@ -981,31 +1004,30 @@ static void friend_timeout(struct k_work *work)
9811004 frnd -> send_last , frnd -> last );
9821005
9831006 if (frnd -> send_last && frnd -> last ) {
984- BT_DBG ("Sending frnd->last" );
1007+ BT_DBG ("Sending frnd->last %p" , frnd -> last );
9851008 frnd -> send_last = 0 ;
9861009 goto send_last ;
9871010 }
9881011
989- if (frnd -> last ) {
990- net_buf_unref (frnd -> last );
1012+ if (frnd -> established && !frnd -> pending_req ) {
1013+ BT_WARN ("Friendship lost with 0x%04x" , frnd -> lpn );
1014+ friend_clear (frnd );
1015+ return ;
9911016 }
9921017
993- /* If the timeout is triggered without anything in the queue, it
994- * means that there was no poll/req from the LPN and the timeout
995- * occured because we hit the poll timeout.
996- */
9971018 frnd -> last = net_buf_slist_get (& frnd -> queue );
9981019 if (!frnd -> last ) {
999- BT_WARN ("Friendship %s" ,
1000- frnd -> established ? "lost" : "not established" );
1020+ BT_WARN ("Friendship not established with 0x%04x" , frnd -> lpn );
10011021 friend_clear (frnd );
10021022 return ;
10031023 }
10041024
10051025 BT_DBG ("Sending buf %p from Friend Queue of LPN 0x%04x" ,
10061026 frnd -> last , frnd -> lpn );
1027+ frnd -> queue_size -- ;
10071028
10081029send_last :
1030+ frnd -> pending_req = 0 ;
10091031 frnd -> pending_buf = 1 ;
10101032 bt_mesh_adv_send (frnd -> last , & buf_sent_cb , frnd );
10111033}
@@ -1049,6 +1071,7 @@ static void friend_purge_old_ack(struct bt_mesh_friend *frnd, u64_t *seq_auth,
10491071 BT_DBG ("Removing old ack from Friend Queue" );
10501072
10511073 sys_slist_remove (& frnd -> queue , prev , cur );
1074+ frnd -> queue_size -- ;
10521075 /* Make sure old slist entry state doesn't remain */
10531076 buf -> frags = NULL ;
10541077
@@ -1066,7 +1089,7 @@ static void friend_lpn_enqueue_rx(struct bt_mesh_friend *frnd,
10661089 struct friend_pdu_info info ;
10671090 struct net_buf * buf ;
10681091
1069- BT_DBG ("LPN 0x%04x" , frnd -> lpn );
1092+ BT_DBG ("LPN 0x%04x queue_size %u " , frnd -> lpn , frnd -> queue_size );
10701093
10711094 if (type == BT_MESH_FRIEND_PDU_SINGLE && seq_auth ) {
10721095 friend_purge_old_ack (frnd , seq_auth , rx -> ctx .addr );
@@ -1101,7 +1124,8 @@ static void friend_lpn_enqueue_rx(struct bt_mesh_friend *frnd,
11011124
11021125 enqueue_friend_pdu (frnd , type , buf );
11031126
1104- BT_DBG ("Queued message for LPN 0x%04x" , frnd -> lpn );
1127+ BT_DBG ("Queued message for LPN 0x%04x, queue_size %u" ,
1128+ frnd -> lpn , frnd -> queue_size );
11051129}
11061130
11071131static void friend_lpn_enqueue_tx (struct bt_mesh_friend * frnd ,
0 commit comments