Home | History | Annotate | Download | only in rfcomm
      1 /******************************************************************************
      2  *
      3  *  Copyright 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  *  Port Emulation entity utilities
     22  *
     23  ******************************************************************************/
     24 #include <base/logging.h>
     25 #include <string.h>
     26 
     27 #include "osi/include/mutex.h"
     28 
     29 #include "bt_common.h"
     30 #include "bt_target.h"
     31 #include "btm_int.h"
     32 #include "btu.h"
     33 #include "l2cdefs.h"
     34 #include "port_api.h"
     35 #include "port_int.h"
     36 #include "rfc_int.h"
     37 #include "rfcdefs.h"
     38 
     39 static const tPORT_STATE default_port_pars = {
     40     PORT_BAUD_RATE_9600,
     41     PORT_8_BITS,
     42     PORT_ONESTOPBIT,
     43     PORT_PARITY_NO,
     44     PORT_ODD_PARITY,
     45     PORT_FC_OFF,
     46     0, /* No rx_char */
     47     PORT_XON_DC1,
     48     PORT_XOFF_DC3,
     49 };
     50 
     51 /*******************************************************************************
     52  *
     53  * Function         port_allocate_port
     54  *
     55  * Description      Look through the Port Control Blocks for a free one.  Note
     56  *                  that one server can open several ports with the same SCN
     57  *                  if it can support simulteneous requests from different
     58  *                  clients.
     59  *
     60  * Returns          Pointer to the PORT or NULL if not found
     61  *
     62  ******************************************************************************/
     63 tPORT* port_allocate_port(uint8_t dlci, const RawAddress& bd_addr) {
     64   tPORT* p_port = &rfc_cb.port.port[0];
     65   uint8_t xx, yy;
     66 
     67   for (xx = 0, yy = rfc_cb.rfc.last_port + 1; xx < MAX_RFC_PORTS; xx++, yy++) {
     68     if (yy >= MAX_RFC_PORTS) yy = 0;
     69 
     70     p_port = &rfc_cb.port.port[yy];
     71     if (!p_port->in_use) {
     72       memset(p_port, 0, sizeof(tPORT));
     73 
     74       p_port->in_use = true;
     75       p_port->inx = yy + 1;
     76 
     77       /* During the open set default state for the port connection */
     78       port_set_defaults(p_port);
     79 
     80       p_port->rfc.port_timer = alarm_new("rfcomm_port.port_timer");
     81       rfc_cb.rfc.last_port = yy;
     82 
     83       p_port->dlci = dlci;
     84       p_port->bd_addr = bd_addr;
     85 
     86       RFCOMM_TRACE_DEBUG("rfc_cb.port.port[%d]:%p allocated, last_port:%d", yy,
     87                          p_port, rfc_cb.rfc.last_port);
     88       VLOG(1) << __func__ << ": bd_addr:" << bd_addr;
     89       return (p_port);
     90     }
     91   }
     92 
     93   /* If here, no free PORT found */
     94   return nullptr;
     95 }
     96 
     97 /*******************************************************************************
     98  *
     99  * Function         port_set_defaults
    100  *
    101  * Description      Set defualt port parameters
    102  *
    103  *
    104  ******************************************************************************/
    105 void port_set_defaults(tPORT* p_port) {
    106   p_port->ev_mask = 0;
    107   p_port->p_callback = nullptr;
    108   p_port->port_ctrl = 0;
    109   p_port->error = 0;
    110   p_port->line_status = 0;
    111   p_port->rx_flag_ev_pending = false;
    112   p_port->peer_mtu = RFCOMM_DEFAULT_MTU;
    113 
    114   p_port->user_port_pars = default_port_pars;
    115   p_port->peer_port_pars = default_port_pars;
    116 
    117   p_port->credit_tx = 0;
    118   p_port->credit_rx = 0;
    119 
    120   memset(&p_port->local_ctrl, 0, sizeof(p_port->local_ctrl));
    121   memset(&p_port->peer_ctrl, 0, sizeof(p_port->peer_ctrl));
    122   memset(&p_port->rx, 0, sizeof(p_port->rx));
    123   memset(&p_port->tx, 0, sizeof(p_port->tx));
    124 
    125   p_port->tx.queue = fixed_queue_new(SIZE_MAX);
    126   p_port->rx.queue = fixed_queue_new(SIZE_MAX);
    127 }
    128 
    129 /*******************************************************************************
    130  *
    131  * Function         port_select_mtu
    132  *
    133  * Description      Select MTU which will best serve connection from our
    134  *                  point of view.
    135  *                  If our device is 1.2 or lower we calculate how many DH5s
    136  *                  fit into 1 RFCOMM buffer.
    137  *
    138  *
    139  ******************************************************************************/
    140 void port_select_mtu(tPORT* p_port) {
    141   uint16_t packet_size;
    142 
    143   /* Will select MTU only if application did not setup something */
    144   if (p_port->mtu == 0) {
    145     /* find packet size which connection supports */
    146     packet_size = btm_get_max_packet_size(p_port->bd_addr);
    147     if (packet_size == 0) {
    148       /* something is very wrong */
    149       RFCOMM_TRACE_WARNING("port_select_mtu bad packet size");
    150       p_port->mtu = RFCOMM_DEFAULT_MTU;
    151     } else {
    152       /* We try to negotiate MTU that each packet can be split into whole
    153       number of max packets.  For example if link is 1.2 max packet size is 339
    154       bytes.
    155       At first calculate how many whole packets it is.  MAX L2CAP is 1691 + 4
    156       overhead.
    157       1695, that will be 5 Dh5 packets.  Now maximum RFCOMM packet is
    158       5 * 339 = 1695. Minus 4 bytes L2CAP header 1691.  Minus RFCOMM 6 bytes
    159       header overhead 1685
    160 
    161       For EDR 2.0 packet size is 1027.  So we better send RFCOMM packet as 1
    162       3DH5 packet
    163       1 * 1027 = 1027.  Minus 4 bytes L2CAP header 1023.  Minus RFCOMM 6 bytes
    164       header overhead 1017 */
    165       if ((L2CAP_MTU_SIZE + L2CAP_PKT_OVERHEAD) >= packet_size) {
    166         p_port->mtu = ((L2CAP_MTU_SIZE + L2CAP_PKT_OVERHEAD) / packet_size *
    167                        packet_size) -
    168                       RFCOMM_DATA_OVERHEAD - L2CAP_PKT_OVERHEAD;
    169         RFCOMM_TRACE_DEBUG(
    170             "port_select_mtu selected %d based on connection speed",
    171             p_port->mtu);
    172       } else {
    173         p_port->mtu = L2CAP_MTU_SIZE - RFCOMM_DATA_OVERHEAD;
    174         RFCOMM_TRACE_DEBUG(
    175             "port_select_mtu selected %d based on l2cap PDU size", p_port->mtu);
    176       }
    177     }
    178   } else {
    179     RFCOMM_TRACE_DEBUG("port_select_mtu application selected %d", p_port->mtu);
    180   }
    181   p_port->credit_rx_max = (PORT_RX_HIGH_WM / p_port->mtu);
    182   if (p_port->credit_rx_max > PORT_RX_BUF_HIGH_WM)
    183     p_port->credit_rx_max = PORT_RX_BUF_HIGH_WM;
    184   p_port->credit_rx_low = (PORT_RX_LOW_WM / p_port->mtu);
    185   if (p_port->credit_rx_low > PORT_RX_BUF_LOW_WM)
    186     p_port->credit_rx_low = PORT_RX_BUF_LOW_WM;
    187   p_port->rx_buf_critical = (PORT_RX_CRITICAL_WM / p_port->mtu);
    188   if (p_port->rx_buf_critical > PORT_RX_BUF_CRITICAL_WM)
    189     p_port->rx_buf_critical = PORT_RX_BUF_CRITICAL_WM;
    190   RFCOMM_TRACE_DEBUG(
    191       "port_select_mtu credit_rx_max %d, credit_rx_low %d, rx_buf_critical %d",
    192       p_port->credit_rx_max, p_port->credit_rx_low, p_port->rx_buf_critical);
    193 }
    194 
    195 /*******************************************************************************
    196  *
    197  * Function         port_release_port
    198  *
    199  * Description      Release port control block.
    200  *
    201  * Returns          Pointer to the PORT or NULL if not found
    202  *
    203  ******************************************************************************/
    204 void port_release_port(tPORT* p_port) {
    205   RFCOMM_TRACE_DEBUG("%s p_port: %p state: %d keep_handle: %d", __func__,
    206                      p_port, p_port->rfc.state, p_port->keep_port_handle);
    207 
    208   mutex_global_lock();
    209   BT_HDR* p_buf;
    210   while ((p_buf = (BT_HDR*)fixed_queue_try_dequeue(p_port->rx.queue)) !=
    211          nullptr) {
    212     osi_free(p_buf);
    213   }
    214   p_port->rx.queue_size = 0;
    215 
    216   while ((p_buf = (BT_HDR*)fixed_queue_try_dequeue(p_port->tx.queue)) !=
    217          nullptr) {
    218     osi_free(p_buf);
    219   }
    220   p_port->tx.queue_size = 0;
    221   mutex_global_unlock();
    222 
    223   alarm_cancel(p_port->rfc.port_timer);
    224 
    225   p_port->state = PORT_STATE_CLOSED;
    226 
    227   if (p_port->rfc.state == RFC_STATE_CLOSED) {
    228     if (p_port->rfc.p_mcb) {
    229       p_port->rfc.p_mcb->port_inx[p_port->dlci] = 0;
    230 
    231       /* If there are no more ports opened on this MCB release it */
    232       rfc_check_mcb_active(p_port->rfc.p_mcb);
    233     }
    234 
    235     rfc_port_timer_stop(p_port);
    236 
    237     mutex_global_lock();
    238     fixed_queue_free(p_port->tx.queue, nullptr);
    239     p_port->tx.queue = nullptr;
    240     fixed_queue_free(p_port->rx.queue, nullptr);
    241     p_port->rx.queue = nullptr;
    242     mutex_global_unlock();
    243 
    244     if (p_port->keep_port_handle) {
    245       RFCOMM_TRACE_DEBUG("%s Re-initialize handle: %d", __func__, p_port->inx);
    246 
    247       /* save event mask and callback */
    248       uint32_t mask = p_port->ev_mask;
    249       tPORT_CALLBACK* p_port_cb = p_port->p_callback;
    250       tPORT_STATE user_port_pars = p_port->user_port_pars;
    251 
    252       port_set_defaults(p_port);
    253 
    254       /* restore */
    255       p_port->ev_mask = mask;
    256       p_port->p_callback = p_port_cb;
    257       p_port->user_port_pars = user_port_pars;
    258       p_port->mtu = p_port->keep_mtu;
    259 
    260       p_port->state = PORT_STATE_OPENING;
    261       p_port->rfc.p_mcb = nullptr;
    262       if (p_port->is_server) p_port->dlci &= 0xfe;
    263 
    264       p_port->local_ctrl.modem_signal = p_port->default_signal_state;
    265       p_port->bd_addr = RawAddress::kAny;
    266     } else {
    267       RFCOMM_TRACE_DEBUG("%s Clean-up handle: %d", __func__, p_port->inx);
    268       alarm_free(p_port->rfc.port_timer);
    269       memset(p_port, 0, sizeof(tPORT));
    270     }
    271   }
    272 }
    273 
    274 /*******************************************************************************
    275  *
    276  * Function         port_find_mcb
    277  *
    278  * Description      This function checks if connection exists to device with
    279  *                  the address.
    280  *
    281  ******************************************************************************/
    282 tRFC_MCB* port_find_mcb(const RawAddress& bd_addr) {
    283   for (tRFC_MCB& mcb : rfc_cb.port.rfc_mcb) {
    284     if ((mcb.state != RFC_MX_STATE_IDLE) && (mcb.bd_addr == bd_addr)) {
    285       /* Multiplexer channel found do not change anything */
    286       VLOG(1) << __func__ << ": found bd_addr=" << bd_addr
    287               << ", rfc_mcb=" << &mcb << ", lcid=" << loghex(mcb.lcid);
    288       return &mcb;
    289     }
    290   }
    291   VLOG(1) << __func__ << ": not found, bd_addr:" << bd_addr;
    292   return nullptr;
    293 }
    294 
    295 /*******************************************************************************
    296  *
    297  * Function         port_find_mcb_dlci_port
    298  *
    299  * Description      Find port on the multiplexer channel based on DLCI.  If
    300  *                  this port with DLCI not found try to use even DLCI.  This
    301  *                  is for the case when client is establishing connection on
    302  *                  none-initiator MCB.
    303  *
    304  * Returns          Pointer to the PORT or NULL if not found
    305  *
    306  ******************************************************************************/
    307 tPORT* port_find_mcb_dlci_port(tRFC_MCB* p_mcb, uint8_t dlci) {
    308   if (!p_mcb) {
    309     LOG(ERROR) << __func__ << ": p_mcb is null, dlci=" << std::to_string(dlci);
    310     return nullptr;
    311   }
    312 
    313   if (dlci > RFCOMM_MAX_DLCI) {
    314     LOG(WARNING) << __func__ << ": DLCI " << std::to_string(dlci)
    315                  << " is too large, bd_addr=" << p_mcb->bd_addr
    316                  << ", p_mcb=" << p_mcb;
    317     return nullptr;
    318   }
    319 
    320   uint8_t inx = p_mcb->port_inx[dlci];
    321   if (inx == 0) {
    322     LOG(INFO) << __func__ << ": Cannot find allocated RFCOMM app port for DLCI "
    323               << std::to_string(dlci) << " on " << p_mcb->bd_addr
    324               << ", p_mcb=" << p_mcb;
    325     return nullptr;
    326   }
    327   return &rfc_cb.port.port[inx - 1];
    328 }
    329 
    330 /*******************************************************************************
    331  *
    332  * Function         port_find_dlci_port
    333  *
    334  * Description      Find port with DLCI not assigned to multiplexer channel
    335  *
    336  * Returns          Pointer to the PORT or NULL if not found
    337  *
    338  ******************************************************************************/
    339 tPORT* port_find_dlci_port(uint8_t dlci) {
    340   for (tPORT& port : rfc_cb.port.port) {
    341     if (port.in_use && (port.rfc.p_mcb == nullptr)) {
    342       if (port.dlci == dlci) {
    343         return &port;
    344       } else if ((dlci & 0x01) && (port.dlci == (dlci - 1))) {
    345         port.dlci++;
    346         return &port;
    347       }
    348     }
    349   }
    350   return nullptr;
    351 }
    352 
    353 /*******************************************************************************
    354  *
    355  * Function         port_find_port
    356  *
    357  * Description      Find port with DLCI, address
    358  *
    359  * Returns          Pointer to the PORT or NULL if not found
    360  *
    361  ******************************************************************************/
    362 tPORT* port_find_port(uint8_t dlci, const RawAddress& bd_addr) {
    363   for (tPORT& port : rfc_cb.port.port) {
    364     if (port.in_use && (port.dlci == dlci) && (port.bd_addr == bd_addr)) {
    365       return &port;
    366     }
    367   }
    368   return nullptr;
    369 }
    370 
    371 /*******************************************************************************
    372  *
    373  * Function         port_flow_control_user
    374  *
    375  * Description      Check the current user flow control and if necessary return
    376  *                  events to be send to the user based on the user's specified
    377  *                  flow control type.
    378  *
    379  * Returns          event mask to be returned to the application
    380  *
    381  ******************************************************************************/
    382 uint32_t port_flow_control_user(tPORT* p_port) {
    383   uint32_t event = 0;
    384 
    385   /* Flow control to the user can be caused by flow controlling by the peer */
    386   /* (FlowInd, or flow control by the peer RFCOMM (Fcon) or internally if */
    387   /* tx_queue is full */
    388   bool fc = p_port->tx.peer_fc || !p_port->rfc.p_mcb ||
    389             !p_port->rfc.p_mcb->peer_ready ||
    390             (p_port->tx.queue_size > PORT_TX_HIGH_WM) ||
    391             (fixed_queue_length(p_port->tx.queue) > PORT_TX_BUF_HIGH_WM);
    392 
    393   if (p_port->tx.user_fc == fc) return (0);
    394 
    395   p_port->tx.user_fc = fc;
    396 
    397   if (fc)
    398     event = PORT_EV_FC;
    399   else
    400     event = PORT_EV_FC | PORT_EV_FCS;
    401 
    402   return (event);
    403 }
    404 
    405 /*******************************************************************************
    406  *
    407  * Function         port_get_signal_changes
    408  *
    409  * Description      Check modem signals that has been changed
    410  *
    411  * Returns          event mask to be returned to the application
    412  *
    413  ******************************************************************************/
    414 uint32_t port_get_signal_changes(tPORT* p_port, uint8_t old_signals,
    415                                  uint8_t signal) {
    416   uint8_t changed_signals = (signal ^ old_signals);
    417   uint32_t events = 0;
    418 
    419   if (changed_signals & PORT_DTRDSR_ON) {
    420     events |= PORT_EV_DSR;
    421 
    422     if (signal & PORT_DTRDSR_ON) events |= PORT_EV_DSRS;
    423   }
    424 
    425   if (changed_signals & PORT_CTSRTS_ON) {
    426     events |= PORT_EV_CTS;
    427 
    428     if (signal & PORT_CTSRTS_ON) events |= PORT_EV_CTSS;
    429   }
    430 
    431   if (changed_signals & PORT_RING_ON) events |= PORT_EV_RING;
    432 
    433   if (changed_signals & PORT_DCD_ON) {
    434     events |= PORT_EV_RLSD;
    435 
    436     if (signal & PORT_DCD_ON) events |= PORT_EV_RLSDS;
    437   }
    438 
    439   return (p_port->ev_mask & events);
    440 }
    441 
    442 /*******************************************************************************
    443  *
    444  * Function         port_flow_control_peer
    445  *
    446  * Description      Send flow control messages to the peer for both enabling
    447  *                  and disabling flow control, for both credit-based and
    448  *                  TS 07.10 flow control mechanisms.
    449  *
    450  * Returns          nothing
    451  *
    452  ******************************************************************************/
    453 void port_flow_control_peer(tPORT* p_port, bool enable, uint16_t count) {
    454   if (!p_port->rfc.p_mcb) return;
    455 
    456   /* If using credit based flow control */
    457   if (p_port->rfc.p_mcb->flow == PORT_FC_CREDIT) {
    458     /* if want to enable flow from peer */
    459     if (enable) {
    460       /* update rx credits */
    461       if (count > p_port->credit_rx) {
    462         p_port->credit_rx = 0;
    463       } else {
    464         p_port->credit_rx -= count;
    465       }
    466 
    467       /* If credit count is less than low credit watermark, and user */
    468       /* did not force flow control, send a credit update */
    469       /* There might be a special case when we just adjusted rx_max */
    470       if ((p_port->credit_rx <= p_port->credit_rx_low) && !p_port->rx.user_fc &&
    471           (p_port->credit_rx_max > p_port->credit_rx)) {
    472         rfc_send_credit(p_port->rfc.p_mcb, p_port->dlci,
    473                         (uint8_t)(p_port->credit_rx_max - p_port->credit_rx));
    474 
    475         p_port->credit_rx = p_port->credit_rx_max;
    476 
    477         p_port->rx.peer_fc = false;
    478       }
    479     }
    480     /* else want to disable flow from peer */
    481     else {
    482       /* if client registered data callback, just do what they want */
    483       if (p_port->p_data_callback || p_port->p_data_co_callback) {
    484         p_port->rx.peer_fc = true;
    485       }
    486       /* if queue count reached credit rx max, set peer fc */
    487       else if (fixed_queue_length(p_port->rx.queue) >= p_port->credit_rx_max) {
    488         p_port->rx.peer_fc = true;
    489       }
    490     }
    491   }
    492   /* else using TS 07.10 flow control */
    493   else {
    494     /* if want to enable flow from peer */
    495     if (enable) {
    496       /* If rfcomm suspended traffic from the peer based on the rx_queue_size */
    497       /* check if it can be resumed now */
    498       if (p_port->rx.peer_fc && (p_port->rx.queue_size < PORT_RX_LOW_WM) &&
    499           (fixed_queue_length(p_port->rx.queue) < PORT_RX_BUF_LOW_WM)) {
    500         p_port->rx.peer_fc = false;
    501 
    502         /* If user did not force flow control allow traffic now */
    503         if (!p_port->rx.user_fc)
    504           RFCOMM_FlowReq(p_port->rfc.p_mcb, p_port->dlci, true);
    505       }
    506     }
    507     /* else want to disable flow from peer */
    508     else {
    509       /* if client registered data callback, just do what they want */
    510       if (p_port->p_data_callback || p_port->p_data_co_callback) {
    511         p_port->rx.peer_fc = true;
    512         RFCOMM_FlowReq(p_port->rfc.p_mcb, p_port->dlci, false);
    513       }
    514       /* Check the size of the rx queue.  If it exceeds certain */
    515       /* level and flow control has not been sent to the peer do it now */
    516       else if (((p_port->rx.queue_size > PORT_RX_HIGH_WM) ||
    517                 (fixed_queue_length(p_port->rx.queue) > PORT_RX_BUF_HIGH_WM)) &&
    518                !p_port->rx.peer_fc) {
    519         RFCOMM_TRACE_EVENT("PORT_DataInd Data reached HW. Sending FC set.");
    520 
    521         p_port->rx.peer_fc = true;
    522         RFCOMM_FlowReq(p_port->rfc.p_mcb, p_port->dlci, false);
    523       }
    524     }
    525   }
    526 }
    527