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