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