OSDN Git Service

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