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