@@ -19,14 +19,15 @@ LOG_MODULE_REGISTER(LOG_MODULE_NAME, CONFIG_BTTESTER_LOG_LEVEL);
19
19
20
20
#include "btp/btp.h"
21
21
22
- #define DATA_MTU_INITIAL 128
23
- #define DATA_MTU 256
24
- #define DATA_BUF_SIZE BT_L2CAP_SDU_BUF_SIZE(DATA_MTU)
22
+ #define L2CAP_MPS 96
23
+ #define DATA_MTU (3 * L2CAP_MPS)
24
+ #define DATA_MTU_INITIAL (2 * L2CAP_MPS)
25
+
25
26
#define CHANNELS 2
26
27
#define SERVERS 1
27
28
28
- NET_BUF_POOL_FIXED_DEFINE (data_pool , CHANNELS , DATA_BUF_SIZE , CONFIG_BT_CONN_TX_USER_DATA_SIZE ,
29
- NULL );
29
+ NET_BUF_POOL_FIXED_DEFINE (data_pool , CHANNELS , BT_L2CAP_SDU_BUF_SIZE ( DATA_MTU ) ,
30
+ CONFIG_BT_CONN_TX_USER_DATA_SIZE , NULL );
30
31
31
32
static bool authorize_flag ;
32
33
static uint8_t req_keysize ;
@@ -36,18 +37,51 @@ static struct channel {
36
37
struct bt_l2cap_le_chan le ;
37
38
bool in_use ;
38
39
bool hold_credit ;
40
+ #if defined(CONFIG_BT_L2CAP_SEG_RECV )
41
+ unsigned int pending_credits ;
42
+ uint8_t recv_cb_buf [DATA_MTU + sizeof (struct btp_l2cap_data_received_ev )];
43
+ #else
39
44
struct net_buf * pending_credit ;
45
+ #endif
40
46
} channels [CHANNELS ];
41
47
42
48
/* TODO Extend to support multiple servers */
43
49
static struct bt_l2cap_server servers [SERVERS ];
44
50
51
+ #if defined(CONFIG_BT_L2CAP_SEG_RECV )
52
+ static void seg_recv_cb (struct bt_l2cap_chan * l2cap_chan , size_t sdu_len , off_t seg_offset ,
53
+ struct net_buf_simple * seg )
54
+ {
55
+ struct btp_l2cap_data_received_ev * ev ;
56
+ struct bt_l2cap_le_chan * l2cap_le_chan =
57
+ CONTAINER_OF (l2cap_chan , struct bt_l2cap_le_chan , chan );
58
+ struct channel * chan = CONTAINER_OF (l2cap_le_chan , struct channel , le );
59
+
60
+ ev = (void * )chan -> recv_cb_buf ;
61
+ memcpy (& ev -> data [seg_offset ], seg -> data , seg -> len );
62
+
63
+ /* complete SDU received */
64
+ if (seg_offset + seg -> len == sdu_len ) {
65
+ ev -> chan_id = chan -> chan_id ;
66
+ ev -> data_length = sys_cpu_to_le16 (sdu_len );
67
+
68
+ tester_event (BTP_SERVICE_ID_L2CAP , BTP_L2CAP_EV_DATA_RECEIVED , chan -> recv_cb_buf ,
69
+ sizeof (* ev ) + sdu_len );
70
+ }
71
+
72
+ if (chan -> hold_credit ) {
73
+ chan -> pending_credits ++ ;
74
+ } else {
75
+ bt_l2cap_chan_give_credits (l2cap_chan , 1 );
76
+ }
77
+ }
78
+ #else
45
79
static struct net_buf * alloc_buf_cb (struct bt_l2cap_chan * chan )
46
80
{
47
81
return net_buf_alloc (& data_pool , K_FOREVER );
48
82
}
49
83
50
- static uint8_t recv_cb_buf [DATA_BUF_SIZE + sizeof (struct btp_l2cap_data_received_ev )];
84
+ static uint8_t recv_cb_buf [DATA_MTU + sizeof (struct btp_l2cap_data_received_ev )];
51
85
52
86
static int recv_cb (struct bt_l2cap_chan * l2cap_chan , struct net_buf * buf )
53
87
{
@@ -73,6 +107,7 @@ static int recv_cb(struct bt_l2cap_chan *l2cap_chan, struct net_buf *buf)
73
107
74
108
return 0 ;
75
109
}
110
+ #endif
76
111
77
112
static void connected_cb (struct bt_l2cap_chan * l2cap_chan )
78
113
{
@@ -111,11 +146,13 @@ static void disconnected_cb(struct bt_l2cap_chan *l2cap_chan)
111
146
struct channel * chan = CONTAINER_OF (l2cap_le_chan , struct channel , le );
112
147
struct bt_conn_info info ;
113
148
149
+ #if !defined(CONFIG_BT_L2CAP_SEG_RECV )
114
150
/* release netbuf on premature disconnection */
115
151
if (chan -> pending_credit ) {
116
152
net_buf_unref (chan -> pending_credit );
117
153
chan -> pending_credit = NULL ;
118
154
}
155
+ #endif
119
156
120
157
(void )memset (& ev , 0 , sizeof (struct btp_l2cap_disconnected_ev ));
121
158
@@ -160,12 +197,16 @@ static void reconfigured_cb(struct bt_l2cap_chan *l2cap_chan)
160
197
#endif
161
198
162
199
static const struct bt_l2cap_chan_ops l2cap_ops = {
163
- .alloc_buf = alloc_buf_cb ,
164
- .recv = recv_cb ,
165
- .connected = connected_cb ,
166
- .disconnected = disconnected_cb ,
200
+ #if defined(CONFIG_BT_L2CAP_SEG_RECV )
201
+ .seg_recv = seg_recv_cb ,
202
+ #else
203
+ .alloc_buf = alloc_buf_cb ,
204
+ .recv = recv_cb ,
205
+ #endif
206
+ .connected = connected_cb ,
207
+ .disconnected = disconnected_cb ,
167
208
#if defined(CONFIG_BT_L2CAP_ECRED )
168
- .reconfigured = reconfigured_cb ,
209
+ .reconfigured = reconfigured_cb ,
169
210
#endif
170
211
};
171
212
@@ -222,10 +263,15 @@ static uint8_t connect(const void *cmd, uint16_t cmd_len,
222
263
}
223
264
chan -> le .chan .ops = & l2cap_ops ;
224
265
chan -> le .rx .mtu = mtu ;
266
+ #if defined(CONFIG_BT_L2CAP_SEG_RECV )
267
+ chan -> le .rx .mps = L2CAP_MPS ;
268
+ #endif
225
269
rp -> chan_id [i ] = chan -> chan_id ;
226
270
allocated_channels [i ] = & chan -> le .chan ;
227
271
228
272
chan -> hold_credit = cp -> options & BTP_L2CAP_CONNECT_OPT_HOLD_CREDIT ;
273
+
274
+ bt_l2cap_chan_give_credits (& chan -> le .chan , 1 );
229
275
}
230
276
231
277
if (cp -> num == 1 && !ecfc ) {
@@ -289,6 +335,7 @@ static uint8_t reconfigure(const void *cmd, uint16_t cmd_len,
289
335
{
290
336
const struct btp_l2cap_reconfigure_cmd * cp = cmd ;
291
337
uint16_t mtu ;
338
+ uint16_t mps ;
292
339
struct bt_conn * conn ;
293
340
int err ;
294
341
struct bt_l2cap_chan * reconf_channels [CHANNELS + 1 ] = {};
@@ -321,7 +368,8 @@ static uint8_t reconfigure(const void *cmd, uint16_t cmd_len,
321
368
return BTP_STATUS_FAILED ;
322
369
}
323
370
324
- err = bt_l2cap_ecred_chan_reconfigure (reconf_channels , mtu );
371
+ mps = MIN (L2CAP_MPS , BT_L2CAP_RX_MTU );
372
+ err = bt_l2cap_ecred_chan_reconfigure_explicit (reconf_channels , mtu , mps );
325
373
if (err ) {
326
374
bt_conn_unref (conn );
327
375
return BTP_STATUS_FAILED ;
@@ -454,9 +502,14 @@ static int accept(struct bt_conn *conn, struct bt_l2cap_server *server,
454
502
455
503
chan -> le .chan .ops = & l2cap_ops ;
456
504
chan -> le .rx .mtu = DATA_MTU_INITIAL ;
505
+ #if defined(CONFIG_BT_L2CAP_SEG_RECV )
506
+ chan -> le .rx .mps = L2CAP_MPS ;
507
+ #endif
457
508
458
509
* l2cap_chan = & chan -> le .chan ;
459
510
511
+ bt_l2cap_chan_give_credits (& chan -> le .chan , 1 );
512
+
460
513
return 0 ;
461
514
}
462
515
@@ -524,7 +577,15 @@ static uint8_t credits(const void *cmd, uint16_t cmd_len,
524
577
if (!chan -> in_use ) {
525
578
return BTP_STATUS_FAILED ;
526
579
}
580
+ #if defined(CONFIG_BT_L2CAP_SEG_RECV )
581
+ if (chan -> pending_credits ) {
582
+ if (bt_l2cap_chan_give_credits (& chan -> le .chan , chan -> pending_credits ) < 0 ) {
583
+ return BTP_STATUS_FAILED ;
584
+ }
527
585
586
+ chan -> pending_credits = 0 ;
587
+ }
588
+ #else
528
589
if (chan -> pending_credit ) {
529
590
if (bt_l2cap_chan_recv_complete (& chan -> le .chan ,
530
591
chan -> pending_credit ) < 0 ) {
@@ -533,6 +594,7 @@ static uint8_t credits(const void *cmd, uint16_t cmd_len,
533
594
534
595
chan -> pending_credit = NULL ;
535
596
}
597
+ #endif
536
598
537
599
return BTP_STATUS_SUCCESS ;
538
600
}
0 commit comments