@@ -471,33 +471,32 @@ static int send_iso(struct bt_conn *conn, struct net_buf *buf, uint8_t flags)
471471 return bt_send (buf );
472472}
473473
474- static int send_frag (struct bt_conn * conn , struct net_buf * buf , uint8_t flags ,
475- bool always_consume )
474+ static inline uint16_t conn_mtu (struct bt_conn * conn )
475+ {
476+ #if defined(CONFIG_BT_BREDR )
477+ if (conn -> type == BT_CONN_TYPE_BR || !bt_dev .le .acl_mtu ) {
478+ return bt_dev .br .mtu ;
479+ }
480+ #endif /* CONFIG_BT_BREDR */
481+ #if defined(CONFIG_BT_ISO )
482+ if (conn -> type == BT_CONN_TYPE_ISO && bt_dev .le .iso_mtu ) {
483+ return bt_dev .le .iso_mtu ;
484+ }
485+ #endif /* CONFIG_BT_ISO */
486+ #if defined(CONFIG_BT_CONN )
487+ return bt_dev .le .acl_mtu ;
488+ #else
489+ return 0 ;
490+ #endif /* CONFIG_BT_CONN */
491+ }
492+
493+ static int do_send_frag (struct bt_conn * conn , struct net_buf * buf , uint8_t flags )
476494{
477495 struct bt_conn_tx * tx = tx_data (buf )-> tx ;
478- uint32_t * pending_no_cb ;
496+ uint32_t * pending_no_cb = NULL ;
479497 unsigned int key ;
480498 int err = 0 ;
481499
482- /* Check if the controller can accept ACL packets */
483- if (k_sem_take (bt_conn_get_pkts (conn ), K_NO_WAIT )) {
484- /* not `goto fail`, we don't want to free the tx context: in the
485- * case where it is the original buffer, it will contain the
486- * callback ptr.
487- */
488- BT_DBG ("no CTLR bufs" );
489- return - ENOBUFS ;
490- }
491-
492- if (flags == FRAG_SINGLE || flags == FRAG_END ) {
493- /* De-queue the buffer now that we know we can send it.
494- * Only applies if the buffer to be sent is the original buffer,
495- * and not one of its fragments.
496- * This buffer was fetched from the FIFO using a peek operation.
497- */
498- buf = net_buf_get (& conn -> tx_queue , K_NO_WAIT );
499- }
500-
501500 /* Check for disconnection while waiting for pkts_sem */
502501 if (conn -> state != BT_CONN_CONNECTED ) {
503502 err = - ENOTCONN ;
@@ -564,35 +563,41 @@ static int send_frag(struct bt_conn *conn, struct net_buf *buf, uint8_t flags,
564563 tx_free (tx );
565564 }
566565
567- if (always_consume ) {
568- net_buf_unref (buf );
569- }
570566 return err ;
571567}
572568
573- static inline uint16_t conn_mtu (struct bt_conn * conn )
569+ static int send_frag (struct bt_conn * conn ,
570+ struct net_buf * buf , struct net_buf * frag ,
571+ uint8_t flags )
574572{
575- #if defined(CONFIG_BT_BREDR )
576- if (conn -> type == BT_CONN_TYPE_BR || !bt_dev .le .acl_mtu ) {
577- return bt_dev .br .mtu ;
573+ /* Check if the controller can accept ACL packets */
574+ if (k_sem_take (bt_conn_get_pkts (conn ), K_NO_WAIT )) {
575+ BT_DBG ("no controller bufs" );
576+ return - ENOBUFS ;
578577 }
579- #endif /* CONFIG_BT_BREDR */
580- #if defined(CONFIG_BT_ISO )
581- if (conn -> type == BT_CONN_TYPE_ISO && bt_dev .le .iso_mtu ) {
582- return bt_dev .le .iso_mtu ;
578+
579+ /* Add the data to the buffer */
580+ if (frag ) {
581+ uint16_t frag_len = MIN (conn_mtu (conn ), net_buf_tailroom (frag ));
582+
583+ net_buf_add_mem (frag , buf -> data , frag_len );
584+ net_buf_pull (buf , frag_len );
585+ } else {
586+ /* De-queue the buffer now that we know we can send it.
587+ * Only applies if the buffer to be sent is the original buffer,
588+ * and not one of its fragments.
589+ * This buffer was fetched from the FIFO using a peek operation.
590+ */
591+ buf = net_buf_get (& conn -> tx_queue , K_NO_WAIT );
592+ frag = buf ;
583593 }
584- #endif /* CONFIG_BT_ISO */
585- #if defined(CONFIG_BT_CONN )
586- return bt_dev .le .acl_mtu ;
587- #else
588- return 0 ;
589- #endif /* CONFIG_BT_CONN */
594+
595+ return do_send_frag (conn , frag , flags );
590596}
591597
592598static struct net_buf * create_frag (struct bt_conn * conn , struct net_buf * buf )
593599{
594600 struct net_buf * frag ;
595- uint16_t frag_len ;
596601
597602 switch (conn -> type ) {
598603#if defined(CONFIG_BT_ISO )
@@ -618,11 +623,6 @@ static struct net_buf *create_frag(struct bt_conn *conn, struct net_buf *buf)
618623 tx_data (frag )-> tx = NULL ;
619624 tx_data (frag )-> is_cont = false;
620625
621- frag_len = MIN (conn_mtu (conn ), net_buf_tailroom (frag ));
622-
623- net_buf_add_mem (frag , buf -> data , frag_len );
624- net_buf_pull (buf , frag_len );
625-
626626 return frag ;
627627}
628628
@@ -637,13 +637,13 @@ static int send_buf(struct bt_conn *conn, struct net_buf *buf)
637637 /* Send directly if the packet fits the ACL MTU */
638638 if (buf -> len <= conn_mtu (conn ) && !tx_data (buf )-> is_cont ) {
639639 BT_DBG ("send single" );
640- return send_frag (conn , buf , FRAG_SINGLE , false );
640+ return send_frag (conn , buf , NULL , FRAG_SINGLE );
641641 }
642642
643643 BT_DBG ("start fragmenting" );
644644 /*
645645 * Send the fragments. For the last one simply use the original
646- * buffer (which works since we've used net_buf_pull on it.
646+ * buffer (which works since we've used net_buf_pull on it) .
647647 */
648648 flags = FRAG_START ;
649649 if (tx_data (buf )-> is_cont ) {
@@ -656,12 +656,10 @@ static int send_buf(struct bt_conn *conn, struct net_buf *buf)
656656 return - ENOMEM ;
657657 }
658658
659- err = send_frag (conn , frag , flags , false );
659+ err = send_frag (conn , buf , frag , flags );
660660 if (err ) {
661661 BT_DBG ("%p failed, mark as existing frag" , buf );
662662 tx_data (buf )-> is_cont = flags != FRAG_START ;
663- /* Put the frag back into the original buffer */
664- net_buf_push_mem (buf , frag -> data , frag -> len );
665663 net_buf_unref (frag );
666664 return err ;
667665 }
@@ -671,7 +669,7 @@ static int send_buf(struct bt_conn *conn, struct net_buf *buf)
671669
672670 BT_DBG ("last frag" );
673671 tx_data (buf )-> is_cont = true;
674- return send_frag (conn , buf , FRAG_END , false );
672+ return send_frag (conn , buf , NULL , FRAG_END );
675673}
676674
677675static struct k_poll_signal conn_change =
0 commit comments