54
54
/* Acked messages, will do retransmissions manually, taking acks into account:
55
55
*/
56
56
#define RETRANSMITS_RELIABLE 0
57
- /* Unacked messages: */
58
- #define RETRANSMITS_UNRELIABLE 2
59
57
/* PDU acks: */
60
58
#define RETRANSMITS_ACK 2
59
+ /* Link close retransmits: */
60
+ #define RETRANSMITS_LINK_CLOSE 2
61
61
62
62
enum {
63
63
ADV_LINK_ACTIVE , /* Link has been opened */
@@ -126,17 +126,25 @@ static void link_open(struct prov_rx *rx, struct net_buf_simple *buf);
126
126
static void link_ack (struct prov_rx * rx , struct net_buf_simple * buf );
127
127
static void link_close (struct prov_rx * rx , struct net_buf_simple * buf );
128
128
static void prov_link_close (enum prov_bearer_link_status status );
129
+ static void close_link (enum prov_bearer_link_status status );
129
130
130
131
static void buf_sent (int err , void * user_data )
131
132
{
132
- if (!link .tx .buf [0 ]) {
133
+ if (atomic_test_and_clear_bit (link .flags , ADV_LINK_CLOSING )) {
134
+ close_link (PROV_BEARER_LINK_STATUS_SUCCESS );
133
135
return ;
134
136
}
137
+ }
135
138
136
- k_work_reschedule (& link .tx .retransmit , RETRANSMIT_TIMEOUT );
139
+ static void buf_start (uint16_t duration , int err , void * user_data )
140
+ {
141
+ if (err ) {
142
+ buf_sent (err , user_data );
143
+ }
137
144
}
138
145
139
146
static struct bt_mesh_send_cb buf_sent_cb = {
147
+ .start = buf_start ,
140
148
.end = buf_sent ,
141
149
};
142
150
@@ -573,64 +581,40 @@ static void send_reliable(void)
573
581
574
582
BT_DBG ("%u bytes: %s" , buf -> len , bt_hex (buf -> data , buf -> len ));
575
583
576
- if (i + 1 < ARRAY_SIZE (link .tx .buf ) && link .tx .buf [i + 1 ]) {
577
- bt_mesh_adv_send (buf , NULL , NULL );
578
- } else {
579
- bt_mesh_adv_send (buf , & buf_sent_cb , NULL );
580
- }
584
+ bt_mesh_adv_send (buf , NULL , NULL );
581
585
}
586
+
587
+ k_work_reschedule (& link .tx .retransmit , RETRANSMIT_TIMEOUT );
582
588
}
583
589
584
590
static void prov_retransmit (struct k_work * work )
585
591
{
586
- int32_t timeout_ms ;
587
-
588
592
BT_DBG ("" );
589
593
590
594
if (!atomic_test_bit (link .flags , ADV_LINK_ACTIVE )) {
591
595
BT_WARN ("Link not active" );
592
596
return ;
593
597
}
594
598
595
- /*
596
- * According to mesh profile spec (5.3.1.4.3), the close message should
597
- * be restransmitted at least three times. Retransmit the link_close
598
- * message until CLOSING_TIMEOUT has elapsed.
599
- */
600
- if (atomic_test_bit (link .flags , ADV_LINK_CLOSING )) {
601
- timeout_ms = CLOSING_TIMEOUT ;
602
- } else {
603
- timeout_ms = TRANSACTION_TIMEOUT ;
604
- }
605
-
606
- if (k_uptime_get () - link .tx .start > timeout_ms ) {
607
- if (atomic_test_bit (link .flags , ADV_LINK_CLOSING )) {
608
- close_link (PROV_BEARER_LINK_STATUS_SUCCESS );
609
- } else {
610
- BT_WARN ("Giving up transaction" );
611
- prov_link_close (PROV_BEARER_LINK_STATUS_FAIL );
612
- }
613
-
599
+ if (k_uptime_get () - link .tx .start > TRANSACTION_TIMEOUT ) {
600
+ BT_WARN ("Giving up transaction" );
601
+ prov_link_close (PROV_BEARER_LINK_STATUS_FAIL );
614
602
return ;
615
603
}
616
604
617
605
send_reliable ();
618
606
}
619
607
620
- static int bearer_ctl_send (uint8_t op , const void * data , uint8_t data_len ,
621
- bool reliable )
608
+ static struct net_buf * ctl_buf_create (uint8_t op , const void * data , uint8_t data_len ,
609
+ uint8_t retransmits )
622
610
{
623
611
struct net_buf * buf ;
624
612
625
613
BT_DBG ("op 0x%02x data_len %u" , op , data_len );
626
614
627
- prov_clear_tx ();
628
- k_work_reschedule (& link .prot_timer , PROTOCOL_TIMEOUT );
629
-
630
- buf = adv_buf_create (reliable ? RETRANSMITS_RELIABLE :
631
- RETRANSMITS_UNRELIABLE );
615
+ buf = adv_buf_create (retransmits );
632
616
if (!buf ) {
633
- return - ENOBUFS ;
617
+ return NULL ;
634
618
}
635
619
636
620
net_buf_add_be32 (buf , link .id );
@@ -639,15 +623,37 @@ static int bearer_ctl_send(uint8_t op, const void *data, uint8_t data_len,
639
623
net_buf_add_u8 (buf , GPC_CTL (op ));
640
624
net_buf_add_mem (buf , data , data_len );
641
625
642
- if ( reliable ) {
643
- link . tx . start = k_uptime_get ();
644
- link . tx . buf [ 0 ] = buf ;
645
- send_reliable ();
646
- } else {
647
- bt_mesh_adv_send ( buf , & buf_sent_cb , NULL );
648
- net_buf_unref ( buf ) ;
626
+ return buf ;
627
+ }
628
+
629
+ static int bearer_ctl_send ( struct net_buf * buf )
630
+ {
631
+ if (! buf ) {
632
+ return - ENOMEM ;
649
633
}
650
634
635
+ prov_clear_tx ();
636
+ k_work_reschedule (& link .prot_timer , PROTOCOL_TIMEOUT );
637
+
638
+ link .tx .start = k_uptime_get ();
639
+ link .tx .buf [0 ] = buf ;
640
+ send_reliable ();
641
+
642
+ return 0 ;
643
+ }
644
+
645
+ static int bearer_ctl_send_unacked (struct net_buf * buf )
646
+ {
647
+ if (!buf ) {
648
+ return - ENOMEM ;
649
+ }
650
+
651
+ prov_clear_tx ();
652
+ k_work_reschedule (& link .prot_timer , PROTOCOL_TIMEOUT );
653
+
654
+ bt_mesh_adv_send (buf , & buf_sent_cb , NULL );
655
+ net_buf_unref (buf );
656
+
651
657
return 0 ;
652
658
}
653
659
@@ -724,6 +730,8 @@ static int prov_send_adv(struct net_buf_simple *msg,
724
730
725
731
static void link_open (struct prov_rx * rx , struct net_buf_simple * buf )
726
732
{
733
+ int err ;
734
+
727
735
BT_DBG ("len %u" , buf -> len );
728
736
729
737
if (buf -> len < 16 ) {
@@ -733,13 +741,14 @@ static void link_open(struct prov_rx *rx, struct net_buf_simple *buf)
733
741
734
742
if (atomic_test_bit (link .flags , ADV_LINK_ACTIVE )) {
735
743
/* Send another link ack if the provisioner missed the last */
736
- if (link .id == rx -> link_id ) {
737
- BT_DBG ("Resending link ack" );
738
- bearer_ctl_send (LINK_ACK , NULL , 0 , false);
739
- } else {
744
+ if (link .id != rx -> link_id ) {
740
745
BT_DBG ("Ignoring bearer open: link already active" );
746
+ return ;
741
747
}
742
748
749
+ BT_DBG ("Resending link ack" );
750
+ /* Ignore errors, message will be attempted again if we keep receiving link open: */
751
+ (void )bearer_ctl_send_unacked (ctl_buf_create (LINK_ACK , NULL , 0 , RETRANSMITS_ACK ));
743
752
return ;
744
753
}
745
754
@@ -752,7 +761,11 @@ static void link_open(struct prov_rx *rx, struct net_buf_simple *buf)
752
761
atomic_set_bit (link .flags , ADV_LINK_ACTIVE );
753
762
net_buf_simple_reset (link .rx .buf );
754
763
755
- bearer_ctl_send (LINK_ACK , NULL , 0 , false);
764
+ err = bearer_ctl_send_unacked (ctl_buf_create (LINK_ACK , NULL , 0 , RETRANSMITS_ACK ));
765
+ if (err ) {
766
+ reset_adv_link ();
767
+ return ;
768
+ }
756
769
757
770
link .cb -> link_opened (& pb_adv , link .cb_data );
758
771
}
@@ -840,9 +853,7 @@ static int prov_link_open(const uint8_t uuid[16], k_timeout_t timeout,
840
853
841
854
net_buf_simple_reset (link .rx .buf );
842
855
843
- bearer_ctl_send (LINK_OPEN , uuid , 16 , true);
844
-
845
- return 0 ;
856
+ return bearer_ctl_send (ctl_buf_create (LINK_OPEN , uuid , 16 , RETRANSMITS_RELIABLE ));
846
857
}
847
858
848
859
static int prov_link_accept (const struct prov_bearer_cb * cb , void * cb_data )
@@ -878,7 +889,8 @@ static void prov_link_close(enum prov_bearer_link_status status)
878
889
return ;
879
890
}
880
891
881
- bearer_ctl_send (LINK_CLOSE , & status , 1 , true);
892
+ /* Ignore errors, the link will time out eventually if this doesn't get sent */
893
+ bearer_ctl_send_unacked (ctl_buf_create (LINK_CLOSE , & status , 1 , RETRANSMITS_LINK_CLOSE ));
882
894
}
883
895
884
896
void pb_adv_init (void )
0 commit comments