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