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 <base/logging.h>
28 #include <string.h>
29
30 #include "osi/include/log.h"
31 #include "osi/include/mutex.h"
32
33 #include "bt_common.h"
34 #include "btm_api.h"
35 #include "btm_int.h"
36 #include "l2c_api.h"
37 #include "port_api.h"
38 #include "port_int.h"
39 #include "rfc_int.h"
40 #include "rfcdefs.h"
41 #include "sdp_api.h"
42
43 /* duration of break in 200ms units */
44 #define PORT_BREAK_DURATION 1
45
46 #define info(fmt, ...) LOG_INFO(LOG_TAG, "%s: " fmt, __func__, ##__VA_ARGS__)
47 #define debug(fmt, ...) LOG_DEBUG(LOG_TAG, "%s: " fmt, __func__, ##__VA_ARGS__)
48 #define error(fmt, ...) \
49 LOG_ERROR(LOG_TAG, "## ERROR : %s: " fmt "##", __func__, ##__VA_ARGS__)
50 #define asrt(s) \
51 if (!(s)) \
52 LOG_ERROR(LOG_TAG, "## %s assert %s failed at line:%d ##", __func__, #s, \
53 __LINE__)
54
55 /* Mapping from PORT_* result codes to human readable strings. */
56 static const char* result_code_strings[] = {"Success",
57 "Unknown error",
58 "Already opened",
59 "Command pending",
60 "App not registered",
61 "No memory",
62 "No resources",
63 "Bad BD address",
64 "Unspecified error",
65 "Bad handle",
66 "Not opened",
67 "Line error",
68 "Start failed",
69 "Parameter negotiation failed",
70 "Port negotiation failed",
71 "Sec failed",
72 "Peer connection failed",
73 "Peer failed",
74 "Peer timeout",
75 "Closed",
76 "TX full",
77 "Local closed",
78 "Local timeout",
79 "TX queue disabled",
80 "Page timeout",
81 "Invalid SCN",
82 "Unknown result code"};
83
84 /*******************************************************************************
85 *
86 * Function RFCOMM_CreateConnection
87 *
88 * Description RFCOMM_CreateConnection function is used from the
89 * application to establish serial port connection to the peer
90 * device, or allow RFCOMM to accept a connection from the peer
91 * application.
92 *
93 * Parameters: scn - Service Channel Number as registered with
94 * the SDP (server) or obtained using SDP from
95 * the peer device (client).
96 * is_server - true if requesting application is a server
97 * mtu - Maximum frame size the application can accept
98 * bd_addr - address of the peer (client)
99 * mask - specifies events to be enabled. A value
100 * of zero disables all events.
101 * p_handle - OUT pointer to the handle.
102 * p_mgmt_cb - pointer to callback function to receive
103 * connection up/down events.
104 * Notes:
105 *
106 * Server can call this function with the same scn parameter multiple times if
107 * it is ready to accept multiple simulteneous connections.
108 *
109 * DLCI for the connection is (scn * 2 + 1) if client originates connection on
110 * existing none initiator multiplexer channel. Otherwise it is (scn * 2).
111 * For the server DLCI can be changed later if client will be calling it using
112 * (scn * 2 + 1) dlci.
113 *
114 ******************************************************************************/
RFCOMM_CreateConnection(uint16_t uuid,uint8_t scn,bool is_server,uint16_t mtu,const RawAddress & bd_addr,uint16_t * p_handle,tPORT_CALLBACK * p_mgmt_cb)115 int RFCOMM_CreateConnection(uint16_t uuid, uint8_t scn, bool is_server,
116 uint16_t mtu, const RawAddress& bd_addr,
117 uint16_t* p_handle, tPORT_CALLBACK* p_mgmt_cb) {
118 *p_handle = 0;
119
120 if ((scn == 0) || (scn >= PORT_MAX_RFC_PORTS)) {
121 // Server Channel Number (SCN) should be in range [1, 30]
122 LOG(ERROR) << __func__ << ": Invalid SCN, bd_addr=" << bd_addr
123 << ", scn=" << static_cast<int>(scn)
124 << ", is_server=" << is_server
125 << ", mtu=" << static_cast<int>(mtu)
126 << ", uuid=" << loghex(uuid);
127 return (PORT_INVALID_SCN);
128 }
129
130 // For client that originates connection on the existing none initiator
131 // multiplexer channel, DLCI should be odd.
132 uint8_t dlci;
133 tRFC_MCB* p_mcb = port_find_mcb(bd_addr);
134 if (p_mcb && !p_mcb->is_initiator && !is_server) {
135 dlci = static_cast<uint8_t>((scn << 1) + 1);
136 } else {
137 dlci = (scn << 1);
138 }
139
140 // On the client side, do not allow the same (dlci, bd_addr) to be opened
141 // twice by application
142 tPORT* p_port;
143 if (!is_server) {
144 p_port = port_find_port(dlci, bd_addr);
145 if (p_port != nullptr) {
146 // if existing port is also a client port, error out
147 if (!p_port->is_server) {
148 LOG(ERROR) << __func__ << ": already at opened state "
149 << static_cast<int>(p_port->state)
150 << ", RFC_state=" << static_cast<int>(p_port->rfc.state)
151 << ", MCB_state="
152 << (p_port->rfc.p_mcb ? p_port->rfc.p_mcb->state : 0)
153 << ", bd_addr=" << bd_addr << ", scn=" << std::to_string(scn)
154 << ", is_server=" << is_server << ", mtu=" << mtu
155 << ", uuid=" << loghex(uuid) << ", dlci=" << +dlci
156 << ", p_mcb=" << p_mcb
157 << ", port=" << std::to_string(p_port->handle);
158 *p_handle = p_port->handle;
159 return (PORT_ALREADY_OPENED);
160 }
161 }
162 }
163
164 // On the server side, always allocate a new port.
165 p_port = port_allocate_port(dlci, bd_addr);
166 if (p_port == nullptr) {
167 LOG(ERROR) << __func__ << ": no resources, bd_addr=" << bd_addr
168 << ", scn=" << std::to_string(scn) << ", is_server=" << is_server
169 << ", mtu=" << mtu << ", uuid=" << loghex(uuid)
170 << ", dlci=" << +dlci;
171 return PORT_NO_RESOURCES;
172 }
173 *p_handle = p_port->handle;
174
175 // Get default signal state
176 switch (uuid) {
177 case UUID_PROTOCOL_OBEX:
178 p_port->default_signal_state = PORT_OBEX_DEFAULT_SIGNAL_STATE;
179 break;
180 case UUID_SERVCLASS_SERIAL_PORT:
181 p_port->default_signal_state = PORT_SPP_DEFAULT_SIGNAL_STATE;
182 break;
183 case UUID_SERVCLASS_LAN_ACCESS_USING_PPP:
184 p_port->default_signal_state = PORT_PPP_DEFAULT_SIGNAL_STATE;
185 break;
186 case UUID_SERVCLASS_DIALUP_NETWORKING:
187 case UUID_SERVCLASS_FAX:
188 p_port->default_signal_state = PORT_DUN_DEFAULT_SIGNAL_STATE;
189 break;
190 default:
191 p_port->default_signal_state =
192 (PORT_DTRDSR_ON | PORT_CTSRTS_ON | PORT_DCD_ON);
193 break;
194 }
195
196 // Assign port specific values
197 p_port->state = PORT_STATE_OPENING;
198 p_port->uuid = uuid;
199 p_port->is_server = is_server;
200 p_port->scn = scn;
201 p_port->ev_mask = 0;
202
203 // Find MTU
204 // If the MTU is not specified (0), keep MTU decision until the PN frame has
205 // to be send at that time connection should be established and we will know
206 // for sure our prefered MTU
207 uint16_t rfcomm_mtu = L2CAP_MTU_SIZE - RFCOMM_DATA_OVERHEAD;
208 if (mtu) {
209 p_port->mtu = (mtu < rfcomm_mtu) ? mtu : rfcomm_mtu;
210 } else {
211 p_port->mtu = rfcomm_mtu;
212 }
213
214 // Other states
215 // server doesn't need to release port when closing
216 if (is_server) {
217 p_port->keep_port_handle = true;
218 // keep mtu that user asked, p_port->mtu could be updated during param
219 // negotiation
220 p_port->keep_mtu = p_port->mtu;
221 }
222 p_port->local_ctrl.modem_signal = p_port->default_signal_state;
223 p_port->local_ctrl.fc = false;
224 p_port->p_mgmt_callback = p_mgmt_cb;
225 p_port->bd_addr = bd_addr;
226
227 LOG(INFO) << __func__ << ": bd_addr=" << bd_addr
228 << ", scn=" << std::to_string(scn) << ", is_server=" << is_server
229 << ", mtu=" << mtu << ", uuid=" << loghex(uuid)
230 << ", dlci=" << std::to_string(dlci)
231 << ", signal_state=" << loghex(p_port->default_signal_state)
232 << ", p_port=" << p_port;
233
234 // If this is not initiator of the connection need to just wait
235 if (p_port->is_server) {
236 return (PORT_SUCCESS);
237 }
238
239 // Open will be continued after security checks are passed
240 return port_open_continue(p_port);
241 }
242
243 /*******************************************************************************
244 *
245 * Function RFCOMM_RemoveConnection
246 *
247 * Description This function is called to close the specified connection.
248 *
249 * Parameters: handle - Handle returned in the RFCOMM_CreateConnection
250 *
251 ******************************************************************************/
RFCOMM_RemoveConnection(uint16_t handle)252 int RFCOMM_RemoveConnection(uint16_t handle) {
253 tPORT* p_port;
254
255 RFCOMM_TRACE_API("RFCOMM_RemoveConnection() handle:%d", handle);
256
257 /* Check if handle is valid to avoid crashing */
258 if ((handle == 0) || (handle > MAX_RFC_PORTS)) {
259 RFCOMM_TRACE_ERROR("RFCOMM_RemoveConnection() BAD handle:%d", handle);
260 return (PORT_BAD_HANDLE);
261 }
262 p_port = &rfc_cb.port.port[handle - 1];
263
264 if (!p_port->in_use || (p_port->state == PORT_STATE_CLOSED)) {
265 RFCOMM_TRACE_EVENT("RFCOMM_RemoveConnection() Not opened:%d", handle);
266 return (PORT_SUCCESS);
267 }
268
269 p_port->state = PORT_STATE_CLOSING;
270
271 port_start_close(p_port);
272
273 return (PORT_SUCCESS);
274 }
275
276 /*******************************************************************************
277 *
278 * Function RFCOMM_RemoveServer
279 *
280 * Description This function is called to close the server port.
281 *
282 * Parameters: handle - Handle returned in the RFCOMM_CreateConnection
283 *
284 ******************************************************************************/
RFCOMM_RemoveServer(uint16_t handle)285 int RFCOMM_RemoveServer(uint16_t handle) {
286 /* Check if handle is valid to avoid crashing */
287 if ((handle == 0) || (handle > MAX_RFC_PORTS)) {
288 LOG(ERROR) << __func__ << ": bad handle " << handle;
289 return (PORT_BAD_HANDLE);
290 }
291 tPORT* p_port = &rfc_cb.port.port[handle - 1];
292
293 /* Do not report any events to the client any more. */
294 p_port->p_mgmt_callback = nullptr;
295
296 if (!p_port->in_use || (p_port->state == PORT_STATE_CLOSED)) {
297 VLOG(1) << __func__ << ": handle " << handle << " not opened";
298 return (PORT_SUCCESS);
299 }
300 LOG(INFO) << __func__ << ": handle=" << handle;
301
302 /* this port will be deallocated after closing */
303 p_port->keep_port_handle = false;
304 p_port->state = PORT_STATE_CLOSING;
305
306 port_start_close(p_port);
307
308 return (PORT_SUCCESS);
309 }
310
311 /*******************************************************************************
312 *
313 * Function PORT_SetEventCallback
314 *
315 * Description This function is called to provide an address of the
316 * function which will be called when one of the events
317 * specified in the mask occures.
318 *
319 * Parameters: handle - Handle returned in the RFCOMM_CreateConnection
320 * p_callback - address of the callback function which should
321 * be called from the RFCOMM when an event
322 * specified in the mask occures.
323 *
324 *
325 ******************************************************************************/
PORT_SetEventCallback(uint16_t port_handle,tPORT_CALLBACK * p_port_cb)326 int PORT_SetEventCallback(uint16_t port_handle, tPORT_CALLBACK* p_port_cb) {
327 tPORT* p_port;
328
329 /* Check if handle is valid to avoid crashing */
330 if ((port_handle == 0) || (port_handle > MAX_RFC_PORTS)) {
331 return (PORT_BAD_HANDLE);
332 }
333
334 p_port = &rfc_cb.port.port[port_handle - 1];
335
336 if (!p_port->in_use || (p_port->state == PORT_STATE_CLOSED)) {
337 return (PORT_NOT_OPENED);
338 }
339
340 RFCOMM_TRACE_API("PORT_SetEventCallback() handle:%d", port_handle);
341
342 p_port->p_callback = p_port_cb;
343
344 return (PORT_SUCCESS);
345 }
346 /*******************************************************************************
347 *
348 * Function PORT_ClearKeepHandleFlag
349 *
350 * Description Clear the keep handle flag, which will cause not to keep the
351 * port handle open when closed
352 * Parameters: handle - Handle returned in the RFCOMM_CreateConnection
353 *
354 ******************************************************************************/
355
PORT_ClearKeepHandleFlag(uint16_t port_handle)356 int PORT_ClearKeepHandleFlag(uint16_t port_handle) {
357 tPORT* p_port;
358
359 /* Check if handle is valid to avoid crashing */
360 if ((port_handle == 0) || (port_handle > MAX_RFC_PORTS)) {
361 return (PORT_BAD_HANDLE);
362 }
363
364 p_port = &rfc_cb.port.port[port_handle - 1];
365 p_port->keep_port_handle = 0;
366 return (PORT_SUCCESS);
367 }
368
369 /*******************************************************************************
370 *
371 * Function PORT_SetDataCallback
372 *
373 * Description This function is when a data packet is received
374 *
375 * Parameters: handle - Handle returned in the RFCOMM_CreateConnection
376 * p_callback - address of the callback function which should
377 * be called from the RFCOMM when data packet
378 * is received.
379 *
380 *
381 ******************************************************************************/
PORT_SetDataCallback(uint16_t port_handle,tPORT_DATA_CALLBACK * p_port_cb)382 int PORT_SetDataCallback(uint16_t port_handle, tPORT_DATA_CALLBACK* p_port_cb) {
383 tPORT* p_port;
384
385 RFCOMM_TRACE_API("PORT_SetDataCallback() handle:%d cb 0x%x", port_handle,
386 p_port_cb);
387
388 /* Check if handle is valid to avoid crashing */
389 if ((port_handle == 0) || (port_handle > MAX_RFC_PORTS)) {
390 return (PORT_BAD_HANDLE);
391 }
392
393 p_port = &rfc_cb.port.port[port_handle - 1];
394
395 if (!p_port->in_use || (p_port->state == PORT_STATE_CLOSED)) {
396 return (PORT_NOT_OPENED);
397 }
398
399 p_port->p_data_callback = p_port_cb;
400
401 return (PORT_SUCCESS);
402 }
403 /*******************************************************************************
404 *
405 * Function PORT_SetCODataCallback
406 *
407 * Description This function is when a data packet is received
408 *
409 * Parameters: handle - Handle returned in the RFCOMM_CreateConnection
410 * p_callback - address of the callback function which should
411 * be called from the RFCOMM when data packet
412 * is received.
413 *
414 *
415 ******************************************************************************/
PORT_SetDataCOCallback(uint16_t port_handle,tPORT_DATA_CO_CALLBACK * p_port_cb)416 int PORT_SetDataCOCallback(uint16_t port_handle,
417 tPORT_DATA_CO_CALLBACK* p_port_cb) {
418 tPORT* p_port;
419
420 RFCOMM_TRACE_API("PORT_SetDataCOCallback() handle:%d cb 0x%x", port_handle,
421 p_port_cb);
422
423 /* Check if handle is valid to avoid crashing */
424 if ((port_handle == 0) || (port_handle > MAX_RFC_PORTS)) {
425 return (PORT_BAD_HANDLE);
426 }
427
428 p_port = &rfc_cb.port.port[port_handle - 1];
429
430 if (!p_port->in_use || (p_port->state == PORT_STATE_CLOSED)) {
431 return (PORT_NOT_OPENED);
432 }
433
434 p_port->p_data_co_callback = p_port_cb;
435
436 return (PORT_SUCCESS);
437 }
438
439 /*******************************************************************************
440 *
441 * Function PORT_SetEventMask
442 *
443 * Description This function is called to close the specified connection.
444 *
445 * Parameters: handle - Handle returned in the RFCOMM_CreateConnection
446 * mask - Bitmask of the events the host is interested in
447 *
448 ******************************************************************************/
PORT_SetEventMask(uint16_t port_handle,uint32_t mask)449 int PORT_SetEventMask(uint16_t port_handle, uint32_t mask) {
450 tPORT* p_port;
451
452 RFCOMM_TRACE_API("PORT_SetEventMask() handle:%d mask:0x%x", port_handle,
453 mask);
454
455 /* Check if handle is valid to avoid crashing */
456 if ((port_handle == 0) || (port_handle > MAX_RFC_PORTS)) {
457 return (PORT_BAD_HANDLE);
458 }
459
460 p_port = &rfc_cb.port.port[port_handle - 1];
461
462 if (!p_port->in_use || (p_port->state == PORT_STATE_CLOSED)) {
463 return (PORT_NOT_OPENED);
464 }
465
466 p_port->ev_mask = mask;
467
468 return (PORT_SUCCESS);
469 }
470
471 /*******************************************************************************
472 *
473 * Function PORT_CheckConnection
474 *
475 * Description This function returns PORT_SUCCESS if connection referenced
476 * by handle is up and running
477 *
478 * Parameters: handle - Handle returned in the RFCOMM_CreateConnection
479 * bd_addr - OUT bd_addr of the peer
480 * p_lcid - OUT L2CAP's LCID
481 *
482 ******************************************************************************/
PORT_CheckConnection(uint16_t handle,RawAddress * bd_addr,uint16_t * p_lcid)483 int PORT_CheckConnection(uint16_t handle, RawAddress* bd_addr,
484 uint16_t* p_lcid) {
485 /* Check if handle is valid to avoid crashing */
486 if ((handle == 0) || (handle > MAX_RFC_PORTS)) {
487 return (PORT_BAD_HANDLE);
488 }
489 tPORT* p_port = &rfc_cb.port.port[handle - 1];
490 RFCOMM_TRACE_DEBUG(
491 "%s: handle=%d, in_use=%d, port_state=%d, p_mcb=%p, peer_ready=%d, "
492 "rfc_state=%d",
493 __func__, handle, p_port->in_use, p_port->state, p_port->rfc.p_mcb,
494 (p_port->rfc.p_mcb ? p_port->rfc.p_mcb->peer_ready : -1),
495 p_port->rfc.state);
496
497 if (!p_port->in_use || (p_port->state == PORT_STATE_CLOSED)) {
498 return (PORT_NOT_OPENED);
499 }
500
501 if (!p_port->rfc.p_mcb || !p_port->rfc.p_mcb->peer_ready ||
502 (p_port->rfc.state != RFC_STATE_OPENED)) {
503 return (PORT_LINE_ERR);
504 }
505
506 *bd_addr = p_port->rfc.p_mcb->bd_addr;
507 if (p_lcid) *p_lcid = p_port->rfc.p_mcb->lcid;
508
509 return (PORT_SUCCESS);
510 }
511
512 /*******************************************************************************
513 *
514 * Function PORT_IsOpening
515 *
516 * Description This function returns true if there is any RFCOMM connection
517 * opening in process.
518 *
519 * Parameters: true if any connection opening is found
520 * bd_addr - bd_addr of the peer
521 *
522 ******************************************************************************/
PORT_IsOpening(RawAddress * bd_addr)523 bool PORT_IsOpening(RawAddress* bd_addr) {
524 /* Check for any rfc_mcb which is in the middle of opening. */
525 for (auto& multiplexer_cb : rfc_cb.port.rfc_mcb) {
526 if ((multiplexer_cb.state > RFC_MX_STATE_IDLE) &&
527 (multiplexer_cb.state < RFC_MX_STATE_CONNECTED)) {
528 *bd_addr = multiplexer_cb.bd_addr;
529 return true;
530 }
531
532 if (multiplexer_cb.state == RFC_MX_STATE_CONNECTED) {
533 bool found_port = false;
534 tPORT* p_port = nullptr;
535
536 for (tPORT& port : rfc_cb.port.port) {
537 if (port.rfc.p_mcb == &multiplexer_cb) {
538 found_port = true;
539 p_port = &port;
540 break;
541 }
542 }
543
544 if ((!found_port) ||
545 (found_port && (p_port->rfc.state < RFC_STATE_OPENED))) {
546 /* Port is not established yet. */
547 *bd_addr = multiplexer_cb.bd_addr;
548 return true;
549 }
550 }
551 }
552
553 return false;
554 }
555
556 /*******************************************************************************
557 *
558 * Function PORT_SetState
559 *
560 * Description This function configures connection according to the
561 * specifications in the tPORT_STATE structure.
562 *
563 * Parameters: handle - Handle returned in the RFCOMM_CreateConnection
564 * p_settings - Pointer to a tPORT_STATE structure containing
565 * configuration information for the connection.
566 *
567 *
568 ******************************************************************************/
PORT_SetState(uint16_t handle,tPORT_STATE * p_settings)569 int PORT_SetState(uint16_t handle, tPORT_STATE* p_settings) {
570 tPORT* p_port;
571 uint8_t baud_rate;
572
573 RFCOMM_TRACE_API("PORT_SetState() handle:%d", handle);
574
575 /* Check if handle is valid to avoid crashing */
576 if ((handle == 0) || (handle > MAX_RFC_PORTS)) {
577 return (PORT_BAD_HANDLE);
578 }
579
580 p_port = &rfc_cb.port.port[handle - 1];
581
582 if (!p_port->in_use || (p_port->state == PORT_STATE_CLOSED)) {
583 return (PORT_NOT_OPENED);
584 }
585
586 if (p_port->line_status) {
587 return (PORT_LINE_ERR);
588 }
589
590 RFCOMM_TRACE_API("PORT_SetState() handle:%d FC_TYPE:0x%x", handle,
591 p_settings->fc_type);
592
593 baud_rate = p_port->user_port_pars.baud_rate;
594 p_port->user_port_pars = *p_settings;
595
596 /* for now we've been asked to pass only baud rate */
597 if (baud_rate != p_settings->baud_rate) {
598 port_start_par_neg(p_port);
599 }
600 return (PORT_SUCCESS);
601 }
602
603 /*******************************************************************************
604 *
605 * Function PORT_GetRxQueueCnt
606 *
607 * Description This function return number of buffers on the rx queue.
608 *
609 * Parameters: handle - Handle returned in the RFCOMM_CreateConnection
610 * p_rx_queue_count - Pointer to return queue count in.
611 *
612 ******************************************************************************/
PORT_GetRxQueueCnt(uint16_t handle,uint16_t * p_rx_queue_count)613 int PORT_GetRxQueueCnt(uint16_t handle, uint16_t* p_rx_queue_count) {
614 tPORT* p_port;
615
616 RFCOMM_TRACE_API("PORT_GetRxQueueCnt() handle:%d", handle);
617
618 /* Check if handle is valid to avoid crashing */
619 if ((handle == 0) || (handle > MAX_RFC_PORTS)) {
620 return (PORT_BAD_HANDLE);
621 }
622
623 p_port = &rfc_cb.port.port[handle - 1];
624
625 if (!p_port->in_use || (p_port->state == PORT_STATE_CLOSED)) {
626 return (PORT_NOT_OPENED);
627 }
628
629 if (p_port->line_status) {
630 return (PORT_LINE_ERR);
631 }
632
633 *p_rx_queue_count = p_port->rx.queue_size;
634
635 RFCOMM_TRACE_API(
636 "PORT_GetRxQueueCnt() p_rx_queue_count:%d, p_port->rx.queue.count = %d",
637 *p_rx_queue_count, p_port->rx.queue_size);
638
639 return (PORT_SUCCESS);
640 }
641
642 /*******************************************************************************
643 *
644 * Function PORT_GetState
645 *
646 * Description This function is called to fill tPORT_STATE structure
647 * with the curremt control settings for the port
648 *
649 * Parameters: handle - Handle returned in the RFCOMM_CreateConnection
650 * p_settings - Pointer to a tPORT_STATE structure in which
651 * configuration information is returned.
652 *
653 ******************************************************************************/
PORT_GetState(uint16_t handle,tPORT_STATE * p_settings)654 int PORT_GetState(uint16_t handle, tPORT_STATE* p_settings) {
655 tPORT* p_port;
656
657 RFCOMM_TRACE_API("PORT_GetState() handle:%d", handle);
658
659 /* Check if handle is valid to avoid crashing */
660 if ((handle == 0) || (handle > MAX_RFC_PORTS)) {
661 return (PORT_BAD_HANDLE);
662 }
663
664 p_port = &rfc_cb.port.port[handle - 1];
665
666 if (!p_port->in_use || (p_port->state == PORT_STATE_CLOSED)) {
667 return (PORT_NOT_OPENED);
668 }
669
670 if (p_port->line_status) {
671 return (PORT_LINE_ERR);
672 }
673
674 *p_settings = p_port->user_port_pars;
675 return (PORT_SUCCESS);
676 }
677
678 /*******************************************************************************
679 *
680 * Function PORT_Control
681 *
682 * Description This function directs a specified connection to pass control
683 * control information to the peer device.
684 *
685 * Parameters: handle - Handle returned in the RFCOMM_CreateConnection
686 * signal = specify the function to be passed
687 *
688 ******************************************************************************/
PORT_Control(uint16_t handle,uint8_t signal)689 int PORT_Control(uint16_t handle, uint8_t signal) {
690 tPORT* p_port;
691 uint8_t old_modem_signal;
692
693 RFCOMM_TRACE_API("PORT_Control() handle:%d signal:0x%x", handle, signal);
694
695 /* Check if handle is valid to avoid crashing */
696 if ((handle == 0) || (handle > MAX_RFC_PORTS)) {
697 return (PORT_BAD_HANDLE);
698 }
699
700 p_port = &rfc_cb.port.port[handle - 1];
701
702 if (!p_port->in_use || (p_port->state == PORT_STATE_CLOSED)) {
703 return (PORT_NOT_OPENED);
704 }
705
706 old_modem_signal = p_port->local_ctrl.modem_signal;
707 p_port->local_ctrl.break_signal = 0;
708
709 switch (signal) {
710 case PORT_SET_CTSRTS:
711 p_port->local_ctrl.modem_signal |= PORT_CTSRTS_ON;
712 break;
713
714 case PORT_CLR_CTSRTS:
715 p_port->local_ctrl.modem_signal &= ~PORT_CTSRTS_ON;
716 break;
717
718 case PORT_SET_DTRDSR:
719 p_port->local_ctrl.modem_signal |= PORT_DTRDSR_ON;
720 break;
721
722 case PORT_CLR_DTRDSR:
723 p_port->local_ctrl.modem_signal &= ~PORT_DTRDSR_ON;
724 break;
725
726 case PORT_SET_RI:
727 p_port->local_ctrl.modem_signal |= PORT_RING_ON;
728 break;
729
730 case PORT_CLR_RI:
731 p_port->local_ctrl.modem_signal &= ~PORT_RING_ON;
732 break;
733
734 case PORT_SET_DCD:
735 p_port->local_ctrl.modem_signal |= PORT_DCD_ON;
736 break;
737
738 case PORT_CLR_DCD:
739 p_port->local_ctrl.modem_signal &= ~PORT_DCD_ON;
740 break;
741 }
742
743 if (signal == PORT_BREAK)
744 p_port->local_ctrl.break_signal = PORT_BREAK_DURATION;
745 else if (p_port->local_ctrl.modem_signal == old_modem_signal)
746 return (PORT_SUCCESS);
747
748 port_start_control(p_port);
749
750 RFCOMM_TRACE_EVENT(
751 "PORT_Control DTR_DSR : %d, RTS_CTS : %d, RI : %d, DCD : %d",
752 ((p_port->local_ctrl.modem_signal & MODEM_SIGNAL_DTRDSR) ? 1 : 0),
753 ((p_port->local_ctrl.modem_signal & MODEM_SIGNAL_RTSCTS) ? 1 : 0),
754 ((p_port->local_ctrl.modem_signal & MODEM_SIGNAL_RI) ? 1 : 0),
755 ((p_port->local_ctrl.modem_signal & MODEM_SIGNAL_DCD) ? 1 : 0));
756
757 return (PORT_SUCCESS);
758 }
759
760 /*******************************************************************************
761 *
762 * Function PORT_FlowControl
763 *
764 * Description This function directs a specified connection to pass
765 * flow control message to the peer device. Enable flag passed
766 * shows if port can accept more data.
767 *
768 * Parameters: handle - Handle returned in the RFCOMM_CreateConnection
769 * enable - enables data flow
770 *
771 ******************************************************************************/
PORT_FlowControl(uint16_t handle,bool enable)772 int PORT_FlowControl(uint16_t handle, bool enable) {
773 tPORT* p_port;
774 bool old_fc;
775 uint32_t events;
776
777 RFCOMM_TRACE_API("PORT_FlowControl() handle:%d enable: %d", handle, enable);
778
779 /* Check if handle is valid to avoid crashing */
780 if ((handle == 0) || (handle > MAX_RFC_PORTS)) {
781 return (PORT_BAD_HANDLE);
782 }
783
784 p_port = &rfc_cb.port.port[handle - 1];
785
786 if (!p_port->in_use || (p_port->state == PORT_STATE_CLOSED)) {
787 return (PORT_NOT_OPENED);
788 }
789
790 if (!p_port->rfc.p_mcb) {
791 return (PORT_NOT_OPENED);
792 }
793
794 p_port->rx.user_fc = !enable;
795
796 if (p_port->rfc.p_mcb->flow == PORT_FC_CREDIT) {
797 if (!p_port->rx.user_fc) {
798 port_flow_control_peer(p_port, true, 0);
799 }
800 } else {
801 old_fc = p_port->local_ctrl.fc;
802
803 /* FC is set if user is set or peer is set */
804 p_port->local_ctrl.fc = (p_port->rx.user_fc | p_port->rx.peer_fc);
805
806 if (p_port->local_ctrl.fc != old_fc) port_start_control(p_port);
807 }
808
809 /* Need to take care of the case when we could not deliver events */
810 /* to the application because we were flow controlled */
811 if (enable && (p_port->rx.queue_size != 0)) {
812 events = PORT_EV_RXCHAR;
813 if (p_port->rx_flag_ev_pending) {
814 p_port->rx_flag_ev_pending = false;
815 events |= PORT_EV_RXFLAG;
816 }
817
818 events &= p_port->ev_mask;
819 if (p_port->p_callback && events) {
820 p_port->p_callback(events, p_port->handle);
821 }
822 }
823 return (PORT_SUCCESS);
824 }
825 /*******************************************************************************
826 *
827 * Function PORT_FlowControl_MaxCredit
828 *
829 * Description This function directs a specified connection to pass
830 * flow control message to the peer device. Enable flag passed
831 * shows if port can accept more data. It also sends max credit
832 * when data flow enabled
833 *
834 * Parameters: handle - Handle returned in the RFCOMM_CreateConnection
835 * enable - enables data flow
836 *
837 ******************************************************************************/
838
PORT_FlowControl_MaxCredit(uint16_t handle,bool enable)839 int PORT_FlowControl_MaxCredit(uint16_t handle, bool enable) {
840 tPORT* p_port;
841 bool old_fc;
842 uint32_t events;
843
844 RFCOMM_TRACE_API("PORT_FlowControl() handle:%d enable: %d", handle, enable);
845
846 /* Check if handle is valid to avoid crashing */
847 if ((handle == 0) || (handle > MAX_RFC_PORTS)) {
848 return (PORT_BAD_HANDLE);
849 }
850
851 p_port = &rfc_cb.port.port[handle - 1];
852
853 if (!p_port->in_use || (p_port->state == PORT_STATE_CLOSED)) {
854 return (PORT_NOT_OPENED);
855 }
856
857 if (!p_port->rfc.p_mcb) {
858 return (PORT_NOT_OPENED);
859 }
860
861 p_port->rx.user_fc = !enable;
862
863 if (p_port->rfc.p_mcb->flow == PORT_FC_CREDIT) {
864 if (!p_port->rx.user_fc) {
865 port_flow_control_peer(p_port, true, p_port->credit_rx);
866 }
867 } else {
868 old_fc = p_port->local_ctrl.fc;
869
870 /* FC is set if user is set or peer is set */
871 p_port->local_ctrl.fc = (p_port->rx.user_fc | p_port->rx.peer_fc);
872
873 if (p_port->local_ctrl.fc != old_fc) port_start_control(p_port);
874 }
875
876 /* Need to take care of the case when we could not deliver events */
877 /* to the application because we were flow controlled */
878 if (enable && (p_port->rx.queue_size != 0)) {
879 events = PORT_EV_RXCHAR;
880 if (p_port->rx_flag_ev_pending) {
881 p_port->rx_flag_ev_pending = false;
882 events |= PORT_EV_RXFLAG;
883 }
884
885 events &= p_port->ev_mask;
886 if (p_port->p_callback && events) {
887 p_port->p_callback(events, p_port->handle);
888 }
889 }
890 return (PORT_SUCCESS);
891 }
892
893 /*******************************************************************************
894 *
895 * Function PORT_GetModemStatus
896 *
897 * Description This function retrieves modem control signals. Normally
898 * application will call this function after a callback
899 * function is called with notification that one of signals
900 * has been changed.
901 *
902 * Parameters: handle - Handle returned in the RFCOMM_CreateConnection
903 * p_signal - specify the pointer to control signals info
904 *
905 ******************************************************************************/
PORT_GetModemStatus(uint16_t handle,uint8_t * p_signal)906 int PORT_GetModemStatus(uint16_t handle, uint8_t* p_signal) {
907 tPORT* p_port;
908
909 if ((handle == 0) || (handle > MAX_RFC_PORTS)) {
910 return (PORT_BAD_HANDLE);
911 }
912
913 p_port = &rfc_cb.port.port[handle - 1];
914
915 if (!p_port->in_use || (p_port->state == PORT_STATE_CLOSED)) {
916 return (PORT_NOT_OPENED);
917 }
918
919 *p_signal = p_port->peer_ctrl.modem_signal;
920
921 RFCOMM_TRACE_API("PORT_GetModemStatus() handle:%d signal:%x", handle,
922 *p_signal);
923
924 return (PORT_SUCCESS);
925 }
926
927 /*******************************************************************************
928 *
929 * Function PORT_ClearError
930 *
931 * Description This function retreives information about a communications
932 * error and reports current status of a connection. The
933 * function should be called when an error occures to clear
934 * the connection error flag and to enable additional read
935 * and write operations.
936 *
937 * Parameters: handle - Handle returned in the RFCOMM_CreateConnection
938 * p_errors - pointer of the variable to receive error codes
939 * p_status - pointer to the tPORT_STATUS structur to receive
940 * connection status
941 *
942 ******************************************************************************/
PORT_ClearError(uint16_t handle,uint16_t * p_errors,tPORT_STATUS * p_status)943 int PORT_ClearError(uint16_t handle, uint16_t* p_errors,
944 tPORT_STATUS* p_status) {
945 tPORT* p_port;
946
947 RFCOMM_TRACE_API("PORT_ClearError() handle:%d", handle);
948
949 if ((handle == 0) || (handle > MAX_RFC_PORTS)) {
950 return (PORT_BAD_HANDLE);
951 }
952
953 p_port = &rfc_cb.port.port[handle - 1];
954
955 if (!p_port->in_use || (p_port->state == PORT_STATE_CLOSED)) {
956 return (PORT_NOT_OPENED);
957 }
958
959 *p_errors = p_port->line_status;
960
961 /* This is the only call to clear error status. We can not clear */
962 /* connection failed status. To clean it port should be closed and reopened
963 */
964 p_port->line_status = (p_port->line_status & LINE_STATUS_FAILED);
965
966 PORT_GetQueueStatus(handle, p_status);
967 return (PORT_SUCCESS);
968 }
969
970 /*******************************************************************************
971 *
972 * Function PORT_SendError
973 *
974 * Description This function send a communications error to the peer device
975 *
976 * Parameters: handle - Handle returned in the RFCOMM_CreateConnection
977 * errors - receive error codes
978 *
979 ******************************************************************************/
PORT_SendError(uint16_t handle,uint8_t errors)980 int PORT_SendError(uint16_t handle, uint8_t errors) {
981 tPORT* p_port;
982
983 RFCOMM_TRACE_API("PORT_SendError() handle:%d errors:0x%x", handle, errors);
984
985 if ((handle == 0) || (handle > MAX_RFC_PORTS)) {
986 return (PORT_BAD_HANDLE);
987 }
988
989 p_port = &rfc_cb.port.port[handle - 1];
990
991 if (!p_port->in_use || (p_port->state == PORT_STATE_CLOSED)) {
992 return (PORT_NOT_OPENED);
993 }
994
995 if (!p_port->rfc.p_mcb) {
996 return (PORT_NOT_OPENED);
997 }
998
999 RFCOMM_LineStatusReq(p_port->rfc.p_mcb, p_port->dlci, errors);
1000 return (PORT_SUCCESS);
1001 }
1002
1003 /*******************************************************************************
1004 *
1005 * Function PORT_GetQueueStatus
1006 *
1007 * Description This function reports current status of a connection.
1008 *
1009 * Parameters: handle - Handle returned in the RFCOMM_CreateConnection
1010 * p_status - pointer to the tPORT_STATUS structur to receive
1011 * connection status
1012 *
1013 ******************************************************************************/
PORT_GetQueueStatus(uint16_t handle,tPORT_STATUS * p_status)1014 int PORT_GetQueueStatus(uint16_t handle, tPORT_STATUS* p_status) {
1015 tPORT* p_port;
1016
1017 /* RFCOMM_TRACE_API ("PORT_GetQueueStatus() handle:%d", handle); */
1018
1019 if ((handle == 0) || (handle > MAX_RFC_PORTS)) {
1020 return (PORT_BAD_HANDLE);
1021 }
1022
1023 p_port = &rfc_cb.port.port[handle - 1];
1024
1025 if (!p_port->in_use || (p_port->state == PORT_STATE_CLOSED)) {
1026 return (PORT_NOT_OPENED);
1027 }
1028
1029 p_status->in_queue_size = (uint16_t)p_port->rx.queue_size;
1030 p_status->out_queue_size = (uint16_t)p_port->tx.queue_size;
1031
1032 p_status->mtu_size = (uint16_t)p_port->peer_mtu;
1033
1034 p_status->flags = 0;
1035
1036 if (!(p_port->peer_ctrl.modem_signal & PORT_CTSRTS_ON))
1037 p_status->flags |= PORT_FLAG_CTS_HOLD;
1038
1039 if (!(p_port->peer_ctrl.modem_signal & PORT_DTRDSR_ON))
1040 p_status->flags |= PORT_FLAG_DSR_HOLD;
1041
1042 if (!(p_port->peer_ctrl.modem_signal & PORT_DCD_ON))
1043 p_status->flags |= PORT_FLAG_RLSD_HOLD;
1044
1045 return (PORT_SUCCESS);
1046 }
1047
1048 /*******************************************************************************
1049 *
1050 * Function PORT_Purge
1051 *
1052 * Description This function discards all the data from the output or
1053 * input queues of the specified connection.
1054 *
1055 * Parameters: handle - Handle returned in the RFCOMM_CreateConnection
1056 * purge_flags - specify the action to take.
1057 *
1058 ******************************************************************************/
PORT_Purge(uint16_t handle,uint8_t purge_flags)1059 int PORT_Purge(uint16_t handle, uint8_t purge_flags) {
1060 tPORT* p_port;
1061 BT_HDR* p_buf;
1062 uint16_t count;
1063 uint32_t events;
1064
1065 RFCOMM_TRACE_API("PORT_Purge() handle:%d flags:0x%x", handle, purge_flags);
1066
1067 /* Check if handle is valid to avoid crashing */
1068 if ((handle == 0) || (handle > MAX_RFC_PORTS)) {
1069 return (PORT_BAD_HANDLE);
1070 }
1071
1072 p_port = &rfc_cb.port.port[handle - 1];
1073
1074 if (!p_port->in_use || (p_port->state == PORT_STATE_CLOSED)) {
1075 return (PORT_NOT_OPENED);
1076 }
1077
1078 if (purge_flags & PORT_PURGE_RXCLEAR) {
1079 mutex_global_lock(); /* to prevent missing credit */
1080
1081 count = fixed_queue_length(p_port->rx.queue);
1082
1083 while ((p_buf = (BT_HDR*)fixed_queue_try_dequeue(p_port->rx.queue)) != NULL)
1084 osi_free(p_buf);
1085
1086 p_port->rx.queue_size = 0;
1087
1088 mutex_global_unlock();
1089
1090 /* If we flowed controlled peer based on rx_queue size enable data again */
1091 if (count) port_flow_control_peer(p_port, true, count);
1092 }
1093
1094 if (purge_flags & PORT_PURGE_TXCLEAR) {
1095 mutex_global_lock(); /* to prevent tx.queue_size from being negative */
1096
1097 while ((p_buf = (BT_HDR*)fixed_queue_try_dequeue(p_port->tx.queue)) != NULL)
1098 osi_free(p_buf);
1099
1100 p_port->tx.queue_size = 0;
1101
1102 mutex_global_unlock();
1103
1104 events = PORT_EV_TXEMPTY;
1105
1106 events |= port_flow_control_user(p_port);
1107
1108 events &= p_port->ev_mask;
1109
1110 if ((p_port->p_callback != NULL) && events)
1111 (p_port->p_callback)(events, p_port->handle);
1112 }
1113
1114 return (PORT_SUCCESS);
1115 }
1116
1117 /*******************************************************************************
1118 *
1119 * Function PORT_ReadData
1120 *
1121 * Description Normally not GKI aware application will call this function
1122 * after receiving PORT_EV_RXCHAR event.
1123 *
1124 * Parameters: handle - Handle returned in the RFCOMM_CreateConnection
1125 * p_data - Data area
1126 * max_len - Byte count requested
1127 * p_len - Byte count received
1128 *
1129 ******************************************************************************/
PORT_ReadData(uint16_t handle,char * p_data,uint16_t max_len,uint16_t * p_len)1130 int PORT_ReadData(uint16_t handle, char* p_data, uint16_t max_len,
1131 uint16_t* p_len) {
1132 tPORT* p_port;
1133 BT_HDR* p_buf;
1134 uint16_t count;
1135
1136 RFCOMM_TRACE_API("PORT_ReadData() handle:%d max_len:%d", handle, max_len);
1137
1138 /* Initialize this in case of an error */
1139 *p_len = 0;
1140
1141 /* Check if handle is valid to avoid crashing */
1142 if ((handle == 0) || (handle > MAX_RFC_PORTS)) {
1143 return (PORT_BAD_HANDLE);
1144 }
1145
1146 p_port = &rfc_cb.port.port[handle - 1];
1147
1148 if (!p_port->in_use || (p_port->state == PORT_STATE_CLOSED)) {
1149 return (PORT_NOT_OPENED);
1150 }
1151
1152 if (p_port->line_status) {
1153 return (PORT_LINE_ERR);
1154 }
1155
1156 if (fixed_queue_is_empty(p_port->rx.queue)) return (PORT_SUCCESS);
1157
1158 count = 0;
1159
1160 while (max_len) {
1161 p_buf = (BT_HDR*)fixed_queue_try_peek_first(p_port->rx.queue);
1162 if (p_buf == NULL) break;
1163
1164 if (p_buf->len > max_len) {
1165 memcpy(p_data, (uint8_t*)(p_buf + 1) + p_buf->offset, max_len);
1166 p_buf->offset += max_len;
1167 p_buf->len -= max_len;
1168
1169 *p_len += max_len;
1170
1171 mutex_global_lock();
1172
1173 p_port->rx.queue_size -= max_len;
1174
1175 mutex_global_unlock();
1176
1177 break;
1178 } else {
1179 memcpy(p_data, (uint8_t*)(p_buf + 1) + p_buf->offset, p_buf->len);
1180
1181 *p_len += p_buf->len;
1182 max_len -= p_buf->len;
1183
1184 mutex_global_lock();
1185
1186 p_port->rx.queue_size -= p_buf->len;
1187
1188 if (max_len) {
1189 p_data += p_buf->len;
1190 }
1191
1192 osi_free(fixed_queue_try_dequeue(p_port->rx.queue));
1193
1194 mutex_global_unlock();
1195
1196 count++;
1197 }
1198 }
1199
1200 if (*p_len == 1) {
1201 RFCOMM_TRACE_EVENT("PORT_ReadData queue:%d returned:%d %x",
1202 p_port->rx.queue_size, *p_len, (p_data[0]));
1203 } else {
1204 RFCOMM_TRACE_EVENT("PORT_ReadData queue:%d returned:%d",
1205 p_port->rx.queue_size, *p_len);
1206 }
1207
1208 /* If rfcomm suspended traffic from the peer based on the rx_queue_size */
1209 /* check if it can be resumed now */
1210 port_flow_control_peer(p_port, true, count);
1211
1212 return (PORT_SUCCESS);
1213 }
1214
1215 /*******************************************************************************
1216 *
1217 * Function PORT_Read
1218 *
1219 * Description Normally application will call this function after receiving
1220 * PORT_EV_RXCHAR event.
1221 *
1222 * Parameters: handle - Handle returned in the RFCOMM_CreateConnection
1223 * pp_buf - pointer to address of buffer with data,
1224 *
1225 ******************************************************************************/
PORT_Read(uint16_t handle,BT_HDR ** pp_buf)1226 int PORT_Read(uint16_t handle, BT_HDR** pp_buf) {
1227 tPORT* p_port;
1228 BT_HDR* p_buf;
1229
1230 RFCOMM_TRACE_API("PORT_Read() handle:%d", handle);
1231
1232 /* Check if handle is valid to avoid crashing */
1233 if ((handle == 0) || (handle > MAX_RFC_PORTS)) {
1234 return (PORT_BAD_HANDLE);
1235 }
1236 p_port = &rfc_cb.port.port[handle - 1];
1237
1238 if (!p_port->in_use || (p_port->state == PORT_STATE_CLOSED)) {
1239 return (PORT_NOT_OPENED);
1240 }
1241
1242 if (p_port->line_status) {
1243 return (PORT_LINE_ERR);
1244 }
1245
1246 mutex_global_lock();
1247
1248 p_buf = (BT_HDR*)fixed_queue_try_dequeue(p_port->rx.queue);
1249 if (p_buf) {
1250 p_port->rx.queue_size -= p_buf->len;
1251
1252 mutex_global_unlock();
1253
1254 /* If rfcomm suspended traffic from the peer based on the rx_queue_size */
1255 /* check if it can be resumed now */
1256 port_flow_control_peer(p_port, true, 1);
1257 } else {
1258 mutex_global_unlock();
1259 }
1260
1261 *pp_buf = p_buf;
1262 return (PORT_SUCCESS);
1263 }
1264
1265 /*******************************************************************************
1266 *
1267 * Function port_write
1268 *
1269 * Description This function when a data packet is received from the apper
1270 * layer task.
1271 *
1272 * Parameters: p_port - pointer to address of port control block
1273 * p_buf - pointer to address of buffer with data,
1274 *
1275 ******************************************************************************/
port_write(tPORT * p_port,BT_HDR * p_buf)1276 static int port_write(tPORT* p_port, BT_HDR* p_buf) {
1277 /* We should not allow to write data in to server port when connection is not
1278 * opened */
1279 if (p_port->is_server && (p_port->rfc.state != RFC_STATE_OPENED)) {
1280 osi_free(p_buf);
1281 return (PORT_CLOSED);
1282 }
1283
1284 /* Keep the data in pending queue if peer does not allow data, or */
1285 /* Peer is not ready or Port is not yet opened or initial port control */
1286 /* command has not been sent */
1287 if (p_port->tx.peer_fc || !p_port->rfc.p_mcb ||
1288 !p_port->rfc.p_mcb->peer_ready ||
1289 (p_port->rfc.state != RFC_STATE_OPENED) ||
1290 ((p_port->port_ctrl & (PORT_CTRL_REQ_SENT | PORT_CTRL_IND_RECEIVED)) !=
1291 (PORT_CTRL_REQ_SENT | PORT_CTRL_IND_RECEIVED))) {
1292 if ((p_port->tx.queue_size > PORT_TX_CRITICAL_WM) ||
1293 (fixed_queue_length(p_port->tx.queue) > PORT_TX_BUF_CRITICAL_WM)) {
1294 RFCOMM_TRACE_WARNING("PORT_Write: Queue size: %d", p_port->tx.queue_size);
1295
1296 osi_free(p_buf);
1297
1298 if ((p_port->p_callback != NULL) && (p_port->ev_mask & PORT_EV_ERR))
1299 p_port->p_callback(PORT_EV_ERR, p_port->handle);
1300
1301 return (PORT_TX_FULL);
1302 }
1303
1304 RFCOMM_TRACE_EVENT(
1305 "PORT_Write : Data is enqued. flow disabled %d peer_ready %d state %d "
1306 "ctrl_state %x",
1307 p_port->tx.peer_fc,
1308 (p_port->rfc.p_mcb && p_port->rfc.p_mcb->peer_ready), p_port->rfc.state,
1309 p_port->port_ctrl);
1310
1311 fixed_queue_enqueue(p_port->tx.queue, p_buf);
1312 p_port->tx.queue_size += p_buf->len;
1313
1314 return (PORT_CMD_PENDING);
1315 } else {
1316 RFCOMM_TRACE_EVENT("PORT_Write : Data is being sent");
1317
1318 RFCOMM_DataReq(p_port->rfc.p_mcb, p_port->dlci, p_buf);
1319 return (PORT_SUCCESS);
1320 }
1321 }
1322
1323 /*******************************************************************************
1324 *
1325 * Function PORT_Write
1326 *
1327 * Description This function when a data packet is received from the apper
1328 * layer task.
1329 *
1330 * Parameters: handle - Handle returned in the RFCOMM_CreateConnection
1331 * pp_buf - pointer to address of buffer with data,
1332 *
1333 ******************************************************************************/
PORT_Write(uint16_t handle,BT_HDR * p_buf)1334 int PORT_Write(uint16_t handle, BT_HDR* p_buf) {
1335 tPORT* p_port;
1336 uint32_t event = 0;
1337 int rc;
1338
1339 RFCOMM_TRACE_API("PORT_Write() handle:%d", handle);
1340
1341 /* Check if handle is valid to avoid crashing */
1342 if ((handle == 0) || (handle > MAX_RFC_PORTS)) {
1343 osi_free(p_buf);
1344 return (PORT_BAD_HANDLE);
1345 }
1346
1347 p_port = &rfc_cb.port.port[handle - 1];
1348
1349 if (!p_port->in_use || (p_port->state == PORT_STATE_CLOSED)) {
1350 osi_free(p_buf);
1351 return (PORT_NOT_OPENED);
1352 }
1353
1354 if (p_port->line_status) {
1355 RFCOMM_TRACE_WARNING("PORT_Write: Data dropped line_status:0x%x",
1356 p_port->line_status);
1357 osi_free(p_buf);
1358 return (PORT_LINE_ERR);
1359 }
1360
1361 rc = port_write(p_port, p_buf);
1362 event |= port_flow_control_user(p_port);
1363
1364 switch (rc) {
1365 case PORT_TX_FULL:
1366 event |= PORT_EV_ERR;
1367 break;
1368
1369 case PORT_SUCCESS:
1370 event |= (PORT_EV_TXCHAR | PORT_EV_TXEMPTY);
1371 break;
1372 }
1373 /* Mask out all events that are not of interest to user */
1374 event &= p_port->ev_mask;
1375
1376 /* Send event to the application */
1377 if (p_port->p_callback && event) (p_port->p_callback)(event, p_port->handle);
1378
1379 return (PORT_SUCCESS);
1380 }
1381 /*******************************************************************************
1382 *
1383 * Function PORT_WriteDataCO
1384 *
1385 * Description Normally not GKI aware application will call this function
1386 * to send data to the port by callout functions
1387 *
1388 * Parameters: handle - Handle returned in the RFCOMM_CreateConnection
1389 * fd - socket fd
1390 * p_len - Byte count returned
1391 *
1392 ******************************************************************************/
PORT_WriteDataCO(uint16_t handle,int * p_len)1393 int PORT_WriteDataCO(uint16_t handle, int* p_len) {
1394 tPORT* p_port;
1395 BT_HDR* p_buf;
1396 uint32_t event = 0;
1397 int rc = 0;
1398 uint16_t length;
1399
1400 RFCOMM_TRACE_API("PORT_WriteDataCO() handle:%d", handle);
1401 *p_len = 0;
1402
1403 /* Check if handle is valid to avoid crashing */
1404 if ((handle == 0) || (handle > MAX_RFC_PORTS)) {
1405 return (PORT_BAD_HANDLE);
1406 }
1407 p_port = &rfc_cb.port.port[handle - 1];
1408
1409 if (!p_port->in_use || (p_port->state == PORT_STATE_CLOSED)) {
1410 RFCOMM_TRACE_WARNING("PORT_WriteDataByFd() no port state:%d",
1411 p_port->state);
1412 return (PORT_NOT_OPENED);
1413 }
1414
1415 if (!p_port->peer_mtu) {
1416 RFCOMM_TRACE_ERROR("PORT_WriteDataByFd() peer_mtu:%d", p_port->peer_mtu);
1417 return (PORT_UNKNOWN_ERROR);
1418 }
1419 int available = 0;
1420 // if(ioctl(fd, FIONREAD, &available) < 0)
1421 if (!p_port->p_data_co_callback(handle, (uint8_t*)&available,
1422 sizeof(available),
1423 DATA_CO_CALLBACK_TYPE_OUTGOING_SIZE)) {
1424 RFCOMM_TRACE_ERROR(
1425 "p_data_co_callback DATA_CO_CALLBACK_TYPE_INCOMING_SIZE failed, "
1426 "available:%d",
1427 available);
1428 return (PORT_UNKNOWN_ERROR);
1429 }
1430 if (available == 0) return PORT_SUCCESS;
1431 /* Length for each buffer is the smaller of GKI buffer, peer MTU, or max_len
1432 */
1433 length = RFCOMM_DATA_BUF_SIZE -
1434 (uint16_t)(sizeof(BT_HDR) + L2CAP_MIN_OFFSET + RFCOMM_DATA_OVERHEAD);
1435
1436 /* If there are buffers scheduled for transmission check if requested */
1437 /* data fits into the end of the queue */
1438 mutex_global_lock();
1439
1440 p_buf = (BT_HDR*)fixed_queue_try_peek_last(p_port->tx.queue);
1441 if ((p_buf != NULL) &&
1442 (((int)p_buf->len + available) <= (int)p_port->peer_mtu) &&
1443 (((int)p_buf->len + available) <= (int)length)) {
1444 // if(recv(fd, (uint8_t *)(p_buf + 1) + p_buf->offset + p_buf->len,
1445 // available, 0) != available)
1446 if (!p_port->p_data_co_callback(
1447 handle, (uint8_t*)(p_buf + 1) + p_buf->offset + p_buf->len,
1448 available, DATA_CO_CALLBACK_TYPE_OUTGOING))
1449
1450 {
1451 error(
1452 "p_data_co_callback DATA_CO_CALLBACK_TYPE_OUTGOING failed, "
1453 "available:%d",
1454 available);
1455 mutex_global_unlock();
1456 return (PORT_UNKNOWN_ERROR);
1457 }
1458 // memcpy ((uint8_t *)(p_buf + 1) + p_buf->offset + p_buf->len, p_data,
1459 // max_len);
1460 p_port->tx.queue_size += (uint16_t)available;
1461
1462 *p_len = available;
1463 p_buf->len += (uint16_t)available;
1464
1465 mutex_global_unlock();
1466
1467 return (PORT_SUCCESS);
1468 }
1469
1470 mutex_global_unlock();
1471
1472 // int max_read = length < p_port->peer_mtu ? length : p_port->peer_mtu;
1473
1474 // max_read = available < max_read ? available : max_read;
1475
1476 while (available) {
1477 /* if we're over buffer high water mark, we're done */
1478 if ((p_port->tx.queue_size > PORT_TX_HIGH_WM) ||
1479 (fixed_queue_length(p_port->tx.queue) > PORT_TX_BUF_HIGH_WM)) {
1480 port_flow_control_user(p_port);
1481 event |= PORT_EV_FC;
1482 RFCOMM_TRACE_EVENT(
1483 "tx queue is full,tx.queue_size:%d,tx.queue.count:%d,available:%d",
1484 p_port->tx.queue_size, fixed_queue_length(p_port->tx.queue),
1485 available);
1486 break;
1487 }
1488
1489 /* continue with rfcomm data write */
1490 p_buf = (BT_HDR*)osi_malloc(RFCOMM_DATA_BUF_SIZE);
1491 p_buf->offset = L2CAP_MIN_OFFSET + RFCOMM_MIN_OFFSET;
1492 p_buf->layer_specific = handle;
1493
1494 if (p_port->peer_mtu < length) length = p_port->peer_mtu;
1495 if (available < (int)length) length = (uint16_t)available;
1496 p_buf->len = length;
1497 p_buf->event = BT_EVT_TO_BTU_SP_DATA;
1498
1499 // memcpy ((uint8_t *)(p_buf + 1) + p_buf->offset, p_data, length);
1500 // if(recv(fd, (uint8_t *)(p_buf + 1) + p_buf->offset, (int)length, 0) !=
1501 // (int)length)
1502 if (!p_port->p_data_co_callback(handle,
1503 (uint8_t*)(p_buf + 1) + p_buf->offset,
1504 length, DATA_CO_CALLBACK_TYPE_OUTGOING)) {
1505 error(
1506 "p_data_co_callback DATA_CO_CALLBACK_TYPE_OUTGOING failed, length:%d",
1507 length);
1508 return (PORT_UNKNOWN_ERROR);
1509 }
1510
1511 RFCOMM_TRACE_EVENT("PORT_WriteData %d bytes", length);
1512
1513 rc = port_write(p_port, p_buf);
1514
1515 /* If queue went below the threashold need to send flow control */
1516 event |= port_flow_control_user(p_port);
1517
1518 if (rc == PORT_SUCCESS) event |= PORT_EV_TXCHAR;
1519
1520 if ((rc != PORT_SUCCESS) && (rc != PORT_CMD_PENDING)) break;
1521
1522 *p_len += length;
1523 available -= (int)length;
1524 }
1525 if (!available && (rc != PORT_CMD_PENDING) && (rc != PORT_TX_QUEUE_DISABLED))
1526 event |= PORT_EV_TXEMPTY;
1527
1528 /* Mask out all events that are not of interest to user */
1529 event &= p_port->ev_mask;
1530
1531 /* Send event to the application */
1532 if (p_port->p_callback && event) (p_port->p_callback)(event, p_port->handle);
1533
1534 return (PORT_SUCCESS);
1535 }
1536
1537 /*******************************************************************************
1538 *
1539 * Function PORT_WriteData
1540 *
1541 * Description Normally not GKI aware application will call this function
1542 * to send data to the port.
1543 *
1544 * Parameters: handle - Handle returned in the RFCOMM_CreateConnection
1545 * p_data - Data area
1546 * max_len - Byte count requested
1547 * p_len - Byte count received
1548 *
1549 ******************************************************************************/
PORT_WriteData(uint16_t handle,const char * p_data,uint16_t max_len,uint16_t * p_len)1550 int PORT_WriteData(uint16_t handle, const char* p_data, uint16_t max_len,
1551 uint16_t* p_len) {
1552 tPORT* p_port;
1553 BT_HDR* p_buf;
1554 uint32_t event = 0;
1555 int rc = 0;
1556 uint16_t length;
1557
1558 RFCOMM_TRACE_API("PORT_WriteData() max_len:%d", max_len);
1559
1560 *p_len = 0;
1561
1562 /* Check if handle is valid to avoid crashing */
1563 if ((handle == 0) || (handle > MAX_RFC_PORTS)) {
1564 return (PORT_BAD_HANDLE);
1565 }
1566 p_port = &rfc_cb.port.port[handle - 1];
1567
1568 if (!p_port->in_use || (p_port->state == PORT_STATE_CLOSED)) {
1569 RFCOMM_TRACE_WARNING("PORT_WriteData() no port state:%d", p_port->state);
1570 return (PORT_NOT_OPENED);
1571 }
1572
1573 if (!max_len || !p_port->peer_mtu) {
1574 RFCOMM_TRACE_ERROR("PORT_WriteData() peer_mtu:%d", p_port->peer_mtu);
1575 return (PORT_UNKNOWN_ERROR);
1576 }
1577
1578 /* Length for each buffer is the smaller of GKI buffer, peer MTU, or max_len
1579 */
1580 length = RFCOMM_DATA_BUF_SIZE -
1581 (uint16_t)(sizeof(BT_HDR) + L2CAP_MIN_OFFSET + RFCOMM_DATA_OVERHEAD);
1582
1583 /* If there are buffers scheduled for transmission check if requested */
1584 /* data fits into the end of the queue */
1585 mutex_global_lock();
1586
1587 p_buf = (BT_HDR*)fixed_queue_try_peek_last(p_port->tx.queue);
1588 if ((p_buf != NULL) && ((p_buf->len + max_len) <= p_port->peer_mtu) &&
1589 ((p_buf->len + max_len) <= length)) {
1590 memcpy((uint8_t*)(p_buf + 1) + p_buf->offset + p_buf->len, p_data, max_len);
1591 p_port->tx.queue_size += max_len;
1592
1593 *p_len = max_len;
1594 p_buf->len += max_len;
1595
1596 mutex_global_unlock();
1597
1598 return (PORT_SUCCESS);
1599 }
1600
1601 mutex_global_unlock();
1602
1603 while (max_len) {
1604 /* if we're over buffer high water mark, we're done */
1605 if ((p_port->tx.queue_size > PORT_TX_HIGH_WM) ||
1606 (fixed_queue_length(p_port->tx.queue) > PORT_TX_BUF_HIGH_WM))
1607 break;
1608
1609 /* continue with rfcomm data write */
1610 p_buf = (BT_HDR*)osi_malloc(RFCOMM_DATA_BUF_SIZE);
1611 p_buf->offset = L2CAP_MIN_OFFSET + RFCOMM_MIN_OFFSET;
1612 p_buf->layer_specific = handle;
1613
1614 if (p_port->peer_mtu < length) length = p_port->peer_mtu;
1615 if (max_len < length) length = max_len;
1616 p_buf->len = length;
1617 p_buf->event = BT_EVT_TO_BTU_SP_DATA;
1618
1619 memcpy((uint8_t*)(p_buf + 1) + p_buf->offset, p_data, length);
1620
1621 RFCOMM_TRACE_EVENT("PORT_WriteData %d bytes", length);
1622
1623 rc = port_write(p_port, p_buf);
1624
1625 /* If queue went below the threashold need to send flow control */
1626 event |= port_flow_control_user(p_port);
1627
1628 if (rc == PORT_SUCCESS) event |= PORT_EV_TXCHAR;
1629
1630 if ((rc != PORT_SUCCESS) && (rc != PORT_CMD_PENDING)) break;
1631
1632 *p_len += length;
1633 max_len -= length;
1634 p_data += length;
1635 }
1636 if (!max_len && (rc != PORT_CMD_PENDING) && (rc != PORT_TX_QUEUE_DISABLED))
1637 event |= PORT_EV_TXEMPTY;
1638
1639 /* Mask out all events that are not of interest to user */
1640 event &= p_port->ev_mask;
1641
1642 /* Send event to the application */
1643 if (p_port->p_callback && event) (p_port->p_callback)(event, p_port->handle);
1644
1645 return (PORT_SUCCESS);
1646 }
1647
1648 /*******************************************************************************
1649 *
1650 * Function PORT_Test
1651 *
1652 * Description Application can call this function to send RFCOMM Test frame
1653 *
1654 * Parameters: handle - Handle returned in the RFCOMM_CreateConnection
1655 * p_data - Data area
1656 * max_len - Byte count requested
1657 *
1658 ******************************************************************************/
PORT_Test(uint16_t handle,uint8_t * p_data,uint16_t len)1659 int PORT_Test(uint16_t handle, uint8_t* p_data, uint16_t len) {
1660 tPORT* p_port;
1661
1662 RFCOMM_TRACE_API("PORT_Test() len:%d", len);
1663
1664 if ((handle == 0) || (handle > MAX_RFC_PORTS)) {
1665 return (PORT_BAD_HANDLE);
1666 }
1667 p_port = &rfc_cb.port.port[handle - 1];
1668
1669 if (!p_port->in_use || (p_port->state == PORT_STATE_CLOSED)) {
1670 return (PORT_NOT_OPENED);
1671 }
1672
1673 if (len > ((p_port->mtu == 0) ? RFCOMM_DEFAULT_MTU : p_port->mtu)) {
1674 return (PORT_UNKNOWN_ERROR);
1675 }
1676
1677 BT_HDR* p_buf = (BT_HDR*)osi_malloc(RFCOMM_CMD_BUF_SIZE);
1678 p_buf->offset = L2CAP_MIN_OFFSET + RFCOMM_MIN_OFFSET + 2;
1679 p_buf->len = len;
1680
1681 memcpy((uint8_t*)(p_buf + 1) + p_buf->offset, p_data, p_buf->len);
1682
1683 rfc_send_test(p_port->rfc.p_mcb, true, p_buf);
1684
1685 return (PORT_SUCCESS);
1686 }
1687
1688 /*******************************************************************************
1689 *
1690 * Function RFCOMM_Init
1691 *
1692 * Description This function is called to initialize RFCOMM layer
1693 *
1694 ******************************************************************************/
RFCOMM_Init(void)1695 void RFCOMM_Init(void) {
1696 memset(&rfc_cb, 0, sizeof(tRFC_CB)); /* Init RFCOMM control block */
1697
1698 rfc_cb.rfc.last_mux = MAX_BD_CONNECTIONS;
1699
1700 #if defined(RFCOMM_INITIAL_TRACE_LEVEL)
1701 rfc_cb.trace_level = RFCOMM_INITIAL_TRACE_LEVEL;
1702 #else
1703 rfc_cb.trace_level = BT_TRACE_LEVEL_NONE; /* No traces */
1704 #endif
1705
1706 rfcomm_l2cap_if_init();
1707 }
1708
1709 /*******************************************************************************
1710 *
1711 * Function PORT_SetTraceLevel
1712 *
1713 * Description Set the trace level for RFCOMM. If called with 0xFF, it
1714 * simply reads the current trace level.
1715 *
1716 * Returns the new (current) trace level
1717 *
1718 ******************************************************************************/
PORT_SetTraceLevel(uint8_t new_level)1719 uint8_t PORT_SetTraceLevel(uint8_t new_level) {
1720 if (new_level != 0xFF) rfc_cb.trace_level = new_level;
1721
1722 return (rfc_cb.trace_level);
1723 }
1724
1725 /*******************************************************************************
1726 *
1727 * Function PORT_GetResultString
1728 *
1729 * Description This function returns the human-readable string for a given
1730 * result code.
1731 *
1732 * Returns a pointer to the human-readable string for the given result.
1733 *
1734 ******************************************************************************/
PORT_GetResultString(const uint8_t result_code)1735 const char* PORT_GetResultString(const uint8_t result_code) {
1736 if (result_code > PORT_ERR_MAX) {
1737 return result_code_strings[PORT_ERR_MAX];
1738 }
1739
1740 return result_code_strings[result_code];
1741 }
1742