@@ -1160,21 +1160,51 @@ static void l2cap_chan_ready(struct l2cap_chan *chan)
1160
1160
chan -> ops -> ready (chan );
1161
1161
}
1162
1162
1163
+ static void l2cap_le_connect (struct l2cap_chan * chan )
1164
+ {
1165
+ struct l2cap_conn * conn = chan -> conn ;
1166
+ struct l2cap_le_conn_req req ;
1167
+
1168
+ req .psm = chan -> psm ;
1169
+ req .scid = cpu_to_le16 (chan -> scid );
1170
+ req .mtu = cpu_to_le16 (chan -> imtu );
1171
+ req .mps = __constant_cpu_to_le16 (L2CAP_LE_DEFAULT_MPS );
1172
+ req .credits = __constant_cpu_to_le16 (L2CAP_LE_MAX_CREDITS );
1173
+
1174
+ chan -> ident = l2cap_get_ident (conn );
1175
+
1176
+ l2cap_send_cmd (conn , chan -> ident , L2CAP_LE_CONN_REQ ,
1177
+ sizeof (req ), & req );
1178
+ }
1179
+
1180
+ static void l2cap_le_start (struct l2cap_chan * chan )
1181
+ {
1182
+ struct l2cap_conn * conn = chan -> conn ;
1183
+
1184
+ if (!smp_conn_security (conn -> hcon , chan -> sec_level ))
1185
+ return ;
1186
+
1187
+ if (!chan -> psm ) {
1188
+ l2cap_chan_ready (chan );
1189
+ return ;
1190
+ }
1191
+
1192
+ if (chan -> state == BT_CONNECT )
1193
+ l2cap_le_connect (chan );
1194
+ }
1195
+
1163
1196
static void l2cap_start_connection (struct l2cap_chan * chan )
1164
1197
{
1165
1198
if (__amp_capable (chan )) {
1166
1199
BT_DBG ("chan %p AMP capable: discover AMPs" , chan );
1167
1200
a2mp_discover_amp (chan );
1201
+ } else if (chan -> conn -> hcon -> type == LE_LINK ) {
1202
+ l2cap_le_start (chan );
1168
1203
} else {
1169
1204
l2cap_send_conn_req (chan );
1170
1205
}
1171
1206
}
1172
1207
1173
- static void l2cap_le_start (struct l2cap_chan * chan )
1174
- {
1175
- l2cap_chan_ready (chan );
1176
- }
1177
-
1178
1208
static void l2cap_do_start (struct l2cap_chan * chan )
1179
1209
{
1180
1210
struct l2cap_conn * conn = chan -> conn ;
@@ -1438,9 +1468,7 @@ static void l2cap_conn_ready(struct l2cap_conn *conn)
1438
1468
}
1439
1469
1440
1470
if (hcon -> type == LE_LINK ) {
1441
- if (smp_conn_security (hcon , chan -> sec_level ))
1442
- l2cap_chan_ready (chan );
1443
-
1471
+ l2cap_le_start (chan );
1444
1472
} else if (chan -> chan_type != L2CAP_CHAN_CONN_ORIENTED ) {
1445
1473
l2cap_chan_ready (chan );
1446
1474
@@ -5210,6 +5238,64 @@ static inline int l2cap_conn_param_update_req(struct l2cap_conn *conn,
5210
5238
return 0 ;
5211
5239
}
5212
5240
5241
+ static int l2cap_le_connect_rsp (struct l2cap_conn * conn ,
5242
+ struct l2cap_cmd_hdr * cmd , u16 cmd_len ,
5243
+ u8 * data )
5244
+ {
5245
+ struct l2cap_le_conn_rsp * rsp = (struct l2cap_le_conn_rsp * ) data ;
5246
+ u16 dcid , mtu , mps , credits , result ;
5247
+ struct l2cap_chan * chan ;
5248
+ int err ;
5249
+
5250
+ if (cmd_len < sizeof (* rsp ))
5251
+ return - EPROTO ;
5252
+
5253
+ dcid = __le16_to_cpu (rsp -> dcid );
5254
+ mtu = __le16_to_cpu (rsp -> mtu );
5255
+ mps = __le16_to_cpu (rsp -> mps );
5256
+ credits = __le16_to_cpu (rsp -> credits );
5257
+ result = __le16_to_cpu (rsp -> result );
5258
+
5259
+ if (result == L2CAP_CR_SUCCESS && (mtu < 23 || mps < 23 ))
5260
+ return - EPROTO ;
5261
+
5262
+ BT_DBG ("dcid 0x%4.4x mtu %u mps %u credits %u result 0x%2.2x" ,
5263
+ dcid , mtu , mps , credits , result );
5264
+
5265
+ mutex_lock (& conn -> chan_lock );
5266
+
5267
+ chan = __l2cap_get_chan_by_ident (conn , cmd -> ident );
5268
+ if (!chan ) {
5269
+ err = - EBADSLT ;
5270
+ goto unlock ;
5271
+ }
5272
+
5273
+ err = 0 ;
5274
+
5275
+ l2cap_chan_lock (chan );
5276
+
5277
+ switch (result ) {
5278
+ case L2CAP_CR_SUCCESS :
5279
+ chan -> ident = 0 ;
5280
+ chan -> dcid = dcid ;
5281
+ chan -> omtu = mtu ;
5282
+ chan -> remote_mps = mps ;
5283
+ l2cap_chan_ready (chan );
5284
+ break ;
5285
+
5286
+ default :
5287
+ l2cap_chan_del (chan , ECONNREFUSED );
5288
+ break ;
5289
+ }
5290
+
5291
+ l2cap_chan_unlock (chan );
5292
+
5293
+ unlock :
5294
+ mutex_unlock (& conn -> chan_lock );
5295
+
5296
+ return err ;
5297
+ }
5298
+
5213
5299
static inline int l2cap_bredr_sig_cmd (struct l2cap_conn * conn ,
5214
5300
struct l2cap_cmd_hdr * cmd , u16 cmd_len ,
5215
5301
u8 * data )
@@ -5304,6 +5390,10 @@ static inline int l2cap_le_sig_cmd(struct l2cap_conn *conn,
5304
5390
case L2CAP_CONN_PARAM_UPDATE_RSP :
5305
5391
return 0 ;
5306
5392
5393
+ case L2CAP_LE_CONN_RSP :
5394
+ l2cap_le_connect_rsp (conn , cmd , cmd_len , data );
5395
+ return 0 ;
5396
+
5307
5397
default :
5308
5398
BT_ERR ("Unknown LE signaling command 0x%2.2x" , cmd -> code );
5309
5399
return - EINVAL ;
0 commit comments