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