1 /******************************************************************************
3 * Copyright (C) 2014 Google, Inc.
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at:
9 * http://www.apache.org/licenses/LICENSE-2.0
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
17 ******************************************************************************/
19 #define LOG_TAG "bt_l2cap_client"
21 #include "stack/include/l2cap_client.h"
26 #include "btcore/include/bdaddr.h"
27 #include "gki/common/gki.h"
28 #include "osi/include/allocator.h"
29 #include "osi/include/buffer.h"
30 #include "osi/include/list.h"
31 #include "osi/include/log.h"
32 #include "osi/include/osi.h"
33 #include "stack/include/l2c_api.h"
35 struct l2cap_client_t {
36 l2cap_client_callbacks_t callbacks;
39 uint16_t local_channel_id;
44 list_t *outbound_fragments;
47 static void connect_completed_cb(uint16_t local_channel_id, uint16_t error_code);
48 static void config_request_cb(uint16_t local_channel_id, tL2CAP_CFG_INFO *requested_parameters);
49 static void config_completed_cb(uint16_t local_channel_id, tL2CAP_CFG_INFO *negotiated_parameters);
50 static void disconnect_request_cb(uint16_t local_channel_id, bool ack_required);
51 static void disconnect_completed_cb(uint16_t local_channel_id, uint16_t error_code);
52 static void congestion_cb(uint16_t local_channel_id, bool is_congested);
53 static void read_ready_cb(uint16_t local_channel_id, BT_HDR *packet);
54 static void write_completed_cb(uint16_t local_channel_id, uint16_t packets_completed);
56 static void fragment_packet(l2cap_client_t *client, buffer_t *packet);
57 static void dispatch_fragments(l2cap_client_t *client);
58 static l2cap_client_t *find(uint16_t local_channel_id);
60 // From the Bluetooth Core specification.
61 static const uint16_t L2CAP_MTU_DEFAULT = 672;
62 static const uint16_t L2CAP_MTU_MINIMUM = 48;
64 static const tL2CAP_APPL_INFO l2cap_callbacks = {
65 .pL2CA_ConnectCfm_Cb = connect_completed_cb,
66 .pL2CA_ConfigInd_Cb = config_request_cb,
67 .pL2CA_ConfigCfm_Cb = config_completed_cb,
68 .pL2CA_DisconnectInd_Cb = disconnect_request_cb,
69 .pL2CA_DisconnectCfm_Cb = disconnect_completed_cb,
70 .pL2CA_CongestionStatus_Cb = congestion_cb,
71 .pL2CA_DataInd_Cb = read_ready_cb,
72 .pL2CA_TxComplete_Cb = write_completed_cb,
75 static list_t *l2cap_clients; // A list of l2cap_client_t. Container does not own objects.
77 buffer_t *l2cap_buffer_new(size_t size) {
78 buffer_t *buf = buffer_new(size + L2CAP_MIN_OFFSET);
79 buffer_t *slice = NULL;
81 slice = buffer_new_slice(buf, size);
86 l2cap_client_t *l2cap_client_new(const l2cap_client_callbacks_t *callbacks, void *context) {
87 assert(callbacks != NULL);
88 assert(callbacks->connected != NULL);
89 assert(callbacks->disconnected != NULL);
90 assert(callbacks->read_ready != NULL);
91 assert(callbacks->write_ready != NULL);
94 l2cap_clients = list_new(NULL);
96 LOG_ERROR(LOG_TAG, "%s unable to allocate space for L2CAP client list.", __func__);
101 l2cap_client_t *ret = (l2cap_client_t *)osi_calloc(sizeof(l2cap_client_t));
103 LOG_ERROR(LOG_TAG, "%s unable to allocate L2CAP client.", __func__);
107 ret->callbacks = *callbacks;
108 ret->context = context;
110 ret->remote_mtu = L2CAP_MTU_DEFAULT;
111 ret->outbound_fragments = list_new(NULL);
113 LOG_ERROR(LOG_TAG, "%s unable to allocate outbound L2CAP fragment list.", __func__);
117 list_append(l2cap_clients, ret);
126 void l2cap_client_free(l2cap_client_t *client) {
130 list_remove(l2cap_clients, client);
131 l2cap_client_disconnect(client);
132 list_free(client->outbound_fragments);
136 bool l2cap_client_connect(l2cap_client_t *client, const bt_bdaddr_t *remote_bdaddr, uint16_t psm) {
137 assert(client != NULL);
138 assert(remote_bdaddr != NULL);
140 assert(!bdaddr_is_empty(remote_bdaddr));
141 assert(client->local_channel_id == 0);
142 assert(!client->configured_self);
143 assert(!client->configured_peer);
144 assert(!L2C_INVALID_PSM(psm));
146 client->local_channel_id = L2CA_ConnectReq(psm, (uint8_t *)remote_bdaddr);
147 if (!client->local_channel_id) {
148 LOG_ERROR(LOG_TAG, "%s unable to create L2CAP connection.", __func__);
152 L2CA_SetConnectionCallbacks(client->local_channel_id, &l2cap_callbacks);
156 void l2cap_client_disconnect(l2cap_client_t *client) {
157 assert(client != NULL);
159 if (client->local_channel_id && !L2CA_DisconnectReq(client->local_channel_id))
160 LOG_ERROR(LOG_TAG, "%s unable to send disconnect message for LCID 0x%04x.", __func__, client->local_channel_id);
162 client->local_channel_id = 0;
163 client->remote_mtu = L2CAP_MTU_DEFAULT;
164 client->configured_self = false;
165 client->configured_peer = false;
166 client->is_congested = false;
168 for (const list_node_t *node = list_begin(client->outbound_fragments); node != list_end(client->outbound_fragments); node = list_next(node))
169 GKI_freebuf(list_node(node));
171 list_clear(client->outbound_fragments);
174 bool l2cap_client_is_connected(const l2cap_client_t *client) {
175 assert(client != NULL);
177 return client->local_channel_id != 0 && client->configured_self && client->configured_peer;
180 bool l2cap_client_write(l2cap_client_t *client, buffer_t *packet) {
181 assert(client != NULL);
182 assert(packet != NULL);
183 assert(l2cap_client_is_connected(client));
185 if (client->is_congested)
188 fragment_packet(client, packet);
189 dispatch_fragments(client);
193 static void connect_completed_cb(uint16_t local_channel_id, uint16_t error_code) {
194 assert(local_channel_id != 0);
196 l2cap_client_t *client = find(local_channel_id);
198 LOG_ERROR(LOG_TAG, "%s unable to find L2CAP client for LCID 0x%04x.", __func__, local_channel_id);
202 if (error_code != L2CAP_CONN_OK) {
203 LOG_ERROR(LOG_TAG, "%s error connecting L2CAP channel: %d.", __func__, error_code);
204 client->callbacks.disconnected(client, client->context);
208 // Use default L2CAP parameters.
209 tL2CAP_CFG_INFO desired_parameters = { 0 };
210 if (!L2CA_ConfigReq(local_channel_id, &desired_parameters)) {
211 LOG_ERROR(LOG_TAG, "%s error sending L2CAP config parameters.", __func__);
212 client->callbacks.disconnected(client, client->context);
216 static void config_request_cb(uint16_t local_channel_id, tL2CAP_CFG_INFO *requested_parameters) {
217 tL2CAP_CFG_INFO response = { 0 };
218 l2cap_client_t *client = find(local_channel_id);
221 LOG_ERROR(LOG_TAG, "%s unable to find L2CAP client matching LCID 0x%04x.", __func__, local_channel_id);
225 response.result = L2CAP_CFG_OK;
227 if (requested_parameters->mtu_present) {
228 // Make sure the peer chose an MTU at least as large as the minimum L2CAP MTU defined
229 // by the Bluetooth Core spec.
230 if (requested_parameters->mtu < L2CAP_MTU_MINIMUM) {
231 response.mtu = L2CAP_MTU_MINIMUM;
232 response.mtu_present = true;
233 response.result = L2CAP_CFG_UNACCEPTABLE_PARAMS;
235 client->remote_mtu = requested_parameters->mtu;
239 if (requested_parameters->fcr_present) {
240 if (requested_parameters->fcr.mode != L2CAP_FCR_BASIC_MODE) {
241 response.fcr_present = true;
242 response.fcr = requested_parameters->fcr;
243 response.fcr.mode = L2CAP_FCR_BASIC_MODE;
244 response.result = L2CAP_CFG_UNACCEPTABLE_PARAMS;
248 if (!L2CA_ConfigRsp(local_channel_id, &response)) {
249 LOG_ERROR(LOG_TAG, "%s unable to send config response for LCID 0x%04x.", __func__, local_channel_id);
250 l2cap_client_disconnect(client);
254 // If we've configured both endpoints, let the listener know we've connected.
255 client->configured_peer = true;
256 if (l2cap_client_is_connected(client))
257 client->callbacks.connected(client, client->context);
260 static void config_completed_cb(uint16_t local_channel_id, tL2CAP_CFG_INFO *negotiated_parameters) {
261 l2cap_client_t *client = find(local_channel_id);
264 LOG_ERROR(LOG_TAG, "%s unable to find L2CAP client matching LCID 0x%04x.", __func__, local_channel_id);
268 switch (negotiated_parameters->result) {
269 // We'll get another configuration response later.
270 case L2CAP_CFG_PENDING:
273 case L2CAP_CFG_UNACCEPTABLE_PARAMS:
274 // TODO: see if we can renegotiate parameters instead of dropping the connection.
275 LOG_WARN(LOG_TAG, "%s dropping L2CAP connection due to unacceptable config parameters.", __func__);
276 l2cap_client_disconnect(client);
280 // If we've configured both endpoints, let the listener know we've connected.
281 client->configured_self = true;
282 if (l2cap_client_is_connected(client))
283 client->callbacks.connected(client, client->context);
286 // Failure, no further parameter negotiation possible.
288 LOG_WARN(LOG_TAG, "%s L2CAP parameter negotiation failed with error code %d.", __func__, negotiated_parameters->result);
289 l2cap_client_disconnect(client);
294 static void disconnect_request_cb(uint16_t local_channel_id, bool ack_required) {
295 l2cap_client_t *client = find(local_channel_id);
297 LOG_ERROR(LOG_TAG, "%s unable to find L2CAP client with LCID 0x%04x.", __func__, local_channel_id);
302 L2CA_DisconnectRsp(local_channel_id);
304 // We already sent a disconnect response so this LCID is now invalid.
305 client->local_channel_id = 0;
306 l2cap_client_disconnect(client);
308 client->callbacks.disconnected(client, client->context);
311 static void disconnect_completed_cb(uint16_t local_channel_id, UNUSED_ATTR uint16_t error_code) {
312 assert(local_channel_id != 0);
314 l2cap_client_t *client = find(local_channel_id);
316 LOG_ERROR(LOG_TAG, "%s unable to find L2CAP client with LCID 0x%04x.", __func__, local_channel_id);
320 client->local_channel_id = 0;
321 l2cap_client_disconnect(client);
323 client->callbacks.disconnected(client, client->context);
326 static void congestion_cb(uint16_t local_channel_id, bool is_congested) {
327 assert(local_channel_id != 0);
329 l2cap_client_t *client = find(local_channel_id);
331 LOG_ERROR(LOG_TAG, "%s unable to find L2CAP client matching LCID 0x%04x.", __func__, local_channel_id);
335 client->is_congested = is_congested;
338 // If we just decongested, dispatch whatever we have left over in our queue.
339 // Once that's done, if we're still decongested, notify the listener so it
340 // can start writing again.
341 dispatch_fragments(client);
342 if (!client->is_congested)
343 client->callbacks.write_ready(client, client->context);
347 static void read_ready_cb(uint16_t local_channel_id, BT_HDR *packet) {
348 assert(local_channel_id != 0);
350 l2cap_client_t *client = find(local_channel_id);
352 LOG_ERROR(LOG_TAG, "%s unable to find L2CAP client matching LCID 0x%04x.", __func__, local_channel_id);
356 // TODO(sharvil): eliminate copy from BT_HDR.
357 buffer_t *buffer = buffer_new(packet->len);
358 memcpy(buffer_ptr(buffer), packet->data + packet->offset, packet->len);
361 client->callbacks.read_ready(client, buffer, client->context);
365 static void write_completed_cb(UNUSED_ATTR uint16_t local_channel_id, UNUSED_ATTR uint16_t packets_completed) {
366 // Do nothing. We update congestion state based on the congestion callback
367 // and we've already removed items from outbound_fragments list so we don't
368 // really care how many packets were successfully dispatched.
371 static void fragment_packet(l2cap_client_t *client, buffer_t *packet) {
372 assert(client != NULL);
373 assert(packet != NULL);
375 // TODO(sharvil): eliminate copy into BT_HDR.
376 BT_HDR *bt_packet = GKI_getbuf(buffer_length(packet) + L2CAP_MIN_OFFSET);
377 bt_packet->offset = L2CAP_MIN_OFFSET;
378 bt_packet->len = buffer_length(packet);
379 memcpy(bt_packet->data + bt_packet->offset, buffer_ptr(packet), buffer_length(packet));
382 if (bt_packet->len <= client->remote_mtu) {
383 if (bt_packet->len > 0)
384 list_append(client->outbound_fragments, bt_packet);
386 GKI_freebuf(bt_packet);
390 BT_HDR *fragment = GKI_getbuf(client->remote_mtu + L2CAP_MIN_OFFSET);
391 fragment->offset = L2CAP_MIN_OFFSET;
392 fragment->len = client->remote_mtu;
393 memcpy(fragment->data + fragment->offset, bt_packet->data + bt_packet->offset, client->remote_mtu);
395 list_append(client->outbound_fragments, fragment);
397 bt_packet->offset += client->remote_mtu;
398 bt_packet->len -= client->remote_mtu;
402 static void dispatch_fragments(l2cap_client_t *client) {
403 assert(client != NULL);
404 assert(!client->is_congested);
406 while (!list_is_empty(client->outbound_fragments)) {
407 BT_HDR *packet = (BT_HDR *)list_front(client->outbound_fragments);
408 list_remove(client->outbound_fragments, packet);
410 switch (L2CA_DataWrite(client->local_channel_id, packet)) {
411 case L2CAP_DW_CONGESTED:
412 client->is_congested = true;
415 case L2CAP_DW_FAILED:
416 LOG_ERROR(LOG_TAG, "%s error writing data to L2CAP connection LCID 0x%04x; disconnecting.", __func__, client->local_channel_id);
417 l2cap_client_disconnect(client);
420 case L2CAP_DW_SUCCESS:
426 static l2cap_client_t *find(uint16_t local_channel_id) {
427 assert(local_channel_id != 0);
429 for (const list_node_t *node = list_begin(l2cap_clients); node != list_end(l2cap_clients); node = list_next(node)) {
430 l2cap_client_t *client = (l2cap_client_t *)list_node(node);
431 if (client->local_channel_id == local_channel_id)