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