blob: 1f85c732b231500ba0404718e316cb92d16fd0e7 [file] [log] [blame]
Kim Schulz8372aa52015-03-25 10:39:40 +01001/*
Jakub Pawlowski5b790fe2017-09-18 09:00:20 -07002 * Copyright 2014 Samsung System LSI
3 * Copyright 2013 The Android Open Source Project
Jakub Pawlowskia09c3482017-06-16 08:42:05 -07004 *
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
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
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.
16 */
Kim Schulz8372aa52015-03-25 10:39:40 +010017
Marie Janssen49a86702015-07-08 11:48:57 -070018#include "btif_sock_l2cap.h"
19
Jakub Pawlowski35ee0232018-02-02 11:47:09 -080020#include <base/logging.h>
Marie Janssendb554582015-06-26 14:53:46 -070021#include <errno.h>
Marie Janssendb554582015-06-26 14:53:46 -070022#include <stdlib.h>
23#include <sys/ioctl.h>
24#include <sys/socket.h>
25#include <sys/types.h>
26#include <unistd.h>
Jakub Pawlowskif47bfde2018-01-29 13:54:24 -080027#include <vector>
Marie Janssendb554582015-06-26 14:53:46 -070028
Marie Janssena5764682016-10-10 13:38:30 -070029#include <mutex>
30
Jack He83f86832019-02-06 20:24:24 -080031#include <frameworks/base/core/proto/android/bluetooth/enums.pb.h>
Kim Schulz8372aa52015-03-25 10:39:40 +010032#include <hardware/bt_sock.h>
Kim Schulz8372aa52015-03-25 10:39:40 +010033
Pavlin Radoslavov56a3be02015-06-02 13:54:58 -070034#include "osi/include/allocator.h"
Kim Schulz8372aa52015-03-25 10:39:40 +010035
Myles Watson6bd442f2016-10-19 09:50:22 -070036#include "bt_common.h"
Kim Schulz8372aa52015-03-25 10:39:40 +010037#include "bt_target.h"
Marie Janssendb554582015-06-26 14:53:46 -070038#include "bta_api.h"
Kim Schulz8372aa52015-03-25 10:39:40 +010039#include "bta_jv_api.h"
40#include "bta_jv_co.h"
Marie Janssendb554582015-06-26 14:53:46 -070041#include "btif_common.h"
Marie Janssendb554582015-06-26 14:53:46 -070042#include "btif_sock_sdp.h"
43#include "btif_sock_thread.h"
44#include "btif_sock_util.h"
Adam Lesinski0620f972015-12-02 22:15:08 -080045#include "btif_uid.h"
Marie Janssendb554582015-06-26 14:53:46 -070046#include "btif_util.h"
47#include "btm_api.h"
48#include "btm_int.h"
49#include "btu.h"
Jack He83f86832019-02-06 20:24:24 -080050#include "common/metrics.h"
Marie Janssendb554582015-06-26 14:53:46 -070051#include "hcimsgs.h"
Kim Schulz8372aa52015-03-25 10:39:40 +010052#include "l2c_api.h"
Jakub Pawlowski8452b052018-01-05 02:41:36 -080053#include "l2c_int.h"
Marie Janssendb554582015-06-26 14:53:46 -070054#include "l2cdefs.h"
55#include "port_api.h"
56#include "sdp_api.h"
Kim Schulz8372aa52015-03-25 10:39:40 +010057
Kim Schulz8372aa52015-03-25 10:39:40 +010058struct packet {
Myles Watson6bd442f2016-10-19 09:50:22 -070059 struct packet *next, *prev;
60 uint32_t len;
61 uint8_t* data;
Kim Schulz8372aa52015-03-25 10:39:40 +010062};
63
64typedef struct l2cap_socket {
Myles Watson6bd442f2016-10-19 09:50:22 -070065 struct l2cap_socket* prev; // link to prev list item
66 struct l2cap_socket* next; // link to next list item
Jakub Pawlowskia484a882017-06-24 17:30:18 -070067 RawAddress addr; // other side's address
Myles Watson6bd442f2016-10-19 09:50:22 -070068 char name[256]; // user-friendly name of the service
69 uint32_t id; // just a tag to find this struct
70 int app_uid; // The UID of the app who requested this socket
71 int handle; // handle from lower layers
72 unsigned security; // security flags
73 int channel; // channel (fixed_chan) or PSM (!fixed_chan)
74 int our_fd; // fd from our side
75 int app_fd; // fd from app's side
Kim Schulz8372aa52015-03-25 10:39:40 +010076
Myles Watson6bd442f2016-10-19 09:50:22 -070077 unsigned bytes_buffered;
78 struct packet* first_packet; // fist packet to be delivered to app
79 struct packet* last_packet; // last packet to be delivered to app
Kim Schulz8372aa52015-03-25 10:39:40 +010080
Myles Watson6bd442f2016-10-19 09:50:22 -070081 unsigned fixed_chan : 1; // fixed channel (or psm?)
82 unsigned server : 1; // is a server? (or connecting?)
83 unsigned connected : 1; // is connected?
84 unsigned outgoing_congest : 1; // should we hold?
85 unsigned server_psm_sent : 1; // The server shall only send PSM once.
86 bool is_le_coc; // is le connection oriented channel?
Jakub Pawlowski622bd222018-01-30 15:40:03 -080087 uint16_t rx_mtu;
88 uint16_t tx_mtu;
Jack He83f86832019-02-06 20:24:24 -080089 // Cumulative number of bytes transmitted on this socket
90 int64_t tx_bytes;
91 // Cumulative number of bytes received on this socket
92 int64_t rx_bytes;
Marie Janssendb554582015-06-26 14:53:46 -070093} l2cap_socket;
Kim Schulz8372aa52015-03-25 10:39:40 +010094
Jakub Pawlowskie5e2dd52018-01-30 21:46:08 -080095static void btsock_l2cap_server_listen(l2cap_socket* sock);
Kim Schulz8372aa52015-03-25 10:39:40 +010096
Marie Janssena5764682016-10-10 13:38:30 -070097static std::mutex state_lock;
Kim Schulz8372aa52015-03-25 10:39:40 +010098
Myles Watson6bd442f2016-10-19 09:50:22 -070099l2cap_socket* socks = NULL;
Adam Lesinski0620f972015-12-02 22:15:08 -0800100static uid_set_t* uid_set = NULL;
Kim Schulz8372aa52015-03-25 10:39:40 +0100101static int pth = -1;
102
Myles Watson6bd442f2016-10-19 09:50:22 -0700103static void btsock_l2cap_cbk(tBTA_JV_EVT event, tBTA_JV* p_data,
Ajay Panicker531fe1a2016-11-22 13:28:43 -0800104 uint32_t l2cap_socket_id);
Kim Schulz8372aa52015-03-25 10:39:40 +0100105
Myles Watson6bd442f2016-10-19 09:50:22 -0700106/* TODO: Consider to remove this buffer, as we have a buffer in l2cap as well,
107 * and we risk
108 * a buffer overflow with this implementation if the socket data is not
109 * read from
110 * JAVA for a while. In such a case we should use flow control to tell the
111 * sender to
Kim Schulz8372aa52015-03-25 10:39:40 +0100112 * back off.
Myles Watson6bd442f2016-10-19 09:50:22 -0700113 * BUT remember we need to avoid blocking the BTA task execution - hence
114 * we cannot
Kim Schulz8372aa52015-03-25 10:39:40 +0100115 * directly write to the socket.
Myles Watson6bd442f2016-10-19 09:50:22 -0700116 * we should be able to change to store the data pointer here, and just
117 * wait
Kim Schulz8372aa52015-03-25 10:39:40 +0100118 * confirming the l2cap_ind until we have more space in the buffer. */
119
Marie Janssenb7f64bc2016-06-22 12:52:19 -0700120/* returns false if none - caller must free "data" memory when done with it */
Myles Watson6bd442f2016-10-19 09:50:22 -0700121static char packet_get_head_l(l2cap_socket* sock, uint8_t** data,
122 uint32_t* len) {
123 struct packet* p = sock->first_packet;
Kim Schulz8372aa52015-03-25 10:39:40 +0100124
Myles Watson6bd442f2016-10-19 09:50:22 -0700125 if (!p) return false;
Kim Schulz8372aa52015-03-25 10:39:40 +0100126
Myles Watson6bd442f2016-10-19 09:50:22 -0700127 if (data) *data = sock->first_packet->data;
128 if (len) *len = sock->first_packet->len;
129 sock->first_packet = p->next;
130 if (sock->first_packet)
131 sock->first_packet->prev = NULL;
132 else
133 sock->last_packet = NULL;
Kim Schulz8372aa52015-03-25 10:39:40 +0100134
Myles Watson6bd442f2016-10-19 09:50:22 -0700135 if (len) sock->bytes_buffered -= *len;
Kim Schulz8372aa52015-03-25 10:39:40 +0100136
Myles Watson6bd442f2016-10-19 09:50:22 -0700137 osi_free(p);
Kim Schulz8372aa52015-03-25 10:39:40 +0100138
Myles Watson6bd442f2016-10-19 09:50:22 -0700139 return true;
Kim Schulz8372aa52015-03-25 10:39:40 +0100140}
141
Myles Watson6bd442f2016-10-19 09:50:22 -0700142static struct packet* packet_alloc(const uint8_t* data, uint32_t len) {
143 struct packet* p = (struct packet*)osi_calloc(sizeof(*p));
144 uint8_t* buf = (uint8_t*)osi_malloc(len);
Kim Schulz8372aa52015-03-25 10:39:40 +0100145
Myles Watson6bd442f2016-10-19 09:50:22 -0700146 p->data = buf;
147 p->len = len;
148 memcpy(p->data, data, len);
149 return p;
Kim Schulz8372aa52015-03-25 10:39:40 +0100150}
151
Marie Janssenb7f64bc2016-06-22 12:52:19 -0700152/* makes a copy of the data, returns true on success */
Myles Watson6bd442f2016-10-19 09:50:22 -0700153static char packet_put_head_l(l2cap_socket* sock, const void* data,
154 uint32_t len) {
155 struct packet* p = packet_alloc((const uint8_t*)data, len);
Kim Schulz8372aa52015-03-25 10:39:40 +0100156
Myles Watson6bd442f2016-10-19 09:50:22 -0700157 /*
158 * We do not check size limits here since this is used to undo "getting" a
159 * packet that the user read incompletely. That is to say the packet was
160 * already in the queue. We do check thos elimits in packet_put_tail_l() since
161 * that function is used to put new data into the queue.
162 */
Kim Schulz8372aa52015-03-25 10:39:40 +0100163
Myles Watson6bd442f2016-10-19 09:50:22 -0700164 if (!p) return false;
Kim Schulz8372aa52015-03-25 10:39:40 +0100165
Myles Watson6bd442f2016-10-19 09:50:22 -0700166 p->prev = NULL;
167 p->next = sock->first_packet;
168 sock->first_packet = p;
169 if (p->next)
170 p->next->prev = p;
171 else
Kim Schulz8372aa52015-03-25 10:39:40 +0100172 sock->last_packet = p;
Kim Schulz8372aa52015-03-25 10:39:40 +0100173
Myles Watson6bd442f2016-10-19 09:50:22 -0700174 sock->bytes_buffered += len;
Kim Schulz8372aa52015-03-25 10:39:40 +0100175
Myles Watson6bd442f2016-10-19 09:50:22 -0700176 return true;
Kim Schulz8372aa52015-03-25 10:39:40 +0100177}
178
Myles Watson6bd442f2016-10-19 09:50:22 -0700179/* makes a copy of the data, returns true on success */
180static char packet_put_tail_l(l2cap_socket* sock, const void* data,
181 uint32_t len) {
Myles Watson6bd442f2016-10-19 09:50:22 -0700182 if (sock->bytes_buffered >= L2CAP_MAX_RX_BUFFER) {
Jakub Pawlowski35ee0232018-02-02 11:47:09 -0800183 LOG(ERROR) << __func__ << ": buffer overflow";
Myles Watson6bd442f2016-10-19 09:50:22 -0700184 return false;
185 }
186
Jakub Pawlowski35ee0232018-02-02 11:47:09 -0800187 struct packet* p = packet_alloc((const uint8_t*)data, len);
Myles Watson6bd442f2016-10-19 09:50:22 -0700188 p->next = NULL;
189 p->prev = sock->last_packet;
190 sock->last_packet = p;
191 if (p->prev)
192 p->prev->next = p;
193 else
194 sock->first_packet = p;
195
196 sock->bytes_buffered += len;
197
198 return true;
Kim Schulz8372aa52015-03-25 10:39:40 +0100199}
200
Myles Watson6bd442f2016-10-19 09:50:22 -0700201static char is_inited(void) {
202 std::unique_lock<std::mutex> lock(state_lock);
203 return pth != -1;
Kim Schulz8372aa52015-03-25 10:39:40 +0100204}
205
Marie Janssena5764682016-10-10 13:38:30 -0700206/* only call with std::mutex taken */
Myles Watson6bd442f2016-10-19 09:50:22 -0700207static l2cap_socket* btsock_l2cap_find_by_id_l(uint32_t id) {
208 l2cap_socket* sock = socks;
Kim Schulz8372aa52015-03-25 10:39:40 +0100209
Myles Watson6bd442f2016-10-19 09:50:22 -0700210 while (sock && sock->id != id) sock = sock->next;
Kim Schulz8372aa52015-03-25 10:39:40 +0100211
Myles Watson6bd442f2016-10-19 09:50:22 -0700212 return sock;
Kim Schulz8372aa52015-03-25 10:39:40 +0100213}
214
Myles Watson6bd442f2016-10-19 09:50:22 -0700215static void btsock_l2cap_free_l(l2cap_socket* sock) {
216 uint8_t* buf;
217 l2cap_socket* t = socks;
Kim Schulz8372aa52015-03-25 10:39:40 +0100218
Myles Watson6bd442f2016-10-19 09:50:22 -0700219 while (t && t != sock) t = t->next;
Kim Schulz8372aa52015-03-25 10:39:40 +0100220
Myles Watson6bd442f2016-10-19 09:50:22 -0700221 if (!t) /* prever double-frees */
222 return;
Kim Schulz8372aa52015-03-25 10:39:40 +0100223
Jack He83f86832019-02-06 20:24:24 -0800224 // Whenever a socket is freed, the connection must be dropped
225 bluetooth::common::LogSocketConnectionState(
226 sock->addr, sock->id, sock->is_le_coc ? BTSOCK_L2CAP_LE : BTSOCK_L2CAP,
227 android::bluetooth::SOCKET_CONNECTION_STATE_DISCONNECTED, sock->tx_bytes,
228 sock->rx_bytes, sock->app_uid, sock->channel,
229 sock->server ? android::bluetooth::SOCKET_ROLE_LISTEN
230 : android::bluetooth::SOCKET_ROLE_CONNECTION);
231
Myles Watson6bd442f2016-10-19 09:50:22 -0700232 if (sock->next) sock->next->prev = sock->prev;
Kim Schulz8372aa52015-03-25 10:39:40 +0100233
Myles Watson6bd442f2016-10-19 09:50:22 -0700234 if (sock->prev)
235 sock->prev->next = sock->next;
236 else
237 socks = sock->next;
Kim Schulz8372aa52015-03-25 10:39:40 +0100238
Myles Watson6bd442f2016-10-19 09:50:22 -0700239 shutdown(sock->our_fd, SHUT_RDWR);
240 close(sock->our_fd);
241 if (sock->app_fd != -1) {
242 close(sock->app_fd);
243 } else {
Jakub Pawlowski35ee0232018-02-02 11:47:09 -0800244 LOG(ERROR) << "SOCK_LIST: free(id = " << sock->id << ") - NO app_fd!";
Myles Watson6bd442f2016-10-19 09:50:22 -0700245 }
246
247 while (packet_get_head_l(sock, &buf, NULL)) osi_free(buf);
248
249 // lower-level close() should be idempotent... so let's call it and see...
250 if (sock->is_le_coc) {
251 // Only call if we are non server connections
Myles Watsonb749ebd2017-10-06 16:39:05 -0700252 if (sock->handle >= 0 && (!sock->server)) {
Myles Watson6bd442f2016-10-19 09:50:22 -0700253 BTA_JvL2capClose(sock->handle);
Kim Schulz8372aa52015-03-25 10:39:40 +0100254 }
Myles Watsonb749ebd2017-10-06 16:39:05 -0700255 if ((sock->channel >= 0) && (sock->server)) {
Stanley Tng49dd53c2017-12-20 09:38:30 -0800256 BTA_JvFreeChannel(sock->channel, BTA_JV_CONN_TYPE_L2CAP_LE);
Navin Kochar67212322016-03-09 23:11:53 +0530257 }
Myles Watson6bd442f2016-10-19 09:50:22 -0700258 } else {
259 // Only call if we are non server connections
Myles Watsonb749ebd2017-10-06 16:39:05 -0700260 if ((sock->handle >= 0) && (!sock->server)) {
Myles Watson6bd442f2016-10-19 09:50:22 -0700261 if (sock->fixed_chan)
262 BTA_JvL2capCloseLE(sock->handle);
263 else
264 BTA_JvL2capClose(sock->handle);
Kim Schulz8372aa52015-03-25 10:39:40 +0100265 }
Myles Watsonb749ebd2017-10-06 16:39:05 -0700266 if ((sock->channel >= 0) && (sock->server)) {
Myles Watson6bd442f2016-10-19 09:50:22 -0700267 if (sock->fixed_chan)
268 BTA_JvFreeChannel(sock->channel, BTA_JV_CONN_TYPE_L2CAP_LE);
269 else
270 BTA_JvFreeChannel(sock->channel, BTA_JV_CONN_TYPE_L2CAP);
Kim Schulz8372aa52015-03-25 10:39:40 +0100271
Myles Watson6bd442f2016-10-19 09:50:22 -0700272 if (!sock->fixed_chan) {
Jakub Pawlowski35ee0232018-02-02 11:47:09 -0800273 DVLOG(2) << __func__ << ": stopping L2CAP server channel "
274 << sock->channel;
Ajay Panicker531fe1a2016-11-22 13:28:43 -0800275 BTA_JvL2capStopServer(sock->channel, sock->id);
Myles Watson6bd442f2016-10-19 09:50:22 -0700276 }
277 }
278 }
279
Jakub Pawlowski35ee0232018-02-02 11:47:09 -0800280 DVLOG(2) << __func__ << ": free id:" << sock->id;
Myles Watson6bd442f2016-10-19 09:50:22 -0700281 osi_free(sock);
Kim Schulz8372aa52015-03-25 10:39:40 +0100282}
283
Myles Watson6bd442f2016-10-19 09:50:22 -0700284static l2cap_socket* btsock_l2cap_alloc_l(const char* name,
Jakub Pawlowskia484a882017-06-24 17:30:18 -0700285 const RawAddress* addr,
Myles Watson6bd442f2016-10-19 09:50:22 -0700286 char is_server, int flags) {
287 unsigned security = 0;
288 int fds[2];
289 l2cap_socket* sock = (l2cap_socket*)osi_calloc(sizeof(*sock));
Kim Schulz8372aa52015-03-25 10:39:40 +0100290
Myles Watson6bd442f2016-10-19 09:50:22 -0700291 if (flags & BTSOCK_FLAG_ENCRYPT)
292 security |= is_server ? BTM_SEC_IN_ENCRYPT : BTM_SEC_OUT_ENCRYPT;
293 if (flags & BTSOCK_FLAG_AUTH)
294 security |= is_server ? BTM_SEC_IN_AUTHENTICATE : BTM_SEC_OUT_AUTHENTICATE;
295 if (flags & BTSOCK_FLAG_AUTH_MITM)
296 security |= is_server ? BTM_SEC_IN_MITM : BTM_SEC_OUT_MITM;
297 if (flags & BTSOCK_FLAG_AUTH_16_DIGIT)
298 security |= BTM_SEC_IN_MIN_16_DIGIT_PIN;
Kim Schulz8372aa52015-03-25 10:39:40 +0100299
Myles Watson6bd442f2016-10-19 09:50:22 -0700300 if (socketpair(AF_LOCAL, SOCK_SEQPACKET, 0, fds)) {
Jakub Pawlowski35ee0232018-02-02 11:47:09 -0800301 LOG(ERROR) << "socketpair failed, errno:" << errno;
Myles Watson6bd442f2016-10-19 09:50:22 -0700302 goto fail_sockpair;
303 }
304
305 sock->our_fd = fds[0];
306 sock->app_fd = fds[1];
307 sock->security = security;
308 sock->server = is_server;
309 sock->connected = false;
310 sock->handle = 0;
311 sock->server_psm_sent = false;
312 sock->app_uid = -1;
313
314 if (name) strncpy(sock->name, name, sizeof(sock->name) - 1);
315 if (addr) sock->addr = *addr;
316
317 sock->first_packet = NULL;
318 sock->last_packet = NULL;
319
Jakub Pawlowski622bd222018-01-30 15:40:03 -0800320 sock->tx_mtu = L2CAP_LE_MIN_MTU;
Jakub Pawlowski8452b052018-01-05 02:41:36 -0800321
Myles Watson6bd442f2016-10-19 09:50:22 -0700322 sock->next = socks;
323 sock->prev = NULL;
324 if (socks) socks->prev = sock;
325 sock->id = (socks ? socks->id : 0) + 1;
Jack He83f86832019-02-06 20:24:24 -0800326 sock->tx_bytes = 0;
327 sock->rx_bytes = 0;
Myles Watson6bd442f2016-10-19 09:50:22 -0700328 socks = sock;
329 /* paranoia cap on: verify no ID duplicates due to overflow and fix as needed
330 */
331 while (1) {
332 l2cap_socket* t;
333 t = socks->next;
334 while (t && t->id != sock->id) {
335 t = t->next;
Kim Schulz8372aa52015-03-25 10:39:40 +0100336 }
Myles Watson6bd442f2016-10-19 09:50:22 -0700337 if (!t && sock->id) /* non-zeor handle is unique -> we're done */
338 break;
339 /* if we're here, we found a duplicate */
340 if (!++sock->id) /* no zero IDs allowed */
341 sock->id++;
342 }
Jakub Pawlowski35ee0232018-02-02 11:47:09 -0800343 DVLOG(2) << __func__ << " SOCK_LIST: alloc id:" << sock->id;
Myles Watson6bd442f2016-10-19 09:50:22 -0700344 return sock;
Kim Schulz8372aa52015-03-25 10:39:40 +0100345
346fail_sockpair:
Myles Watson6bd442f2016-10-19 09:50:22 -0700347 osi_free(sock);
348 return NULL;
Kim Schulz8372aa52015-03-25 10:39:40 +0100349}
350
Myles Watson6bd442f2016-10-19 09:50:22 -0700351bt_status_t btsock_l2cap_init(int handle, uid_set_t* set) {
Jakub Pawlowski35ee0232018-02-02 11:47:09 -0800352 DVLOG(2) << __func__ << ": handle: " << handle;
Myles Watson6bd442f2016-10-19 09:50:22 -0700353 std::unique_lock<std::mutex> lock(state_lock);
354 pth = handle;
355 socks = NULL;
356 uid_set = set;
357 return BT_STATUS_SUCCESS;
Kim Schulz8372aa52015-03-25 10:39:40 +0100358}
359
Myles Watson6bd442f2016-10-19 09:50:22 -0700360bt_status_t btsock_l2cap_cleanup() {
361 std::unique_lock<std::mutex> lock(state_lock);
362 pth = -1;
363 while (socks) btsock_l2cap_free_l(socks);
364 return BT_STATUS_SUCCESS;
Kim Schulz8372aa52015-03-25 10:39:40 +0100365}
366
Myles Watson6bd442f2016-10-19 09:50:22 -0700367static inline bool send_app_psm_or_chan_l(l2cap_socket* sock) {
Jakub Pawlowski35ee0232018-02-02 11:47:09 -0800368 DVLOG(2) << __func__ << ": channel: " << sock->channel;
Myles Watson6bd442f2016-10-19 09:50:22 -0700369 return sock_send_all(sock->our_fd, (const uint8_t*)&sock->channel,
370 sizeof(sock->channel)) == sizeof(sock->channel);
Kim Schulz8372aa52015-03-25 10:39:40 +0100371}
372
Jakub Pawlowskia484a882017-06-24 17:30:18 -0700373static bool send_app_connect_signal(int fd, const RawAddress* addr, int channel,
Jakub Pawlowski622bd222018-01-30 15:40:03 -0800374 int status, int send_fd, uint16_t rx_mtu,
375 uint16_t tx_mtu) {
Myles Watson6bd442f2016-10-19 09:50:22 -0700376 sock_connect_signal_t cs;
377 cs.size = sizeof(cs);
378 cs.bd_addr = *addr;
379 cs.channel = channel;
380 cs.status = status;
Jakub Pawlowski622bd222018-01-30 15:40:03 -0800381 cs.max_rx_packet_size = rx_mtu;
Myles Watson6bd442f2016-10-19 09:50:22 -0700382 cs.max_tx_packet_size = tx_mtu;
383 if (send_fd != -1) {
384 if (sock_send_fd(fd, (const uint8_t*)&cs, sizeof(cs), send_fd) ==
385 sizeof(cs))
386 return true;
387 else
Jakub Pawlowski35ee0232018-02-02 11:47:09 -0800388 LOG(ERROR) << "sock_send_fd failed, fd: " << fd
389 << ", send_fd:" << send_fd;
Myles Watson6bd442f2016-10-19 09:50:22 -0700390 } else if (sock_send_all(fd, (const uint8_t*)&cs, sizeof(cs)) == sizeof(cs)) {
391 return true;
392 }
393 return false;
Kim Schulz8372aa52015-03-25 10:39:40 +0100394}
395
Myles Watson6bd442f2016-10-19 09:50:22 -0700396static void on_srv_l2cap_listen_started(tBTA_JV_L2CAP_START* p_start,
397 uint32_t id) {
398 l2cap_socket* sock;
Kim Schulz8372aa52015-03-25 10:39:40 +0100399
Myles Watson6bd442f2016-10-19 09:50:22 -0700400 std::unique_lock<std::mutex> lock(state_lock);
401 sock = btsock_l2cap_find_by_id_l(id);
402 if (!sock) return;
Marie Janssena5764682016-10-10 13:38:30 -0700403
Myles Watson6bd442f2016-10-19 09:50:22 -0700404 if (p_start->status != BTA_JV_SUCCESS) {
Jakub Pawlowski35ee0232018-02-02 11:47:09 -0800405 LOG(ERROR) << "Error starting l2cap_listen - status: "
406 << loghex(p_start->status);
Myles Watson6bd442f2016-10-19 09:50:22 -0700407 btsock_l2cap_free_l(sock);
408 return;
409 }
410
411 sock->handle = p_start->handle;
Jakub Pawlowski35ee0232018-02-02 11:47:09 -0800412 DVLOG(2) << __func__ << ": sock->handle: " << sock->handle
413 << ", id: " << sock->id;
Myles Watson6bd442f2016-10-19 09:50:22 -0700414
Jack He83f86832019-02-06 20:24:24 -0800415 bluetooth::common::LogSocketConnectionState(
416 sock->addr, sock->id, sock->is_le_coc ? BTSOCK_L2CAP_LE : BTSOCK_L2CAP,
417 android::bluetooth::SocketConnectionstateEnum::
418 SOCKET_CONNECTION_STATE_LISTENING,
419 0, 0, sock->app_uid, sock->channel,
420 sock->server ? android::bluetooth::SOCKET_ROLE_LISTEN
421 : android::bluetooth::SOCKET_ROLE_CONNECTION);
422
Myles Watsonb749ebd2017-10-06 16:39:05 -0700423 if (!sock->server_psm_sent) {
Myles Watson6bd442f2016-10-19 09:50:22 -0700424 if (!send_app_psm_or_chan_l(sock)) {
425 // closed
Jakub Pawlowski35ee0232018-02-02 11:47:09 -0800426 DVLOG(2) << "send_app_psm() failed, close rs->id: " << sock->id;
Myles Watson6bd442f2016-10-19 09:50:22 -0700427 btsock_l2cap_free_l(sock);
428 } else {
429 sock->server_psm_sent = true;
Marie Janssena5764682016-10-10 13:38:30 -0700430 }
Myles Watson6bd442f2016-10-19 09:50:22 -0700431 }
Kim Schulz8372aa52015-03-25 10:39:40 +0100432}
433
Myles Watson6bd442f2016-10-19 09:50:22 -0700434static void on_cl_l2cap_init(tBTA_JV_L2CAP_CL_INIT* p_init, uint32_t id) {
435 l2cap_socket* sock;
Kim Schulz8372aa52015-03-25 10:39:40 +0100436
Myles Watson6bd442f2016-10-19 09:50:22 -0700437 std::unique_lock<std::mutex> lock(state_lock);
438 sock = btsock_l2cap_find_by_id_l(id);
439 if (!sock) return;
Marie Janssena5764682016-10-10 13:38:30 -0700440
Myles Watson6bd442f2016-10-19 09:50:22 -0700441 if (p_init->status != BTA_JV_SUCCESS) {
442 btsock_l2cap_free_l(sock);
443 return;
444 }
Marie Janssena5764682016-10-10 13:38:30 -0700445
Myles Watson6bd442f2016-10-19 09:50:22 -0700446 sock->handle = p_init->handle;
Kim Schulz8372aa52015-03-25 10:39:40 +0100447}
448
449/**
Myles Watson6bd442f2016-10-19 09:50:22 -0700450 * Here we allocate a new sock instance to mimic the BluetoothSocket. The socket
Jakub Pawlowski8452b052018-01-05 02:41:36 -0800451 * will be a clone of the sock representing the BluetoothServerSocket.
Kim Schulz8372aa52015-03-25 10:39:40 +0100452 * */
Myles Watson6bd442f2016-10-19 09:50:22 -0700453static void on_srv_l2cap_psm_connect_l(tBTA_JV_L2CAP_OPEN* p_open,
454 l2cap_socket* sock) {
Myles Watson6bd442f2016-10-19 09:50:22 -0700455 // std::mutex locked by caller
Jakub Pawlowski622bd222018-01-30 15:40:03 -0800456 l2cap_socket* accept_rs =
457 btsock_l2cap_alloc_l(sock->name, &p_open->rem_bda, false, 0);
Myles Watson6bd442f2016-10-19 09:50:22 -0700458 accept_rs->connected = true;
459 accept_rs->security = sock->security;
460 accept_rs->fixed_chan = sock->fixed_chan;
461 accept_rs->channel = sock->channel;
462 accept_rs->handle = sock->handle;
463 accept_rs->app_uid = sock->app_uid;
464 sock->handle =
465 -1; /* We should no longer associate this handle with the server socket */
466 accept_rs->is_le_coc = sock->is_le_coc;
Jakub Pawlowski622bd222018-01-30 15:40:03 -0800467 accept_rs->tx_mtu = sock->tx_mtu = p_open->tx_mtu;
Kim Schulz8372aa52015-03-25 10:39:40 +0100468
Myles Watson6bd442f2016-10-19 09:50:22 -0700469 /* Swap IDs to hand over the GAP connection to the accepted socket, and start
Jakub Pawlowski622bd222018-01-30 15:40:03 -0800470 a new server on the newly create socket ID. */
471 uint32_t new_listen_id = accept_rs->id;
Myles Watson6bd442f2016-10-19 09:50:22 -0700472 accept_rs->id = sock->id;
473 sock->id = new_listen_id;
474
Jack He83f86832019-02-06 20:24:24 -0800475 bluetooth::common::LogSocketConnectionState(
476 accept_rs->addr, accept_rs->id,
477 accept_rs->is_le_coc ? BTSOCK_L2CAP_LE : BTSOCK_L2CAP,
478 android::bluetooth::SOCKET_CONNECTION_STATE_CONNECTED, 0, 0,
479 accept_rs->app_uid, accept_rs->channel,
480 accept_rs->server ? android::bluetooth::SOCKET_ROLE_LISTEN
481 : android::bluetooth::SOCKET_ROLE_CONNECTION);
482
Jakub Pawlowski622bd222018-01-30 15:40:03 -0800483 // start monitor the socket
484 btsock_thread_add_fd(pth, sock->our_fd, BTSOCK_L2CAP,
485 SOCK_THREAD_FD_EXCEPTION, sock->id);
486 btsock_thread_add_fd(pth, accept_rs->our_fd, BTSOCK_L2CAP, SOCK_THREAD_FD_RD,
487 accept_rs->id);
Jakub Pawlowski35ee0232018-02-02 11:47:09 -0800488 DVLOG(2) << "sending connect signal & app fd: " << accept_rs->app_fd
489 << " to app server to accept() the connection";
490 DVLOG(2) << "server fd: << " << sock->our_fd << ", scn:" << sock->channel;
Jakub Pawlowski622bd222018-01-30 15:40:03 -0800491 send_app_connect_signal(sock->our_fd, &accept_rs->addr, sock->channel, 0,
492 accept_rs->app_fd, sock->rx_mtu, p_open->tx_mtu);
493 accept_rs->app_fd =
494 -1; // The fd is closed after sent to app in send_app_connect_signal()
495 // But for some reason we still leak a FD - either the server socket
496 // one or the accept socket one.
497 btsock_l2cap_server_listen(sock);
Myles Watson6bd442f2016-10-19 09:50:22 -0700498}
499
500static void on_srv_l2cap_le_connect_l(tBTA_JV_L2CAP_LE_OPEN* p_open,
501 l2cap_socket* sock) {
Myles Watson6bd442f2016-10-19 09:50:22 -0700502 // std::mutex locked by caller
Jakub Pawlowski622bd222018-01-30 15:40:03 -0800503 l2cap_socket* accept_rs =
504 btsock_l2cap_alloc_l(sock->name, &p_open->rem_bda, false, 0);
505 if (!accept_rs) return;
Kim Schulz8372aa52015-03-25 10:39:40 +0100506
Jakub Pawlowski622bd222018-01-30 15:40:03 -0800507 // swap IDs
508 uint32_t new_listen_id = accept_rs->id;
509 accept_rs->id = sock->id;
510 sock->id = new_listen_id;
Myles Watson6bd442f2016-10-19 09:50:22 -0700511
Jakub Pawlowski622bd222018-01-30 15:40:03 -0800512 accept_rs->handle = p_open->handle;
513 accept_rs->connected = true;
514 accept_rs->security = sock->security;
515 accept_rs->fixed_chan = sock->fixed_chan;
516 accept_rs->channel = sock->channel;
517 accept_rs->app_uid = sock->app_uid;
518 accept_rs->tx_mtu = sock->tx_mtu = p_open->tx_mtu;
Myles Watson6bd442f2016-10-19 09:50:22 -0700519
Jakub Pawlowski622bd222018-01-30 15:40:03 -0800520 // if we do not set a callback, this socket will be dropped */
521 *(p_open->p_p_cback) = (void*)btsock_l2cap_cbk;
522 *(p_open->p_user_data) = UINT_TO_PTR(accept_rs->id);
523
Jack He83f86832019-02-06 20:24:24 -0800524 bluetooth::common::LogSocketConnectionState(
525 accept_rs->addr, accept_rs->id,
526 accept_rs->is_le_coc ? BTSOCK_L2CAP_LE : BTSOCK_L2CAP,
527 android::bluetooth::SOCKET_CONNECTION_STATE_CONNECTED, 0, 0,
528 accept_rs->app_uid, accept_rs->channel,
529 accept_rs->server ? android::bluetooth::SOCKET_ROLE_LISTEN
530 : android::bluetooth::SOCKET_ROLE_CONNECTION);
531
Jakub Pawlowski622bd222018-01-30 15:40:03 -0800532 // start monitor the socket
533 btsock_thread_add_fd(pth, sock->our_fd, BTSOCK_L2CAP,
534 SOCK_THREAD_FD_EXCEPTION, sock->id);
535 btsock_thread_add_fd(pth, accept_rs->our_fd, BTSOCK_L2CAP, SOCK_THREAD_FD_RD,
536 accept_rs->id);
Jakub Pawlowski35ee0232018-02-02 11:47:09 -0800537 DVLOG(2) << "sending connect signal & app fd: " << accept_rs->app_fd
538 << " to app server to accept() the connection";
539 DVLOG(2) << "server fd: << " << sock->our_fd << ", scn:" << sock->channel;
Jakub Pawlowski622bd222018-01-30 15:40:03 -0800540 send_app_connect_signal(sock->our_fd, &accept_rs->addr, sock->channel, 0,
541 accept_rs->app_fd, sock->rx_mtu, p_open->tx_mtu);
542 accept_rs->app_fd = -1; // the fd is closed after sent to app
Kim Schulz8372aa52015-03-25 10:39:40 +0100543}
544
Myles Watson6bd442f2016-10-19 09:50:22 -0700545static void on_cl_l2cap_psm_connect_l(tBTA_JV_L2CAP_OPEN* p_open,
546 l2cap_socket* sock) {
Jakub Pawlowskia09c3482017-06-16 08:42:05 -0700547 sock->addr = p_open->rem_bda;
Jakub Pawlowski622bd222018-01-30 15:40:03 -0800548 sock->tx_mtu = p_open->tx_mtu;
Kim Schulz8372aa52015-03-25 10:39:40 +0100549
Myles Watson6bd442f2016-10-19 09:50:22 -0700550 if (!send_app_psm_or_chan_l(sock)) {
Jakub Pawlowski35ee0232018-02-02 11:47:09 -0800551 LOG(ERROR) << "send_app_psm_or_chan_l failed";
Myles Watson6bd442f2016-10-19 09:50:22 -0700552 return;
553 }
Kim Schulz8372aa52015-03-25 10:39:40 +0100554
Jakub Pawlowski622bd222018-01-30 15:40:03 -0800555 if (!send_app_connect_signal(sock->our_fd, &sock->addr, sock->channel, 0, -1,
556 sock->rx_mtu, p_open->tx_mtu)) {
Jakub Pawlowski35ee0232018-02-02 11:47:09 -0800557 LOG(ERROR) << "send_app_connect_signal failed";
Jakub Pawlowski622bd222018-01-30 15:40:03 -0800558 return;
559 }
560
Jack He83f86832019-02-06 20:24:24 -0800561 bluetooth::common::LogSocketConnectionState(
562 sock->addr, sock->id, sock->is_le_coc ? BTSOCK_L2CAP_LE : BTSOCK_L2CAP,
563 android::bluetooth::SOCKET_CONNECTION_STATE_CONNECTED, 0, 0,
564 sock->app_uid, sock->channel,
565 sock->server ? android::bluetooth::SOCKET_ROLE_LISTEN
566 : android::bluetooth::SOCKET_ROLE_CONNECTION);
567
Jakub Pawlowski622bd222018-01-30 15:40:03 -0800568 // start monitoring the socketpair to get call back when app writing data
Jakub Pawlowski35ee0232018-02-02 11:47:09 -0800569 DVLOG(2) << " connect signal sent, slot id: " << sock->id
570 << ", chan: " << sock->channel << ", server: " << sock->server;
Jakub Pawlowski622bd222018-01-30 15:40:03 -0800571 btsock_thread_add_fd(pth, sock->our_fd, BTSOCK_L2CAP, SOCK_THREAD_FD_RD,
572 sock->id);
573 sock->connected = true;
Kim Schulz8372aa52015-03-25 10:39:40 +0100574}
575
Myles Watson6bd442f2016-10-19 09:50:22 -0700576static void on_cl_l2cap_le_connect_l(tBTA_JV_L2CAP_LE_OPEN* p_open,
577 l2cap_socket* sock) {
Jakub Pawlowskia09c3482017-06-16 08:42:05 -0700578 sock->addr = p_open->rem_bda;
Jakub Pawlowski622bd222018-01-30 15:40:03 -0800579 sock->tx_mtu = p_open->tx_mtu;
Kim Schulz8372aa52015-03-25 10:39:40 +0100580
Myles Watson6bd442f2016-10-19 09:50:22 -0700581 if (!send_app_psm_or_chan_l(sock)) {
Jakub Pawlowski35ee0232018-02-02 11:47:09 -0800582 LOG(ERROR) << "send_app_psm_or_chan_l failed";
Myles Watson6bd442f2016-10-19 09:50:22 -0700583 return;
584 }
Kim Schulz8372aa52015-03-25 10:39:40 +0100585
Jakub Pawlowski622bd222018-01-30 15:40:03 -0800586 if (!send_app_connect_signal(sock->our_fd, &sock->addr, sock->channel, 0, -1,
587 sock->rx_mtu, p_open->tx_mtu)) {
Jakub Pawlowski35ee0232018-02-02 11:47:09 -0800588 LOG(ERROR) << "send_app_connect_signal failed";
Jakub Pawlowski622bd222018-01-30 15:40:03 -0800589 return;
590 }
591
Jack He83f86832019-02-06 20:24:24 -0800592 bluetooth::common::LogSocketConnectionState(
593 sock->addr, sock->id, sock->is_le_coc ? BTSOCK_L2CAP_LE : BTSOCK_L2CAP,
594 android::bluetooth::SOCKET_CONNECTION_STATE_CONNECTED, 0, 0,
595 sock->app_uid, sock->channel,
596 sock->server ? android::bluetooth::SOCKET_ROLE_LISTEN
597 : android::bluetooth::SOCKET_ROLE_CONNECTION);
598
Jakub Pawlowski622bd222018-01-30 15:40:03 -0800599 // start monitoring the socketpair to get call back when app writing data
Jakub Pawlowski35ee0232018-02-02 11:47:09 -0800600 DVLOG(2) << " connect signal sent, slot id: " << sock->id
601 << ", chan: " << sock->channel << ", server: " << sock->server;
Jakub Pawlowski622bd222018-01-30 15:40:03 -0800602 btsock_thread_add_fd(pth, sock->our_fd, BTSOCK_L2CAP, SOCK_THREAD_FD_RD,
603 sock->id);
604 sock->connected = true;
Kim Schulz8372aa52015-03-25 10:39:40 +0100605}
606
Myles Watson6bd442f2016-10-19 09:50:22 -0700607static void on_l2cap_connect(tBTA_JV* p_data, uint32_t id) {
608 l2cap_socket* sock;
609 tBTA_JV_L2CAP_OPEN* psm_open = &p_data->l2c_open;
610 tBTA_JV_L2CAP_LE_OPEN* le_open = &p_data->l2c_le_open;
Kim Schulz8372aa52015-03-25 10:39:40 +0100611
Myles Watson6bd442f2016-10-19 09:50:22 -0700612 std::unique_lock<std::mutex> lock(state_lock);
613 sock = btsock_l2cap_find_by_id_l(id);
614 if (!sock) {
Jakub Pawlowski35ee0232018-02-02 11:47:09 -0800615 LOG(ERROR) << __func__ << ": unknown socket";
Myles Watson6bd442f2016-10-19 09:50:22 -0700616 return;
617 }
Kim Schulz8372aa52015-03-25 10:39:40 +0100618
Jakub Pawlowski622bd222018-01-30 15:40:03 -0800619 sock->tx_mtu = le_open->tx_mtu;
Myles Watson6bd442f2016-10-19 09:50:22 -0700620 if (sock->fixed_chan && le_open->status == BTA_JV_SUCCESS) {
Jack He83f86832019-02-06 20:24:24 -0800621 if (!sock->server) {
Myles Watson6bd442f2016-10-19 09:50:22 -0700622 on_cl_l2cap_le_connect_l(le_open, sock);
Jack He83f86832019-02-06 20:24:24 -0800623 } else {
Myles Watson6bd442f2016-10-19 09:50:22 -0700624 on_srv_l2cap_le_connect_l(le_open, sock);
Jack He83f86832019-02-06 20:24:24 -0800625 }
Myles Watson6bd442f2016-10-19 09:50:22 -0700626 } else if (!sock->fixed_chan && psm_open->status == BTA_JV_SUCCESS) {
Jack He83f86832019-02-06 20:24:24 -0800627 if (!sock->server) {
Myles Watson6bd442f2016-10-19 09:50:22 -0700628 on_cl_l2cap_psm_connect_l(psm_open, sock);
Jack He83f86832019-02-06 20:24:24 -0800629 } else {
Myles Watson6bd442f2016-10-19 09:50:22 -0700630 on_srv_l2cap_psm_connect_l(psm_open, sock);
Jack He83f86832019-02-06 20:24:24 -0800631 }
632 } else {
Marie Janssena5764682016-10-10 13:38:30 -0700633 btsock_l2cap_free_l(sock);
Jack He83f86832019-02-06 20:24:24 -0800634 }
Kim Schulz8372aa52015-03-25 10:39:40 +0100635}
636
Myles Watson6bd442f2016-10-19 09:50:22 -0700637static void on_l2cap_close(tBTA_JV_L2CAP_CLOSE* p_close, uint32_t id) {
638 l2cap_socket* sock;
Kim Schulz8372aa52015-03-25 10:39:40 +0100639
Myles Watson6bd442f2016-10-19 09:50:22 -0700640 std::unique_lock<std::mutex> lock(state_lock);
641 sock = btsock_l2cap_find_by_id_l(id);
642 if (!sock) return;
Kim Schulz8372aa52015-03-25 10:39:40 +0100643
Jack He83f86832019-02-06 20:24:24 -0800644 bluetooth::common::LogSocketConnectionState(
645 sock->addr, sock->id, sock->is_le_coc ? BTSOCK_L2CAP_LE : BTSOCK_L2CAP,
646 android::bluetooth::SOCKET_CONNECTION_STATE_DISCONNECTING, 0, 0,
647 sock->app_uid, sock->channel,
648 sock->server ? android::bluetooth::SOCKET_ROLE_LISTEN
649 : android::bluetooth::SOCKET_ROLE_CONNECTION);
650
Jakub Pawlowski35ee0232018-02-02 11:47:09 -0800651 DVLOG(2) << __func__ << ": slot id: " << sock->id << ", fd: " << sock->our_fd
652 << (sock->fixed_chan ? ", fixed_chan:" : ", PSM: ") << sock->channel
653 << ", server:" << sock->server;
Myles Watson6bd442f2016-10-19 09:50:22 -0700654 // TODO: This does not seem to be called...
655 // I'm not sure if this will be called for non-server sockets?
Myles Watsonb749ebd2017-10-06 16:39:05 -0700656 if (!sock->fixed_chan && (sock->server)) {
Myles Watson6bd442f2016-10-19 09:50:22 -0700657 BTA_JvFreeChannel(sock->channel, BTA_JV_CONN_TYPE_L2CAP);
658 }
659 btsock_l2cap_free_l(sock);
Kim Schulz8372aa52015-03-25 10:39:40 +0100660}
661
Myles Watson6bd442f2016-10-19 09:50:22 -0700662static void on_l2cap_outgoing_congest(tBTA_JV_L2CAP_CONG* p, uint32_t id) {
663 l2cap_socket* sock;
Kim Schulz8372aa52015-03-25 10:39:40 +0100664
Myles Watson6bd442f2016-10-19 09:50:22 -0700665 std::unique_lock<std::mutex> lock(state_lock);
666 sock = btsock_l2cap_find_by_id_l(id);
667 if (!sock) return;
Kim Schulz8372aa52015-03-25 10:39:40 +0100668
Myles Watson6bd442f2016-10-19 09:50:22 -0700669 sock->outgoing_congest = p->cong ? 1 : 0;
670 // mointer the fd for any outgoing data
671 if (!sock->outgoing_congest) {
Jakub Pawlowski35ee0232018-02-02 11:47:09 -0800672 DVLOG(2) << __func__ << ": adding fd to btsock_thread...";
Myles Watson6bd442f2016-10-19 09:50:22 -0700673 btsock_thread_add_fd(pth, sock->our_fd, BTSOCK_L2CAP, SOCK_THREAD_FD_RD,
674 sock->id);
675 }
Kim Schulz8372aa52015-03-25 10:39:40 +0100676}
677
Jakub Pawlowskic4743422018-01-11 07:34:39 -0800678static void on_l2cap_write_done(uint16_t len, uint32_t id) {
Myles Watson6bd442f2016-10-19 09:50:22 -0700679 std::unique_lock<std::mutex> lock(state_lock);
Jakub Pawlowski19d30612018-01-08 01:23:52 -0800680 l2cap_socket* sock = btsock_l2cap_find_by_id_l(id);
Myles Watson6bd442f2016-10-19 09:50:22 -0700681 if (!sock) return;
682
Jakub Pawlowski19d30612018-01-08 01:23:52 -0800683 int app_uid = sock->app_uid;
Myles Watson6bd442f2016-10-19 09:50:22 -0700684 if (!sock->outgoing_congest) {
685 // monitor the fd for any outgoing data
Jakub Pawlowski35ee0232018-02-02 11:47:09 -0800686 DVLOG(2) << __func__ << ": adding fd to btsock_thread...";
Myles Watson6bd442f2016-10-19 09:50:22 -0700687 btsock_thread_add_fd(pth, sock->our_fd, BTSOCK_L2CAP, SOCK_THREAD_FD_RD,
688 sock->id);
689 }
690
Jack He83f86832019-02-06 20:24:24 -0800691 sock->tx_bytes += len;
Myles Watson6bd442f2016-10-19 09:50:22 -0700692 uid_set_add_tx(uid_set, app_uid, len);
Kim Schulz8372aa52015-03-25 10:39:40 +0100693}
694
Myles Watson6bd442f2016-10-19 09:50:22 -0700695static void on_l2cap_data_ind(tBTA_JV* evt, uint32_t id) {
696 l2cap_socket* sock;
Kim Schulz8372aa52015-03-25 10:39:40 +0100697
Myles Watson6bd442f2016-10-19 09:50:22 -0700698 int app_uid = -1;
699 uint32_t bytes_read = 0;
Kim Schulz8372aa52015-03-25 10:39:40 +0100700
Myles Watson6bd442f2016-10-19 09:50:22 -0700701 std::unique_lock<std::mutex> lock(state_lock);
702 sock = btsock_l2cap_find_by_id_l(id);
703 if (!sock) return;
704
705 app_uid = sock->app_uid;
706
707 if (sock->fixed_chan) { /* we do these differently */
708
709 tBTA_JV_LE_DATA_IND* p_le_data_ind = &evt->le_data_ind;
710 BT_HDR* p_buf = p_le_data_ind->p_buf;
711 uint8_t* data = (uint8_t*)(p_buf + 1) + p_buf->offset;
712
713 if (packet_put_tail_l(sock, data, p_buf->len)) {
714 bytes_read = p_buf->len;
715 btsock_thread_add_fd(pth, sock->our_fd, BTSOCK_L2CAP, SOCK_THREAD_FD_WR,
716 sock->id);
717 } else { // connection must be dropped
Jakub Pawlowski35ee0232018-02-02 11:47:09 -0800718 DVLOG(2) << __func__
719 << ": unable to push data to socket - closing fixed channel";
Myles Watson6bd442f2016-10-19 09:50:22 -0700720 BTA_JvL2capCloseLE(sock->handle);
721 btsock_l2cap_free_l(sock);
722 }
723
724 } else {
Myles Watson6bd442f2016-10-19 09:50:22 -0700725 uint32_t count;
726
727 if (BTA_JvL2capReady(sock->handle, &count) == BTA_JV_SUCCESS) {
Jakub Pawlowskif47bfde2018-01-29 13:54:24 -0800728 std::vector<uint8_t> buffer(count);
729 if (BTA_JvL2capRead(sock->handle, sock->id, buffer.data(), count) ==
Myles Watson6bd442f2016-10-19 09:50:22 -0700730 BTA_JV_SUCCESS) {
Jakub Pawlowskif47bfde2018-01-29 13:54:24 -0800731 if (packet_put_tail_l(sock, buffer.data(), count)) {
Myles Watson6bd442f2016-10-19 09:50:22 -0700732 bytes_read = count;
733 btsock_thread_add_fd(pth, sock->our_fd, BTSOCK_L2CAP,
734 SOCK_THREAD_FD_WR, sock->id);
735 } else { // connection must be dropped
Jakub Pawlowski35ee0232018-02-02 11:47:09 -0800736 DVLOG(2) << __func__
737 << ": unable to push data to socket - closing channel";
Myles Watson6bd442f2016-10-19 09:50:22 -0700738 BTA_JvL2capClose(sock->handle);
739 btsock_l2cap_free_l(sock);
Marie Janssena5764682016-10-10 13:38:30 -0700740 }
Myles Watson6bd442f2016-10-19 09:50:22 -0700741 }
Kim Schulz8372aa52015-03-25 10:39:40 +0100742 }
Myles Watson6bd442f2016-10-19 09:50:22 -0700743 }
Adam Lesinski0620f972015-12-02 22:15:08 -0800744
Jack He83f86832019-02-06 20:24:24 -0800745 sock->rx_bytes += bytes_read;
Myles Watson6bd442f2016-10-19 09:50:22 -0700746 uid_set_add_rx(uid_set, app_uid, bytes_read);
Kim Schulz8372aa52015-03-25 10:39:40 +0100747}
748
Myles Watson6bd442f2016-10-19 09:50:22 -0700749static void btsock_l2cap_cbk(tBTA_JV_EVT event, tBTA_JV* p_data,
Ajay Panicker531fe1a2016-11-22 13:28:43 -0800750 uint32_t l2cap_socket_id) {
Myles Watson6bd442f2016-10-19 09:50:22 -0700751 switch (event) {
Kim Schulz8372aa52015-03-25 10:39:40 +0100752 case BTA_JV_L2CAP_START_EVT:
Ajay Panicker531fe1a2016-11-22 13:28:43 -0800753 on_srv_l2cap_listen_started(&p_data->l2c_start, l2cap_socket_id);
Myles Watson6bd442f2016-10-19 09:50:22 -0700754 break;
Kim Schulz8372aa52015-03-25 10:39:40 +0100755
756 case BTA_JV_L2CAP_CL_INIT_EVT:
Ajay Panicker531fe1a2016-11-22 13:28:43 -0800757 on_cl_l2cap_init(&p_data->l2c_cl_init, l2cap_socket_id);
Myles Watson6bd442f2016-10-19 09:50:22 -0700758 break;
Kim Schulz8372aa52015-03-25 10:39:40 +0100759
760 case BTA_JV_L2CAP_OPEN_EVT:
Ajay Panicker531fe1a2016-11-22 13:28:43 -0800761 on_l2cap_connect(p_data, l2cap_socket_id);
Myles Watson6bd442f2016-10-19 09:50:22 -0700762 BTA_JvSetPmProfile(p_data->l2c_open.handle, BTA_JV_PM_ID_1,
763 BTA_JV_CONN_OPEN);
764 break;
Kim Schulz8372aa52015-03-25 10:39:40 +0100765
766 case BTA_JV_L2CAP_CLOSE_EVT:
Jakub Pawlowski35ee0232018-02-02 11:47:09 -0800767 DVLOG(2) << "BTA_JV_L2CAP_CLOSE_EVT: id: " << l2cap_socket_id;
Ajay Panicker531fe1a2016-11-22 13:28:43 -0800768 on_l2cap_close(&p_data->l2c_close, l2cap_socket_id);
Myles Watson6bd442f2016-10-19 09:50:22 -0700769 break;
Kim Schulz8372aa52015-03-25 10:39:40 +0100770
771 case BTA_JV_L2CAP_DATA_IND_EVT:
Ajay Panicker531fe1a2016-11-22 13:28:43 -0800772 on_l2cap_data_ind(p_data, l2cap_socket_id);
Jakub Pawlowski35ee0232018-02-02 11:47:09 -0800773 DVLOG(2) << "BTA_JV_L2CAP_DATA_IND_EVT";
Myles Watson6bd442f2016-10-19 09:50:22 -0700774 break;
Kim Schulz8372aa52015-03-25 10:39:40 +0100775
776 case BTA_JV_L2CAP_READ_EVT:
Jakub Pawlowski35ee0232018-02-02 11:47:09 -0800777 DVLOG(2) << "BTA_JV_L2CAP_READ_EVT not used";
Myles Watson6bd442f2016-10-19 09:50:22 -0700778 break;
Kim Schulz8372aa52015-03-25 10:39:40 +0100779
Kim Schulz8372aa52015-03-25 10:39:40 +0100780 case BTA_JV_L2CAP_WRITE_EVT:
Jakub Pawlowski35ee0232018-02-02 11:47:09 -0800781 DVLOG(2) << "BTA_JV_L2CAP_WRITE_EVT: id: " << l2cap_socket_id;
Jakub Pawlowskic4743422018-01-11 07:34:39 -0800782 on_l2cap_write_done(p_data->l2c_write.len, l2cap_socket_id);
Myles Watson6bd442f2016-10-19 09:50:22 -0700783 break;
Kim Schulz8372aa52015-03-25 10:39:40 +0100784
785 case BTA_JV_L2CAP_WRITE_FIXED_EVT:
Jakub Pawlowski35ee0232018-02-02 11:47:09 -0800786 DVLOG(2) << "BTA_JV_L2CAP_WRITE_FIXED_EVT: id: " << l2cap_socket_id;
Jakub Pawlowskic4743422018-01-11 07:34:39 -0800787 on_l2cap_write_done(p_data->l2c_write.len, l2cap_socket_id);
Myles Watson6bd442f2016-10-19 09:50:22 -0700788 break;
Kim Schulz8372aa52015-03-25 10:39:40 +0100789
790 case BTA_JV_L2CAP_CONG_EVT:
Ajay Panicker531fe1a2016-11-22 13:28:43 -0800791 on_l2cap_outgoing_congest(&p_data->l2c_cong, l2cap_socket_id);
Myles Watson6bd442f2016-10-19 09:50:22 -0700792 break;
Kim Schulz8372aa52015-03-25 10:39:40 +0100793
794 default:
Jakub Pawlowski35ee0232018-02-02 11:47:09 -0800795 LOG(ERROR) << "unhandled event: " << event
796 << ", slot id: " << l2cap_socket_id;
Myles Watson6bd442f2016-10-19 09:50:22 -0700797 break;
798 }
Kim Schulz8372aa52015-03-25 10:39:40 +0100799}
800
801/* L2CAP default options for OBEX socket connections */
Myles Watsonf4548162016-10-19 09:53:56 -0700802const tL2CAP_FCR_OPTS obex_l2c_fcr_opts_def = {
803 L2CAP_FCR_ERTM_MODE, /* Mandatory for OBEX over l2cap */
804 OBX_FCR_OPT_TX_WINDOW_SIZE_BR_EDR, /* Tx window size */
805 OBX_FCR_OPT_MAX_TX_B4_DISCNT, /* Maximum transmissions before
806 disconnecting */
807 OBX_FCR_OPT_RETX_TOUT, /* Retransmission timeout (2 secs) */
808 OBX_FCR_OPT_MONITOR_TOUT, /* Monitor timeout (12 secs) */
809 OBX_FCR_OPT_MAX_PDU_SIZE /* MPS segment size */
Kim Schulz8372aa52015-03-25 10:39:40 +0100810};
Myles Watson6bd442f2016-10-19 09:50:22 -0700811const tL2CAP_ERTM_INFO obex_l2c_etm_opt = {
812 L2CAP_FCR_ERTM_MODE, /* Mandatory for OBEX over l2cap */
813 L2CAP_FCR_CHAN_OPT_ERTM, /* Mandatory for OBEX over l2cap */
814 OBX_USER_RX_BUF_SIZE, OBX_USER_TX_BUF_SIZE,
815 OBX_FCR_RX_BUF_SIZE, OBX_FCR_TX_BUF_SIZE};
Kim Schulz8372aa52015-03-25 10:39:40 +0100816
817/**
Myles Watson6bd442f2016-10-19 09:50:22 -0700818 * When using a dynamic PSM, a PSM allocation is requested from
819 * btsock_l2cap_listen_or_connect().
820 * The PSM allocation event is refeived in the JV-callback - currently located
821 * in RFC-code -
Kim Schulz8372aa52015-03-25 10:39:40 +0100822 * and this function is called with the newly allocated PSM.
823 */
824void on_l2cap_psm_assigned(int id, int psm) {
Myles Watson6bd442f2016-10-19 09:50:22 -0700825 /* Setup ETM settings:
826 * mtu will be set below */
827 std::unique_lock<std::mutex> lock(state_lock);
828 l2cap_socket* sock = btsock_l2cap_find_by_id_l(id);
829 if (!sock) {
Jakub Pawlowski35ee0232018-02-02 11:47:09 -0800830 LOG(ERROR) << __func__ << ": sock is null";
Myles Watson6bd442f2016-10-19 09:50:22 -0700831 return;
832 }
Kim Schulz8372aa52015-03-25 10:39:40 +0100833
Myles Watson6bd442f2016-10-19 09:50:22 -0700834 sock->channel = psm;
Marie Janssena5764682016-10-10 13:38:30 -0700835
Jakub Pawlowskie5e2dd52018-01-30 21:46:08 -0800836 btsock_l2cap_server_listen(sock);
Kim Schulz8372aa52015-03-25 10:39:40 +0100837}
838
Jakub Pawlowskie5e2dd52018-01-30 21:46:08 -0800839static void btsock_l2cap_server_listen(l2cap_socket* sock) {
Jakub Pawlowski35ee0232018-02-02 11:47:09 -0800840 DVLOG(2) << __func__ << ": fixed_chan: " << sock->fixed_chan
841 << ", channel: " << sock->channel
842 << ", is_le_coc: " << sock->is_le_coc;
Stanley Tng49dd53c2017-12-20 09:38:30 -0800843
Myles Watson6bd442f2016-10-19 09:50:22 -0700844 if (sock->fixed_chan) {
Jakub Pawlowskie5e2dd52018-01-30 21:46:08 -0800845 BTA_JvL2capStartServerLE(sock->channel, btsock_l2cap_cbk, sock->id);
846 return;
Myles Watson6bd442f2016-10-19 09:50:22 -0700847 }
Jakub Pawlowskie5e2dd52018-01-30 21:46:08 -0800848
849 int connection_type =
850 sock->is_le_coc ? BTA_JV_CONN_TYPE_L2CAP_LE : BTA_JV_CONN_TYPE_L2CAP;
851
852 /* If we have a channel specified in the request, just start the server,
853 * else we request a PSM and start the server after we receive a PSM. */
854 if (sock->channel <= 0) {
855 BTA_JvGetChannelId(connection_type, sock->id, 0);
856 return;
857 }
858
Jakub Pawlowski3538b642018-01-30 22:35:11 -0800859 /* Setup ETM settings: mtu will be set below */
Jakub Pawlowskie5e2dd52018-01-30 21:46:08 -0800860 std::unique_ptr<tL2CAP_CFG_INFO> cfg = std::make_unique<tL2CAP_CFG_INFO>(
861 tL2CAP_CFG_INFO{.fcr_present = true, .fcr = obex_l2c_fcr_opts_def});
862
863 std::unique_ptr<tL2CAP_ERTM_INFO> ertm_info;
864 if (!sock->is_le_coc) {
865 ertm_info.reset(new tL2CAP_ERTM_INFO(obex_l2c_etm_opt));
866 }
867
Jakub Pawlowski622bd222018-01-30 15:40:03 -0800868 BTA_JvL2capStartServer(connection_type, sock->security, 0,
869 std::move(ertm_info), sock->channel, sock->rx_mtu,
870 std::move(cfg), btsock_l2cap_cbk, sock->id);
Myles Watson6bd442f2016-10-19 09:50:22 -0700871}
872
873static bt_status_t btsock_l2cap_listen_or_connect(const char* name,
Jakub Pawlowskia484a882017-06-24 17:30:18 -0700874 const RawAddress* addr,
Myles Watson6bd442f2016-10-19 09:50:22 -0700875 int channel, int* sock_fd,
876 int flags, char listen,
877 int app_uid) {
Myles Watson6bd442f2016-10-19 09:50:22 -0700878 int fixed_chan = 1;
Myles Watson6bd442f2016-10-19 09:50:22 -0700879 bool is_le_coc = false;
880
881 if (!sock_fd) return BT_STATUS_PARM_INVALID;
882
883 if (channel < 0) {
884 // We need to auto assign a PSM
885 fixed_chan = 0;
886 } else {
Stanley Tnga34e9b42018-01-05 09:25:11 -0800887 is_le_coc = (flags & BTSOCK_FLAG_LE_COC) != 0;
Myles Watson6bd442f2016-10-19 09:50:22 -0700888 fixed_chan = (channel & L2CAP_MASK_FIXED_CHANNEL) != 0;
Stanley Tnga34e9b42018-01-05 09:25:11 -0800889 channel &= ~L2CAP_MASK_FIXED_CHANNEL;
Myles Watson6bd442f2016-10-19 09:50:22 -0700890 }
891
892 if (!is_inited()) return BT_STATUS_NOT_READY;
893
894 // TODO: This is kind of bad to lock here, but it is needed for the current
895 // design.
896 std::unique_lock<std::mutex> lock(state_lock);
Jakub Pawlowski3538b642018-01-30 22:35:11 -0800897 l2cap_socket* sock = btsock_l2cap_alloc_l(name, addr, listen, flags);
Myles Watson6bd442f2016-10-19 09:50:22 -0700898 if (!sock) {
899 return BT_STATUS_NOMEM;
900 }
901
902 sock->fixed_chan = fixed_chan;
903 sock->channel = channel;
904 sock->app_uid = app_uid;
905 sock->is_le_coc = is_le_coc;
Jakub Pawlowski622bd222018-01-30 15:40:03 -0800906 sock->rx_mtu = is_le_coc ? L2CAP_SDU_LENGTH_LE_MAX : L2CAP_SDU_LENGTH_MAX;
Myles Watson6bd442f2016-10-19 09:50:22 -0700907
Myles Watson6bd442f2016-10-19 09:50:22 -0700908 /* "role" is never initialized in rfcomm code */
909 if (listen) {
Jakub Pawlowskie5e2dd52018-01-30 21:46:08 -0800910 btsock_l2cap_server_listen(sock);
Myles Watson6bd442f2016-10-19 09:50:22 -0700911 } else {
912 if (fixed_chan) {
Jakub Pawlowski3538b642018-01-30 22:35:11 -0800913 BTA_JvL2capConnectLE(channel, sock->addr, btsock_l2cap_cbk, sock->id);
Kim Schulz8372aa52015-03-25 10:39:40 +0100914 } else {
Jakub Pawlowski3538b642018-01-30 22:35:11 -0800915 int connection_type =
916 sock->is_le_coc ? BTA_JV_CONN_TYPE_L2CAP_LE : BTA_JV_CONN_TYPE_L2CAP;
917
918 /* Setup ETM settings: mtu will be set below */
919 std::unique_ptr<tL2CAP_CFG_INFO> cfg = std::make_unique<tL2CAP_CFG_INFO>(
920 tL2CAP_CFG_INFO{.fcr_present = true, .fcr = obex_l2c_fcr_opts_def});
921
922 std::unique_ptr<tL2CAP_ERTM_INFO> ertm_info;
923 if (!sock->is_le_coc) {
924 ertm_info.reset(new tL2CAP_ERTM_INFO(obex_l2c_etm_opt));
Myles Watson6bd442f2016-10-19 09:50:22 -0700925 }
Jakub Pawlowski3538b642018-01-30 22:35:11 -0800926
Jakub Pawlowski622bd222018-01-30 15:40:03 -0800927 BTA_JvL2capConnect(
928 connection_type, sock->security, 0, std::move(ertm_info), channel,
929 sock->rx_mtu, std::move(cfg), sock->addr, btsock_l2cap_cbk, sock->id);
Kim Schulz8372aa52015-03-25 10:39:40 +0100930 }
Myles Watson6bd442f2016-10-19 09:50:22 -0700931 }
932
Jakub Pawlowski8ba54322017-10-30 12:38:30 -0700933 *sock_fd = sock->app_fd;
934 /* We pass the FD to JAVA, but since it runs in another process, we need to
935 * also close it in native, either straight away, as done when accepting an
936 * incoming connection, or when doing cleanup after this socket */
937 sock->app_fd = -1;
938 /*This leaks the file descriptor. The FD should be closed in JAVA but it
939 * apparently do not work */
940 btsock_thread_add_fd(pth, sock->our_fd, BTSOCK_L2CAP,
941 SOCK_THREAD_FD_EXCEPTION, sock->id);
Myles Watson6bd442f2016-10-19 09:50:22 -0700942
Jakub Pawlowski8ba54322017-10-30 12:38:30 -0700943 return BT_STATUS_SUCCESS;
Kim Schulz8372aa52015-03-25 10:39:40 +0100944}
945
Myles Watson6bd442f2016-10-19 09:50:22 -0700946bt_status_t btsock_l2cap_listen(const char* name, int channel, int* sock_fd,
947 int flags, int app_uid) {
948 return btsock_l2cap_listen_or_connect(name, NULL, channel, sock_fd, flags, 1,
949 app_uid);
Kim Schulz8372aa52015-03-25 10:39:40 +0100950}
951
Jakub Pawlowskia484a882017-06-24 17:30:18 -0700952bt_status_t btsock_l2cap_connect(const RawAddress* bd_addr, int channel,
Myles Watson6bd442f2016-10-19 09:50:22 -0700953 int* sock_fd, int flags, int app_uid) {
954 return btsock_l2cap_listen_or_connect(NULL, bd_addr, channel, sock_fd, flags,
955 0, app_uid);
Kim Schulz8372aa52015-03-25 10:39:40 +0100956}
957
Myles Watson6bd442f2016-10-19 09:50:22 -0700958/* return true if we have more to send and should wait for user readiness, false
959 * else
Kim Schulz8372aa52015-03-25 10:39:40 +0100960 * (for example: unrecoverable error or no data)
961 */
Myles Watson6bd442f2016-10-19 09:50:22 -0700962static bool flush_incoming_que_on_wr_signal_l(l2cap_socket* sock) {
963 uint8_t* buf;
964 uint32_t len;
Kim Schulz8372aa52015-03-25 10:39:40 +0100965
Myles Watson6bd442f2016-10-19 09:50:22 -0700966 while (packet_get_head_l(sock, &buf, &len)) {
967 ssize_t sent;
968 OSI_NO_INTR(sent = send(sock->our_fd, buf, len, MSG_DONTWAIT));
969 int saved_errno = errno;
Kim Schulz8372aa52015-03-25 10:39:40 +0100970
Myles Watson6bd442f2016-10-19 09:50:22 -0700971 if (sent == (signed)len)
972 osi_free(buf);
973 else if (sent >= 0) {
974 packet_put_head_l(sock, buf + sent, len - sent);
975 osi_free(buf);
976 if (!sent) /* special case if other end not keeping up */
977 return true;
978 } else {
979 packet_put_head_l(sock, buf, len);
980 osi_free(buf);
981 return saved_errno == EWOULDBLOCK || saved_errno == EAGAIN;
Kim Schulz8372aa52015-03-25 10:39:40 +0100982 }
Myles Watson6bd442f2016-10-19 09:50:22 -0700983 }
Kim Schulz8372aa52015-03-25 10:39:40 +0100984
Myles Watson6bd442f2016-10-19 09:50:22 -0700985 return false;
Kim Schulz8372aa52015-03-25 10:39:40 +0100986}
987
Jakub Pawlowski84519312018-01-12 06:22:43 -0800988inline BT_HDR* malloc_l2cap_buf(uint16_t len) {
989 // We need FCS only for L2CAP_FCR_ERTM_MODE, but it's just 2 bytes so it's ok
990 BT_HDR* msg = (BT_HDR*)osi_malloc(BT_HDR_SIZE + L2CAP_MIN_OFFSET + len +
991 L2CAP_FCS_LENGTH);
992 msg->offset = L2CAP_MIN_OFFSET;
993 msg->len = len;
994 return msg;
995}
996
997inline uint8_t* get_l2cap_sdu_start_ptr(BT_HDR* msg) {
998 return (uint8_t*)(msg) + BT_HDR_SIZE + msg->offset;
999}
1000
Myles Watson6bd442f2016-10-19 09:50:22 -07001001void btsock_l2cap_signaled(int fd, int flags, uint32_t user_id) {
Myles Watson6bd442f2016-10-19 09:50:22 -07001002 char drop_it = false;
Kim Schulz8372aa52015-03-25 10:39:40 +01001003
Myles Watson6bd442f2016-10-19 09:50:22 -07001004 /* We use MSG_DONTWAIT when sending data to JAVA, hence it can be accepted to
1005 * hold the lock. */
1006 std::unique_lock<std::mutex> lock(state_lock);
Jakub Pawlowski8452b052018-01-05 02:41:36 -08001007 l2cap_socket* sock = btsock_l2cap_find_by_id_l(user_id);
Myles Watson6bd442f2016-10-19 09:50:22 -07001008 if (!sock) return;
Kim Schulz8372aa52015-03-25 10:39:40 +01001009
Myles Watson6bd442f2016-10-19 09:50:22 -07001010 if ((flags & SOCK_THREAD_FD_RD) && !sock->server) {
1011 // app sending data
1012 if (sock->connected) {
1013 int size = 0;
Jakub Pawlowski8452b052018-01-05 02:41:36 -08001014 bool ioctl_success = ioctl(sock->our_fd, FIONREAD, &size) == 0;
1015 if (!(flags & SOCK_THREAD_FD_EXCEPTION) || (ioctl_success && size)) {
1016 /* FIONREAD return number of bytes that are immediately available for
1017 reading, might be bigger than awaiting packet.
Arman Uguraybb954522015-06-02 21:11:07 -07001018
Jakub Pawlowski8452b052018-01-05 02:41:36 -08001019 BluetoothSocket.write(...) guarantees that any packet send to this
Jakub Pawlowski6ee309d2018-01-30 19:39:52 -08001020 socket is broken into pieces no bigger than MTU bytes (as requested
Jakub Pawlowski8452b052018-01-05 02:41:36 -08001021 by BT spec). */
Jakub Pawlowski622bd222018-01-30 15:40:03 -08001022 size = std::min(size, (int)sock->tx_mtu);
Jakub Pawlowski8452b052018-01-05 02:41:36 -08001023
Jakub Pawlowski84519312018-01-12 06:22:43 -08001024 BT_HDR* buffer = malloc_l2cap_buf(size);
Myles Watson6bd442f2016-10-19 09:50:22 -07001025 /* The socket is created with SOCK_SEQPACKET, hence we read one message
Jakub Pawlowski8452b052018-01-05 02:41:36 -08001026 * at the time. */
Myles Watson6bd442f2016-10-19 09:50:22 -07001027 ssize_t count;
Jakub Pawlowski84519312018-01-12 06:22:43 -08001028 OSI_NO_INTR(count = recv(fd, get_l2cap_sdu_start_ptr(buffer), size,
Jakub Pawlowski8452b052018-01-05 02:41:36 -08001029 MSG_NOSIGNAL | MSG_DONTWAIT | MSG_TRUNC));
Jakub Pawlowski622bd222018-01-30 15:40:03 -08001030 if (count > sock->tx_mtu) {
Jakub Pawlowski8452b052018-01-05 02:41:36 -08001031 /* This can't happen thanks to check in BluetoothSocket.java but leave
1032 * this in case this socket is ever used anywhere else*/
Jakub Pawlowski6ee309d2018-01-30 19:39:52 -08001033 LOG(ERROR) << "recv more than MTU. Data will be lost: " << count;
Jakub Pawlowski622bd222018-01-30 15:40:03 -08001034 count = sock->tx_mtu;
Jakub Pawlowski8452b052018-01-05 02:41:36 -08001035 }
1036
Stanley Tng44922882018-01-25 11:40:35 -08001037 /* When multiple packets smaller than MTU are flushed to the socket, the
1038 size of the single packet read could be smaller than the ioctl
1039 reported total size of awaiting packets. Hence, we adjust the buffer
1040 length. */
1041 buffer->len = count;
Jakub Pawlowski8452b052018-01-05 02:41:36 -08001042 DVLOG(2) << __func__ << ": bytes received from socket: " << count;
Marie Janssena5764682016-10-10 13:38:30 -07001043
Myles Watson6bd442f2016-10-19 09:50:22 -07001044 if (sock->fixed_chan) {
Jakub Pawlowskic4743422018-01-11 07:34:39 -08001045 // will take care of freeing buffer
1046 BTA_JvL2capWriteFixed(sock->channel, sock->addr, PTR_TO_UINT(buffer),
Jakub Pawlowski84519312018-01-12 06:22:43 -08001047 btsock_l2cap_cbk, buffer, user_id);
Myles Watson6bd442f2016-10-19 09:50:22 -07001048 } else {
Jakub Pawlowskic4743422018-01-11 07:34:39 -08001049 // will take care of freeing buffer
Jakub Pawlowski84519312018-01-12 06:22:43 -08001050 BTA_JvL2capWrite(sock->handle, PTR_TO_UINT(buffer), buffer, user_id);
Myles Watson6bd442f2016-10-19 09:50:22 -07001051 }
1052 }
1053 } else
1054 drop_it = true;
1055 }
1056 if (flags & SOCK_THREAD_FD_WR) {
1057 // app is ready to receive more data, tell stack to enable the data flow
1058 if (flush_incoming_que_on_wr_signal_l(sock) && sock->connected)
1059 btsock_thread_add_fd(pth, sock->our_fd, BTSOCK_L2CAP, SOCK_THREAD_FD_WR,
1060 sock->id);
1061 }
1062 if (drop_it || (flags & SOCK_THREAD_FD_EXCEPTION)) {
1063 int size = 0;
1064 if (drop_it || ioctl(sock->our_fd, FIONREAD, &size) != 0 || size == 0)
1065 btsock_l2cap_free_l(sock);
1066 }
Kim Schulz8372aa52015-03-25 10:39:40 +01001067}