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