blob: 9dcfd7b2fd88409f3924a2bf05d9cc1645522883 [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#define LOG_TAG "bt_btif_sock"
19
20#include "btif_sock_l2cap.h"
21
Marie Janssendb554582015-06-26 14:53:46 -070022#include <errno.h>
Marie Janssendb554582015-06-26 14:53:46 -070023#include <stdlib.h>
24#include <sys/ioctl.h>
25#include <sys/socket.h>
26#include <sys/types.h>
27#include <unistd.h>
Jakub Pawlowskif47bfde2018-01-29 13:54:24 -080028#include <vector>
Marie Janssendb554582015-06-26 14:53:46 -070029
Marie Janssena5764682016-10-10 13:38:30 -070030#include <mutex>
31
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"
Marie Janssendb554582015-06-26 14:53:46 -070035#include "osi/include/log.h"
Kim Schulz8372aa52015-03-25 10:39:40 +010036
Myles Watson6bd442f2016-10-19 09:50:22 -070037#include "bt_common.h"
Kim Schulz8372aa52015-03-25 10:39:40 +010038#include "bt_target.h"
Marie Janssendb554582015-06-26 14:53:46 -070039#include "bta_api.h"
Kim Schulz8372aa52015-03-25 10:39:40 +010040#include "bta_jv_api.h"
41#include "bta_jv_co.h"
Marie Janssendb554582015-06-26 14:53:46 -070042#include "btif_common.h"
Marie Janssendb554582015-06-26 14:53:46 -070043#include "btif_sock_sdp.h"
44#include "btif_sock_thread.h"
45#include "btif_sock_util.h"
Adam Lesinski0620f972015-12-02 22:15:08 -080046#include "btif_uid.h"
Marie Janssendb554582015-06-26 14:53:46 -070047#include "btif_util.h"
48#include "btm_api.h"
49#include "btm_int.h"
50#include "btu.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 Pawlowski6ee309d2018-01-30 19:39:52 -080087 uint16_t mtu;
Marie Janssendb554582015-06-26 14:53:46 -070088} l2cap_socket;
Kim Schulz8372aa52015-03-25 10:39:40 +010089
Jakub Pawlowskie5e2dd52018-01-30 21:46:08 -080090static void btsock_l2cap_server_listen(l2cap_socket* sock);
Kim Schulz8372aa52015-03-25 10:39:40 +010091
Marie Janssena5764682016-10-10 13:38:30 -070092static std::mutex state_lock;
Kim Schulz8372aa52015-03-25 10:39:40 +010093
Myles Watson6bd442f2016-10-19 09:50:22 -070094l2cap_socket* socks = NULL;
Adam Lesinski0620f972015-12-02 22:15:08 -080095static uid_set_t* uid_set = NULL;
Kim Schulz8372aa52015-03-25 10:39:40 +010096static int pth = -1;
97
Myles Watson6bd442f2016-10-19 09:50:22 -070098static void btsock_l2cap_cbk(tBTA_JV_EVT event, tBTA_JV* p_data,
Ajay Panicker531fe1a2016-11-22 13:28:43 -080099 uint32_t l2cap_socket_id);
Kim Schulz8372aa52015-03-25 10:39:40 +0100100
Myles Watson6bd442f2016-10-19 09:50:22 -0700101/* TODO: Consider to remove this buffer, as we have a buffer in l2cap as well,
102 * and we risk
103 * a buffer overflow with this implementation if the socket data is not
104 * read from
105 * JAVA for a while. In such a case we should use flow control to tell the
106 * sender to
Kim Schulz8372aa52015-03-25 10:39:40 +0100107 * back off.
Myles Watson6bd442f2016-10-19 09:50:22 -0700108 * BUT remember we need to avoid blocking the BTA task execution - hence
109 * we cannot
Kim Schulz8372aa52015-03-25 10:39:40 +0100110 * directly write to the socket.
Myles Watson6bd442f2016-10-19 09:50:22 -0700111 * we should be able to change to store the data pointer here, and just
112 * wait
Kim Schulz8372aa52015-03-25 10:39:40 +0100113 * confirming the l2cap_ind until we have more space in the buffer. */
114
Marie Janssenb7f64bc2016-06-22 12:52:19 -0700115/* returns false if none - caller must free "data" memory when done with it */
Myles Watson6bd442f2016-10-19 09:50:22 -0700116static char packet_get_head_l(l2cap_socket* sock, uint8_t** data,
117 uint32_t* len) {
118 struct packet* p = sock->first_packet;
Kim Schulz8372aa52015-03-25 10:39:40 +0100119
Myles Watson6bd442f2016-10-19 09:50:22 -0700120 if (!p) return false;
Kim Schulz8372aa52015-03-25 10:39:40 +0100121
Myles Watson6bd442f2016-10-19 09:50:22 -0700122 if (data) *data = sock->first_packet->data;
123 if (len) *len = sock->first_packet->len;
124 sock->first_packet = p->next;
125 if (sock->first_packet)
126 sock->first_packet->prev = NULL;
127 else
128 sock->last_packet = NULL;
Kim Schulz8372aa52015-03-25 10:39:40 +0100129
Myles Watson6bd442f2016-10-19 09:50:22 -0700130 if (len) sock->bytes_buffered -= *len;
Kim Schulz8372aa52015-03-25 10:39:40 +0100131
Myles Watson6bd442f2016-10-19 09:50:22 -0700132 osi_free(p);
Kim Schulz8372aa52015-03-25 10:39:40 +0100133
Myles Watson6bd442f2016-10-19 09:50:22 -0700134 return true;
Kim Schulz8372aa52015-03-25 10:39:40 +0100135}
136
Myles Watson6bd442f2016-10-19 09:50:22 -0700137static struct packet* packet_alloc(const uint8_t* data, uint32_t len) {
138 struct packet* p = (struct packet*)osi_calloc(sizeof(*p));
139 uint8_t* buf = (uint8_t*)osi_malloc(len);
Kim Schulz8372aa52015-03-25 10:39:40 +0100140
Myles Watson6bd442f2016-10-19 09:50:22 -0700141 p->data = buf;
142 p->len = len;
143 memcpy(p->data, data, len);
144 return p;
Kim Schulz8372aa52015-03-25 10:39:40 +0100145}
146
Marie Janssenb7f64bc2016-06-22 12:52:19 -0700147/* makes a copy of the data, returns true on success */
Myles Watson6bd442f2016-10-19 09:50:22 -0700148static char packet_put_head_l(l2cap_socket* sock, const void* data,
149 uint32_t len) {
150 struct packet* p = packet_alloc((const uint8_t*)data, len);
Kim Schulz8372aa52015-03-25 10:39:40 +0100151
Myles Watson6bd442f2016-10-19 09:50:22 -0700152 /*
153 * We do not check size limits here since this is used to undo "getting" a
154 * packet that the user read incompletely. That is to say the packet was
155 * already in the queue. We do check thos elimits in packet_put_tail_l() since
156 * that function is used to put new data into the queue.
157 */
Kim Schulz8372aa52015-03-25 10:39:40 +0100158
Myles Watson6bd442f2016-10-19 09:50:22 -0700159 if (!p) return false;
Kim Schulz8372aa52015-03-25 10:39:40 +0100160
Myles Watson6bd442f2016-10-19 09:50:22 -0700161 p->prev = NULL;
162 p->next = sock->first_packet;
163 sock->first_packet = p;
164 if (p->next)
165 p->next->prev = p;
166 else
Kim Schulz8372aa52015-03-25 10:39:40 +0100167 sock->last_packet = p;
Kim Schulz8372aa52015-03-25 10:39:40 +0100168
Myles Watson6bd442f2016-10-19 09:50:22 -0700169 sock->bytes_buffered += len;
Kim Schulz8372aa52015-03-25 10:39:40 +0100170
Myles Watson6bd442f2016-10-19 09:50:22 -0700171 return true;
Kim Schulz8372aa52015-03-25 10:39:40 +0100172}
173
Myles Watson6bd442f2016-10-19 09:50:22 -0700174/* makes a copy of the data, returns true on success */
175static char packet_put_tail_l(l2cap_socket* sock, const void* data,
176 uint32_t len) {
177 struct packet* p = packet_alloc((const uint8_t*)data, len);
178
179 if (sock->bytes_buffered >= L2CAP_MAX_RX_BUFFER) {
180 LOG_ERROR(LOG_TAG, "packet_put_tail_l: buffer overflow");
181 return false;
182 }
183
184 if (!p) {
185 LOG_ERROR(LOG_TAG, "packet_put_tail_l: unable to allocate packet...");
186 return false;
187 }
188
189 p->next = NULL;
190 p->prev = sock->last_packet;
191 sock->last_packet = p;
192 if (p->prev)
193 p->prev->next = p;
194 else
195 sock->first_packet = p;
196
197 sock->bytes_buffered += len;
198
199 return true;
Kim Schulz8372aa52015-03-25 10:39:40 +0100200}
201
Myles Watson6bd442f2016-10-19 09:50:22 -0700202static char is_inited(void) {
203 std::unique_lock<std::mutex> lock(state_lock);
204 return pth != -1;
Kim Schulz8372aa52015-03-25 10:39:40 +0100205}
206
Marie Janssena5764682016-10-10 13:38:30 -0700207/* only call with std::mutex taken */
Myles Watson6bd442f2016-10-19 09:50:22 -0700208static l2cap_socket* btsock_l2cap_find_by_id_l(uint32_t id) {
209 l2cap_socket* sock = socks;
Kim Schulz8372aa52015-03-25 10:39:40 +0100210
Myles Watson6bd442f2016-10-19 09:50:22 -0700211 while (sock && sock->id != id) sock = sock->next;
Kim Schulz8372aa52015-03-25 10:39:40 +0100212
Myles Watson6bd442f2016-10-19 09:50:22 -0700213 return sock;
Kim Schulz8372aa52015-03-25 10:39:40 +0100214}
215
Myles Watson6bd442f2016-10-19 09:50:22 -0700216static void btsock_l2cap_free_l(l2cap_socket* sock) {
217 uint8_t* buf;
218 l2cap_socket* t = socks;
Kim Schulz8372aa52015-03-25 10:39:40 +0100219
Myles Watson6bd442f2016-10-19 09:50:22 -0700220 while (t && t != sock) t = t->next;
Kim Schulz8372aa52015-03-25 10:39:40 +0100221
Myles Watson6bd442f2016-10-19 09:50:22 -0700222 if (!t) /* prever double-frees */
223 return;
Kim Schulz8372aa52015-03-25 10:39:40 +0100224
Myles Watson6bd442f2016-10-19 09:50:22 -0700225 if (sock->next) sock->next->prev = sock->prev;
Kim Schulz8372aa52015-03-25 10:39:40 +0100226
Myles Watson6bd442f2016-10-19 09:50:22 -0700227 if (sock->prev)
228 sock->prev->next = sock->next;
229 else
230 socks = sock->next;
Kim Schulz8372aa52015-03-25 10:39:40 +0100231
Myles Watson6bd442f2016-10-19 09:50:22 -0700232 shutdown(sock->our_fd, SHUT_RDWR);
233 close(sock->our_fd);
234 if (sock->app_fd != -1) {
235 close(sock->app_fd);
236 } else {
237 APPL_TRACE_ERROR("SOCK_LIST: free(id = %d) - NO app_fd!", sock->id);
238 }
239
240 while (packet_get_head_l(sock, &buf, NULL)) osi_free(buf);
241
242 // lower-level close() should be idempotent... so let's call it and see...
243 if (sock->is_le_coc) {
244 // Only call if we are non server connections
Myles Watsonb749ebd2017-10-06 16:39:05 -0700245 if (sock->handle >= 0 && (!sock->server)) {
Myles Watson6bd442f2016-10-19 09:50:22 -0700246 BTA_JvL2capClose(sock->handle);
Kim Schulz8372aa52015-03-25 10:39:40 +0100247 }
Myles Watsonb749ebd2017-10-06 16:39:05 -0700248 if ((sock->channel >= 0) && (sock->server)) {
Stanley Tng49dd53c2017-12-20 09:38:30 -0800249 BTA_JvFreeChannel(sock->channel, BTA_JV_CONN_TYPE_L2CAP_LE);
Navin Kochar67212322016-03-09 23:11:53 +0530250 }
Myles Watson6bd442f2016-10-19 09:50:22 -0700251 } else {
252 // Only call if we are non server connections
Myles Watsonb749ebd2017-10-06 16:39:05 -0700253 if ((sock->handle >= 0) && (!sock->server)) {
Myles Watson6bd442f2016-10-19 09:50:22 -0700254 if (sock->fixed_chan)
255 BTA_JvL2capCloseLE(sock->handle);
256 else
257 BTA_JvL2capClose(sock->handle);
Kim Schulz8372aa52015-03-25 10:39:40 +0100258 }
Myles Watsonb749ebd2017-10-06 16:39:05 -0700259 if ((sock->channel >= 0) && (sock->server)) {
Myles Watson6bd442f2016-10-19 09:50:22 -0700260 if (sock->fixed_chan)
261 BTA_JvFreeChannel(sock->channel, BTA_JV_CONN_TYPE_L2CAP_LE);
262 else
263 BTA_JvFreeChannel(sock->channel, BTA_JV_CONN_TYPE_L2CAP);
Kim Schulz8372aa52015-03-25 10:39:40 +0100264
Myles Watson6bd442f2016-10-19 09:50:22 -0700265 if (!sock->fixed_chan) {
266 APPL_TRACE_DEBUG("%s stopping L2CAP server channel %d", __func__,
267 sock->channel);
Ajay Panicker531fe1a2016-11-22 13:28:43 -0800268 BTA_JvL2capStopServer(sock->channel, sock->id);
Myles Watson6bd442f2016-10-19 09:50:22 -0700269 }
270 }
271 }
272
273 APPL_TRACE_DEBUG("%s: free(id = %d)", __func__, sock->id);
274 osi_free(sock);
Kim Schulz8372aa52015-03-25 10:39:40 +0100275}
276
Myles Watson6bd442f2016-10-19 09:50:22 -0700277static l2cap_socket* btsock_l2cap_alloc_l(const char* name,
Jakub Pawlowskia484a882017-06-24 17:30:18 -0700278 const RawAddress* addr,
Myles Watson6bd442f2016-10-19 09:50:22 -0700279 char is_server, int flags) {
280 unsigned security = 0;
281 int fds[2];
282 l2cap_socket* sock = (l2cap_socket*)osi_calloc(sizeof(*sock));
Kim Schulz8372aa52015-03-25 10:39:40 +0100283
Myles Watson6bd442f2016-10-19 09:50:22 -0700284 if (flags & BTSOCK_FLAG_ENCRYPT)
285 security |= is_server ? BTM_SEC_IN_ENCRYPT : BTM_SEC_OUT_ENCRYPT;
286 if (flags & BTSOCK_FLAG_AUTH)
287 security |= is_server ? BTM_SEC_IN_AUTHENTICATE : BTM_SEC_OUT_AUTHENTICATE;
288 if (flags & BTSOCK_FLAG_AUTH_MITM)
289 security |= is_server ? BTM_SEC_IN_MITM : BTM_SEC_OUT_MITM;
290 if (flags & BTSOCK_FLAG_AUTH_16_DIGIT)
291 security |= BTM_SEC_IN_MIN_16_DIGIT_PIN;
Kim Schulz8372aa52015-03-25 10:39:40 +0100292
Myles Watson6bd442f2016-10-19 09:50:22 -0700293 if (socketpair(AF_LOCAL, SOCK_SEQPACKET, 0, fds)) {
294 APPL_TRACE_ERROR("socketpair failed, errno:%d", errno);
295 goto fail_sockpair;
296 }
297
298 sock->our_fd = fds[0];
299 sock->app_fd = fds[1];
300 sock->security = security;
301 sock->server = is_server;
302 sock->connected = false;
303 sock->handle = 0;
304 sock->server_psm_sent = false;
305 sock->app_uid = -1;
306
307 if (name) strncpy(sock->name, name, sizeof(sock->name) - 1);
308 if (addr) sock->addr = *addr;
309
310 sock->first_packet = NULL;
311 sock->last_packet = NULL;
312
Jakub Pawlowski6ee309d2018-01-30 19:39:52 -0800313 sock->mtu = L2CAP_LE_MIN_MTU;
Jakub Pawlowski8452b052018-01-05 02:41:36 -0800314
Myles Watson6bd442f2016-10-19 09:50:22 -0700315 sock->next = socks;
316 sock->prev = NULL;
317 if (socks) socks->prev = sock;
318 sock->id = (socks ? socks->id : 0) + 1;
319 socks = sock;
320 /* paranoia cap on: verify no ID duplicates due to overflow and fix as needed
321 */
322 while (1) {
323 l2cap_socket* t;
324 t = socks->next;
325 while (t && t->id != sock->id) {
326 t = t->next;
Kim Schulz8372aa52015-03-25 10:39:40 +0100327 }
Myles Watson6bd442f2016-10-19 09:50:22 -0700328 if (!t && sock->id) /* non-zeor handle is unique -> we're done */
329 break;
330 /* if we're here, we found a duplicate */
331 if (!++sock->id) /* no zero IDs allowed */
332 sock->id++;
333 }
334 APPL_TRACE_DEBUG("SOCK_LIST: alloc(id = %d)", sock->id);
335 return sock;
Kim Schulz8372aa52015-03-25 10:39:40 +0100336
337fail_sockpair:
Myles Watson6bd442f2016-10-19 09:50:22 -0700338 osi_free(sock);
339 return NULL;
Kim Schulz8372aa52015-03-25 10:39:40 +0100340}
341
Myles Watson6bd442f2016-10-19 09:50:22 -0700342bt_status_t btsock_l2cap_init(int handle, uid_set_t* set) {
Stanley Tng49dd53c2017-12-20 09:38:30 -0800343 APPL_TRACE_DEBUG("%s: handle = %d", __func__, handle);
Myles Watson6bd442f2016-10-19 09:50:22 -0700344 std::unique_lock<std::mutex> lock(state_lock);
345 pth = handle;
346 socks = NULL;
347 uid_set = set;
348 return BT_STATUS_SUCCESS;
Kim Schulz8372aa52015-03-25 10:39:40 +0100349}
350
Myles Watson6bd442f2016-10-19 09:50:22 -0700351bt_status_t btsock_l2cap_cleanup() {
352 std::unique_lock<std::mutex> lock(state_lock);
353 pth = -1;
354 while (socks) btsock_l2cap_free_l(socks);
355 return BT_STATUS_SUCCESS;
Kim Schulz8372aa52015-03-25 10:39:40 +0100356}
357
Myles Watson6bd442f2016-10-19 09:50:22 -0700358static inline bool send_app_psm_or_chan_l(l2cap_socket* sock) {
Stanley Tng49dd53c2017-12-20 09:38:30 -0800359 APPL_TRACE_DEBUG("%s: channel=%d", __func__, sock->channel);
Myles Watson6bd442f2016-10-19 09:50:22 -0700360 return sock_send_all(sock->our_fd, (const uint8_t*)&sock->channel,
361 sizeof(sock->channel)) == sizeof(sock->channel);
Kim Schulz8372aa52015-03-25 10:39:40 +0100362}
363
Jakub Pawlowskia484a882017-06-24 17:30:18 -0700364static bool send_app_connect_signal(int fd, const RawAddress* addr, int channel,
365 int status, int send_fd, int tx_mtu) {
Myles Watson6bd442f2016-10-19 09:50:22 -0700366 sock_connect_signal_t cs;
367 cs.size = sizeof(cs);
368 cs.bd_addr = *addr;
369 cs.channel = channel;
370 cs.status = status;
371 cs.max_rx_packet_size = L2CAP_MAX_SDU_LENGTH;
372 cs.max_tx_packet_size = tx_mtu;
373 if (send_fd != -1) {
374 if (sock_send_fd(fd, (const uint8_t*)&cs, sizeof(cs), send_fd) ==
375 sizeof(cs))
376 return true;
377 else
378 APPL_TRACE_ERROR("sock_send_fd failed, fd:%d, send_fd:%d", fd, send_fd);
379 } else if (sock_send_all(fd, (const uint8_t*)&cs, sizeof(cs)) == sizeof(cs)) {
380 return true;
381 }
382 return false;
Kim Schulz8372aa52015-03-25 10:39:40 +0100383}
384
Myles Watson6bd442f2016-10-19 09:50:22 -0700385static void on_srv_l2cap_listen_started(tBTA_JV_L2CAP_START* p_start,
386 uint32_t id) {
387 l2cap_socket* sock;
Kim Schulz8372aa52015-03-25 10:39:40 +0100388
Myles Watson6bd442f2016-10-19 09:50:22 -0700389 std::unique_lock<std::mutex> lock(state_lock);
390 sock = btsock_l2cap_find_by_id_l(id);
391 if (!sock) return;
Marie Janssena5764682016-10-10 13:38:30 -0700392
Myles Watson6bd442f2016-10-19 09:50:22 -0700393 if (p_start->status != BTA_JV_SUCCESS) {
394 APPL_TRACE_ERROR("Error starting l2cap_listen - status: 0x%04x",
395 p_start->status);
396 btsock_l2cap_free_l(sock);
397 return;
398 }
399
400 sock->handle = p_start->handle;
401 APPL_TRACE_DEBUG("on_srv_l2cap_listen_started() sock->handle =%d id:%d",
402 sock->handle, sock->id);
403
Myles Watsonb749ebd2017-10-06 16:39:05 -0700404 if (!sock->server_psm_sent) {
Myles Watson6bd442f2016-10-19 09:50:22 -0700405 if (!send_app_psm_or_chan_l(sock)) {
406 // closed
407 APPL_TRACE_DEBUG("send_app_psm() failed, close rs->id:%d", sock->id);
408 btsock_l2cap_free_l(sock);
409 } else {
410 sock->server_psm_sent = true;
Marie Janssena5764682016-10-10 13:38:30 -0700411 }
Myles Watson6bd442f2016-10-19 09:50:22 -0700412 }
Kim Schulz8372aa52015-03-25 10:39:40 +0100413}
414
Myles Watson6bd442f2016-10-19 09:50:22 -0700415static void on_cl_l2cap_init(tBTA_JV_L2CAP_CL_INIT* p_init, uint32_t id) {
416 l2cap_socket* sock;
Kim Schulz8372aa52015-03-25 10:39:40 +0100417
Myles Watson6bd442f2016-10-19 09:50:22 -0700418 std::unique_lock<std::mutex> lock(state_lock);
419 sock = btsock_l2cap_find_by_id_l(id);
420 if (!sock) return;
Marie Janssena5764682016-10-10 13:38:30 -0700421
Myles Watson6bd442f2016-10-19 09:50:22 -0700422 if (p_init->status != BTA_JV_SUCCESS) {
423 btsock_l2cap_free_l(sock);
424 return;
425 }
Marie Janssena5764682016-10-10 13:38:30 -0700426
Myles Watson6bd442f2016-10-19 09:50:22 -0700427 sock->handle = p_init->handle;
Kim Schulz8372aa52015-03-25 10:39:40 +0100428}
429
430/**
Myles Watson6bd442f2016-10-19 09:50:22 -0700431 * Here we allocate a new sock instance to mimic the BluetoothSocket. The socket
Jakub Pawlowski8452b052018-01-05 02:41:36 -0800432 * will be a clone of the sock representing the BluetoothServerSocket.
Kim Schulz8372aa52015-03-25 10:39:40 +0100433 * */
Myles Watson6bd442f2016-10-19 09:50:22 -0700434static void on_srv_l2cap_psm_connect_l(tBTA_JV_L2CAP_OPEN* p_open,
435 l2cap_socket* sock) {
436 l2cap_socket* accept_rs;
437 uint32_t new_listen_id;
Kim Schulz8372aa52015-03-25 10:39:40 +0100438
Myles Watson6bd442f2016-10-19 09:50:22 -0700439 // std::mutex locked by caller
Jakub Pawlowskia09c3482017-06-16 08:42:05 -0700440 accept_rs = btsock_l2cap_alloc_l(sock->name, &p_open->rem_bda, false, 0);
Myles Watson6bd442f2016-10-19 09:50:22 -0700441 accept_rs->connected = true;
442 accept_rs->security = sock->security;
443 accept_rs->fixed_chan = sock->fixed_chan;
444 accept_rs->channel = sock->channel;
445 accept_rs->handle = sock->handle;
446 accept_rs->app_uid = sock->app_uid;
447 sock->handle =
448 -1; /* We should no longer associate this handle with the server socket */
449 accept_rs->is_le_coc = sock->is_le_coc;
Jakub Pawlowski6ee309d2018-01-30 19:39:52 -0800450 accept_rs->mtu = sock->mtu;
Kim Schulz8372aa52015-03-25 10:39:40 +0100451
Myles Watson6bd442f2016-10-19 09:50:22 -0700452 /* Swap IDs to hand over the GAP connection to the accepted socket, and start
453 a new server on
454 the newly create socket ID. */
455 new_listen_id = accept_rs->id;
456 accept_rs->id = sock->id;
457 sock->id = new_listen_id;
458
459 if (accept_rs) {
460 // start monitor the socket
461 btsock_thread_add_fd(pth, sock->our_fd, BTSOCK_L2CAP,
462 SOCK_THREAD_FD_EXCEPTION, sock->id);
463 btsock_thread_add_fd(pth, accept_rs->our_fd, BTSOCK_L2CAP,
464 SOCK_THREAD_FD_RD, accept_rs->id);
465 APPL_TRACE_DEBUG(
466 "sending connect signal & app fd: %d to app server to accept() the"
467 " connection",
468 accept_rs->app_fd);
469 APPL_TRACE_DEBUG("server fd:%d, scn:%d", sock->our_fd, sock->channel);
470 send_app_connect_signal(sock->our_fd, &accept_rs->addr, sock->channel, 0,
471 accept_rs->app_fd, p_open->tx_mtu);
472 accept_rs->app_fd =
473 -1; // The fd is closed after sent to app in send_app_connect_signal()
474 // But for some reason we still leak a FD - either the server socket
475 // one or the accept socket one.
Jakub Pawlowskie5e2dd52018-01-30 21:46:08 -0800476 btsock_l2cap_server_listen(sock);
Myles Watson6bd442f2016-10-19 09:50:22 -0700477 }
478}
479
480static void on_srv_l2cap_le_connect_l(tBTA_JV_L2CAP_LE_OPEN* p_open,
481 l2cap_socket* sock) {
482 l2cap_socket* accept_rs;
483 uint32_t new_listen_id;
484
485 // std::mutex locked by caller
Jakub Pawlowskia09c3482017-06-16 08:42:05 -0700486 accept_rs = btsock_l2cap_alloc_l(sock->name, &p_open->rem_bda, false, 0);
Myles Watson6bd442f2016-10-19 09:50:22 -0700487 if (accept_rs) {
488 // swap IDs
Kim Schulz8372aa52015-03-25 10:39:40 +0100489 new_listen_id = accept_rs->id;
490 accept_rs->id = sock->id;
491 sock->id = new_listen_id;
492
Myles Watson6bd442f2016-10-19 09:50:22 -0700493 accept_rs->handle = p_open->handle;
494 accept_rs->connected = true;
495 accept_rs->security = sock->security;
496 accept_rs->fixed_chan = sock->fixed_chan;
497 accept_rs->channel = sock->channel;
498 accept_rs->app_uid = sock->app_uid;
Jakub Pawlowski6ee309d2018-01-30 19:39:52 -0800499 accept_rs->mtu = sock->mtu;
Myles Watson6bd442f2016-10-19 09:50:22 -0700500
501 // if we do not set a callback, this socket will be dropped */
502 *(p_open->p_p_cback) = (void*)btsock_l2cap_cbk;
503 *(p_open->p_user_data) = UINT_TO_PTR(accept_rs->id);
504
505 // start monitor the socket
506 btsock_thread_add_fd(pth, sock->our_fd, BTSOCK_L2CAP,
507 SOCK_THREAD_FD_EXCEPTION, sock->id);
508 btsock_thread_add_fd(pth, accept_rs->our_fd, BTSOCK_L2CAP,
509 SOCK_THREAD_FD_RD, accept_rs->id);
510 APPL_TRACE_DEBUG(
511 "sending connect signal & app fd:%dto app server to accept() the"
512 " connection",
513 accept_rs->app_fd);
514 APPL_TRACE_DEBUG("server fd:%d, scn:%d", sock->our_fd, sock->channel);
515 send_app_connect_signal(sock->our_fd, &accept_rs->addr, sock->channel, 0,
516 accept_rs->app_fd, p_open->tx_mtu);
517 accept_rs->app_fd = -1; // the fd is closed after sent to app
518 }
Kim Schulz8372aa52015-03-25 10:39:40 +0100519}
520
Myles Watson6bd442f2016-10-19 09:50:22 -0700521static void on_cl_l2cap_psm_connect_l(tBTA_JV_L2CAP_OPEN* p_open,
522 l2cap_socket* sock) {
Jakub Pawlowskia09c3482017-06-16 08:42:05 -0700523 sock->addr = p_open->rem_bda;
Kim Schulz8372aa52015-03-25 10:39:40 +0100524
Myles Watson6bd442f2016-10-19 09:50:22 -0700525 if (!send_app_psm_or_chan_l(sock)) {
526 APPL_TRACE_ERROR("send_app_psm_or_chan_l failed");
527 return;
528 }
Kim Schulz8372aa52015-03-25 10:39:40 +0100529
Myles Watson6bd442f2016-10-19 09:50:22 -0700530 if (send_app_connect_signal(sock->our_fd, &sock->addr, sock->channel, 0, -1,
531 p_open->tx_mtu)) {
532 // start monitoring the socketpair to get call back when app writing data
533 APPL_TRACE_DEBUG(
534 "on_l2cap_connect_ind, connect signal sent, slot id:%d, psm:%d,"
535 " server:%d",
536 sock->id, sock->channel, sock->server);
537 btsock_thread_add_fd(pth, sock->our_fd, BTSOCK_L2CAP, SOCK_THREAD_FD_RD,
538 sock->id);
539 sock->connected = true;
540 } else
541 APPL_TRACE_ERROR("send_app_connect_signal failed");
Kim Schulz8372aa52015-03-25 10:39:40 +0100542}
543
Myles Watson6bd442f2016-10-19 09:50:22 -0700544static void on_cl_l2cap_le_connect_l(tBTA_JV_L2CAP_LE_OPEN* p_open,
545 l2cap_socket* sock) {
Jakub Pawlowskia09c3482017-06-16 08:42:05 -0700546 sock->addr = p_open->rem_bda;
Kim Schulz8372aa52015-03-25 10:39:40 +0100547
Myles Watson6bd442f2016-10-19 09:50:22 -0700548 if (!send_app_psm_or_chan_l(sock)) {
549 APPL_TRACE_ERROR("send_app_psm_or_chan_l failed");
550 return;
551 }
Kim Schulz8372aa52015-03-25 10:39:40 +0100552
Myles Watson6bd442f2016-10-19 09:50:22 -0700553 if (send_app_connect_signal(sock->our_fd, &sock->addr, sock->channel, 0, -1,
554 p_open->tx_mtu)) {
555 // start monitoring the socketpair to get call back when app writing data
556 APPL_TRACE_DEBUG(
557 "on_l2cap_connect_ind, connect signal sent, slot id:%d, Chan:%d,"
558 " server:%d",
559 sock->id, sock->channel, sock->server);
560 btsock_thread_add_fd(pth, sock->our_fd, BTSOCK_L2CAP, SOCK_THREAD_FD_RD,
561 sock->id);
562 sock->connected = true;
563 } else
564 APPL_TRACE_ERROR("send_app_connect_signal failed");
Kim Schulz8372aa52015-03-25 10:39:40 +0100565}
566
Myles Watson6bd442f2016-10-19 09:50:22 -0700567static void on_l2cap_connect(tBTA_JV* p_data, uint32_t id) {
568 l2cap_socket* sock;
569 tBTA_JV_L2CAP_OPEN* psm_open = &p_data->l2c_open;
570 tBTA_JV_L2CAP_LE_OPEN* le_open = &p_data->l2c_le_open;
Kim Schulz8372aa52015-03-25 10:39:40 +0100571
Myles Watson6bd442f2016-10-19 09:50:22 -0700572 std::unique_lock<std::mutex> lock(state_lock);
573 sock = btsock_l2cap_find_by_id_l(id);
574 if (!sock) {
575 APPL_TRACE_ERROR("on_l2cap_connect on unknown socket");
576 return;
577 }
Kim Schulz8372aa52015-03-25 10:39:40 +0100578
Jakub Pawlowski6ee309d2018-01-30 19:39:52 -0800579 sock->mtu = le_open->tx_mtu;
Myles Watson6bd442f2016-10-19 09:50:22 -0700580 if (sock->fixed_chan && le_open->status == BTA_JV_SUCCESS) {
581 if (!sock->server)
582 on_cl_l2cap_le_connect_l(le_open, sock);
Marie Janssena5764682016-10-10 13:38:30 -0700583 else
Myles Watson6bd442f2016-10-19 09:50:22 -0700584 on_srv_l2cap_le_connect_l(le_open, sock);
585 } else if (!sock->fixed_chan && psm_open->status == BTA_JV_SUCCESS) {
586 if (!sock->server)
587 on_cl_l2cap_psm_connect_l(psm_open, sock);
588 else
589 on_srv_l2cap_psm_connect_l(psm_open, sock);
590 } else
Marie Janssena5764682016-10-10 13:38:30 -0700591 btsock_l2cap_free_l(sock);
Kim Schulz8372aa52015-03-25 10:39:40 +0100592}
593
Myles Watson6bd442f2016-10-19 09:50:22 -0700594static void on_l2cap_close(tBTA_JV_L2CAP_CLOSE* p_close, uint32_t id) {
595 l2cap_socket* sock;
Kim Schulz8372aa52015-03-25 10:39:40 +0100596
Myles Watson6bd442f2016-10-19 09:50:22 -0700597 std::unique_lock<std::mutex> lock(state_lock);
598 sock = btsock_l2cap_find_by_id_l(id);
599 if (!sock) return;
Kim Schulz8372aa52015-03-25 10:39:40 +0100600
Myles Watson6bd442f2016-10-19 09:50:22 -0700601 APPL_TRACE_DEBUG("on_l2cap_close, slot id:%d, fd:%d, %s:%d, server:%d",
602 sock->id, sock->our_fd,
603 sock->fixed_chan ? "fixed_chan" : "PSM", sock->channel,
604 sock->server);
605 // TODO: This does not seem to be called...
606 // I'm not sure if this will be called for non-server sockets?
Myles Watsonb749ebd2017-10-06 16:39:05 -0700607 if (!sock->fixed_chan && (sock->server)) {
Myles Watson6bd442f2016-10-19 09:50:22 -0700608 BTA_JvFreeChannel(sock->channel, BTA_JV_CONN_TYPE_L2CAP);
609 }
610 btsock_l2cap_free_l(sock);
Kim Schulz8372aa52015-03-25 10:39:40 +0100611}
612
Myles Watson6bd442f2016-10-19 09:50:22 -0700613static void on_l2cap_outgoing_congest(tBTA_JV_L2CAP_CONG* p, uint32_t id) {
614 l2cap_socket* sock;
Kim Schulz8372aa52015-03-25 10:39:40 +0100615
Myles Watson6bd442f2016-10-19 09:50:22 -0700616 std::unique_lock<std::mutex> lock(state_lock);
617 sock = btsock_l2cap_find_by_id_l(id);
618 if (!sock) return;
Kim Schulz8372aa52015-03-25 10:39:40 +0100619
Myles Watson6bd442f2016-10-19 09:50:22 -0700620 sock->outgoing_congest = p->cong ? 1 : 0;
621 // mointer the fd for any outgoing data
622 if (!sock->outgoing_congest) {
623 APPL_TRACE_DEBUG(
624 "on_l2cap_outgoing_congest: adding fd to btsock_thread...");
625 btsock_thread_add_fd(pth, sock->our_fd, BTSOCK_L2CAP, SOCK_THREAD_FD_RD,
626 sock->id);
627 }
Kim Schulz8372aa52015-03-25 10:39:40 +0100628}
629
Jakub Pawlowskic4743422018-01-11 07:34:39 -0800630static void on_l2cap_write_done(uint16_t len, uint32_t id) {
Myles Watson6bd442f2016-10-19 09:50:22 -0700631 std::unique_lock<std::mutex> lock(state_lock);
Jakub Pawlowski19d30612018-01-08 01:23:52 -0800632 l2cap_socket* sock = btsock_l2cap_find_by_id_l(id);
Myles Watson6bd442f2016-10-19 09:50:22 -0700633 if (!sock) return;
634
Jakub Pawlowski19d30612018-01-08 01:23:52 -0800635 int app_uid = sock->app_uid;
Myles Watson6bd442f2016-10-19 09:50:22 -0700636 if (!sock->outgoing_congest) {
637 // monitor the fd for any outgoing data
638 APPL_TRACE_DEBUG("on_l2cap_write_done: adding fd to btsock_thread...");
639 btsock_thread_add_fd(pth, sock->our_fd, BTSOCK_L2CAP, SOCK_THREAD_FD_RD,
640 sock->id);
641 }
642
643 uid_set_add_tx(uid_set, app_uid, len);
Kim Schulz8372aa52015-03-25 10:39:40 +0100644}
645
Myles Watson6bd442f2016-10-19 09:50:22 -0700646static void on_l2cap_data_ind(tBTA_JV* evt, uint32_t id) {
647 l2cap_socket* sock;
Kim Schulz8372aa52015-03-25 10:39:40 +0100648
Myles Watson6bd442f2016-10-19 09:50:22 -0700649 int app_uid = -1;
650 uint32_t bytes_read = 0;
Kim Schulz8372aa52015-03-25 10:39:40 +0100651
Myles Watson6bd442f2016-10-19 09:50:22 -0700652 std::unique_lock<std::mutex> lock(state_lock);
653 sock = btsock_l2cap_find_by_id_l(id);
654 if (!sock) return;
655
656 app_uid = sock->app_uid;
657
658 if (sock->fixed_chan) { /* we do these differently */
659
660 tBTA_JV_LE_DATA_IND* p_le_data_ind = &evt->le_data_ind;
661 BT_HDR* p_buf = p_le_data_ind->p_buf;
662 uint8_t* data = (uint8_t*)(p_buf + 1) + p_buf->offset;
663
664 if (packet_put_tail_l(sock, data, p_buf->len)) {
665 bytes_read = p_buf->len;
666 btsock_thread_add_fd(pth, sock->our_fd, BTSOCK_L2CAP, SOCK_THREAD_FD_WR,
667 sock->id);
668 } else { // connection must be dropped
669 APPL_TRACE_DEBUG(
670 "on_l2cap_data_ind() unable to push data to socket - closing"
671 " fixed channel");
672 BTA_JvL2capCloseLE(sock->handle);
673 btsock_l2cap_free_l(sock);
674 }
675
676 } else {
Myles Watson6bd442f2016-10-19 09:50:22 -0700677 uint32_t count;
678
679 if (BTA_JvL2capReady(sock->handle, &count) == BTA_JV_SUCCESS) {
Jakub Pawlowskif47bfde2018-01-29 13:54:24 -0800680 std::vector<uint8_t> buffer(count);
681 if (BTA_JvL2capRead(sock->handle, sock->id, buffer.data(), count) ==
Myles Watson6bd442f2016-10-19 09:50:22 -0700682 BTA_JV_SUCCESS) {
Jakub Pawlowskif47bfde2018-01-29 13:54:24 -0800683 if (packet_put_tail_l(sock, buffer.data(), count)) {
Myles Watson6bd442f2016-10-19 09:50:22 -0700684 bytes_read = count;
685 btsock_thread_add_fd(pth, sock->our_fd, BTSOCK_L2CAP,
686 SOCK_THREAD_FD_WR, sock->id);
687 } else { // connection must be dropped
688 APPL_TRACE_DEBUG(
689 "on_l2cap_data_ind() unable to push data to socket"
690 " - closing channel");
691 BTA_JvL2capClose(sock->handle);
692 btsock_l2cap_free_l(sock);
Marie Janssena5764682016-10-10 13:38:30 -0700693 }
Myles Watson6bd442f2016-10-19 09:50:22 -0700694 }
Kim Schulz8372aa52015-03-25 10:39:40 +0100695 }
Myles Watson6bd442f2016-10-19 09:50:22 -0700696 }
Adam Lesinski0620f972015-12-02 22:15:08 -0800697
Myles Watson6bd442f2016-10-19 09:50:22 -0700698 uid_set_add_rx(uid_set, app_uid, bytes_read);
Kim Schulz8372aa52015-03-25 10:39:40 +0100699}
700
Myles Watson6bd442f2016-10-19 09:50:22 -0700701static void btsock_l2cap_cbk(tBTA_JV_EVT event, tBTA_JV* p_data,
Ajay Panicker531fe1a2016-11-22 13:28:43 -0800702 uint32_t l2cap_socket_id) {
Myles Watson6bd442f2016-10-19 09:50:22 -0700703 switch (event) {
Kim Schulz8372aa52015-03-25 10:39:40 +0100704 case BTA_JV_L2CAP_START_EVT:
Ajay Panicker531fe1a2016-11-22 13:28:43 -0800705 on_srv_l2cap_listen_started(&p_data->l2c_start, l2cap_socket_id);
Myles Watson6bd442f2016-10-19 09:50:22 -0700706 break;
Kim Schulz8372aa52015-03-25 10:39:40 +0100707
708 case BTA_JV_L2CAP_CL_INIT_EVT:
Ajay Panicker531fe1a2016-11-22 13:28:43 -0800709 on_cl_l2cap_init(&p_data->l2c_cl_init, l2cap_socket_id);
Myles Watson6bd442f2016-10-19 09:50:22 -0700710 break;
Kim Schulz8372aa52015-03-25 10:39:40 +0100711
712 case BTA_JV_L2CAP_OPEN_EVT:
Ajay Panicker531fe1a2016-11-22 13:28:43 -0800713 on_l2cap_connect(p_data, l2cap_socket_id);
Myles Watson6bd442f2016-10-19 09:50:22 -0700714 BTA_JvSetPmProfile(p_data->l2c_open.handle, BTA_JV_PM_ID_1,
715 BTA_JV_CONN_OPEN);
716 break;
Kim Schulz8372aa52015-03-25 10:39:40 +0100717
718 case BTA_JV_L2CAP_CLOSE_EVT:
Ajay Panicker531fe1a2016-11-22 13:28:43 -0800719 APPL_TRACE_DEBUG("BTA_JV_L2CAP_CLOSE_EVT: id: %u", l2cap_socket_id);
720 on_l2cap_close(&p_data->l2c_close, l2cap_socket_id);
Myles Watson6bd442f2016-10-19 09:50:22 -0700721 break;
Kim Schulz8372aa52015-03-25 10:39:40 +0100722
723 case BTA_JV_L2CAP_DATA_IND_EVT:
Ajay Panicker531fe1a2016-11-22 13:28:43 -0800724 on_l2cap_data_ind(p_data, l2cap_socket_id);
Myles Watson6bd442f2016-10-19 09:50:22 -0700725 APPL_TRACE_DEBUG("BTA_JV_L2CAP_DATA_IND_EVT");
726 break;
Kim Schulz8372aa52015-03-25 10:39:40 +0100727
728 case BTA_JV_L2CAP_READ_EVT:
Myles Watson6bd442f2016-10-19 09:50:22 -0700729 APPL_TRACE_DEBUG("BTA_JV_L2CAP_READ_EVT not used");
730 break;
Kim Schulz8372aa52015-03-25 10:39:40 +0100731
Kim Schulz8372aa52015-03-25 10:39:40 +0100732 case BTA_JV_L2CAP_WRITE_EVT:
Ajay Panicker531fe1a2016-11-22 13:28:43 -0800733 APPL_TRACE_DEBUG("BTA_JV_L2CAP_WRITE_EVT: id: %u", l2cap_socket_id);
Jakub Pawlowskic4743422018-01-11 07:34:39 -0800734 on_l2cap_write_done(p_data->l2c_write.len, l2cap_socket_id);
Myles Watson6bd442f2016-10-19 09:50:22 -0700735 break;
Kim Schulz8372aa52015-03-25 10:39:40 +0100736
737 case BTA_JV_L2CAP_WRITE_FIXED_EVT:
Ajay Panicker531fe1a2016-11-22 13:28:43 -0800738 APPL_TRACE_DEBUG("BTA_JV_L2CAP_WRITE_FIXED_EVT: id: %u", l2cap_socket_id);
Jakub Pawlowskic4743422018-01-11 07:34:39 -0800739 on_l2cap_write_done(p_data->l2c_write.len, l2cap_socket_id);
Myles Watson6bd442f2016-10-19 09:50:22 -0700740 break;
Kim Schulz8372aa52015-03-25 10:39:40 +0100741
742 case BTA_JV_L2CAP_CONG_EVT:
Ajay Panicker531fe1a2016-11-22 13:28:43 -0800743 on_l2cap_outgoing_congest(&p_data->l2c_cong, l2cap_socket_id);
Myles Watson6bd442f2016-10-19 09:50:22 -0700744 break;
Kim Schulz8372aa52015-03-25 10:39:40 +0100745
746 default:
Myles Watson911d1ae2016-11-28 16:44:40 -0800747 APPL_TRACE_ERROR("unhandled event %d, slot id: %u", event,
748 l2cap_socket_id);
Myles Watson6bd442f2016-10-19 09:50:22 -0700749 break;
750 }
Kim Schulz8372aa52015-03-25 10:39:40 +0100751}
752
753/* L2CAP default options for OBEX socket connections */
Myles Watsonf4548162016-10-19 09:53:56 -0700754const tL2CAP_FCR_OPTS obex_l2c_fcr_opts_def = {
755 L2CAP_FCR_ERTM_MODE, /* Mandatory for OBEX over l2cap */
756 OBX_FCR_OPT_TX_WINDOW_SIZE_BR_EDR, /* Tx window size */
757 OBX_FCR_OPT_MAX_TX_B4_DISCNT, /* Maximum transmissions before
758 disconnecting */
759 OBX_FCR_OPT_RETX_TOUT, /* Retransmission timeout (2 secs) */
760 OBX_FCR_OPT_MONITOR_TOUT, /* Monitor timeout (12 secs) */
761 OBX_FCR_OPT_MAX_PDU_SIZE /* MPS segment size */
Kim Schulz8372aa52015-03-25 10:39:40 +0100762};
Myles Watson6bd442f2016-10-19 09:50:22 -0700763const tL2CAP_ERTM_INFO obex_l2c_etm_opt = {
764 L2CAP_FCR_ERTM_MODE, /* Mandatory for OBEX over l2cap */
765 L2CAP_FCR_CHAN_OPT_ERTM, /* Mandatory for OBEX over l2cap */
766 OBX_USER_RX_BUF_SIZE, OBX_USER_TX_BUF_SIZE,
767 OBX_FCR_RX_BUF_SIZE, OBX_FCR_TX_BUF_SIZE};
Kim Schulz8372aa52015-03-25 10:39:40 +0100768
769/**
Myles Watson6bd442f2016-10-19 09:50:22 -0700770 * When using a dynamic PSM, a PSM allocation is requested from
771 * btsock_l2cap_listen_or_connect().
772 * The PSM allocation event is refeived in the JV-callback - currently located
773 * in RFC-code -
Kim Schulz8372aa52015-03-25 10:39:40 +0100774 * and this function is called with the newly allocated PSM.
775 */
776void on_l2cap_psm_assigned(int id, int psm) {
Myles Watson6bd442f2016-10-19 09:50:22 -0700777 /* Setup ETM settings:
778 * mtu will be set below */
779 std::unique_lock<std::mutex> lock(state_lock);
780 l2cap_socket* sock = btsock_l2cap_find_by_id_l(id);
781 if (!sock) {
782 APPL_TRACE_ERROR("%s: Error: sock is null", __func__);
783 return;
784 }
Kim Schulz8372aa52015-03-25 10:39:40 +0100785
Myles Watson6bd442f2016-10-19 09:50:22 -0700786 sock->channel = psm;
Marie Janssena5764682016-10-10 13:38:30 -0700787
Jakub Pawlowskie5e2dd52018-01-30 21:46:08 -0800788 btsock_l2cap_server_listen(sock);
Kim Schulz8372aa52015-03-25 10:39:40 +0100789}
790
Jakub Pawlowskie5e2dd52018-01-30 21:46:08 -0800791static void btsock_l2cap_server_listen(l2cap_socket* sock) {
Stanley Tng49dd53c2017-12-20 09:38:30 -0800792 APPL_TRACE_DEBUG("%s: fixed_chan=%d, channel=%d, is_le_coc=%d", __func__,
793 sock->fixed_chan, sock->channel, sock->is_le_coc);
794
Myles Watson6bd442f2016-10-19 09:50:22 -0700795 if (sock->fixed_chan) {
Jakub Pawlowskie5e2dd52018-01-30 21:46:08 -0800796 BTA_JvL2capStartServerLE(sock->channel, btsock_l2cap_cbk, sock->id);
797 return;
Myles Watson6bd442f2016-10-19 09:50:22 -0700798 }
Jakub Pawlowskie5e2dd52018-01-30 21:46:08 -0800799
800 int connection_type =
801 sock->is_le_coc ? BTA_JV_CONN_TYPE_L2CAP_LE : BTA_JV_CONN_TYPE_L2CAP;
802
803 /* If we have a channel specified in the request, just start the server,
804 * else we request a PSM and start the server after we receive a PSM. */
805 if (sock->channel <= 0) {
806 BTA_JvGetChannelId(connection_type, sock->id, 0);
807 return;
808 }
809
810 /* Setup ETM settings: mtu will be set below */
811 std::unique_ptr<tL2CAP_CFG_INFO> cfg = std::make_unique<tL2CAP_CFG_INFO>(
812 tL2CAP_CFG_INFO{.fcr_present = true, .fcr = obex_l2c_fcr_opts_def});
813
814 std::unique_ptr<tL2CAP_ERTM_INFO> ertm_info;
815 if (!sock->is_le_coc) {
816 ertm_info.reset(new tL2CAP_ERTM_INFO(obex_l2c_etm_opt));
817 }
818
819 BTA_JvL2capStartServer(
820 connection_type, sock->security, 0, std::move(ertm_info), sock->channel,
821 L2CAP_MAX_SDU_LENGTH, std::move(cfg), btsock_l2cap_cbk, sock->id);
Myles Watson6bd442f2016-10-19 09:50:22 -0700822}
823
824static bt_status_t btsock_l2cap_listen_or_connect(const char* name,
Jakub Pawlowskia484a882017-06-24 17:30:18 -0700825 const RawAddress* addr,
Myles Watson6bd442f2016-10-19 09:50:22 -0700826 int channel, int* sock_fd,
827 int flags, char listen,
828 int app_uid) {
Myles Watson6bd442f2016-10-19 09:50:22 -0700829 int fixed_chan = 1;
830 l2cap_socket* sock;
831 tL2CAP_CFG_INFO cfg;
832 bool is_le_coc = false;
833
834 if (!sock_fd) return BT_STATUS_PARM_INVALID;
835
836 if (channel < 0) {
837 // We need to auto assign a PSM
838 fixed_chan = 0;
839 } else {
Stanley Tnga34e9b42018-01-05 09:25:11 -0800840 is_le_coc = (flags & BTSOCK_FLAG_LE_COC) != 0;
Myles Watson6bd442f2016-10-19 09:50:22 -0700841 fixed_chan = (channel & L2CAP_MASK_FIXED_CHANNEL) != 0;
Stanley Tnga34e9b42018-01-05 09:25:11 -0800842 channel &= ~L2CAP_MASK_FIXED_CHANNEL;
Myles Watson6bd442f2016-10-19 09:50:22 -0700843 }
844
845 if (!is_inited()) return BT_STATUS_NOT_READY;
846
847 // TODO: This is kind of bad to lock here, but it is needed for the current
848 // design.
849 std::unique_lock<std::mutex> lock(state_lock);
850 sock = btsock_l2cap_alloc_l(name, addr, listen, flags);
851 if (!sock) {
852 return BT_STATUS_NOMEM;
853 }
854
855 sock->fixed_chan = fixed_chan;
856 sock->channel = channel;
857 sock->app_uid = app_uid;
858 sock->is_le_coc = is_le_coc;
859
Jakub Pawlowski8ba54322017-10-30 12:38:30 -0700860 /* Setup ETM settings: mtu will be set below */
Myles Watson6bd442f2016-10-19 09:50:22 -0700861 memset(&cfg, 0, sizeof(tL2CAP_CFG_INFO));
862
863 cfg.fcr_present = true;
864 cfg.fcr = obex_l2c_fcr_opts_def;
865
866 /* "role" is never initialized in rfcomm code */
867 if (listen) {
Jakub Pawlowskie5e2dd52018-01-30 21:46:08 -0800868 btsock_l2cap_server_listen(sock);
Myles Watson6bd442f2016-10-19 09:50:22 -0700869 } else {
870 if (fixed_chan) {
Jakub Pawlowski8ba54322017-10-30 12:38:30 -0700871 BTA_JvL2capConnectLE(sock->security, 0, NULL, channel, L2CAP_DEFAULT_MTU,
872 NULL, sock->addr, btsock_l2cap_cbk, sock->id);
Kim Schulz8372aa52015-03-25 10:39:40 +0100873 } else {
Myles Watson6bd442f2016-10-19 09:50:22 -0700874 if (sock->is_le_coc) {
Jakub Pawlowski8ba54322017-10-30 12:38:30 -0700875 BTA_JvL2capConnect(BTA_JV_CONN_TYPE_L2CAP_LE, sock->security, 0, NULL,
876 channel, L2CAP_MAX_SDU_LENGTH, &cfg, sock->addr,
877 btsock_l2cap_cbk, sock->id);
Myles Watson6bd442f2016-10-19 09:50:22 -0700878 } else {
Jakub Pawlowski8ba54322017-10-30 12:38:30 -0700879 BTA_JvL2capConnect(BTA_JV_CONN_TYPE_L2CAP, sock->security, 0,
880 &obex_l2c_etm_opt, channel, L2CAP_MAX_SDU_LENGTH,
881 &cfg, sock->addr, btsock_l2cap_cbk, sock->id);
Myles Watson6bd442f2016-10-19 09:50:22 -0700882 }
Kim Schulz8372aa52015-03-25 10:39:40 +0100883 }
Myles Watson6bd442f2016-10-19 09:50:22 -0700884 }
885
Jakub Pawlowski8ba54322017-10-30 12:38:30 -0700886 *sock_fd = sock->app_fd;
887 /* We pass the FD to JAVA, but since it runs in another process, we need to
888 * also close it in native, either straight away, as done when accepting an
889 * incoming connection, or when doing cleanup after this socket */
890 sock->app_fd = -1;
891 /*This leaks the file descriptor. The FD should be closed in JAVA but it
892 * apparently do not work */
893 btsock_thread_add_fd(pth, sock->our_fd, BTSOCK_L2CAP,
894 SOCK_THREAD_FD_EXCEPTION, sock->id);
Myles Watson6bd442f2016-10-19 09:50:22 -0700895
Jakub Pawlowski8ba54322017-10-30 12:38:30 -0700896 return BT_STATUS_SUCCESS;
Kim Schulz8372aa52015-03-25 10:39:40 +0100897}
898
Myles Watson6bd442f2016-10-19 09:50:22 -0700899bt_status_t btsock_l2cap_listen(const char* name, int channel, int* sock_fd,
900 int flags, int app_uid) {
901 return btsock_l2cap_listen_or_connect(name, NULL, channel, sock_fd, flags, 1,
902 app_uid);
Kim Schulz8372aa52015-03-25 10:39:40 +0100903}
904
Jakub Pawlowskia484a882017-06-24 17:30:18 -0700905bt_status_t btsock_l2cap_connect(const RawAddress* bd_addr, int channel,
Myles Watson6bd442f2016-10-19 09:50:22 -0700906 int* sock_fd, int flags, int app_uid) {
907 return btsock_l2cap_listen_or_connect(NULL, bd_addr, channel, sock_fd, flags,
908 0, app_uid);
Kim Schulz8372aa52015-03-25 10:39:40 +0100909}
910
Myles Watson6bd442f2016-10-19 09:50:22 -0700911/* return true if we have more to send and should wait for user readiness, false
912 * else
Kim Schulz8372aa52015-03-25 10:39:40 +0100913 * (for example: unrecoverable error or no data)
914 */
Myles Watson6bd442f2016-10-19 09:50:22 -0700915static bool flush_incoming_que_on_wr_signal_l(l2cap_socket* sock) {
916 uint8_t* buf;
917 uint32_t len;
Kim Schulz8372aa52015-03-25 10:39:40 +0100918
Myles Watson6bd442f2016-10-19 09:50:22 -0700919 while (packet_get_head_l(sock, &buf, &len)) {
920 ssize_t sent;
921 OSI_NO_INTR(sent = send(sock->our_fd, buf, len, MSG_DONTWAIT));
922 int saved_errno = errno;
Kim Schulz8372aa52015-03-25 10:39:40 +0100923
Myles Watson6bd442f2016-10-19 09:50:22 -0700924 if (sent == (signed)len)
925 osi_free(buf);
926 else if (sent >= 0) {
927 packet_put_head_l(sock, buf + sent, len - sent);
928 osi_free(buf);
929 if (!sent) /* special case if other end not keeping up */
930 return true;
931 } else {
932 packet_put_head_l(sock, buf, len);
933 osi_free(buf);
934 return saved_errno == EWOULDBLOCK || saved_errno == EAGAIN;
Kim Schulz8372aa52015-03-25 10:39:40 +0100935 }
Myles Watson6bd442f2016-10-19 09:50:22 -0700936 }
Kim Schulz8372aa52015-03-25 10:39:40 +0100937
Myles Watson6bd442f2016-10-19 09:50:22 -0700938 return false;
Kim Schulz8372aa52015-03-25 10:39:40 +0100939}
940
Jakub Pawlowski84519312018-01-12 06:22:43 -0800941inline BT_HDR* malloc_l2cap_buf(uint16_t len) {
942 // We need FCS only for L2CAP_FCR_ERTM_MODE, but it's just 2 bytes so it's ok
943 BT_HDR* msg = (BT_HDR*)osi_malloc(BT_HDR_SIZE + L2CAP_MIN_OFFSET + len +
944 L2CAP_FCS_LENGTH);
945 msg->offset = L2CAP_MIN_OFFSET;
946 msg->len = len;
947 return msg;
948}
949
950inline uint8_t* get_l2cap_sdu_start_ptr(BT_HDR* msg) {
951 return (uint8_t*)(msg) + BT_HDR_SIZE + msg->offset;
952}
953
Myles Watson6bd442f2016-10-19 09:50:22 -0700954void btsock_l2cap_signaled(int fd, int flags, uint32_t user_id) {
Myles Watson6bd442f2016-10-19 09:50:22 -0700955 char drop_it = false;
Kim Schulz8372aa52015-03-25 10:39:40 +0100956
Myles Watson6bd442f2016-10-19 09:50:22 -0700957 /* We use MSG_DONTWAIT when sending data to JAVA, hence it can be accepted to
958 * hold the lock. */
959 std::unique_lock<std::mutex> lock(state_lock);
Jakub Pawlowski8452b052018-01-05 02:41:36 -0800960 l2cap_socket* sock = btsock_l2cap_find_by_id_l(user_id);
Myles Watson6bd442f2016-10-19 09:50:22 -0700961 if (!sock) return;
Kim Schulz8372aa52015-03-25 10:39:40 +0100962
Myles Watson6bd442f2016-10-19 09:50:22 -0700963 if ((flags & SOCK_THREAD_FD_RD) && !sock->server) {
964 // app sending data
965 if (sock->connected) {
966 int size = 0;
Jakub Pawlowski8452b052018-01-05 02:41:36 -0800967 bool ioctl_success = ioctl(sock->our_fd, FIONREAD, &size) == 0;
968 if (!(flags & SOCK_THREAD_FD_EXCEPTION) || (ioctl_success && size)) {
969 /* FIONREAD return number of bytes that are immediately available for
970 reading, might be bigger than awaiting packet.
Arman Uguraybb954522015-06-02 21:11:07 -0700971
Jakub Pawlowski8452b052018-01-05 02:41:36 -0800972 BluetoothSocket.write(...) guarantees that any packet send to this
Jakub Pawlowski6ee309d2018-01-30 19:39:52 -0800973 socket is broken into pieces no bigger than MTU bytes (as requested
Jakub Pawlowski8452b052018-01-05 02:41:36 -0800974 by BT spec). */
Jakub Pawlowski6ee309d2018-01-30 19:39:52 -0800975 size = std::min(size, (int)sock->mtu);
Jakub Pawlowski8452b052018-01-05 02:41:36 -0800976
Jakub Pawlowski84519312018-01-12 06:22:43 -0800977 BT_HDR* buffer = malloc_l2cap_buf(size);
Myles Watson6bd442f2016-10-19 09:50:22 -0700978 /* The socket is created with SOCK_SEQPACKET, hence we read one message
Jakub Pawlowski8452b052018-01-05 02:41:36 -0800979 * at the time. */
Myles Watson6bd442f2016-10-19 09:50:22 -0700980 ssize_t count;
Jakub Pawlowski84519312018-01-12 06:22:43 -0800981 OSI_NO_INTR(count = recv(fd, get_l2cap_sdu_start_ptr(buffer), size,
Jakub Pawlowski8452b052018-01-05 02:41:36 -0800982 MSG_NOSIGNAL | MSG_DONTWAIT | MSG_TRUNC));
Jakub Pawlowski408b5f92018-01-30 19:45:35 -0800983 if (count > sock->mtu) {
Jakub Pawlowski8452b052018-01-05 02:41:36 -0800984 /* This can't happen thanks to check in BluetoothSocket.java but leave
985 * this in case this socket is ever used anywhere else*/
Jakub Pawlowski6ee309d2018-01-30 19:39:52 -0800986 LOG(ERROR) << "recv more than MTU. Data will be lost: " << count;
Jakub Pawlowski408b5f92018-01-30 19:45:35 -0800987 count = sock->mtu;
Jakub Pawlowski8452b052018-01-05 02:41:36 -0800988 }
989
Stanley Tng44922882018-01-25 11:40:35 -0800990 /* When multiple packets smaller than MTU are flushed to the socket, the
991 size of the single packet read could be smaller than the ioctl
992 reported total size of awaiting packets. Hence, we adjust the buffer
993 length. */
994 buffer->len = count;
Jakub Pawlowski8452b052018-01-05 02:41:36 -0800995 DVLOG(2) << __func__ << ": bytes received from socket: " << count;
Marie Janssena5764682016-10-10 13:38:30 -0700996
Myles Watson6bd442f2016-10-19 09:50:22 -0700997 if (sock->fixed_chan) {
Jakub Pawlowskic4743422018-01-11 07:34:39 -0800998 // will take care of freeing buffer
999 BTA_JvL2capWriteFixed(sock->channel, sock->addr, PTR_TO_UINT(buffer),
Jakub Pawlowski84519312018-01-12 06:22:43 -08001000 btsock_l2cap_cbk, buffer, user_id);
Myles Watson6bd442f2016-10-19 09:50:22 -07001001 } else {
Jakub Pawlowskic4743422018-01-11 07:34:39 -08001002 // will take care of freeing buffer
Jakub Pawlowski84519312018-01-12 06:22:43 -08001003 BTA_JvL2capWrite(sock->handle, PTR_TO_UINT(buffer), buffer, user_id);
Myles Watson6bd442f2016-10-19 09:50:22 -07001004 }
1005 }
1006 } else
1007 drop_it = true;
1008 }
1009 if (flags & SOCK_THREAD_FD_WR) {
1010 // app is ready to receive more data, tell stack to enable the data flow
1011 if (flush_incoming_que_on_wr_signal_l(sock) && sock->connected)
1012 btsock_thread_add_fd(pth, sock->our_fd, BTSOCK_L2CAP, SOCK_THREAD_FD_WR,
1013 sock->id);
1014 }
1015 if (drop_it || (flags & SOCK_THREAD_FD_EXCEPTION)) {
1016 int size = 0;
1017 if (drop_it || ioctl(sock->our_fd, FIONREAD, &size) != 0 || size == 0)
1018 btsock_l2cap_free_l(sock);
1019 }
Kim Schulz8372aa52015-03-25 10:39:40 +01001020}