@@ -94,6 +94,7 @@ static struct seg_tx {
9494 const struct bt_mesh_send_cb * cb ;
9595 void * cb_data ;
9696 struct k_delayed_work rtx_timer ; /* Segment Retransmission timer */
97+ bt_mesh_mutex_t lock ;
9798} seg_tx [CONFIG_BLE_MESH_TX_SEG_MSG_COUNT ];
9899
99100static struct seg_rx {
@@ -120,17 +121,16 @@ static struct seg_rx {
120121static uint8_t seg_rx_buf_data [(CONFIG_BLE_MESH_RX_SEG_MSG_COUNT *
121122 CONFIG_BLE_MESH_RX_SDU_MAX )];
122123
123- static bt_mesh_mutex_t seg_tx_lock ;
124124static bt_mesh_mutex_t seg_rx_lock ;
125125
126- static inline void bt_mesh_seg_tx_lock (void )
126+ static inline void bt_mesh_seg_tx_lock (struct seg_tx * tx )
127127{
128- bt_mesh_mutex_lock ( & seg_tx_lock );
128+ bt_mesh_r_mutex_lock ( & tx -> lock );
129129}
130130
131- static inline void bt_mesh_seg_tx_unlock (void )
131+ static inline void bt_mesh_seg_tx_unlock (struct seg_tx * tx )
132132{
133- bt_mesh_mutex_unlock ( & seg_tx_lock );
133+ bt_mesh_r_mutex_unlock ( & tx -> lock );
134134}
135135
136136static inline void bt_mesh_seg_rx_lock (void )
@@ -331,7 +331,7 @@ static void seg_tx_reset(struct seg_tx *tx)
331331{
332332 int i ;
333333
334- bt_mesh_seg_tx_lock ();
334+ bt_mesh_seg_tx_lock (tx );
335335
336336 k_delayed_work_cancel (& tx -> rtx_timer );
337337
@@ -351,7 +351,7 @@ static void seg_tx_reset(struct seg_tx *tx)
351351
352352 tx -> nack_count = 0U ;
353353
354- bt_mesh_seg_tx_unlock ();
354+ bt_mesh_seg_tx_unlock (tx );
355355
356356 if (bt_mesh_atomic_test_and_clear_bit (bt_mesh .flags , BLE_MESH_IVU_PENDING )) {
357357 BT_DBG ("Proceeding with pending IV Update" );
@@ -380,6 +380,7 @@ static inline void seg_tx_complete(struct seg_tx *tx, int err)
380380
381381static void schedule_retransmit (struct seg_tx * tx )
382382{
383+ bt_mesh_seg_tx_lock (tx );
383384 /* It's possible that a segment broadcast hasn't finished,
384385 * but the tx are already released. Only the seg_pending
385386 * of this segment remains unprocessed. So, here, we
@@ -391,20 +392,24 @@ static void schedule_retransmit(struct seg_tx *tx)
391392 if (tx -> seg_pending ) {
392393 tx -> seg_pending -- ;
393394 }
395+ bt_mesh_seg_tx_unlock (tx );
394396 return ;
395397 }
396398
397399 if (-- tx -> seg_pending ) {
400+ bt_mesh_seg_tx_unlock (tx );
398401 return ;
399402 }
400403
401404 if (!BLE_MESH_ADDR_IS_UNICAST (tx -> dst ) && !tx -> attempts ) {
402405 BT_INFO ("Complete tx sdu to group" );
403406 seg_tx_complete (tx , 0 );
407+ bt_mesh_seg_tx_unlock (tx );
404408 return ;
405409 }
406410
407411 k_delayed_work_submit (& tx -> rtx_timer , SEG_RETRANSMIT_TIMEOUT (tx ));
412+ bt_mesh_seg_tx_unlock (tx );
408413}
409414
410415static void seg_first_send_start (uint16_t duration , int err , void * user_data )
@@ -450,11 +455,11 @@ static void seg_tx_send_unacked(struct seg_tx *tx)
450455{
451456 int i , err = 0 ;
452457
453- bt_mesh_seg_tx_lock ();
458+ bt_mesh_seg_tx_lock (tx );
454459
455460 if (!(tx -> attempts -- )) {
456461 BT_WARN ("Ran out of retransmit attempts" );
457- bt_mesh_seg_tx_unlock ();
462+ bt_mesh_seg_tx_unlock (tx );
458463 seg_tx_complete (tx , - ETIMEDOUT );
459464 return ;
460465 }
@@ -487,13 +492,13 @@ static void seg_tx_send_unacked(struct seg_tx *tx)
487492 & seg_sent_cb , tx );
488493 if (err ) {
489494 BT_ERR ("Sending segment failed" );
490- bt_mesh_seg_tx_unlock ();
495+ bt_mesh_seg_tx_unlock (tx );
491496 seg_tx_complete (tx , - EIO );
492497 return ;
493498 }
494499 }
495500
496- bt_mesh_seg_tx_unlock ();
501+ bt_mesh_seg_tx_unlock (tx );
497502}
498503
499504static void seg_retransmit (struct k_work * work )
@@ -511,6 +516,7 @@ static int send_seg(struct bt_mesh_net_tx *net_tx, struct net_buf_simple *sdu,
511516 uint16_t seq_zero = 0U ;
512517 uint8_t seg_hdr = 0U ;
513518 uint8_t seg_o = 0U ;
519+ int err = 0 ;
514520 int i ;
515521
516522 BT_DBG ("src 0x%04x dst 0x%04x app_idx 0x%04x aszmic %u sdu_len %u" ,
@@ -583,16 +589,17 @@ static int send_seg(struct bt_mesh_net_tx *net_tx, struct net_buf_simple *sdu,
583589 return - ENOBUFS ;
584590 }
585591
592+ bt_mesh_seg_tx_lock (tx );
593+
586594 for (seg_o = 0U ; sdu -> len ; seg_o ++ ) {
587595 struct net_buf * seg = NULL ;
588596 uint16_t len = 0U ;
589- int err = 0 ;
590597
591598 seg = bt_mesh_adv_create (BLE_MESH_ADV_DATA , BUF_TIMEOUT );
592599 if (!seg ) {
593600 BT_ERR ("Out of segment buffers" );
594- seg_tx_reset ( tx ) ;
595- return - ENOBUFS ;
601+ err = - ENOBUFS ;
602+ break ;
596603 }
597604
598605 net_buf_reserve (seg , BLE_MESH_NET_HDR_LEN );
@@ -637,8 +644,7 @@ static int send_seg(struct bt_mesh_net_tx *net_tx, struct net_buf_simple *sdu,
637644 tx );
638645 if (err ) {
639646 BT_ERR ("Sending segment failed (err %d)" , err );
640- seg_tx_reset (tx );
641- return err ;
647+ break ;
642648 }
643649
644650 /* If security credentials is updated in the network layer,
@@ -650,6 +656,13 @@ static int send_seg(struct bt_mesh_net_tx *net_tx, struct net_buf_simple *sdu,
650656 }
651657 }
652658
659+ bt_mesh_seg_tx_unlock (tx );
660+
661+ if (err ) {
662+ seg_tx_reset (tx );
663+ return err ;
664+ }
665+
653666 /* This can happen if segments only went into the Friend Queue */
654667 if (IS_ENABLED (CONFIG_BLE_MESH_FRIEND ) && !tx -> seg [0 ]) {
655668 seg_tx_reset (tx );
@@ -984,9 +997,9 @@ static int trans_ack(struct bt_mesh_net_rx *rx, uint8_t hdr,
984997 while ((bit = find_lsb_set (ack ))) {
985998 if (tx -> seg [bit - 1 ]) {
986999 BT_INFO ("Seg %u/%u acked" , bit - 1 , tx -> seg_n );
987- bt_mesh_seg_tx_lock ();
1000+ bt_mesh_seg_tx_lock (tx );
9881001 seg_tx_done (tx , bit - 1 );
989- bt_mesh_seg_tx_unlock ();
1002+ bt_mesh_seg_tx_unlock (tx );
9901003 }
9911004
9921005 ack &= ~BIT (bit - 1 );
@@ -1786,6 +1799,7 @@ void bt_mesh_trans_init(void)
17861799
17871800 for (i = 0 ; i < ARRAY_SIZE (seg_tx ); i ++ ) {
17881801 k_delayed_work_init (& seg_tx [i ].rtx_timer , seg_retransmit );
1802+ bt_mesh_r_mutex_create (& seg_tx [i ].lock );
17891803 }
17901804
17911805 for (i = 0 ; i < ARRAY_SIZE (seg_rx ); i ++ ) {
@@ -1795,7 +1809,6 @@ void bt_mesh_trans_init(void)
17951809 seg_rx [i ].buf .data = seg_rx [i ].buf .__buf ;
17961810 }
17971811
1798- bt_mesh_mutex_create (& seg_tx_lock );
17991812 bt_mesh_mutex_create (& seg_rx_lock );
18001813}
18011814
@@ -1810,13 +1823,13 @@ void bt_mesh_trans_deinit(bool erase)
18101823
18111824 for (i = 0 ; i < ARRAY_SIZE (seg_tx ); i ++ ) {
18121825 k_delayed_work_free (& seg_tx [i ].rtx_timer );
1826+ bt_mesh_r_mutex_free (& seg_tx [i ].lock );
18131827 }
18141828
18151829 for (i = 0 ; i < ARRAY_SIZE (seg_rx ); i ++ ) {
18161830 k_delayed_work_free (& seg_rx [i ].ack_timer );
18171831 }
18181832
1819- bt_mesh_mutex_free (& seg_tx_lock );
18201833 bt_mesh_mutex_free (& seg_rx_lock );
18211834}
18221835#endif /* CONFIG_BLE_MESH_DEINIT */
0 commit comments