@@ -1298,6 +1298,10 @@ static void le_ecred_reconf_req(struct bt_l2cap *l2cap, uint8_t ident,
12981298 for (int i = 0 ; i < chan_count ; i ++ ) {
12991299 BT_L2CAP_LE_CHAN (chans [i ])-> tx .mtu = mtu ;
13001300 BT_L2CAP_LE_CHAN (chans [i ])-> tx .mps = mps ;
1301+
1302+ if (chans [i ]-> ops -> reconfigured ) {
1303+ chans [i ]-> ops -> reconfigured (chans [i ]);
1304+ }
13011305 }
13021306
13031307 BT_DBG ("mtu %u mps %u" , mtu , mps );
@@ -1311,6 +1315,36 @@ static void le_ecred_reconf_req(struct bt_l2cap *l2cap, uint8_t ident,
13111315
13121316 l2cap_send (conn , BT_L2CAP_CID_LE_SIG , buf );
13131317}
1318+
1319+ static void le_ecred_reconf_rsp (struct bt_l2cap * l2cap , uint8_t ident ,
1320+ struct net_buf * buf )
1321+ {
1322+ struct bt_conn * conn = l2cap -> chan .chan .conn ;
1323+ struct bt_l2cap_ecred_reconf_rsp * rsp ;
1324+ struct bt_l2cap_le_chan * ch ;
1325+ uint16_t result ;
1326+
1327+ if (buf -> len < sizeof (* rsp )) {
1328+ BT_ERR ("Too small ecred reconf rsp packet size" );
1329+ return ;
1330+ }
1331+
1332+ rsp = net_buf_pull_mem (buf , sizeof (* rsp ));
1333+ result = sys_le16_to_cpu (rsp -> result );
1334+
1335+ while ((ch = l2cap_lookup_ident (conn , ident ))) {
1336+ if (result == BT_L2CAP_LE_SUCCESS ) {
1337+ ch -> rx .mtu = ch -> pending_rx_mtu ;
1338+ }
1339+
1340+ ch -> pending_rx_mtu = 0 ;
1341+ ch -> chan .ident = 0U ;
1342+
1343+ if (ch -> chan .ops -> reconfigured ) {
1344+ ch -> chan .ops -> reconfigured (& ch -> chan );
1345+ }
1346+ }
1347+ }
13141348#endif /* defined(CONFIG_BT_L2CAP_ECRED) */
13151349
13161350static struct bt_l2cap_le_chan * l2cap_remove_rx_cid (struct bt_conn * conn ,
@@ -2013,6 +2047,9 @@ static int l2cap_recv(struct bt_l2cap_chan *chan, struct net_buf *buf)
20132047 case BT_L2CAP_ECRED_RECONF_REQ :
20142048 le_ecred_reconf_req (l2cap , hdr -> ident , buf );
20152049 break ;
2050+ case BT_L2CAP_ECRED_RECONF_RSP :
2051+ le_ecred_reconf_rsp (l2cap , hdr -> ident , buf );
2052+ break ;
20162053#endif /* defined(CONFIG_BT_L2CAP_ECRED) */
20172054#else
20182055 case BT_L2CAP_CMD_REJECT :
@@ -2566,6 +2603,105 @@ int bt_l2cap_ecred_chan_connect(struct bt_conn *conn,
25662603
25672604 return err ;
25682605}
2606+
2607+ static struct bt_l2cap_le_chan * l2cap_find_pending_reconf (struct bt_conn * conn )
2608+ {
2609+ struct bt_l2cap_chan * chan ;
2610+
2611+ SYS_SLIST_FOR_EACH_CONTAINER (& conn -> channels , chan , node ) {
2612+ if (BT_L2CAP_LE_CHAN (chan )-> pending_rx_mtu ) {
2613+ return BT_L2CAP_LE_CHAN (chan );
2614+ }
2615+ }
2616+
2617+ return NULL ;
2618+ }
2619+
2620+ int bt_l2cap_ecred_chan_reconfigure (struct bt_l2cap_chan * * chans , uint16_t mtu )
2621+ {
2622+ struct bt_l2cap_ecred_reconf_req * req ;
2623+ struct bt_conn * conn = NULL ;
2624+ struct bt_l2cap_le_chan * ch ;
2625+ struct net_buf * buf ;
2626+ uint8_t ident ;
2627+ int i ;
2628+
2629+ BT_DBG ("chans %p mtu 0x%04x" , chans , mtu );
2630+
2631+ if (!chans ) {
2632+ return - EINVAL ;
2633+ }
2634+
2635+ for (i = 0 ; i < L2CAP_ECRED_CHAN_MAX ; i ++ ) {
2636+ if (!chans [i ]) {
2637+ break ;
2638+ }
2639+
2640+ /* validate that all channels are from same connection */
2641+ if (conn ) {
2642+ if (conn != chans [i ]-> conn ) {
2643+ return - EINVAL ;
2644+ }
2645+ } else {
2646+ conn = chans [i ]-> conn ;
2647+ }
2648+
2649+ /* validate MTU is not decreased */
2650+ if (mtu < BT_L2CAP_LE_CHAN (chans [i ])-> rx .mtu ) {
2651+ return - EINVAL ;
2652+ }
2653+ }
2654+
2655+ if (i == 0 ) {
2656+ return - EINVAL ;
2657+ }
2658+
2659+ if (!conn ) {
2660+ return - ENOTCONN ;
2661+ }
2662+
2663+ if (conn -> type != BT_CONN_TYPE_LE ) {
2664+ return - EINVAL ;
2665+ }
2666+
2667+ /* allow only 1 request at time */
2668+ if (l2cap_find_pending_reconf (conn )) {
2669+ return - EBUSY ;
2670+ }
2671+
2672+ ident = get_ident ();
2673+
2674+ buf = l2cap_create_le_sig_pdu (NULL , BT_L2CAP_ECRED_RECONF_REQ ,
2675+ ident ,
2676+ sizeof (* req ) + (i * sizeof (uint16_t )));
2677+ if (!buf ) {
2678+ return - ENOMEM ;
2679+ }
2680+
2681+ req = net_buf_add (buf , sizeof (* req ));
2682+ req -> mtu = sys_cpu_to_le16 (mtu );
2683+
2684+ /* MPS shall not be bigger than MTU + BT_L2CAP_SDU_HDR_SIZE
2685+ * as the remaining bytes cannot be used.
2686+ */
2687+ req -> mps = sys_cpu_to_le16 (MIN (mtu + BT_L2CAP_SDU_HDR_SIZE ,
2688+ BT_L2CAP_RX_MTU ));
2689+
2690+ for (int j = 0 ; j < i ; j ++ ) {
2691+ ch = BT_L2CAP_LE_CHAN (chans [j ]);
2692+
2693+ ch -> chan .ident = ident ;
2694+ ch -> pending_rx_mtu = mtu ;
2695+
2696+ net_buf_add_le16 (buf , ch -> rx .cid );
2697+ };
2698+
2699+ /* we use first channel for sending and timeouting */
2700+ l2cap_chan_send_req (chans [0 ], buf , L2CAP_CONN_TIMEOUT );
2701+
2702+ return 0 ;
2703+ }
2704+
25692705#endif /* defined(CONFIG_BT_L2CAP_ECRED) */
25702706
25712707int bt_l2cap_chan_connect (struct bt_conn * conn , struct bt_l2cap_chan * chan ,
0 commit comments