1 /******************************************************************************
2 *
3 * Copyright 1999-2012 Broadcom Corporation
4 *
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 *
17 ******************************************************************************/
18
19 /******************************************************************************
20 *
21 * this file contains the Serial Port API code
22 *
23 ******************************************************************************/
24
25 #define LOG_TAG "bt_port_api"
26
27 #include "stack/include/port_api.h"
28
29 #include <base/strings/stringprintf.h>
30 #include <bluetooth/log.h>
31
32 #include <cstdint>
33
34 #include "internal_include/bt_trace.h"
35 #include "os/logging/log_adapter.h"
36 #include "osi/include/allocator.h"
37 #include "osi/include/mutex.h"
38 #include "stack/include/bt_hdr.h"
39 #include "stack/include/bt_types.h"
40 #include "stack/include/bt_uuid16.h"
41 #include "stack/include/btm_log_history.h"
42 #include "stack/include/rfcdefs.h"
43 #include "stack/rfcomm/rfc_int.h"
44 #include "types/raw_address.h"
45
46 using namespace bluetooth;
47
48 /* Mapping from PORT_* result codes to human readable strings. */
49 static const char* result_code_strings[] = {"Success",
50 "Unknown error",
51 "Already opened",
52 "Command pending",
53 "App not registered",
54 "No memory",
55 "No resources",
56 "Bad BD address",
57 "Unspecified error",
58 "Bad handle",
59 "Not opened",
60 "Line error",
61 "Start failed",
62 "Parameter negotiation failed",
63 "Port negotiation failed",
64 "Sec failed",
65 "Peer connection failed",
66 "Peer failed",
67 "Peer timeout",
68 "Closed",
69 "TX full",
70 "Local closed",
71 "Local timeout",
72 "TX queue disabled",
73 "Page timeout",
74 "Invalid SCN",
75 "Unknown result code"};
76
77 namespace {
78 const char kBtmLogTag[] = "RFCOMM";
79 } // namespace
80
81 /*******************************************************************************
82 *
83 * Function RFCOMM_CreateConnectionWithSecurity
84 *
85 * Description RFCOMM_CreateConnectionWithSecurity function is used from
86 *the application to establish serial port connection to the peer device, or
87 *allow RFCOMM to accept a connection from the peer application.
88 *
89 * Parameters: scn - Service Channel Number as registered with
90 * the SDP (server) or obtained using SDP from
91 * the peer device (client).
92 * is_server - true if requesting application is a server
93 * mtu - Maximum frame size the application can accept
94 * bd_addr - address of the peer (client)
95 * p_handle - OUT pointer to the handle.
96 * p_mgmt_callback - pointer to callback function to receive
97 * connection up/down events.
98 * sec_mask - bitmask of BTM_SEC_* values indicating the
99 * minimum security requirements for this
100 *connection Notes:
101 *
102 * Server can call this function with the same scn parameter multiple times if
103 * it is ready to accept multiple simulteneous connections.
104 *
105 * DLCI for the connection is (scn * 2 + 1) if client originates connection on
106 * existing none initiator multiplexer channel. Otherwise it is (scn * 2).
107 * For the server DLCI can be changed later if client will be calling it using
108 * (scn * 2 + 1) dlci.
109 *
110 ******************************************************************************/
RFCOMM_CreateConnectionWithSecurity(uint16_t uuid,uint8_t scn,bool is_server,uint16_t mtu,const RawAddress & bd_addr,uint16_t * p_handle,tPORT_MGMT_CALLBACK * p_mgmt_callback,uint16_t sec_mask)111 int RFCOMM_CreateConnectionWithSecurity(uint16_t uuid, uint8_t scn, bool is_server, uint16_t mtu,
112 const RawAddress& bd_addr, uint16_t* p_handle,
113 tPORT_MGMT_CALLBACK* p_mgmt_callback, uint16_t sec_mask) {
114 *p_handle = 0;
115
116 if ((scn == 0) || (scn > RFCOMM_MAX_SCN)) {
117 // Server Channel Number (SCN) should be in range [1, 30]
118 log::error("Invalid SCN, bd_addr={}, scn={}, is_server={}, mtu={}, uuid=0x{:x}", bd_addr,
119 static_cast<int>(scn), is_server, static_cast<int>(mtu), uuid);
120 return PORT_INVALID_SCN;
121 }
122
123 // For client that originates connection on the existing none initiator
124 // multiplexer channel, DLCI should be odd.
125 uint8_t dlci;
126 tRFC_MCB* p_mcb = port_find_mcb(bd_addr);
127 if (p_mcb && !p_mcb->is_initiator && !is_server) {
128 dlci = static_cast<uint8_t>((scn << 1) + 1);
129 } else {
130 dlci = (scn << 1);
131 }
132
133 // On the client side, do not allow the same (dlci, bd_addr) to be opened
134 // twice by application
135 tPORT* p_port{nullptr};
136 if (!is_server) {
137 p_port = port_find_port(dlci, bd_addr);
138 if (p_port != nullptr) {
139 // if existing port is also a client port, error out
140 if (!p_port->is_server) {
141 log::error(
142 "already at opened state {}, RFC_state={}, MCB_state={}, "
143 "bd_addr={}, scn={}, is_server={}, mtu={}, uuid=0x{:x}, dlci={}, p_mcb={}, port={}",
144 static_cast<int>(p_port->state), static_cast<int>(p_port->rfc.state),
145 p_port->rfc.p_mcb ? p_port->rfc.p_mcb->state : 0, bd_addr, scn, is_server, mtu,
146 uuid, dlci, std::format_ptr(p_mcb), p_port->handle);
147 *p_handle = p_port->handle;
148 return PORT_ALREADY_OPENED;
149 }
150 }
151 }
152
153 // On the server side, always allocate a new port.
154 p_port = port_allocate_port(dlci, bd_addr);
155 if (p_port == nullptr) {
156 log::error("no resources, bd_addr={}, scn={}, is_server={}, mtu={}, uuid=0x{:x}, dlci={}",
157 bd_addr, scn, is_server, mtu, uuid, dlci);
158 return PORT_NO_RESOURCES;
159 }
160 p_port->sec_mask = sec_mask;
161 *p_handle = p_port->handle;
162
163 // Get default signal state
164 switch (uuid) {
165 case UUID_PROTOCOL_OBEX:
166 p_port->default_signal_state = PORT_OBEX_DEFAULT_SIGNAL_STATE;
167 break;
168 case UUID_SERVCLASS_SERIAL_PORT:
169 p_port->default_signal_state = PORT_SPP_DEFAULT_SIGNAL_STATE;
170 break;
171 case UUID_SERVCLASS_LAN_ACCESS_USING_PPP:
172 p_port->default_signal_state = PORT_PPP_DEFAULT_SIGNAL_STATE;
173 break;
174 case UUID_SERVCLASS_DIALUP_NETWORKING:
175 case UUID_SERVCLASS_FAX:
176 p_port->default_signal_state = PORT_DUN_DEFAULT_SIGNAL_STATE;
177 break;
178 default:
179 p_port->default_signal_state = (PORT_DTRDSR_ON | PORT_CTSRTS_ON | PORT_DCD_ON);
180 break;
181 }
182
183 // Assign port specific values
184 p_port->state = PORT_CONNECTION_STATE_OPENING;
185 p_port->uuid = uuid;
186 p_port->is_server = is_server;
187 p_port->scn = scn;
188 p_port->ev_mask = 0;
189
190 // Find MTU
191 // If the MTU is not specified (0), keep MTU decision until the PN frame has
192 // to be send at that time connection should be established and we will know
193 // for sure our prefered MTU
194 uint16_t rfcomm_mtu = L2CAP_MTU_SIZE - RFCOMM_DATA_OVERHEAD;
195 if (mtu) {
196 p_port->mtu = (mtu < rfcomm_mtu) ? mtu : rfcomm_mtu;
197 } else {
198 p_port->mtu = rfcomm_mtu;
199 }
200
201 // Other states
202 // server doesn't need to release port when closing
203 if (is_server) {
204 p_port->keep_port_handle = true;
205 // keep mtu that user asked, p_port->mtu could be updated during param
206 // negotiation
207 p_port->keep_mtu = p_port->mtu;
208 }
209 p_port->local_ctrl.modem_signal = p_port->default_signal_state;
210 p_port->local_ctrl.fc = false;
211 p_port->p_mgmt_callback = p_mgmt_callback;
212 p_port->bd_addr = bd_addr;
213
214 log::info(
215 "bd_addr={}, scn={}, is_server={}, mtu={}, uuid=0x{:x}, dlci={}, "
216 "signal_state=0x{:x}, p_port={}",
217 bd_addr, scn, is_server, mtu, uuid, dlci, p_port->default_signal_state,
218 std::format_ptr(p_port));
219
220 // If this is not initiator of the connection need to just wait
221 if (p_port->is_server) {
222 BTM_LogHistory(
223 kBtmLogTag, bd_addr, "Server started",
224 base::StringPrintf("handle:%hu scn:%hhu dlci:%hhu mtu:%hu", *p_handle, scn, dlci, mtu));
225 return PORT_SUCCESS;
226 }
227
228 BTM_LogHistory(
229 kBtmLogTag, bd_addr, "Connection opened",
230 base::StringPrintf("handle:%hu scn:%hhu dlci:%hhu mtu:%hu", *p_handle, scn, dlci, mtu));
231
232 // Open will be continued after security checks are passed
233 return port_open_continue(p_port);
234 }
235
236 /*******************************************************************************
237 *
238 * Function RFCOMM_ControlReqFromBTSOCK
239 *
240 * Description Send control parameters to the peer.
241 * So far only for qualification use.
242 * RFCOMM layer starts the control request only when it is the
243 * client. This API allows the host to start the control
244 * request while it works as a RFCOMM server.
245 *
246 * Parameters: dlci - the DLCI to send the MSC command
247 * bd_addr - bd_addr of the peer
248 * modem_signal - [DTR/DSR | RTS/CTS | RI | DCD]
249 * break_signal - 0-3 s in steps of 200 ms
250 * discard_buffers - 0 for do not discard, 1 for discard
251 * break_signal_seq - ASAP or in sequence
252 * fc - true when the device is unable to accept
253 * frames
254 *
255 ******************************************************************************/
RFCOMM_ControlReqFromBTSOCK(uint8_t dlci,const RawAddress & bd_addr,uint8_t modem_signal,uint8_t break_signal,uint8_t discard_buffers,uint8_t break_signal_seq,bool fc)256 int RFCOMM_ControlReqFromBTSOCK(uint8_t dlci, const RawAddress& bd_addr, uint8_t modem_signal,
257 uint8_t break_signal, uint8_t discard_buffers,
258 uint8_t break_signal_seq, bool fc) {
259 tRFC_MCB* p_mcb = port_find_mcb(bd_addr);
260 if (!p_mcb) {
261 return PORT_BAD_BD_ADDR;
262 }
263 tPORT* p_port = port_find_mcb_dlci_port(p_mcb, dlci);
264 if (!p_port) {
265 return PORT_NOT_OPENED;
266 }
267 p_port->local_ctrl.modem_signal = modem_signal;
268 p_port->local_ctrl.break_signal = break_signal;
269 p_port->local_ctrl.discard_buffers = discard_buffers;
270 p_port->local_ctrl.break_signal_seq = break_signal_seq;
271 p_port->local_ctrl.fc = fc;
272 RFCOMM_ControlReq(p_mcb, dlci, &p_port->local_ctrl);
273 return PORT_SUCCESS;
274 }
275
get_port_from_handle(uint16_t handle)276 static tPORT* get_port_from_handle(uint16_t handle) {
277 /* Check if handle is valid to avoid crashing */
278 if ((handle == 0) || (handle > MAX_RFC_PORTS)) {
279 return nullptr;
280 }
281 return &rfc_cb.port.port[handle - 1];
282 }
283
284 /*******************************************************************************
285 *
286 * Function RFCOMM_RemoveConnection
287 *
288 * Description This function is called to close the specified connection.
289 *
290 * Parameters: handle - Handle returned in the RFCOMM_CreateConnection
291 *
292 ******************************************************************************/
RFCOMM_RemoveConnection(uint16_t handle)293 int RFCOMM_RemoveConnection(uint16_t handle) {
294 log::verbose("RFCOMM_RemoveConnection() handle:{}", handle);
295
296 tPORT* p_port = get_port_from_handle(handle);
297 if (p_port == nullptr) {
298 log::error("Unable to get RFCOMM port control block bad handle:{}", handle);
299 return PORT_BAD_HANDLE;
300 }
301
302 if (!p_port->in_use || (p_port->state == PORT_CONNECTION_STATE_CLOSED)) {
303 log::verbose("RFCOMM_RemoveConnection() Not opened:{}", handle);
304 return PORT_SUCCESS;
305 }
306
307 const RawAddress bd_addr =
308 (p_port->rfc.p_mcb) ? (p_port->rfc.p_mcb->bd_addr) : (RawAddress::kEmpty);
309 BTM_LogHistory(
310 kBtmLogTag, bd_addr, "Connection closed",
311 base::StringPrintf("handle:%hu scn:%hhu dlci:%hhu is_server:%s", handle, p_port->scn,
312 p_port->dlci, p_port->is_server ? "true" : "false"));
313
314 p_port->state = PORT_CONNECTION_STATE_CLOSING;
315
316 port_start_close(p_port);
317
318 return PORT_SUCCESS;
319 }
320
321 /*******************************************************************************
322 *
323 * Function RFCOMM_RemoveServer
324 *
325 * Description This function is called to close the server port.
326 *
327 * Parameters: handle - Handle returned in the RFCOMM_CreateConnection
328 *
329 ******************************************************************************/
RFCOMM_RemoveServer(uint16_t handle)330 int RFCOMM_RemoveServer(uint16_t handle) {
331 tPORT* p_port = get_port_from_handle(handle);
332 if (p_port == nullptr) {
333 log::error("Unable to get RFCOMM port control block bad handle:{}", handle);
334 return PORT_BAD_HANDLE;
335 }
336
337 /* Do not report any events to the client any more. */
338 p_port->p_mgmt_callback = nullptr;
339
340 if (!p_port->in_use || (p_port->state == PORT_CONNECTION_STATE_CLOSED)) {
341 log::debug("handle {} not opened", handle);
342 return PORT_SUCCESS;
343 }
344 log::info("handle={}", handle);
345
346 const RawAddress bd_addr =
347 (p_port->rfc.p_mcb) ? (p_port->rfc.p_mcb->bd_addr) : (RawAddress::kEmpty);
348 BTM_LogHistory(
349 kBtmLogTag, bd_addr, "Server stopped",
350 base::StringPrintf("handle:%hu scn:%hhu dlci:%hhu is_server:%s", handle, p_port->scn,
351 p_port->dlci, p_port->is_server ? "true" : "false"));
352
353 /* this port will be deallocated after closing */
354 p_port->keep_port_handle = false;
355 p_port->state = PORT_CONNECTION_STATE_CLOSING;
356
357 port_start_close(p_port);
358
359 return PORT_SUCCESS;
360 }
361
PORT_SetEventMaskAndCallback(uint16_t handle,uint32_t mask,tPORT_CALLBACK * p_port_cb)362 int PORT_SetEventMaskAndCallback(uint16_t handle, uint32_t mask, tPORT_CALLBACK* p_port_cb) {
363 log::verbose("handle:{} mask:0x{:x}", handle, mask);
364 tPORT* p_port = get_port_from_handle(handle);
365 if (p_port == nullptr) {
366 log::error("Unable to get RFCOMM port control block bad handle:{}", handle);
367 return PORT_BAD_HANDLE;
368 }
369
370 if (!p_port->in_use || (p_port->state == PORT_CONNECTION_STATE_CLOSED)) {
371 return PORT_NOT_OPENED;
372 }
373
374 p_port->ev_mask = mask;
375 p_port->p_callback = p_port_cb;
376
377 return PORT_SUCCESS;
378 }
379
380 /*******************************************************************************
381 *
382 * Function PORT_ClearKeepHandleFlag
383 *
384 * Description Clear the keep handle flag, which will cause not to keep the
385 * port handle open when closed
386 * Parameters: handle - Handle returned in the RFCOMM_CreateConnection
387 *
388 ******************************************************************************/
389
PORT_ClearKeepHandleFlag(uint16_t handle)390 int PORT_ClearKeepHandleFlag(uint16_t handle) {
391 tPORT* p_port = get_port_from_handle(handle);
392 if (p_port == nullptr) {
393 log::error("Unable to get RFCOMM port control block bad handle:{}", handle);
394 return PORT_BAD_HANDLE;
395 }
396 p_port->keep_port_handle = 0;
397 return PORT_SUCCESS;
398 }
399
400 /*******************************************************************************
401 *
402 * Function PORT_SetCODataCallback
403 *
404 * Description This function is when a data packet is received
405 *
406 * Parameters: handle - Handle returned in the RFCOMM_CreateConnection
407 * p_callback - address of the callback function which should
408 * be called from the RFCOMM when data packet
409 * is received.
410 *
411 *
412 ******************************************************************************/
PORT_SetDataCOCallback(uint16_t handle,tPORT_DATA_CO_CALLBACK * p_port_cb)413 int PORT_SetDataCOCallback(uint16_t handle, tPORT_DATA_CO_CALLBACK* p_port_cb) {
414 log::verbose("handle:{} cb 0x{}", handle, std::format_ptr(p_port_cb));
415
416 tPORT* p_port = get_port_from_handle(handle);
417 if (p_port == nullptr) {
418 log::error("Unable to get RFCOMM port control block bad handle:{}", handle);
419 return PORT_BAD_HANDLE;
420 }
421 if (!p_port->in_use || (p_port->state == PORT_CONNECTION_STATE_CLOSED)) {
422 return PORT_NOT_OPENED;
423 }
424
425 p_port->p_data_co_callback = p_port_cb;
426
427 return PORT_SUCCESS;
428 }
429
430 /*******************************************************************************
431 *
432 * Function PORT_CheckConnection
433 *
434 * Description This function returns PORT_SUCCESS if connection referenced
435 * by handle is up and running
436 *
437 * Parameters: handle - Handle returned in the RFCOMM_CreateConnection
438 * bd_addr - OUT bd_addr of the peer
439 * p_lcid - OUT L2CAP's LCID
440 *
441 ******************************************************************************/
PORT_CheckConnection(uint16_t handle,RawAddress * bd_addr,uint16_t * p_lcid)442 int PORT_CheckConnection(uint16_t handle, RawAddress* bd_addr, uint16_t* p_lcid) {
443 tPORT* p_port = get_port_from_handle(handle);
444 if (p_port == nullptr) {
445 log::error("Unable to get RFCOMM port control block bad handle:{}", handle);
446 return PORT_BAD_HANDLE;
447 }
448 log::verbose("handle={}, in_use={}, port_state={}, p_mcb={}, peer_ready={}, rfc_state={}", handle,
449 p_port->in_use, p_port->state, std::format_ptr(p_port->rfc.p_mcb),
450 p_port->rfc.p_mcb ? p_port->rfc.p_mcb->peer_ready : -1, p_port->rfc.state);
451
452 if (!p_port->in_use || (p_port->state == PORT_CONNECTION_STATE_CLOSED)) {
453 return PORT_NOT_OPENED;
454 }
455
456 if (!p_port->rfc.p_mcb || !p_port->rfc.p_mcb->peer_ready ||
457 (p_port->rfc.state != RFC_STATE_OPENED)) {
458 return PORT_LINE_ERR;
459 }
460
461 *bd_addr = p_port->rfc.p_mcb->bd_addr;
462 if (p_lcid) {
463 *p_lcid = p_port->rfc.p_mcb->lcid;
464 }
465
466 return PORT_SUCCESS;
467 }
468
469 /*******************************************************************************
470 *
471 * Function PORT_IsOpening
472 *
473 * Description This function returns true if there is any RFCOMM connection
474 * opening in process.
475 *
476 * Parameters: true if any connection opening is found
477 * bd_addr - bd_addr of the peer
478 *
479 ******************************************************************************/
get_port_from_mcb(const tRFC_MCB * multiplexer_cb)480 static const tPORT* get_port_from_mcb(const tRFC_MCB* multiplexer_cb) {
481 tPORT* p_port = nullptr;
482
483 for (tPORT& port : rfc_cb.port.port) {
484 if (port.rfc.p_mcb == multiplexer_cb) {
485 return &port;
486 }
487 }
488 return nullptr;
489 }
490
PORT_IsOpening(RawAddress * bd_addr)491 bool PORT_IsOpening(RawAddress* bd_addr) {
492 /* Check for any rfc_mcb which is in the middle of opening. */
493 for (auto& multiplexer_cb : rfc_cb.port.rfc_mcb) {
494 if ((multiplexer_cb.state > RFC_MX_STATE_IDLE) &&
495 (multiplexer_cb.state < RFC_MX_STATE_CONNECTED)) {
496 *bd_addr = multiplexer_cb.bd_addr;
497 log::info("Found a rfc_mcb in the middle of opening a port, returning true");
498 return true;
499 }
500
501 if (multiplexer_cb.state == RFC_MX_STATE_CONNECTED) {
502 const tPORT* p_port = get_port_from_mcb(&multiplexer_cb);
503 log::info("RFC_MX_STATE_CONNECTED, found_port={}, tRFC_PORT_STATE={}",
504 (p_port != nullptr) ? "T" : "F", (p_port != nullptr) ? p_port->rfc.state : 0);
505 if ((p_port == nullptr) || (p_port->rfc.state < RFC_STATE_OPENED)) {
506 /* Port is not established yet. */
507 *bd_addr = multiplexer_cb.bd_addr;
508 log::info("In RFC_MX_STATE_CONNECTED but port is not established yet, returning true");
509 return true;
510 }
511 }
512 }
513 log::info("false");
514 return false;
515 }
516
517 /*******************************************************************************
518 *
519 * Function PORT_IsCollisionDetected
520 *
521 * Description This function returns true if there is already an incoming
522 * RFCOMM connection in progress for this device
523 *
524 * Parameters: true if any connection opening is found
525 * bd_addr - bd_addr of the peer
526 *
527 ******************************************************************************/
PORT_IsCollisionDetected(RawAddress bd_addr)528 bool PORT_IsCollisionDetected(RawAddress bd_addr) {
529 for (auto& multiplexer_cb : rfc_cb.port.rfc_mcb) {
530 if (multiplexer_cb.bd_addr != RawAddress::kEmpty && multiplexer_cb.bd_addr != bd_addr) {
531 // there's no chance of a collision if the bd_addr is different
532 continue;
533 }
534 if (multiplexer_cb.is_initiator == false) {
535 // there's no chance of a collision if this side isn't a server
536 continue;
537 }
538 if ((multiplexer_cb.state > RFC_MX_STATE_IDLE) &&
539 (multiplexer_cb.state < RFC_MX_STATE_CONNECTED)) {
540 // this rfc_mcb is in the middle of opening
541 // bd_addr either matches or is empty and possibly not yet set
542 log::info("Found an opening rfc_mcb, multiplexer bd_addr={},returning true",
543 multiplexer_cb.bd_addr);
544 return true;
545 }
546 if (multiplexer_cb.state == RFC_MX_STATE_CONNECTED) {
547 const tPORT* p_port = get_port_from_mcb(&multiplexer_cb);
548 log::info("RFC_MX_STATE_CONNECTED, found_port={}, tRFC_PORT_STATE={}",
549 (p_port != nullptr) ? "T" : "F", (p_port != nullptr) ? p_port->rfc.state : 0);
550 if ((p_port == nullptr) || (p_port->rfc.state < RFC_STATE_OPENED)) {
551 // Port is not established yet
552 log::info(
553 "In RFC_MX_STATE_CONNECTED but port is not established yet, "
554 "returning true");
555 return true;
556 }
557 }
558 }
559 log::info("returning false");
560 return false;
561 }
562
563 /*******************************************************************************
564 *
565 * Function PORT_SetSettings
566 *
567 * Description This function configures connection according to the
568 * specifications in the PortSettings structure.
569 *
570 * Parameters: handle - Handle returned in the RFCOMM_CreateConnection
571 * p_settings - Pointer to a PortSettings structure containing
572 * configuration information for the connection.
573 *
574 *
575 ******************************************************************************/
PORT_SetSettings(uint16_t handle,PortSettings * p_settings)576 int PORT_SetSettings(uint16_t handle, PortSettings* p_settings) {
577 uint8_t baud_rate;
578
579 log::verbose("handle:{}", handle);
580 tPORT* p_port = get_port_from_handle(handle);
581 if (p_port == nullptr) {
582 log::error("Unable to get RFCOMM port control block bad handle:{}", handle);
583 return PORT_BAD_HANDLE;
584 }
585
586 if (!p_port->in_use || (p_port->state == PORT_CONNECTION_STATE_CLOSED)) {
587 return PORT_NOT_OPENED;
588 }
589
590 if (p_port->line_status) {
591 return PORT_LINE_ERR;
592 }
593
594 log::verbose("handle:{} FC_TYPE:0x{:x}", handle, p_settings->fc_type);
595
596 baud_rate = p_port->user_port_settings.baud_rate;
597 p_port->user_port_settings = *p_settings;
598
599 /* for now we've been asked to pass only baud rate */
600 if (baud_rate != p_settings->baud_rate) {
601 port_start_par_neg(p_port);
602 }
603 return PORT_SUCCESS;
604 }
605
606 /*******************************************************************************
607 *
608 * Function PORT_GetSettings
609 *
610 * Description This function is called to fill PortSettings structure
611 * with the curremt control settings for the port
612 *
613 * Parameters: handle - Handle returned in the RFCOMM_CreateConnection
614 * p_settings - Pointer to a PortSettings structure in which
615 * configuration information is returned.
616 *
617 ******************************************************************************/
PORT_GetSettings(uint16_t handle,PortSettings * p_settings)618 int PORT_GetSettings(uint16_t handle, PortSettings* p_settings) {
619 log::verbose("handle:{}", handle);
620
621 tPORT* p_port = get_port_from_handle(handle);
622 if (p_port == nullptr) {
623 log::error("Unable to get RFCOMM port control block bad handle:{}", handle);
624 return PORT_BAD_HANDLE;
625 }
626
627 if (!p_port->in_use || (p_port->state == PORT_CONNECTION_STATE_CLOSED)) {
628 return PORT_NOT_OPENED;
629 }
630
631 if (p_port->line_status) {
632 return PORT_LINE_ERR;
633 }
634
635 *p_settings = p_port->user_port_settings;
636 return PORT_SUCCESS;
637 }
638
639 /*******************************************************************************
640 *
641 * Function PORT_FlowControl_MaxCredit
642 *
643 * Description This function directs a specified connection to pass
644 * flow control message to the peer device. Enable flag passed
645 * shows if port can accept more data. It also sends max credit
646 * when data flow enabled
647 *
648 * Parameters: handle - Handle returned in the RFCOMM_CreateConnection
649 * enable - enables data flow
650 *
651 ******************************************************************************/
652
PORT_FlowControl_MaxCredit(uint16_t handle,bool enable)653 int PORT_FlowControl_MaxCredit(uint16_t handle, bool enable) {
654 bool old_fc;
655 uint32_t events;
656
657 log::verbose("handle:{} enable: {}", handle, enable);
658
659 tPORT* p_port = get_port_from_handle(handle);
660 if (p_port == nullptr) {
661 log::error("Unable to get RFCOMM port control block bad handle:{}", handle);
662 return PORT_BAD_HANDLE;
663 }
664
665 if (!p_port->in_use || (p_port->state == PORT_CONNECTION_STATE_CLOSED)) {
666 return PORT_NOT_OPENED;
667 }
668
669 if (!p_port->rfc.p_mcb) {
670 return PORT_NOT_OPENED;
671 }
672
673 p_port->rx.user_fc = !enable;
674
675 if (p_port->rfc.p_mcb->flow == PORT_FC_CREDIT) {
676 if (!p_port->rx.user_fc) {
677 port_flow_control_peer(p_port, true, p_port->credit_rx);
678 }
679 } else {
680 old_fc = p_port->local_ctrl.fc;
681
682 /* FC is set if user is set or peer is set */
683 p_port->local_ctrl.fc = (p_port->rx.user_fc | p_port->rx.peer_fc);
684
685 if (p_port->local_ctrl.fc != old_fc) {
686 port_start_control(p_port);
687 }
688 }
689
690 /* Need to take care of the case when we could not deliver events */
691 /* to the application because we were flow controlled */
692 if (enable && (p_port->rx.queue_size != 0)) {
693 events = PORT_EV_RXCHAR;
694 if (p_port->rx_flag_ev_pending) {
695 p_port->rx_flag_ev_pending = false;
696 events |= PORT_EV_RXFLAG;
697 }
698
699 events &= p_port->ev_mask;
700 if (p_port->p_callback && events) {
701 p_port->p_callback(events, p_port->handle);
702 }
703 }
704 return PORT_SUCCESS;
705 }
706
707 /*******************************************************************************
708 *
709 * Function PORT_ReadData
710 *
711 * Description Normally not GKI aware application will call this function
712 * after receiving PORT_EV_RXCHAR event.
713 *
714 * Parameters: handle - Handle returned in the RFCOMM_CreateConnection
715 * p_data - Data area
716 * max_len - Byte count requested
717 * p_len - Byte count received
718 *
719 ******************************************************************************/
PORT_ReadData(uint16_t handle,char * p_data,uint16_t max_len,uint16_t * p_len)720 int PORT_ReadData(uint16_t handle, char* p_data, uint16_t max_len, uint16_t* p_len) {
721 BT_HDR* p_buf;
722 uint16_t count;
723
724 log::verbose("handle:{} max_len:{}", handle, max_len);
725
726 /* Initialize this in case of an error */
727 *p_len = 0;
728
729 tPORT* p_port = get_port_from_handle(handle);
730 if (p_port == nullptr) {
731 log::error("Unable to get RFCOMM port control block bad handle:{}", handle);
732 return PORT_BAD_HANDLE;
733 }
734
735 if (!p_port->in_use || (p_port->state == PORT_CONNECTION_STATE_CLOSED)) {
736 return PORT_NOT_OPENED;
737 }
738
739 if (p_port->state == PORT_CONNECTION_STATE_OPENING) {
740 log::warn("Trying to read a port in PORT_CONNECTION_STATE_OPENING state");
741 }
742
743 if (p_port->line_status) {
744 return PORT_LINE_ERR;
745 }
746
747 if (fixed_queue_is_empty(p_port->rx.queue)) {
748 log::warn("Read on empty input queue");
749 return PORT_SUCCESS;
750 }
751
752 count = 0;
753
754 while (max_len) {
755 p_buf = (BT_HDR*)fixed_queue_try_peek_first(p_port->rx.queue);
756 if (p_buf == NULL) {
757 break;
758 }
759
760 if (p_buf->len > max_len) {
761 memcpy(p_data, (uint8_t*)(p_buf + 1) + p_buf->offset, max_len);
762 p_buf->offset += max_len;
763 p_buf->len -= max_len;
764
765 *p_len += max_len;
766
767 mutex_global_lock();
768
769 p_port->rx.queue_size -= max_len;
770
771 mutex_global_unlock();
772
773 break;
774 } else {
775 memcpy(p_data, (uint8_t*)(p_buf + 1) + p_buf->offset, p_buf->len);
776
777 *p_len += p_buf->len;
778 max_len -= p_buf->len;
779
780 mutex_global_lock();
781
782 p_port->rx.queue_size -= p_buf->len;
783
784 if (max_len) {
785 p_data += p_buf->len;
786 }
787
788 osi_free(fixed_queue_try_dequeue(p_port->rx.queue));
789
790 mutex_global_unlock();
791
792 count++;
793 }
794 }
795
796 if (*p_len == 1) {
797 log::verbose("queue:{} returned:{} {:x}", p_port->rx.queue_size, *p_len, p_data[0]);
798 } else {
799 log::verbose("queue:{} returned:{}", p_port->rx.queue_size, *p_len);
800 }
801
802 /* If rfcomm suspended traffic from the peer based on the rx_queue_size */
803 /* check if it can be resumed now */
804 port_flow_control_peer(p_port, true, count);
805
806 return PORT_SUCCESS;
807 }
808
809 /*******************************************************************************
810 *
811 * Function port_write
812 *
813 * Description This function when a data packet is received from the apper
814 * layer task.
815 *
816 * Parameters: p_port - pointer to address of port control block
817 * p_buf - pointer to address of buffer with data,
818 *
819 ******************************************************************************/
port_write(tPORT * p_port,BT_HDR * p_buf)820 static int port_write(tPORT* p_port, BT_HDR* p_buf) {
821 /* We should not allow to write data in to server port when connection is not
822 * opened */
823 if (p_port->is_server && (p_port->rfc.state != RFC_STATE_OPENED)) {
824 osi_free(p_buf);
825 return PORT_CLOSED;
826 }
827
828 /* Keep the data in pending queue if peer does not allow data, or */
829 /* Peer is not ready or Port is not yet opened or initial port control */
830 /* command has not been sent */
831 if (p_port->tx.peer_fc || !p_port->rfc.p_mcb || !p_port->rfc.p_mcb->peer_ready ||
832 (p_port->rfc.state != RFC_STATE_OPENED) ||
833 ((p_port->port_ctrl & (PORT_CTRL_REQ_SENT | PORT_CTRL_IND_RECEIVED)) !=
834 (PORT_CTRL_REQ_SENT | PORT_CTRL_IND_RECEIVED))) {
835 if ((p_port->tx.queue_size > PORT_TX_CRITICAL_WM) ||
836 (fixed_queue_length(p_port->tx.queue) > PORT_TX_BUF_CRITICAL_WM)) {
837 log::warn("Queue size: {}", p_port->tx.queue_size);
838
839 osi_free(p_buf);
840
841 if ((p_port->p_callback != NULL) && (p_port->ev_mask & PORT_EV_ERR)) {
842 p_port->p_callback(PORT_EV_ERR, p_port->handle);
843 }
844
845 return PORT_TX_FULL;
846 }
847
848 log::verbose(
849 "Data is enqueued. flow disabled {} peer_ready {} state {} ctrl_state "
850 "{:x}",
851 p_port->tx.peer_fc, p_port->rfc.p_mcb && p_port->rfc.p_mcb->peer_ready,
852 p_port->rfc.state, p_port->port_ctrl);
853
854 fixed_queue_enqueue(p_port->tx.queue, p_buf);
855 p_port->tx.queue_size += p_buf->len;
856
857 return PORT_CMD_PENDING;
858 } else {
859 log::verbose("Data is being sent");
860
861 RFCOMM_DataReq(p_port->rfc.p_mcb, p_port->dlci, p_buf);
862 return PORT_SUCCESS;
863 }
864 }
865
866 /*******************************************************************************
867 *
868 * Function PORT_WriteDataCO
869 *
870 * Description Normally not GKI aware application will call this function
871 * to send data to the port by callout functions
872 *
873 * Parameters: handle - Handle returned in the RFCOMM_CreateConnection
874 * fd - socket fd
875 * p_len - Byte count returned
876 *
877 ******************************************************************************/
PORT_WriteDataCO(uint16_t handle,int * p_len)878 int PORT_WriteDataCO(uint16_t handle, int* p_len) {
879 BT_HDR* p_buf;
880 uint32_t event = 0;
881 int rc = 0;
882 uint16_t length;
883
884 log::verbose("handle:{}", handle);
885 *p_len = 0;
886
887 tPORT* p_port = get_port_from_handle(handle);
888 if (p_port == nullptr) {
889 log::error("Unable to get RFCOMM port control block bad handle:{}", handle);
890 return PORT_BAD_HANDLE;
891 }
892
893 if (!p_port->in_use || (p_port->state == PORT_CONNECTION_STATE_CLOSED)) {
894 log::warn("no port state:{}", p_port->state);
895 return PORT_NOT_OPENED;
896 }
897
898 if (!p_port->peer_mtu) {
899 log::error("peer_mtu:{}", p_port->peer_mtu);
900 return PORT_UNKNOWN_ERROR;
901 }
902 int available = 0;
903 // if(ioctl(fd, FIONREAD, &available) < 0)
904 if (!p_port->p_data_co_callback(handle, (uint8_t*)&available, sizeof(available),
905 DATA_CO_CALLBACK_TYPE_OUTGOING_SIZE)) {
906 log::error("p_data_co_callback DATA_CO_CALLBACK_TYPE_INCOMING_SIZE failed, available:{}",
907 available);
908 return PORT_UNKNOWN_ERROR;
909 }
910 if (available == 0) {
911 return PORT_SUCCESS;
912 }
913 /* Length for each buffer is the smaller of GKI buffer, peer MTU, or max_len
914 */
915 length = RFCOMM_DATA_BUF_SIZE -
916 (uint16_t)(sizeof(BT_HDR) + L2CAP_MIN_OFFSET + RFCOMM_DATA_OVERHEAD);
917
918 /* If there are buffers scheduled for transmission check if requested */
919 /* data fits into the end of the queue */
920 mutex_global_lock();
921
922 p_buf = (BT_HDR*)fixed_queue_try_peek_last(p_port->tx.queue);
923 if ((p_buf != NULL) && (((int)p_buf->len + available) <= (int)p_port->peer_mtu) &&
924 (((int)p_buf->len + available) <= (int)length)) {
925 // if(recv(fd, (uint8_t *)(p_buf + 1) + p_buf->offset + p_buf->len,
926 // available, 0) != available)
927 if (!p_port->p_data_co_callback(handle, (uint8_t*)(p_buf + 1) + p_buf->offset + p_buf->len,
928 available, DATA_CO_CALLBACK_TYPE_OUTGOING)) {
929 log::error("p_data_co_callback DATA_CO_CALLBACK_TYPE_OUTGOING failed, available:{}",
930 available);
931 mutex_global_unlock();
932 return PORT_UNKNOWN_ERROR;
933 }
934 // memcpy ((uint8_t *)(p_buf + 1) + p_buf->offset + p_buf->len, p_data,
935 // max_len);
936 p_port->tx.queue_size += (uint16_t)available;
937
938 *p_len = available;
939 p_buf->len += (uint16_t)available;
940
941 mutex_global_unlock();
942
943 return PORT_SUCCESS;
944 }
945
946 mutex_global_unlock();
947
948 // int max_read = length < p_port->peer_mtu ? length : p_port->peer_mtu;
949
950 // max_read = available < max_read ? available : max_read;
951
952 while (available) {
953 /* if we're over buffer high water mark, we're done */
954 if ((p_port->tx.queue_size > PORT_TX_HIGH_WM) ||
955 (fixed_queue_length(p_port->tx.queue) > PORT_TX_BUF_HIGH_WM)) {
956 port_flow_control_user(p_port);
957 event |= PORT_EV_FC;
958 log::verbose("tx queue is full,tx.queue_size:{},tx.queue.count:{},available:{}",
959 p_port->tx.queue_size, fixed_queue_length(p_port->tx.queue), available);
960 break;
961 }
962
963 /* continue with rfcomm data write */
964 p_buf = (BT_HDR*)osi_malloc(RFCOMM_DATA_BUF_SIZE);
965 p_buf->offset = L2CAP_MIN_OFFSET + RFCOMM_MIN_OFFSET;
966 p_buf->layer_specific = handle;
967
968 if (p_port->peer_mtu < length) {
969 length = p_port->peer_mtu;
970 }
971 if (available < (int)length) {
972 length = (uint16_t)available;
973 }
974 p_buf->len = length;
975 p_buf->event = BT_EVT_TO_BTU_SP_DATA;
976
977 // memcpy ((uint8_t *)(p_buf + 1) + p_buf->offset, p_data, length);
978 // if(recv(fd, (uint8_t *)(p_buf + 1) + p_buf->offset, (int)length, 0) !=
979 // (int)length)
980 if (!p_port->p_data_co_callback(handle, (uint8_t*)(p_buf + 1) + p_buf->offset, length,
981 DATA_CO_CALLBACK_TYPE_OUTGOING)) {
982 log::error("p_data_co_callback DATA_CO_CALLBACK_TYPE_OUTGOING failed, length:{}", length);
983 return PORT_UNKNOWN_ERROR;
984 }
985
986 log::verbose("{} bytes", length);
987
988 rc = port_write(p_port, p_buf);
989
990 /* If queue went below the threashold need to send flow control */
991 event |= port_flow_control_user(p_port);
992
993 if (rc == PORT_SUCCESS) {
994 event |= PORT_EV_TXCHAR;
995 }
996
997 if ((rc != PORT_SUCCESS) && (rc != PORT_CMD_PENDING)) {
998 break;
999 }
1000
1001 *p_len += length;
1002 available -= (int)length;
1003 }
1004 if (!available && (rc != PORT_CMD_PENDING) && (rc != PORT_TX_QUEUE_DISABLED)) {
1005 event |= PORT_EV_TXEMPTY;
1006 }
1007
1008 /* Mask out all events that are not of interest to user */
1009 event &= p_port->ev_mask;
1010
1011 /* Send event to the application */
1012 if (p_port->p_callback && event) {
1013 (p_port->p_callback)(event, p_port->handle);
1014 }
1015
1016 return PORT_SUCCESS;
1017 }
1018
1019 /*******************************************************************************
1020 *
1021 * Function PORT_WriteData
1022 *
1023 * Description Normally not GKI aware application will call this function
1024 * to send data to the port.
1025 *
1026 * Parameters: handle - Handle returned in the RFCOMM_CreateConnection
1027 * p_data - Data area
1028 * max_len - Byte count requested
1029 * p_len - Byte count received
1030 *
1031 ******************************************************************************/
PORT_WriteData(uint16_t handle,const char * p_data,uint16_t max_len,uint16_t * p_len)1032 int PORT_WriteData(uint16_t handle, const char* p_data, uint16_t max_len, uint16_t* p_len) {
1033 BT_HDR* p_buf;
1034 uint32_t event = 0;
1035 int rc = 0;
1036 uint16_t length;
1037
1038 log::verbose("max_len:{}", max_len);
1039
1040 *p_len = 0;
1041
1042 tPORT* p_port = get_port_from_handle(handle);
1043 if (p_port == nullptr) {
1044 log::error("Unable to get RFCOMM port control block bad handle:{}", handle);
1045 return PORT_BAD_HANDLE;
1046 }
1047
1048 if (!p_port->in_use || (p_port->state == PORT_CONNECTION_STATE_CLOSED)) {
1049 log::warn("no port state:{}", p_port->state);
1050 return PORT_NOT_OPENED;
1051 }
1052
1053 if (p_port->state == PORT_CONNECTION_STATE_OPENING) {
1054 log::warn("Write data received but port is in OPENING state");
1055 }
1056
1057 if (!max_len || !p_port->peer_mtu) {
1058 log::error("peer_mtu:{}", p_port->peer_mtu);
1059 return PORT_UNKNOWN_ERROR;
1060 }
1061
1062 /* Length for each buffer is the smaller of GKI buffer, peer MTU, or max_len
1063 */
1064 length = RFCOMM_DATA_BUF_SIZE -
1065 (uint16_t)(sizeof(BT_HDR) + L2CAP_MIN_OFFSET + RFCOMM_DATA_OVERHEAD);
1066
1067 /* If there are buffers scheduled for transmission check if requested */
1068 /* data fits into the end of the queue */
1069 mutex_global_lock();
1070
1071 p_buf = (BT_HDR*)fixed_queue_try_peek_last(p_port->tx.queue);
1072 if ((p_buf != NULL) && ((p_buf->len + max_len) <= p_port->peer_mtu) &&
1073 ((p_buf->len + max_len) <= length)) {
1074 memcpy((uint8_t*)(p_buf + 1) + p_buf->offset + p_buf->len, p_data, max_len);
1075 p_port->tx.queue_size += max_len;
1076
1077 *p_len = max_len;
1078 p_buf->len += max_len;
1079
1080 mutex_global_unlock();
1081
1082 return PORT_SUCCESS;
1083 }
1084
1085 mutex_global_unlock();
1086
1087 while (max_len) {
1088 /* if we're over buffer high water mark, we're done */
1089 if ((p_port->tx.queue_size > PORT_TX_HIGH_WM) ||
1090 (fixed_queue_length(p_port->tx.queue) > PORT_TX_BUF_HIGH_WM)) {
1091 break;
1092 }
1093
1094 /* continue with rfcomm data write */
1095 p_buf = (BT_HDR*)osi_malloc(RFCOMM_DATA_BUF_SIZE);
1096 p_buf->offset = L2CAP_MIN_OFFSET + RFCOMM_MIN_OFFSET;
1097 p_buf->layer_specific = handle;
1098
1099 if (p_port->peer_mtu < length) {
1100 length = p_port->peer_mtu;
1101 }
1102 if (max_len < length) {
1103 length = max_len;
1104 }
1105 p_buf->len = length;
1106 p_buf->event = BT_EVT_TO_BTU_SP_DATA;
1107
1108 memcpy((uint8_t*)(p_buf + 1) + p_buf->offset, p_data, length);
1109
1110 log::verbose("{} bytes", length);
1111
1112 rc = port_write(p_port, p_buf);
1113
1114 /* If queue went below the threashold need to send flow control */
1115 event |= port_flow_control_user(p_port);
1116
1117 if (rc == PORT_SUCCESS) {
1118 event |= PORT_EV_TXCHAR;
1119 }
1120
1121 if ((rc != PORT_SUCCESS) && (rc != PORT_CMD_PENDING)) {
1122 break;
1123 }
1124
1125 *p_len += length;
1126 max_len -= length;
1127 p_data += length;
1128 }
1129 if (!max_len && (rc != PORT_CMD_PENDING) && (rc != PORT_TX_QUEUE_DISABLED)) {
1130 event |= PORT_EV_TXEMPTY;
1131 }
1132
1133 /* Mask out all events that are not of interest to user */
1134 event &= p_port->ev_mask;
1135
1136 /* Send event to the application */
1137 if (p_port->p_callback && event) {
1138 (p_port->p_callback)(event, p_port->handle);
1139 }
1140
1141 return PORT_SUCCESS;
1142 }
1143
1144 /*******************************************************************************
1145 *
1146 * Function RFCOMM_Init
1147 *
1148 * Description This function is called to initialize RFCOMM layer
1149 *
1150 ******************************************************************************/
RFCOMM_Init(void)1151 void RFCOMM_Init(void) {
1152 memset(&rfc_cb, 0, sizeof(tRFC_CB)); /* Init RFCOMM control block */
1153 rfc_lcid_mcb = {};
1154
1155 rfc_cb.rfc.last_mux = MAX_BD_CONNECTIONS;
1156
1157 rfcomm_l2cap_if_init();
1158 }
1159
1160 /*******************************************************************************
1161 *
1162 * Function PORT_GetResultString
1163 *
1164 * Description This function returns the human-readable string for a given
1165 * result code.
1166 *
1167 * Returns a pointer to the human-readable string for the given result.
1168 *
1169 ******************************************************************************/
PORT_GetResultString(const uint8_t result_code)1170 const char* PORT_GetResultString(const uint8_t result_code) {
1171 if (result_code > PORT_ERR_MAX) {
1172 return result_code_strings[PORT_ERR_MAX];
1173 }
1174
1175 return result_code_strings[result_code];
1176 }
1177
1178 /*******************************************************************************
1179 *
1180 * Function PORT_GetSecurityMask
1181 *
1182 * Description This function returns the security bitmask for a port.
1183 *
1184 * Returns A result code, and writes the bitmask into the output
1185 *parameter.
1186 *
1187 ******************************************************************************/
PORT_GetSecurityMask(uint16_t handle,uint16_t * sec_mask)1188 int PORT_GetSecurityMask(uint16_t handle, uint16_t* sec_mask) {
1189 tPORT* p_port = get_port_from_handle(handle);
1190 if (p_port == nullptr) {
1191 log::error("Unable to get RFCOMM port control block bad handle:{}", handle);
1192 return PORT_BAD_HANDLE;
1193 }
1194 *sec_mask = p_port->sec_mask;
1195 return PORT_SUCCESS;
1196 }
1197