Home | History | Annotate | Download | only in rfcomm
      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 *******************************************************************************/
    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 *******************************************************************************/
    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 *******************************************************************************/
    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 *******************************************************************************/
    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 
    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 *******************************************************************************/
    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 *******************************************************************************/
    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 *******************************************************************************/
    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 *******************************************************************************/
    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 *******************************************************************************/
    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 *******************************************************************************/
    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 *******************************************************************************/
    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 *******************************************************************************/
    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 *******************************************************************************/
    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 *******************************************************************************/
    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 
    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 *******************************************************************************/
    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 *******************************************************************************/
   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 *******************************************************************************/
   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 *******************************************************************************/
   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 *******************************************************************************/
   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 *******************************************************************************/
   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 *******************************************************************************/
   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 *******************************************************************************/
   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 *******************************************************************************/
   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 *******************************************************************************/
   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 *******************************************************************************/
   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 *******************************************************************************/
   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 *******************************************************************************/
   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 *******************************************************************************/
   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 *******************************************************************************/
   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