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