• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /******************************************************************************
2  *
3  *  Copyright (C) 2000-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 functions that handle ACL connections. This includes
22  *  operations such as hold and sniff modes, supported packet types.
23  *
24  ******************************************************************************/
25 
26 #include <stdlib.h>
27 #include <string.h>
28 #include <stdio.h>
29 #include <stddef.h>
30 
31 #include "bt_types.h"
32 #include "bt_target.h"
33 #include "gki.h"
34 #include "hcimsgs.h"
35 #include "btu.h"
36 #include "btm_api.h"
37 #include "btm_int.h"
38 #include "l2c_int.h"
39 #include "hcidefs.h"
40 
41 static void btm_establish_continue (tACL_CONN *p_acl_cb);
42 static void btm_read_remote_features (UINT16 handle);
43 static void btm_read_remote_ext_features (UINT16 handle, UINT8 page_number);
44 static void btm_process_remote_ext_features_page (tACL_CONN *p_acl_cb, tBTM_SEC_DEV_REC *p_dev_rec,
45                                                   UINT8 page_idx);
46 static void btm_process_remote_ext_features (tACL_CONN *p_acl_cb, UINT8 num_read_pages);
47 
48 #define BTM_DEV_REPLY_TIMEOUT   3       /* 3 second timeout waiting for responses */
49 
50 /*******************************************************************************
51 **
52 ** Function         btm_acl_init
53 **
54 ** Description      This function is called at BTM startup to initialize
55 **
56 ** Returns          void
57 **
58 *******************************************************************************/
btm_acl_init(void)59 void btm_acl_init (void)
60 {
61     BTM_TRACE_DEBUG0 ("btm_acl_init");
62 #if 0  /* cleared in btm_init; put back in if called from anywhere else! */
63     memset (&btm_cb.acl_db, 0, sizeof (btm_cb.acl_db));
64 #if RFCOMM_INCLUDED == TRUE
65     memset (btm_cb.btm_scn, 0, BTM_MAX_SCN);          /* Initialize the SCN usage to FALSE */
66 #endif
67     btm_cb.btm_def_link_policy     = 0;
68 #if (defined(BTM_BUSY_LEVEL_CHANGE_INCLUDED) && BTM_BUSY_LEVEL_CHANGE_INCLUDED == TRUE)
69     btm_cb.p_bl_changed_cb         = NULL;
70 #else
71     btm_cb.p_acl_changed_cb        = NULL;
72 #endif
73 #endif
74 
75     /* Initialize nonzero defaults */
76     btm_cb.btm_def_link_super_tout = HCI_DEFAULT_INACT_TOUT;
77     btm_cb.acl_disc_reason         = 0xff ;
78 }
79 
80 /*******************************************************************************
81 **
82 ** Function         btm_bda_to_acl
83 **
84 ** Description      This function returns the FIRST acl_db entry for the passed BDA.
85 **
86 ** Returns          Returns pointer to the ACL DB for the requested BDA if found.
87 **                  NULL if not found.
88 **
89 *******************************************************************************/
btm_bda_to_acl(BD_ADDR bda)90 tACL_CONN *btm_bda_to_acl (BD_ADDR bda)
91 {
92     tACL_CONN   *p = &btm_cb.acl_db[0];
93     UINT16       xx;
94     if (bda)
95     {
96         for (xx = 0; xx < MAX_L2CAP_LINKS; xx++, p++)
97         {
98             if ((p->in_use) && (!memcmp (p->remote_addr, bda, BD_ADDR_LEN)))
99             {
100                 BTM_TRACE_DEBUG0 ("btm_bda_to_acl found");
101                 return(p);
102             }
103         }
104     }
105 
106     /* If here, no BD Addr found */
107     return((tACL_CONN *)NULL);
108 }
109 
110 /*******************************************************************************
111 **
112 ** Function         btm_handle_to_acl_index
113 **
114 ** Description      This function returns the FIRST acl_db entry for the passed hci_handle.
115 **
116 ** Returns          index to the acl_db or MAX_L2CAP_LINKS.
117 **
118 *******************************************************************************/
btm_handle_to_acl_index(UINT16 hci_handle)119 UINT8 btm_handle_to_acl_index (UINT16 hci_handle)
120 {
121     tACL_CONN   *p = &btm_cb.acl_db[0];
122     UINT8       xx;
123     BTM_TRACE_DEBUG0 ("btm_handle_to_acl_index");
124     for (xx = 0; xx < MAX_L2CAP_LINKS; xx++, p++)
125     {
126         if ((p->in_use) && (p->hci_handle == hci_handle))
127         {
128             break;
129         }
130     }
131 
132     /* If here, no BD Addr found */
133     return(xx);
134 }
135 /*******************************************************************************
136 **
137 ** Function         btm_acl_created
138 **
139 ** Description      This function is called by L2CAP when an ACL connection
140 **                  is created.
141 **
142 ** Returns          void
143 **
144 *******************************************************************************/
btm_acl_created(BD_ADDR bda,DEV_CLASS dc,BD_NAME bdn,UINT16 hci_handle,UINT8 link_role,UINT8 is_le_link)145 void btm_acl_created (BD_ADDR bda, DEV_CLASS dc, BD_NAME bdn,
146                       UINT16 hci_handle, UINT8 link_role, UINT8 is_le_link)
147 {
148     tBTM_SEC_DEV_REC *p_dev_rec = NULL;
149     UINT8             yy;
150     tACL_CONN        *p;
151     UINT8             xx;
152 
153     BTM_TRACE_DEBUG3 ("btm_acl_created hci_handle=%d link_role=%d  is_le_link=%d",
154                       hci_handle,link_role, is_le_link);
155     /* Ensure we don't have duplicates */
156     p = btm_bda_to_acl(bda);
157     if (p != (tACL_CONN *)NULL)
158     {
159         p->hci_handle = hci_handle;
160         p->link_role  = link_role;
161 #if BLE_INCLUDED == TRUE
162         p->is_le_link = is_le_link;
163 #endif
164         BTM_TRACE_DEBUG6 ("Duplicate btm_acl_created: RemBdAddr: %02x%02x%02x%02x%02x%02x",
165                           bda[0], bda[1], bda[2], bda[3], bda[4], bda[5]);
166         BTM_SetLinkPolicy(p->remote_addr, &btm_cb.btm_def_link_policy);
167         return;
168     }
169 
170     /* Allocate acl_db entry */
171     for (xx = 0, p = &btm_cb.acl_db[0]; xx < MAX_L2CAP_LINKS; xx++, p++)
172     {
173         if (!p->in_use)
174         {
175             p->in_use            = TRUE;
176             p->hci_handle        = hci_handle;
177             p->link_role         = link_role;
178             p->link_up_issued    = FALSE;
179 
180 #if BLE_INCLUDED == TRUE
181             p->is_le_link        = is_le_link;
182 
183             if (is_le_link)
184             {
185                 p->conn_addr_type = BLE_ADDR_PUBLIC;
186                 BTM_GetLocalDeviceAddr(p->conn_addr);
187             }
188 
189 #endif
190             p->restore_pkt_types = 0;   /* Only exists while SCO is active */
191             p->switch_role_state = BTM_ACL_SWKEY_STATE_IDLE;
192 
193 #if BTM_PWR_MGR_INCLUDED == FALSE
194             p->mode             = BTM_ACL_MODE_NORMAL;
195 #else
196             btm_pm_sm_alloc(xx);
197 #endif /* BTM_PWR_MGR_INCLUDED == FALSE */
198 
199             memcpy (p->remote_addr, bda, BD_ADDR_LEN);
200 
201             if (dc)
202                 memcpy (p->remote_dc, dc, DEV_CLASS_LEN);
203 
204             if (bdn)
205                 memcpy (p->remote_name, bdn, BTM_MAX_REM_BD_NAME_LEN);
206 
207             /* if BR/EDR do something more */
208             if (!is_le_link)
209             {
210                 btsnd_hcic_read_rmt_clk_offset (p->hci_handle);
211                 btsnd_hcic_rmt_ver_req (p->hci_handle);
212             }
213             p_dev_rec = btm_find_dev_by_handle (hci_handle);
214 
215 #if (BLE_INCLUDED == TRUE)
216             if (p_dev_rec )
217             {
218                 BTM_TRACE_DEBUG1 ("device_type=0x%x", p_dev_rec->device_type);
219             }
220 #endif
221 
222             if (p_dev_rec && !is_le_link)
223             {
224                 /* If remote features already known, copy them and continue connection setup */
225                 if ((p_dev_rec->num_read_pages) &&
226                     (p_dev_rec->num_read_pages <= (HCI_EXT_FEATURES_PAGE_MAX + 1)) /* sanity check */)
227                 {
228                     memcpy (p->peer_lmp_features, p_dev_rec->features,
229                         (HCI_FEATURE_BYTES_PER_PAGE * p_dev_rec->num_read_pages));
230                     p->num_read_pages = p_dev_rec->num_read_pages;
231 
232                     if (BTM_SEC_MODE_SP == btm_cb.security_mode
233                         && HCI_SSP_HOST_SUPPORTED(p_dev_rec->features[HCI_EXT_FEATURES_PAGE_1])
234                         && HCI_SIMPLE_PAIRING_SUPPORTED(p_dev_rec->features[HCI_EXT_FEATURES_PAGE_0]))
235                     {
236                         p_dev_rec->sm4 = BTM_SM4_TRUE;
237                     }
238                     else
239                     {
240                         p_dev_rec->sm4 |= BTM_SM4_KNOWN;
241                     }
242 
243                     btm_establish_continue (p);
244                     return;
245                 }
246             }
247 
248 #if (BLE_INCLUDED == TRUE)
249             /* If here, features are not known yet */
250             if (p_dev_rec && is_le_link)
251             {
252                 btm_establish_continue(p);
253 
254                 if (link_role == HCI_ROLE_MASTER)
255                 {
256                     btsnd_hcic_ble_read_remote_feat(p->hci_handle);
257                 }
258             }
259             else
260 #endif
261             {
262                 btm_read_remote_features (p->hci_handle);
263             }
264 
265             /* read page 1 - on rmt feature event for buffer reasons */
266             return;
267         }
268     }
269 }
270 
271 
272 /*******************************************************************************
273 **
274 ** Function         btm_acl_report_role_change
275 **
276 ** Description      This function is called when the local device is deemed
277 **                  to be down. It notifies L2CAP of the failure.
278 **
279 ** Returns          void
280 **
281 *******************************************************************************/
btm_acl_report_role_change(UINT8 hci_status,BD_ADDR bda)282 void btm_acl_report_role_change (UINT8 hci_status, BD_ADDR bda)
283 {
284     tBTM_ROLE_SWITCH_CMPL   ref_data;
285     BTM_TRACE_DEBUG0 ("btm_acl_report_role_change");
286     if (btm_cb.devcb.p_switch_role_cb
287         && (bda && (0 == memcmp(btm_cb.devcb.switch_role_ref_data.remote_bd_addr, bda, BD_ADDR_LEN))))
288     {
289         memcpy (&ref_data, &btm_cb.devcb.switch_role_ref_data, sizeof(tBTM_ROLE_SWITCH_CMPL));
290         ref_data.hci_status = hci_status;
291         (*btm_cb.devcb.p_switch_role_cb)(&ref_data);
292         memset (&btm_cb.devcb.switch_role_ref_data, 0, sizeof(tBTM_ROLE_SWITCH_CMPL));
293         btm_cb.devcb.p_switch_role_cb = NULL;
294     }
295 }
296 
297 /*******************************************************************************
298 **
299 ** Function         btm_acl_removed
300 **
301 ** Description      This function is called by L2CAP when an ACL connection
302 **                  is removed. Since only L2CAP creates ACL links, we use
303 **                  the L2CAP link index as our index into the control blocks.
304 **
305 ** Returns          void
306 **
307 *******************************************************************************/
btm_acl_removed(BD_ADDR bda)308 void btm_acl_removed (BD_ADDR bda)
309 {
310     tACL_CONN   *p;
311 #if (defined(BTM_BUSY_LEVEL_CHANGE_INCLUDED) && BTM_BUSY_LEVEL_CHANGE_INCLUDED == TRUE)
312     tBTM_BL_EVENT_DATA  evt_data;
313 #endif
314 #if (defined BLE_INCLUDED && BLE_INCLUDED == TRUE)
315     tBTM_SEC_DEV_REC *p_dev_rec=NULL;
316 #endif
317 
318     BTM_TRACE_DEBUG0 ("btm_acl_removed");
319     p = btm_bda_to_acl(bda);
320     if (p != (tACL_CONN *)NULL)
321     {
322         p->in_use = FALSE;
323 
324         /* if the disconnected channel has a pending role switch, clear it now */
325         btm_acl_report_role_change(HCI_ERR_NO_CONNECTION, bda);
326 
327         /* Only notify if link up has had a chance to be issued */
328         if (p->link_up_issued)
329         {
330             p->link_up_issued = FALSE;
331 
332             /* If anyone cares, tell him database changed */
333 #if (defined(BTM_BUSY_LEVEL_CHANGE_INCLUDED) && BTM_BUSY_LEVEL_CHANGE_INCLUDED == TRUE)
334             if (btm_cb.p_bl_changed_cb)
335             {
336                 evt_data.event = BTM_BL_DISCN_EVT;
337                 evt_data.discn.p_bda = bda;
338 
339                 (*btm_cb.p_bl_changed_cb)(&evt_data);
340             }
341 
342             btm_acl_update_busy_level (BTM_BLI_ACL_DOWN_EVT);
343 #else
344             if (btm_cb.p_acl_changed_cb)
345                 (*btm_cb.p_acl_changed_cb) (bda, NULL, NULL, NULL, FALSE);
346 #endif
347         }
348 
349 #if (defined BLE_INCLUDED && BLE_INCLUDED == TRUE)
350 
351         BTM_TRACE_DEBUG4 ("acl hci_handle=%d is_le_link=%d connectable_mode=0x%0x link_role=%d",
352                           p->hci_handle,
353                           p->is_le_link,
354                           btm_cb.ble_ctr_cb.inq_var.connectable_mode,
355                           p->link_role);
356 
357         p_dev_rec = btm_find_dev(bda);
358         if ( p_dev_rec)
359         {
360             BTM_TRACE_DEBUG1("before update p_dev_rec->sec_flags=0x%x", p_dev_rec->sec_flags);
361             if (p->is_le_link)
362             {
363                 BTM_TRACE_DEBUG0("LE link down");
364                 p_dev_rec->sec_flags &= ~(BTM_SEC_ENCRYPTED | BTM_SEC_ROLE_SWITCHED);
365                 if ( (p_dev_rec->sec_flags & BTM_SEC_LINK_KEY_KNOWN) == 0)
366                 {
367                     BTM_TRACE_DEBUG0("Not Bonded");
368                     p_dev_rec->sec_flags &= ~(BTM_SEC_AUTHENTICATED | BTM_SEC_LINK_KEY_AUTHED);
369                 }
370                 else
371                 {
372                     BTM_TRACE_DEBUG0("Bonded");
373                 }
374             }
375             else
376             {
377                 BTM_TRACE_DEBUG0("Bletooth link down");
378                 p_dev_rec->sec_flags &= ~(BTM_SEC_AUTHORIZED | BTM_SEC_AUTHENTICATED
379                                         | BTM_SEC_ENCRYPTED | BTM_SEC_ROLE_SWITCHED);
380             }
381             BTM_TRACE_DEBUG1("after update p_dev_rec->sec_flags=0x%x", p_dev_rec->sec_flags);
382         }
383         else
384         {
385             BTM_TRACE_ERROR0("Device not found");
386 
387         }
388 #endif
389 
390         return;
391     }
392 }
393 
394 
395 /*******************************************************************************
396 **
397 ** Function         btm_acl_device_down
398 **
399 ** Description      This function is called when the local device is deemed
400 **                  to be down. It notifies L2CAP of the failure.
401 **
402 ** Returns          void
403 **
404 *******************************************************************************/
btm_acl_device_down(void)405 void btm_acl_device_down (void)
406 {
407     tACL_CONN   *p = &btm_cb.acl_db[0];
408     UINT16      xx;
409     BTM_TRACE_DEBUG0 ("btm_acl_device_down");
410     for (xx = 0; xx < MAX_L2CAP_LINKS; xx++, p++)
411     {
412         if (p->in_use)
413         {
414             BTM_TRACE_DEBUG1 ("hci_handle=%d HCI_ERR_HW_FAILURE ",p->hci_handle );
415             l2c_link_hci_disc_comp (p->hci_handle, HCI_ERR_HW_FAILURE);
416         }
417     }
418 }
419 
420 #if (defined(BTM_BUSY_LEVEL_CHANGE_INCLUDED) && BTM_BUSY_LEVEL_CHANGE_INCLUDED == TRUE)
421 /*******************************************************************************
422 **
423 ** Function         btm_acl_update_busy_level
424 **
425 ** Description      This function is called to update the busy level of the system
426 **                  .
427 **
428 ** Returns          void
429 **
430 *******************************************************************************/
btm_acl_update_busy_level(tBTM_BLI_EVENT event)431 void btm_acl_update_busy_level (tBTM_BLI_EVENT event)
432 {
433     tBTM_BL_UPDATE_DATA  evt;
434     UINT8 busy_level;
435     BTM_TRACE_DEBUG0 ("btm_acl_update_busy_level");
436     switch (event)
437     {
438         case BTM_BLI_ACL_UP_EVT:
439             BTM_TRACE_DEBUG0 ("BTM_BLI_ACL_UP_EVT");
440             btm_cb.num_acl++;
441             break;
442         case BTM_BLI_ACL_DOWN_EVT:
443             if (btm_cb.num_acl)
444             {
445                 btm_cb.num_acl--;
446                 BTM_TRACE_DEBUG1 ("BTM_BLI_ACL_DOWN_EVT", btm_cb.num_acl);
447             }
448             else
449             {
450                 BTM_TRACE_ERROR0 ("BTM_BLI_ACL_DOWN_EVT issued, but num_acl already zero !!!");
451             }
452             break;
453         case BTM_BLI_PAGE_EVT:
454             BTM_TRACE_DEBUG0 ("BTM_BLI_PAGE_EVT");
455             btm_cb.is_paging = TRUE;
456             evt.busy_level_flags= BTM_BL_PAGING_STARTED;
457             break;
458         case BTM_BLI_PAGE_DONE_EVT:
459             BTM_TRACE_DEBUG0 ("BTM_BLI_PAGE_DONE_EVT");
460             btm_cb.is_paging = FALSE;
461             evt.busy_level_flags = BTM_BL_PAGING_COMPLETE;
462             break;
463         case BTM_BLI_INQ_EVT:
464             BTM_TRACE_DEBUG0 ("BTM_BLI_INQ_EVT");
465             btm_cb.is_inquiry = TRUE;
466             evt.busy_level_flags = BTM_BL_INQUIRY_STARTED;
467             break;
468         case BTM_BLI_INQ_CANCEL_EVT:
469             BTM_TRACE_DEBUG0 ("BTM_BLI_INQ_CANCEL_EVT");
470             btm_cb.is_inquiry = FALSE;
471             evt.busy_level_flags = BTM_BL_INQUIRY_CANCELLED;
472             break;
473         case BTM_BLI_INQ_DONE_EVT:
474             BTM_TRACE_DEBUG0 ("BTM_BLI_INQ_DONE_EVT");
475             btm_cb.is_inquiry = FALSE;
476             evt.busy_level_flags = BTM_BL_INQUIRY_COMPLETE;
477             break;
478     }
479 
480     if (btm_cb.is_paging || btm_cb.is_inquiry)
481         busy_level = 10;
482     else
483         busy_level = (UINT8)btm_cb.num_acl;
484 
485     if (busy_level != btm_cb.busy_level)
486     {
487         evt.event         = BTM_BL_UPDATE_EVT;
488         evt.busy_level    = busy_level;
489         btm_cb.busy_level = busy_level;
490         if (btm_cb.p_bl_changed_cb && (btm_cb.bl_evt_mask & BTM_BL_UPDATE_MASK))
491         {
492             (*btm_cb.p_bl_changed_cb)((tBTM_BL_EVENT_DATA *)&evt);
493         }
494     }
495 }
496 #endif
497 
498 
499 /*******************************************************************************
500 **
501 ** Function         BTM_GetRole
502 **
503 ** Description      This function is called to get the role of the local device
504 **                  for the ACL connection with the specified remote device
505 **
506 ** Returns          BTM_SUCCESS if connection exists.
507 **                  BTM_UNKNOWN_ADDR if no active link with bd addr specified
508 **
509 *******************************************************************************/
BTM_GetRole(BD_ADDR remote_bd_addr,UINT8 * p_role)510 tBTM_STATUS BTM_GetRole (BD_ADDR remote_bd_addr, UINT8 *p_role)
511 {
512     tACL_CONN   *p;
513     BTM_TRACE_DEBUG0 ("BTM_GetRole");
514     if ((p = btm_bda_to_acl(remote_bd_addr)) == NULL)
515     {
516         *p_role = BTM_ROLE_UNDEFINED;
517         return(BTM_UNKNOWN_ADDR);
518     }
519 
520     /* Get the current role */
521     *p_role = p->link_role;
522     return(BTM_SUCCESS);
523 }
524 
525 
526 /*******************************************************************************
527 **
528 ** Function         BTM_SwitchRole
529 **
530 ** Description      This function is called to switch role between master and
531 **                  slave.  If role is already set it will do nothing.  If the
532 **                  command was initiated, the callback function is called upon
533 **                  completion.
534 **
535 ** Returns          BTM_SUCCESS if already in specified role.
536 **                  BTM_CMD_STARTED if command issued to controller.
537 **                  BTM_NO_RESOURCES if couldn't allocate memory to issue command
538 **                  BTM_UNKNOWN_ADDR if no active link with bd addr specified
539 **                  BTM_MODE_UNSUPPORTED if local device does not support role switching
540 **                  BTM_BUSY if the previous command is not completed
541 **
542 *******************************************************************************/
BTM_SwitchRole(BD_ADDR remote_bd_addr,UINT8 new_role,tBTM_CMPL_CB * p_cb)543 tBTM_STATUS BTM_SwitchRole (BD_ADDR remote_bd_addr, UINT8 new_role, tBTM_CMPL_CB *p_cb)
544 {
545     tACL_CONN   *p;
546     tBTM_SEC_DEV_REC  *p_dev_rec = NULL;
547 #if BTM_SCO_INCLUDED == TRUE
548     BOOLEAN    is_sco_active;
549 #endif
550 #if BTM_PWR_MGR_INCLUDED == TRUE
551     tBTM_STATUS  status;
552     tBTM_PM_MODE pwr_mode;
553     tBTM_PM_PWR_MD settings;
554 #endif
555 #if (BT_USE_TRACES == TRUE)
556     BD_ADDR_PTR  p_bda;
557 #endif
558     BTM_TRACE_API6 ("BTM_SwitchRole BDA: %02x-%02x-%02x-%02x-%02x-%02x",
559                     remote_bd_addr[0], remote_bd_addr[1], remote_bd_addr[2],
560                     remote_bd_addr[3], remote_bd_addr[4], remote_bd_addr[5]);
561 
562     /* Make sure the local device supports switching */
563     if (!(HCI_SWITCH_SUPPORTED(btm_cb.devcb.local_lmp_features[HCI_EXT_FEATURES_PAGE_0])))
564         return(BTM_MODE_UNSUPPORTED);
565 
566     if (btm_cb.devcb.p_switch_role_cb && p_cb)
567     {
568 #if (BT_USE_TRACES == TRUE)
569         p_bda = btm_cb.devcb.switch_role_ref_data.remote_bd_addr;
570         BTM_TRACE_DEBUG6 ("Role switch on other device is in progress 0x%02x%02x%02x%02x%02x%02x",
571                           p_bda[0], p_bda[1], p_bda[2],
572                           p_bda[3], p_bda[4], p_bda[5]);
573 #endif
574         return(BTM_BUSY);
575     }
576 
577     if ((p = btm_bda_to_acl(remote_bd_addr)) == NULL)
578         return(BTM_UNKNOWN_ADDR);
579 
580     /* Finished if already in desired role */
581     if (p->link_role == new_role)
582         return(BTM_SUCCESS);
583 
584 #if BTM_SCO_INCLUDED == TRUE
585     /* Check if there is any SCO Active on this BD Address */
586     is_sco_active = btm_is_sco_active_by_bdaddr(remote_bd_addr);
587 
588     if (is_sco_active == TRUE)
589         return(BTM_NO_RESOURCES);
590 #endif
591 
592     /* Ignore role switch request if the previous request was not completed */
593     if (p->switch_role_state != BTM_ACL_SWKEY_STATE_IDLE)
594     {
595         BTM_TRACE_DEBUG1 ("BTM_SwitchRole busy: %d",
596                           p->switch_role_state);
597         return(BTM_BUSY);
598     }
599 
600     /* Cannot switch role while parked or sniffing */
601 #if BTM_PWR_MGR_INCLUDED == FALSE
602     if (p->mode == HCI_MODE_PARK)
603     {
604         if (!btsnd_hcic_exit_park_mode (p->hci_handle))
605             return(BTM_NO_RESOURCES);
606 
607         p->switch_role_state = BTM_ACL_SWKEY_STATE_MODE_CHANGE;
608     }
609     else if (p->mode == HCI_MODE_SNIFF)
610     {
611         if (!btsnd_hcic_exit_sniff_mode (p->hci_handle))
612             return(BTM_NO_RESOURCES);
613 
614         p->switch_role_state = BTM_ACL_SWKEY_STATE_MODE_CHANGE;
615     }
616 #else   /* power manager is in use */
617 
618     if ((status = BTM_ReadPowerMode(p->remote_addr, &pwr_mode)) != BTM_SUCCESS)
619         return(status);
620 
621     /* Wake up the link if in sniff or park before attempting switch */
622     if (pwr_mode == BTM_PM_MD_PARK || pwr_mode == BTM_PM_MD_SNIFF)
623     {
624         memset( (void*)&settings, 0, sizeof(settings));
625         settings.mode = BTM_PM_MD_ACTIVE;
626         status = BTM_SetPowerMode (BTM_PM_SET_ONLY_ID, p->remote_addr, &settings);
627         if (status != BTM_CMD_STARTED)
628             return(BTM_WRONG_MODE);
629 
630         p->switch_role_state = BTM_ACL_SWKEY_STATE_MODE_CHANGE;
631     }
632 #endif
633     /* some devices do not support switch while encryption is on */
634     else
635     {
636         p_dev_rec = btm_find_dev (remote_bd_addr);
637         if ((p_dev_rec != NULL)
638             && ((p_dev_rec->sec_flags & BTM_SEC_ENCRYPTED) != 0)
639             && !BTM_EPR_AVAILABLE(p))
640         {
641             /* bypass turning off encryption if change link key is already doing it */
642             if (p->encrypt_state != BTM_ACL_ENCRYPT_STATE_ENCRYPT_OFF)
643             {
644                 if (!btsnd_hcic_set_conn_encrypt (p->hci_handle, FALSE))
645                     return(BTM_NO_RESOURCES);
646                 else
647                     p->encrypt_state = BTM_ACL_ENCRYPT_STATE_ENCRYPT_OFF;
648             }
649 
650             p->switch_role_state = BTM_ACL_SWKEY_STATE_ENCRYPTION_OFF;
651         }
652         else
653         {
654             if (!btsnd_hcic_switch_role (remote_bd_addr, new_role))
655                 return(BTM_NO_RESOURCES);
656 
657             p->switch_role_state = BTM_ACL_SWKEY_STATE_IN_PROGRESS;
658 
659 #if BTM_DISC_DURING_RS == TRUE
660             if (p_dev_rec)
661                 p_dev_rec->rs_disc_pending = BTM_SEC_RS_PENDING;
662 #endif
663         }
664     }
665 
666     /* Initialize return structure in case request fails */
667     if (p_cb)
668     {
669         memcpy (btm_cb.devcb.switch_role_ref_data.remote_bd_addr, remote_bd_addr,
670                 BD_ADDR_LEN);
671         btm_cb.devcb.switch_role_ref_data.role = new_role;
672         /* initialized to an error code */
673         btm_cb.devcb.switch_role_ref_data.hci_status = HCI_ERR_UNSUPPORTED_VALUE;
674         btm_cb.devcb.p_switch_role_cb = p_cb;
675     }
676     return(BTM_CMD_STARTED);
677 }
678 
679 /*******************************************************************************
680 **
681 ** Function         BTM_ChangeLinkKey
682 **
683 ** Description      This function is called to change the link key of the
684 **                  connection.
685 **
686 ** Returns          BTM_CMD_STARTED if command issued to controller.
687 **                  BTM_NO_RESOURCES if couldn't allocate memory to issue command
688 **                  BTM_UNKNOWN_ADDR if no active link with bd addr specified
689 **                  BTM_BUSY if the previous command is not completed
690 **
691 *******************************************************************************/
BTM_ChangeLinkKey(BD_ADDR remote_bd_addr,tBTM_CMPL_CB * p_cb)692 tBTM_STATUS BTM_ChangeLinkKey (BD_ADDR remote_bd_addr, tBTM_CMPL_CB *p_cb)
693 {
694     tACL_CONN   *p;
695     tBTM_SEC_DEV_REC  *p_dev_rec = NULL;
696 #if BTM_PWR_MGR_INCLUDED == TRUE
697     tBTM_STATUS  status;
698     tBTM_PM_MODE pwr_mode;
699     tBTM_PM_PWR_MD settings;
700 #endif
701     BTM_TRACE_DEBUG0 ("BTM_ChangeLinkKey");
702     if ((p = btm_bda_to_acl(remote_bd_addr)) == NULL)
703         return(BTM_UNKNOWN_ADDR);
704 
705     /* Ignore change link key request if the previsous request has not completed */
706     if (p->change_key_state != BTM_ACL_SWKEY_STATE_IDLE)
707     {
708         BTM_TRACE_DEBUG0 ("Link key change request declined since the previous request"
709                           " for this device has not completed ");
710         return(BTM_BUSY);
711     }
712 
713     memset (&btm_cb.devcb.chg_link_key_ref_data, 0, sizeof(tBTM_CHANGE_KEY_CMPL));
714 
715     /* Cannot change key while parked */
716 #if BTM_PWR_MGR_INCLUDED == FALSE
717     if (p->mode == HCI_MODE_PARK)
718     {
719         if (!btsnd_hcic_exit_park_mode (p->hci_handle))
720             return(BTM_NO_RESOURCES);
721 
722         p->change_key_state = BTM_ACL_SWKEY_STATE_MODE_CHANGE;
723     }
724 #else   /* power manager is in use */
725 
726 
727     if ((status = BTM_ReadPowerMode(p->remote_addr, &pwr_mode)) != BTM_SUCCESS)
728         return(status);
729 
730     /* Wake up the link if in park before attempting to change link keys */
731     if (pwr_mode == BTM_PM_MD_PARK)
732     {
733         memset( (void*)&settings, 0, sizeof(settings));
734         settings.mode = BTM_PM_MD_ACTIVE;
735         status = BTM_SetPowerMode (BTM_PM_SET_ONLY_ID, p->remote_addr, &settings);
736         if (status != BTM_CMD_STARTED)
737             return(BTM_WRONG_MODE);
738 
739         p->change_key_state = BTM_ACL_SWKEY_STATE_MODE_CHANGE;
740     }
741 #endif
742     /* some devices do not support change of link key while encryption is on */
743     else if (((p_dev_rec = btm_find_dev (remote_bd_addr)) != NULL)
744              && ((p_dev_rec->sec_flags & BTM_SEC_ENCRYPTED) != 0) && !BTM_EPR_AVAILABLE(p))
745     {
746         /* bypass turning off encryption if switch role is already doing it */
747         if (p->encrypt_state != BTM_ACL_ENCRYPT_STATE_ENCRYPT_OFF)
748         {
749             if (!btsnd_hcic_set_conn_encrypt (p->hci_handle, FALSE))
750                 return(BTM_NO_RESOURCES);
751             else
752                 p->encrypt_state = BTM_ACL_ENCRYPT_STATE_ENCRYPT_OFF;
753         }
754 
755         p->change_key_state = BTM_ACL_SWKEY_STATE_ENCRYPTION_OFF;
756     }
757     else    /* Ok to initiate change of link key */
758     {
759         if (!btsnd_hcic_change_link_key (p->hci_handle))
760             return(BTM_NO_RESOURCES);
761 
762         p->change_key_state = BTM_ACL_SWKEY_STATE_IN_PROGRESS;
763     }
764 
765     /* Initialize return structure in case request fails */
766     memcpy (btm_cb.devcb.chg_link_key_ref_data.remote_bd_addr, remote_bd_addr,
767             BD_ADDR_LEN);
768     btm_cb.devcb.p_chg_link_key_cb = p_cb;
769     return(BTM_CMD_STARTED);
770 }
771 
772 /*******************************************************************************
773 **
774 ** Function         btm_acl_link_key_change
775 **
776 ** Description      This function is called to when a change link key event
777 **                  is received.
778 **
779 *******************************************************************************/
btm_acl_link_key_change(UINT16 handle,UINT8 status)780 void btm_acl_link_key_change (UINT16 handle, UINT8 status)
781 {
782     tBTM_CHANGE_KEY_CMPL *p_data;
783     tACL_CONN            *p;
784     UINT8                xx;
785     BTM_TRACE_DEBUG0 ("btm_acl_link_key_change");
786     /* Look up the connection by handle and set the current mode */
787     xx = btm_handle_to_acl_index(handle);
788 
789     /* don't assume that we can never get a bad hci_handle */
790     if (xx >= MAX_L2CAP_LINKS)
791         return;
792 
793     p_data = &btm_cb.devcb.chg_link_key_ref_data;
794     p = &btm_cb.acl_db[xx];
795     p_data->hci_status = status;
796 
797     /* if switching state is switching we need to turn encryption on */
798     /* if idle, we did not change encryption */
799     if (p->change_key_state == BTM_ACL_SWKEY_STATE_SWITCHING)
800     {
801         /* Make sure there's not also a role switch going on before re-enabling */
802         if (p->switch_role_state != BTM_ACL_SWKEY_STATE_SWITCHING)
803         {
804             if (btsnd_hcic_set_conn_encrypt (p->hci_handle, TRUE))
805             {
806                 p->encrypt_state = BTM_ACL_ENCRYPT_STATE_ENCRYPT_ON;
807                 p->change_key_state = BTM_ACL_SWKEY_STATE_ENCRYPTION_ON;
808                 return;
809             }
810         }
811         else    /* Set the state and wait for change link key */
812         {
813             p->change_key_state = BTM_ACL_SWKEY_STATE_ENCRYPTION_ON;
814             return;
815         }
816     }
817 
818     /* Set the switch_role_state to IDLE since the reply received from HCI */
819     /* regardless of its result either success or failed. */
820     if (p->change_key_state == BTM_ACL_SWKEY_STATE_IN_PROGRESS)
821     {
822         p->change_key_state = BTM_ACL_SWKEY_STATE_IDLE;
823         p->encrypt_state = BTM_ACL_ENCRYPT_STATE_IDLE;
824     }
825 
826     if (btm_cb.devcb.p_chg_link_key_cb)
827     {
828         (*btm_cb.devcb.p_chg_link_key_cb)((void *)p_data);
829         btm_cb.devcb.p_chg_link_key_cb = NULL;
830     }
831 
832     BTM_TRACE_ERROR2("Change Link Key Complete Event: Handle 0x%02x, HCI Status 0x%02x",
833                      handle, p_data->hci_status);
834 }
835 
836 /*******************************************************************************
837 **
838 ** Function         btm_acl_encrypt_change
839 **
840 ** Description      This function is when encryption of the connection is
841 **                  completed by the LM.  Checks to see if a role switch or
842 **                  change of link key was active and initiates or continues
843 **                  process if needed.
844 **
845 ** Returns          void
846 **
847 *******************************************************************************/
btm_acl_encrypt_change(UINT16 handle,UINT8 status,UINT8 encr_enable)848 void btm_acl_encrypt_change (UINT16 handle, UINT8 status, UINT8 encr_enable)
849 {
850     tACL_CONN *p;
851     UINT8     xx;
852     tBTM_SEC_DEV_REC  *p_dev_rec;
853 #if (defined(BTM_BUSY_LEVEL_CHANGE_INCLUDED) && BTM_BUSY_LEVEL_CHANGE_INCLUDED == TRUE)
854     tBTM_BL_ROLE_CHG_DATA   evt;
855 #endif
856 
857     BTM_TRACE_DEBUG3 ("btm_acl_encrypt_change handle=%d status=%d encr_enabl=%d",
858                       handle, status, encr_enable);
859     xx = btm_handle_to_acl_index(handle);
860     /* don't assume that we can never get a bad hci_handle */
861     if (xx < MAX_L2CAP_LINKS)
862         p = &btm_cb.acl_db[xx];
863     else
864         return;
865 
866     /* Process Role Switch if active */
867     if (p->switch_role_state == BTM_ACL_SWKEY_STATE_ENCRYPTION_OFF)
868     {
869         /* if encryption turn off failed we still will try to switch role */
870         if (encr_enable)
871         {
872             p->switch_role_state = BTM_ACL_SWKEY_STATE_IDLE;
873             p->encrypt_state = BTM_ACL_ENCRYPT_STATE_IDLE;
874         }
875         else
876         {
877             p->switch_role_state = BTM_ACL_SWKEY_STATE_SWITCHING;
878             p->encrypt_state = BTM_ACL_ENCRYPT_STATE_TEMP_FUNC;
879         }
880 
881         if (!btsnd_hcic_switch_role (p->remote_addr, (UINT8)!p->link_role))
882         {
883             p->switch_role_state = BTM_ACL_SWKEY_STATE_IDLE;
884             p->encrypt_state = BTM_ACL_ENCRYPT_STATE_IDLE;
885             btm_acl_report_role_change(btm_cb.devcb.switch_role_ref_data.hci_status, p->remote_addr);
886         }
887 #if BTM_DISC_DURING_RS == TRUE
888         else
889         {
890             if ((p_dev_rec = btm_find_dev (p->remote_addr)) != NULL)
891                 p_dev_rec->rs_disc_pending = BTM_SEC_RS_PENDING;
892         }
893 #endif
894 
895     }
896     /* Finished enabling Encryption after role switch */
897     else if (p->switch_role_state == BTM_ACL_SWKEY_STATE_ENCRYPTION_ON)
898     {
899         p->switch_role_state = BTM_ACL_SWKEY_STATE_IDLE;
900         p->encrypt_state = BTM_ACL_ENCRYPT_STATE_IDLE;
901         btm_acl_report_role_change(btm_cb.devcb.switch_role_ref_data.hci_status, p->remote_addr);
902 
903 #if (defined(BTM_BUSY_LEVEL_CHANGE_INCLUDED) && BTM_BUSY_LEVEL_CHANGE_INCLUDED == TRUE)
904         /* if role change event is registered, report it now */
905         if (btm_cb.p_bl_changed_cb && (btm_cb.bl_evt_mask & BTM_BL_ROLE_CHG_MASK))
906         {
907             evt.event       = BTM_BL_ROLE_CHG_EVT;
908             evt.new_role    = btm_cb.devcb.switch_role_ref_data.role;
909             evt.p_bda       = btm_cb.devcb.switch_role_ref_data.remote_bd_addr;
910             evt.hci_status  = btm_cb.devcb.switch_role_ref_data.hci_status;
911             (*btm_cb.p_bl_changed_cb)((tBTM_BL_EVENT_DATA *)&evt);
912 
913             BTM_TRACE_DEBUG3("Role Switch Event: new_role 0x%02x, HCI Status 0x%02x, rs_st:%d",
914                              evt.new_role, evt.hci_status, p->switch_role_state);
915         }
916 #endif
917 
918 #if BTM_DISC_DURING_RS == TRUE
919         /* If a disconnect is pending, issue it now that role switch has completed */
920         if ((p_dev_rec = btm_find_dev (p->remote_addr)) != NULL)
921         {
922             if (p_dev_rec->rs_disc_pending == BTM_SEC_DISC_PENDING)
923             {
924                 BTM_TRACE_WARNING0("btm_acl_encrypt_change -> Issuing delayed HCI_Disconnect!!!");
925                 btsnd_hcic_disconnect(p_dev_rec->hci_handle, HCI_ERR_PEER_USER);
926             }
927             BTM_TRACE_ERROR2("btm_acl_encrypt_change: tBTM_SEC_DEV:0x%x rs_disc_pending=%d",
928                 (UINT32)p_dev_rec, p_dev_rec->rs_disc_pending);
929             p_dev_rec->rs_disc_pending = BTM_SEC_RS_NOT_PENDING;     /* reset flag */
930         }
931 #endif
932     }
933 
934 
935     /* Process Change Link Key if active */
936     if (p->change_key_state == BTM_ACL_SWKEY_STATE_ENCRYPTION_OFF)
937     {
938         /* if encryption turn off failed we still will try to change link key */
939         if (encr_enable)
940         {
941             p->change_key_state = BTM_ACL_SWKEY_STATE_IDLE;
942             p->encrypt_state = BTM_ACL_ENCRYPT_STATE_IDLE;
943         }
944         else
945         {
946             p->encrypt_state = BTM_ACL_ENCRYPT_STATE_TEMP_FUNC;
947             p->change_key_state = BTM_ACL_SWKEY_STATE_SWITCHING;
948         }
949 
950         if (!btsnd_hcic_change_link_key (p->hci_handle))
951         {
952             p->encrypt_state = BTM_ACL_ENCRYPT_STATE_IDLE;
953             p->change_key_state = BTM_ACL_SWKEY_STATE_IDLE;
954             if (btm_cb.devcb.p_chg_link_key_cb)
955             {
956                 (*btm_cb.devcb.p_chg_link_key_cb)(&btm_cb.devcb.chg_link_key_ref_data);
957                 btm_cb.devcb.p_chg_link_key_cb = NULL;
958             }
959         }
960     }
961     /* Finished enabling Encryption after changing link key */
962     else if (p->change_key_state == BTM_ACL_SWKEY_STATE_ENCRYPTION_ON)
963     {
964         p->encrypt_state = BTM_ACL_ENCRYPT_STATE_IDLE;
965         p->change_key_state = BTM_ACL_SWKEY_STATE_IDLE;
966         if (btm_cb.devcb.p_chg_link_key_cb)
967         {
968             (*btm_cb.devcb.p_chg_link_key_cb)(&btm_cb.devcb.chg_link_key_ref_data);
969             btm_cb.devcb.p_chg_link_key_cb = NULL;
970         }
971     }
972 }
973 /*******************************************************************************
974 **
975 ** Function         BTM_SetLinkPolicy
976 **
977 ** Description      Create and send HCI "Write Policy Set" command
978 **
979 ** Returns          status of the operation
980 **
981 *******************************************************************************/
BTM_SetLinkPolicy(BD_ADDR remote_bda,UINT16 * settings)982 tBTM_STATUS BTM_SetLinkPolicy (BD_ADDR remote_bda, UINT16 *settings)
983 {
984     tACL_CONN   *p;
985     UINT8       *localFeatures = BTM_ReadLocalFeatures();
986     BTM_TRACE_DEBUG0 ("BTM_SetLinkPolicy");
987 /*    BTM_TRACE_API1 ("BTM_SetLinkPolicy: requested settings: 0x%04x", *settings ); */
988 
989     /* First, check if hold mode is supported */
990     if (*settings != HCI_DISABLE_ALL_LM_MODES)
991     {
992         if ( (*settings & HCI_ENABLE_MASTER_SLAVE_SWITCH) && (!HCI_SWITCH_SUPPORTED(localFeatures)) )
993         {
994             *settings &= (~HCI_ENABLE_MASTER_SLAVE_SWITCH);
995             BTM_TRACE_API1 ("BTM_SetLinkPolicy switch not supported (settings: 0x%04x)", *settings );
996         }
997         if ( (*settings & HCI_ENABLE_HOLD_MODE) && (!HCI_HOLD_MODE_SUPPORTED(localFeatures)) )
998         {
999             *settings &= (~HCI_ENABLE_HOLD_MODE);
1000             BTM_TRACE_API1 ("BTM_SetLinkPolicy hold not supported (settings: 0x%04x)", *settings );
1001         }
1002         if ( (*settings & HCI_ENABLE_SNIFF_MODE) && (!HCI_SNIFF_MODE_SUPPORTED(localFeatures)) )
1003         {
1004             *settings &= (~HCI_ENABLE_SNIFF_MODE);
1005             BTM_TRACE_API1 ("BTM_SetLinkPolicy sniff not supported (settings: 0x%04x)", *settings );
1006         }
1007         if ( (*settings & HCI_ENABLE_PARK_MODE) && (!HCI_PARK_MODE_SUPPORTED(localFeatures)) )
1008         {
1009             *settings &= (~HCI_ENABLE_PARK_MODE);
1010             BTM_TRACE_API1 ("BTM_SetLinkPolicy park not supported (settings: 0x%04x)", *settings );
1011         }
1012     }
1013 
1014     if ((p = btm_bda_to_acl(remote_bda)) != NULL)
1015         return(btsnd_hcic_write_policy_set (p->hci_handle, *settings) ?
1016                                                 BTM_CMD_STARTED : BTM_NO_RESOURCES);
1017 
1018     /* If here, no BD Addr found */
1019     return(BTM_UNKNOWN_ADDR);
1020 }
1021 
1022 /*******************************************************************************
1023 **
1024 ** Function         BTM_SetDefaultLinkPolicy
1025 **
1026 ** Description      Set the default value for HCI "Write Policy Set" command
1027 **                  to use when an ACL link is created.
1028 **
1029 ** Returns          void
1030 **
1031 *******************************************************************************/
BTM_SetDefaultLinkPolicy(UINT16 settings)1032 void BTM_SetDefaultLinkPolicy (UINT16 settings)
1033 {
1034     UINT8 *localFeatures = BTM_ReadLocalFeatures();
1035 
1036     BTM_TRACE_DEBUG1("BTM_SetDefaultLinkPolicy setting:0x%04x", settings);
1037 
1038     if((settings & HCI_ENABLE_MASTER_SLAVE_SWITCH) && (!HCI_SWITCH_SUPPORTED(localFeatures)))
1039     {
1040         settings &= ~HCI_ENABLE_MASTER_SLAVE_SWITCH;
1041         BTM_TRACE_DEBUG1("BTM_SetDefaultLinkPolicy switch not supported (settings: 0x%04x)", settings);
1042     }
1043     if ((settings & HCI_ENABLE_HOLD_MODE) && (!HCI_HOLD_MODE_SUPPORTED(localFeatures)))
1044     {
1045         settings &= ~HCI_ENABLE_HOLD_MODE;
1046         BTM_TRACE_DEBUG1("BTM_SetDefaultLinkPolicy hold not supported (settings: 0x%04x)", settings);
1047     }
1048     if ((settings & HCI_ENABLE_SNIFF_MODE) && (!HCI_SNIFF_MODE_SUPPORTED(localFeatures)))
1049     {
1050         settings &= ~HCI_ENABLE_SNIFF_MODE;
1051         BTM_TRACE_DEBUG1("BTM_SetDefaultLinkPolicy sniff not supported (settings: 0x%04x)", settings);
1052     }
1053     if ((settings & HCI_ENABLE_PARK_MODE) && (!HCI_PARK_MODE_SUPPORTED(localFeatures)))
1054     {
1055         settings &= ~HCI_ENABLE_PARK_MODE;
1056         BTM_TRACE_DEBUG1("BTM_SetDefaultLinkPolicy park not supported (settings: 0x%04x)", settings);
1057     }
1058     BTM_TRACE_DEBUG1("Set DefaultLinkPolicy:0x%04x", settings);
1059 
1060     btm_cb.btm_def_link_policy = settings;
1061 
1062     /* Set the default Link Policy of the controller */
1063     btsnd_hcic_write_def_policy_set(settings);
1064 }
1065 
1066 
1067 /*******************************************************************************
1068 **
1069 ** Function         BTM_ReadLinkPolicy
1070 **
1071 ** Description      This function is called to read the link policy settings.
1072 **                  The address of link policy results are returned in the callback.
1073 **                  (tBTM_LNK_POLICY_RESULTS)
1074 **
1075 ** Returns          status of the operation
1076 **
1077 *******************************************************************************/
BTM_ReadLinkPolicy(BD_ADDR remote_bda,tBTM_CMPL_CB * p_cb)1078 tBTM_STATUS BTM_ReadLinkPolicy (BD_ADDR remote_bda, tBTM_CMPL_CB *p_cb)
1079 {
1080     tACL_CONN   *p;
1081 
1082     BTM_TRACE_API6 ("BTM_ReadLinkPolicy: RemBdAddr: %02x%02x%02x%02x%02x%02x",
1083                     remote_bda[0], remote_bda[1], remote_bda[2],
1084                     remote_bda[3], remote_bda[4], remote_bda[5]);
1085 
1086     /* If someone already waiting on the version, do not allow another */
1087     if (btm_cb.devcb.p_rlinkp_cmpl_cb)
1088         return(BTM_BUSY);
1089 
1090     p = btm_bda_to_acl(remote_bda);
1091     if (p != (tACL_CONN *)NULL)
1092     {
1093         btu_start_timer (&btm_cb.devcb.rlinkp_timer, BTU_TTYPE_BTM_ACL, BTM_DEV_REPLY_TIMEOUT);
1094         btm_cb.devcb.p_rlinkp_cmpl_cb = p_cb;
1095 
1096         if (!btsnd_hcic_read_policy_set (p->hci_handle))
1097         {
1098             btu_stop_timer (&btm_cb.devcb.rlinkp_timer);
1099             btm_cb.devcb.p_rlinkp_cmpl_cb = NULL;
1100             return(BTM_NO_RESOURCES);
1101         }
1102 
1103         return(BTM_CMD_STARTED);
1104     }
1105 
1106     /* If here, no BD Addr found */
1107     return(BTM_UNKNOWN_ADDR);
1108 }
1109 
1110 
1111 /*******************************************************************************
1112 **
1113 ** Function         btm_read_link_policy_complete
1114 **
1115 ** Description      This function is called when the command complete message
1116 **                  is received from the HCI for the read local link policy request.
1117 **
1118 ** Returns          void
1119 **
1120 *******************************************************************************/
btm_read_link_policy_complete(UINT8 * p)1121 void btm_read_link_policy_complete (UINT8 *p)
1122 {
1123     tBTM_CMPL_CB            *p_cb = btm_cb.devcb.p_rlinkp_cmpl_cb;
1124     tBTM_LNK_POLICY_RESULTS  lnkpol;
1125     UINT16                   handle;
1126     tACL_CONN               *p_acl_cb = &btm_cb.acl_db[0];
1127     UINT16                   index;
1128     BTM_TRACE_DEBUG0 ("btm_read_link_policy_complete");
1129     btu_stop_timer (&btm_cb.devcb.rlinkp_timer);
1130 
1131     /* If there was a callback address for read local version, call it */
1132     btm_cb.devcb.p_rlinkp_cmpl_cb = NULL;
1133 
1134     if (p_cb)
1135     {
1136         STREAM_TO_UINT8  (lnkpol.hci_status, p);
1137 
1138         if (lnkpol.hci_status == HCI_SUCCESS)
1139         {
1140             lnkpol.status = BTM_SUCCESS;
1141 
1142             STREAM_TO_UINT16 (handle, p);
1143 
1144             STREAM_TO_UINT16 (lnkpol.settings, p);
1145 
1146             /* Search through the list of active channels for the correct BD Addr */
1147             for (index = 0; index < MAX_L2CAP_LINKS; index++, p_acl_cb++)
1148             {
1149                 if ((p_acl_cb->in_use) && (handle == p_acl_cb->hci_handle))
1150                 {
1151                     memcpy (lnkpol.rem_bda, p_acl_cb->remote_addr, BD_ADDR_LEN);
1152                     break;
1153                 }
1154             }
1155         }
1156         else
1157             lnkpol.status = BTM_ERR_PROCESSING;
1158 
1159         (*p_cb)(&lnkpol);
1160     }
1161 }
1162 
1163 
1164 /*******************************************************************************
1165 **
1166 ** Function         btm_read_remote_version_complete
1167 **
1168 ** Description      This function is called when the command complete message
1169 **                  is received from the HCI for the remote version info.
1170 **
1171 ** Returns          void
1172 **
1173 *******************************************************************************/
btm_read_remote_version_complete(UINT8 * p)1174 void btm_read_remote_version_complete (UINT8 *p)
1175 {
1176     tACL_CONN        *p_acl_cb = &btm_cb.acl_db[0];
1177     UINT8             status;
1178     UINT16            handle;
1179     int               xx;
1180     BTM_TRACE_DEBUG0 ("btm_read_remote_version_complete");
1181     STREAM_TO_UINT8  (status, p);
1182     if (status == HCI_SUCCESS)
1183     {
1184         STREAM_TO_UINT16 (handle, p);
1185 
1186         /* Look up the connection by handle and copy features */
1187         for (xx = 0; xx < MAX_L2CAP_LINKS; xx++, p_acl_cb++)
1188         {
1189             if ((p_acl_cb->in_use) && (p_acl_cb->hci_handle == handle))
1190             {
1191                 STREAM_TO_UINT8  (p_acl_cb->lmp_version, p);
1192                 STREAM_TO_UINT16 (p_acl_cb->manufacturer, p);
1193                 STREAM_TO_UINT16 (p_acl_cb->lmp_subversion, p);
1194                 break;
1195             }
1196         }
1197     }
1198 }
1199 
1200 
1201 /*******************************************************************************
1202 **
1203 ** Function         btm_process_remote_ext_features
1204 **
1205 ** Description      Local function called to process all extended features pages
1206 **                  read from a remote device.
1207 **
1208 ** Returns          void
1209 **
1210 *******************************************************************************/
btm_process_remote_ext_features(tACL_CONN * p_acl_cb,UINT8 num_read_pages)1211 void btm_process_remote_ext_features (tACL_CONN *p_acl_cb, UINT8 num_read_pages)
1212 {
1213     UINT16              handle = p_acl_cb->hci_handle;
1214     tBTM_SEC_DEV_REC    *p_dev_rec = btm_find_dev_by_handle (handle);
1215     UINT8               page_idx;
1216 
1217     BTM_TRACE_DEBUG0 ("btm_process_remote_ext_features");
1218 
1219     /* Make sure we have the record to save remote features information */
1220     if (p_dev_rec == NULL)
1221     {
1222         /* Get a new device; might be doing dedicated bonding */
1223         p_dev_rec = btm_find_or_alloc_dev (p_acl_cb->remote_addr);
1224     }
1225 
1226     p_acl_cb->num_read_pages = num_read_pages;
1227     p_dev_rec->num_read_pages = num_read_pages;
1228 
1229     /* Process the pages one by one */
1230     for (page_idx = 0; page_idx < num_read_pages; page_idx++)
1231     {
1232         btm_process_remote_ext_features_page (p_acl_cb, p_dev_rec, page_idx);
1233     }
1234 }
1235 
1236 
1237 /*******************************************************************************
1238 **
1239 ** Function         btm_process_remote_ext_features_page
1240 **
1241 ** Description      Local function called to process the information located
1242 **                  in the specific extended features page read from a remote device.
1243 **
1244 ** Returns          void
1245 **
1246 *******************************************************************************/
btm_process_remote_ext_features_page(tACL_CONN * p_acl_cb,tBTM_SEC_DEV_REC * p_dev_rec,UINT8 page_idx)1247 void btm_process_remote_ext_features_page (tACL_CONN *p_acl_cb, tBTM_SEC_DEV_REC *p_dev_rec,
1248                                            UINT8 page_idx)
1249 {
1250     UINT16            handle;
1251     UINT8             req_pend;
1252 
1253     handle = p_acl_cb->hci_handle;
1254 
1255     memcpy (p_dev_rec->features[page_idx], p_acl_cb->peer_lmp_features[page_idx],
1256             HCI_FEATURE_BYTES_PER_PAGE);
1257 
1258     switch (page_idx)
1259     {
1260     /* Extended (Legacy) Page 0 */
1261     case HCI_EXT_FEATURES_PAGE_0:
1262         /* Page 0 indicates Controller support for SSP */
1263         if (btm_cb.security_mode < BTM_SEC_MODE_SP ||
1264             !HCI_SIMPLE_PAIRING_SUPPORTED(p_dev_rec->features[HCI_EXT_FEATURES_PAGE_0]))
1265         {
1266             req_pend = (p_dev_rec->sm4 & BTM_SM4_REQ_PEND);
1267             p_dev_rec->sm4 = BTM_SM4_KNOWN;
1268             if (req_pend)
1269             {
1270                 l2cu_resubmit_pending_sec_req (p_dev_rec->bd_addr);
1271             }
1272         }
1273         break;
1274 
1275     /* Extended Page 1 */
1276     case HCI_EXT_FEATURES_PAGE_1:
1277         /* Page 1 indicates Host support for SSP and SC */
1278         req_pend = (p_dev_rec->sm4 & BTM_SM4_REQ_PEND);
1279 
1280         if (btm_cb.security_mode == BTM_SEC_MODE_SP
1281             && HCI_SSP_HOST_SUPPORTED(p_dev_rec->features[HCI_EXT_FEATURES_PAGE_1])
1282             && HCI_SIMPLE_PAIRING_SUPPORTED(p_dev_rec->features[HCI_EXT_FEATURES_PAGE_0]))
1283         {
1284             p_dev_rec->sm4 = BTM_SM4_TRUE;
1285         }
1286         else
1287         {
1288             p_dev_rec->sm4 = BTM_SM4_KNOWN;
1289         }
1290 
1291         BTM_TRACE_API4 ("ext_features_complt page_num:%d f[0]:x%02x, sm4:%x, pend:%d",
1292                         HCI_EXT_FEATURES_PAGE_1, *(p_dev_rec->features[HCI_EXT_FEATURES_PAGE_1]),
1293                         p_dev_rec->sm4, req_pend);
1294 
1295         if (req_pend)
1296             l2cu_resubmit_pending_sec_req (p_dev_rec->bd_addr);
1297 
1298         break;
1299 
1300     /* Extended Page 2 */
1301     case HCI_EXT_FEATURES_PAGE_2:
1302         /* Page 2 indicates Ping support*/
1303         break;
1304 
1305     default:
1306         BTM_TRACE_ERROR1("btm_process_remote_ext_features_page page=%d unexpected", page_idx);
1307         break;
1308     }
1309 }
1310 
1311 
1312 /*******************************************************************************
1313 **
1314 ** Function         btm_read_remote_features
1315 **
1316 ** Description      Local function called to send a read remote supported features/
1317 **                  remote extended features page[0].
1318 **
1319 ** Returns          void
1320 **
1321 *******************************************************************************/
btm_read_remote_features(UINT16 handle)1322 void btm_read_remote_features (UINT16 handle)
1323 {
1324     UINT8       acl_idx;
1325     tACL_CONN   *p_acl_cb;
1326 
1327     BTM_TRACE_DEBUG1("btm_read_remote_features() handle: %d", handle);
1328 
1329     if ((acl_idx = btm_handle_to_acl_index(handle)) >= MAX_L2CAP_LINKS)
1330     {
1331         BTM_TRACE_ERROR1("btm_read_remote_features handle=%d invalid", handle);
1332         return;
1333     }
1334 
1335     p_acl_cb = &btm_cb.acl_db[acl_idx];
1336     p_acl_cb->num_read_pages = 0;
1337     memset (p_acl_cb->peer_lmp_features, 0, sizeof(p_acl_cb->peer_lmp_features));
1338 
1339     /* first send read remote supported features HCI command */
1340     /* because we don't know whether the remote support extended feature command */
1341     btsnd_hcic_rmt_features_req (handle);
1342 }
1343 
1344 
1345 /*******************************************************************************
1346 **
1347 ** Function         btm_read_remote_ext_features
1348 **
1349 ** Description      Local function called to send a read remote extended features
1350 **
1351 ** Returns          void
1352 **
1353 *******************************************************************************/
btm_read_remote_ext_features(UINT16 handle,UINT8 page_number)1354 void btm_read_remote_ext_features (UINT16 handle, UINT8 page_number)
1355 {
1356     BTM_TRACE_DEBUG2("btm_read_remote_ext_features() handle: %d page: %d", handle, page_number);
1357 
1358     btsnd_hcic_rmt_ext_features(handle, page_number);
1359 }
1360 
1361 
1362 /*******************************************************************************
1363 **
1364 ** Function         btm_read_remote_features_complete
1365 **
1366 ** Description      This function is called when the remote supported features
1367 **                  complete event is received from the HCI.
1368 **
1369 ** Returns          void
1370 **
1371 *******************************************************************************/
btm_read_remote_features_complete(UINT8 * p)1372 void btm_read_remote_features_complete (UINT8 *p)
1373 {
1374     tACL_CONN        *p_acl_cb;
1375     UINT8             status;
1376     UINT16            handle;
1377     UINT8            acl_idx;
1378 
1379     BTM_TRACE_DEBUG0 ("btm_read_remote_features_complete");
1380     STREAM_TO_UINT8  (status, p);
1381 
1382     if (status != HCI_SUCCESS)
1383     {
1384         BTM_TRACE_ERROR1 ("btm_read_remote_features_complete failed (status 0x%02x)", status);
1385         return;
1386     }
1387 
1388         STREAM_TO_UINT16 (handle, p);
1389 
1390     if ((acl_idx = btm_handle_to_acl_index(handle)) >= MAX_L2CAP_LINKS)
1391         {
1392         BTM_TRACE_ERROR1("btm_read_remote_features_complete handle=%d invalid", handle);
1393         return;
1394                 }
1395 
1396     p_acl_cb = &btm_cb.acl_db[acl_idx];
1397 
1398     /* Copy the received features page */
1399     STREAM_TO_ARRAY(p_acl_cb->peer_lmp_features[HCI_EXT_FEATURES_PAGE_0], p,
1400                     HCI_FEATURE_BYTES_PER_PAGE);
1401 
1402     if ((HCI_LMP_EXTENDED_SUPPORTED(p_acl_cb->peer_lmp_features[HCI_EXT_FEATURES_PAGE_0])) &&
1403         (HCI_READ_REMOTE_EXT_FEATURES_SUPPORTED(btm_cb.devcb.supported_cmds)))
1404     {
1405         /* if the remote controller has extended features and local controller supports
1406         ** HCI_Read_Remote_Extended_Features command then start reading these feature starting
1407         ** with extended features page 1 */
1408         BTM_TRACE_DEBUG0 ("Start reading remote extended features");
1409         btm_read_remote_ext_features(handle, HCI_EXT_FEATURES_PAGE_1);
1410         return;
1411     }
1412 
1413     /* Remote controller has no extended features. Process remote controller supported features
1414        (features page HCI_EXT_FEATURES_PAGE_0). */
1415     btm_process_remote_ext_features (p_acl_cb, 1);
1416 
1417     /* Continue with HCI connection establishment */
1418     btm_establish_continue (p_acl_cb);
1419 }
1420 
1421 /*******************************************************************************
1422 **
1423 ** Function         btm_read_remote_ext_features_complete
1424 **
1425 ** Description      This function is called when the remote extended features
1426 **                  complete event is received from the HCI.
1427 **
1428 ** Returns          void
1429 **
1430 *******************************************************************************/
btm_read_remote_ext_features_complete(UINT8 * p)1431 void btm_read_remote_ext_features_complete (UINT8 *p)
1432 {
1433     tACL_CONN   *p_acl_cb;
1434     UINT8       status, page_num, max_page;
1435     UINT16      handle;
1436     UINT8       acl_idx;
1437 
1438     BTM_TRACE_DEBUG0 ("btm_read_remote_ext_features_complete");
1439 
1440     STREAM_TO_UINT8  (status, p);
1441     STREAM_TO_UINT16 (handle, p);
1442     STREAM_TO_UINT8  (page_num, p);
1443     STREAM_TO_UINT8  (max_page, p);
1444 
1445     /* Validate parameters */
1446     if ((acl_idx = btm_handle_to_acl_index(handle)) >= MAX_L2CAP_LINKS)
1447     {
1448         BTM_TRACE_ERROR1("btm_read_remote_ext_features_complete handle=%d invalid", handle);
1449         return;
1450     }
1451 
1452     if (max_page > HCI_EXT_FEATURES_PAGE_MAX)
1453     {
1454         BTM_TRACE_ERROR1("btm_read_remote_ext_features_complete page=%d unknown", max_page);
1455         return;
1456     }
1457 
1458     p_acl_cb = &btm_cb.acl_db[acl_idx];
1459 
1460     /* Copy the received features page */
1461     STREAM_TO_ARRAY(p_acl_cb->peer_lmp_features[page_num], p, HCI_FEATURE_BYTES_PER_PAGE);
1462 
1463     /* If there is the next remote features page and
1464      * we have space to keep this page data - read this page */
1465     if ((page_num < max_page) && (page_num < HCI_EXT_FEATURES_PAGE_MAX))
1466     {
1467         page_num++;
1468         BTM_TRACE_DEBUG1("BTM reads next remote extended features page (%d)", page_num);
1469         btm_read_remote_ext_features (handle, page_num);
1470         return;
1471     }
1472 
1473     /* Reading of remote feature pages is complete */
1474     BTM_TRACE_DEBUG1("BTM reached last remote extended features page (%d)", page_num);
1475 
1476     /* Process the pages */
1477     btm_process_remote_ext_features (p_acl_cb, (UINT8) (page_num + 1));
1478 
1479     /* Continue with HCI connection establishment */
1480     btm_establish_continue (p_acl_cb);
1481 }
1482 
1483 /*******************************************************************************
1484 **
1485 ** Function         btm_read_remote_ext_features_failed
1486 **
1487 ** Description      This function is called when the remote extended features
1488 **                  complete event returns a failed status.
1489 **
1490 ** Returns          void
1491 **
1492 *******************************************************************************/
btm_read_remote_ext_features_failed(UINT8 status,UINT16 handle)1493 void btm_read_remote_ext_features_failed (UINT8 status, UINT16 handle)
1494 {
1495     tACL_CONN   *p_acl_cb;
1496     UINT8       acl_idx;
1497 
1498     BTM_TRACE_WARNING2 ("btm_read_remote_ext_features_failed (status 0x%02x) for handle %d",
1499                          status, handle);
1500 
1501     if ((acl_idx = btm_handle_to_acl_index(handle)) >= MAX_L2CAP_LINKS)
1502     {
1503         BTM_TRACE_ERROR1("btm_read_remote_ext_features_failed handle=%d invalid", handle);
1504         return;
1505     }
1506 
1507     p_acl_cb = &btm_cb.acl_db[acl_idx];
1508 
1509     /* Process supported features only */
1510     btm_process_remote_ext_features (p_acl_cb, 1);
1511 
1512     /* Continue HCI connection establishment */
1513     btm_establish_continue (p_acl_cb);
1514 }
1515 
1516 /*******************************************************************************
1517 **
1518 ** Function         btm_establish_continue
1519 **
1520 ** Description      This function is called when the command complete message
1521 **                  is received from the HCI for the read local link policy request.
1522 **
1523 ** Returns          void
1524 **
1525 *******************************************************************************/
btm_establish_continue(tACL_CONN * p_acl_cb)1526 static void btm_establish_continue (tACL_CONN *p_acl_cb)
1527 {
1528 #if (defined(BTM_BUSY_LEVEL_CHANGE_INCLUDED) && BTM_BUSY_LEVEL_CHANGE_INCLUDED == TRUE)
1529     tBTM_BL_EVENT_DATA  evt_data;
1530 #endif
1531     BTM_TRACE_DEBUG0 ("btm_establish_continue");
1532 #if (!defined(BTM_BYPASS_EXTRA_ACL_SETUP) || BTM_BYPASS_EXTRA_ACL_SETUP == FALSE)
1533 #if (defined BLE_INCLUDED && BLE_INCLUDED == TRUE)
1534     if (!p_acl_cb->is_le_link)
1535 #endif
1536     {
1537         /* For now there are a some devices that do not like sending */
1538         /* commands events and data at the same time. */
1539         /* Set the packet types to the default allowed by the device */
1540         btm_set_packet_types (p_acl_cb, btm_cb.btm_acl_pkt_types_supported);
1541 
1542         if (btm_cb.btm_def_link_policy)
1543             BTM_SetLinkPolicy (p_acl_cb->remote_addr, &btm_cb.btm_def_link_policy);
1544     }
1545 #endif
1546     p_acl_cb->link_up_issued = TRUE;
1547 
1548     /* If anyone cares, tell him database changed */
1549 #if (defined(BTM_BUSY_LEVEL_CHANGE_INCLUDED) && BTM_BUSY_LEVEL_CHANGE_INCLUDED == TRUE)
1550     if (btm_cb.p_bl_changed_cb)
1551     {
1552         evt_data.event = BTM_BL_CONN_EVT;
1553         evt_data.conn.p_bda = p_acl_cb->remote_addr;
1554         evt_data.conn.p_bdn = p_acl_cb->remote_name;
1555         evt_data.conn.p_dc  = p_acl_cb->remote_dc;
1556         evt_data.conn.p_features = p_acl_cb->peer_lmp_features[HCI_EXT_FEATURES_PAGE_0];
1557 
1558 
1559         (*btm_cb.p_bl_changed_cb)(&evt_data);
1560     }
1561     btm_acl_update_busy_level (BTM_BLI_ACL_UP_EVT);
1562 #else
1563     if (btm_cb.p_acl_changed_cb)
1564         (*btm_cb.p_acl_changed_cb) (p_acl_cb->remote_addr,
1565                                     p_acl_cb->remote_dc,
1566                                     p_acl_cb->remote_name,
1567                                     p_acl_cb->peer_lmp_features[HCI_EXT_FEATURES_PAGE_0],
1568                                     TRUE);
1569 #endif
1570 }
1571 
1572 
1573 /*******************************************************************************
1574 **
1575 ** Function         BTM_SetDefaultLinkSuperTout
1576 **
1577 ** Description      Set the default value for HCI "Write Link Supervision Timeout"
1578 **                  command to use when an ACL link is created.
1579 **
1580 ** Returns          void
1581 **
1582 *******************************************************************************/
BTM_SetDefaultLinkSuperTout(UINT16 timeout)1583 void BTM_SetDefaultLinkSuperTout (UINT16 timeout)
1584 {
1585     BTM_TRACE_DEBUG0 ("BTM_SetDefaultLinkSuperTout");
1586     btm_cb.btm_def_link_super_tout = timeout;
1587 }
1588 
1589 /*******************************************************************************
1590 **
1591 ** Function         BTM_GetLinkSuperTout
1592 **
1593 ** Description      Read the link supervision timeout value of the connection
1594 **
1595 ** Returns          status of the operation
1596 **
1597 *******************************************************************************/
BTM_GetLinkSuperTout(BD_ADDR remote_bda,UINT16 * p_timeout)1598 tBTM_STATUS BTM_GetLinkSuperTout (BD_ADDR remote_bda, UINT16 *p_timeout)
1599 {
1600     tACL_CONN   *p = btm_bda_to_acl(remote_bda);
1601 
1602     BTM_TRACE_DEBUG0 ("BTM_GetLinkSuperTout");
1603     if (p != (tACL_CONN *)NULL)
1604     {
1605         *p_timeout = p->link_super_tout;
1606         return(BTM_SUCCESS);
1607     }
1608     /* If here, no BD Addr found */
1609     return(BTM_UNKNOWN_ADDR);
1610 }
1611 
1612 
1613 /*******************************************************************************
1614 **
1615 ** Function         BTM_SetLinkSuperTout
1616 **
1617 ** Description      Create and send HCI "Write Link Supervision Timeout" command
1618 **
1619 ** Returns          status of the operation
1620 **
1621 *******************************************************************************/
BTM_SetLinkSuperTout(BD_ADDR remote_bda,UINT16 timeout)1622 tBTM_STATUS BTM_SetLinkSuperTout (BD_ADDR remote_bda, UINT16 timeout)
1623 {
1624     tACL_CONN   *p = btm_bda_to_acl(remote_bda);
1625 
1626     BTM_TRACE_DEBUG0 ("BTM_SetLinkSuperTout");
1627     if (p != (tACL_CONN *)NULL)
1628     {
1629         p->link_super_tout = timeout;
1630 
1631         /* Only send if current role is Master; 2.0 spec requires this */
1632         if (p->link_role == BTM_ROLE_MASTER)
1633         {
1634             if (!btsnd_hcic_write_link_super_tout (LOCAL_BR_EDR_CONTROLLER_ID,
1635                                                    p->hci_handle, timeout))
1636                 return(BTM_NO_RESOURCES);
1637 
1638             return(BTM_CMD_STARTED);
1639         }
1640         else
1641             return(BTM_SUCCESS);
1642     }
1643 
1644     /* If here, no BD Addr found */
1645     return(BTM_UNKNOWN_ADDR);
1646 }
1647 
1648 /*******************************************************************************
1649 **
1650 ** Function         BTM_RegForLstoEvt
1651 **
1652 ** Description      register for the HCI "Link Supervision Timeout Change" event
1653 **
1654 ** Returns          void
1655 **
1656 *******************************************************************************/
BTM_RegForLstoEvt(tBTM_LSTO_CBACK * p_cback)1657 void BTM_RegForLstoEvt (tBTM_LSTO_CBACK *p_cback)
1658 {
1659     BTM_TRACE_DEBUG0 ("BTM_RegForLstoEvt");
1660     btm_cb.p_lsto_cback = p_cback;
1661 }
1662 
1663 /*******************************************************************************
1664 **
1665 ** Function         btm_proc_lsto_evt
1666 **
1667 ** Description      process the HCI "Link Supervision Timeout Change" event
1668 **
1669 ** Returns          void
1670 **
1671 *******************************************************************************/
btm_proc_lsto_evt(UINT16 handle,UINT16 timeout)1672 void btm_proc_lsto_evt(UINT16 handle, UINT16 timeout)
1673 {
1674     UINT8 xx;
1675 
1676     BTM_TRACE_DEBUG0 ("btm_proc_lsto_evt");
1677     if (btm_cb.p_lsto_cback)
1678     {
1679         /* Look up the connection by handle and set the current mode */
1680         xx = btm_handle_to_acl_index(handle);
1681 
1682         /* don't assume that we can never get a bad hci_handle */
1683         if (xx < MAX_L2CAP_LINKS)
1684         {
1685             (*btm_cb.p_lsto_cback)(btm_cb.acl_db[xx].remote_addr, timeout);
1686         }
1687     }
1688 }
1689 
1690 #if BTM_PWR_MGR_INCLUDED == FALSE
1691 /*******************************************************************************
1692 **
1693 ** Function         BTM_SetHoldMode
1694 **
1695 ** Description      This function is called to set a connection into hold mode.
1696 **                  A check is made if the connection is in sniff or park mode,
1697 **                  and if yes, the hold mode is ignored.
1698 **
1699 ** Returns          status of the operation
1700 **
1701 *******************************************************************************/
BTM_SetHoldMode(BD_ADDR remote_bda,UINT16 min_interval,UINT16 max_interval)1702 tBTM_STATUS BTM_SetHoldMode (BD_ADDR remote_bda, UINT16 min_interval, UINT16 max_interval)
1703 {
1704     tACL_CONN   *p;
1705 
1706     BTM_TRACE_DEBUG0 ("BTM_SetHoldMode");
1707     /* First, check if hold mode is supported */
1708     if (!HCI_HOLD_MODE_SUPPORTED(BTM_ReadLocalFeatures()))
1709         return(BTM_MODE_UNSUPPORTED);
1710 
1711     p = btm_bda_to_acl(remote_bda);
1712     if (p != (tACL_CONN *)NULL)
1713     {
1714         /* If the connection is in park or sniff mode, forget about holding it */
1715         if (p->mode != BTM_ACL_MODE_NORMAL)
1716             return(BTM_SUCCESS);
1717 
1718         if (!btsnd_hcic_hold_mode (p->hci_handle, max_interval, min_interval))
1719             return(BTM_NO_RESOURCES);
1720 
1721         return(BTM_CMD_STARTED);
1722     }
1723 
1724     /* If here, no BD Addr found */
1725     return(BTM_UNKNOWN_ADDR);
1726 }
1727 
1728 
1729 /*******************************************************************************
1730 **
1731 ** Function         BTM_SetSniffMode
1732 **
1733 ** Description      This function is called to set a connection into sniff mode.
1734 **                  A check is made if the connection is already in sniff or park
1735 **                  mode, and if yes, the sniff mode is ignored.
1736 **
1737 ** Returns          status of the operation
1738 **
1739 *******************************************************************************/
BTM_SetSniffMode(BD_ADDR remote_bda,UINT16 min_period,UINT16 max_period,UINT16 attempt,UINT16 timeout)1740 tBTM_STATUS BTM_SetSniffMode (BD_ADDR remote_bda, UINT16 min_period, UINT16 max_period,
1741                               UINT16 attempt, UINT16 timeout)
1742 {
1743     tACL_CONN   *p;
1744     BTM_TRACE_DEBUG0 ("BTM_SetSniffMode");
1745     /* First, check if sniff mode is supported */
1746     if (!HCI_SNIFF_MODE_SUPPORTED(BTM_ReadLocalFeatures()))
1747         return(BTM_MODE_UNSUPPORTED);
1748 
1749     p = btm_bda_to_acl(remote_bda);
1750     if (p != (tACL_CONN *)NULL)
1751     {
1752         /* If the connection is in park mode, forget about sniffing it */
1753         if (p->mode != BTM_ACL_MODE_NORMAL)
1754             return(BTM_WRONG_MODE);
1755 
1756         if (!btsnd_hcic_sniff_mode (p->hci_handle, max_period,
1757                                     min_period, attempt, timeout))
1758             return(BTM_NO_RESOURCES);
1759 
1760         return(BTM_CMD_STARTED);
1761     }
1762 
1763     /* If here, no BD Addr found */
1764     return(BTM_UNKNOWN_ADDR);
1765 }
1766 
1767 
1768 
1769 
1770 /*******************************************************************************
1771 **
1772 ** Function         BTM_CancelSniffMode
1773 **
1774 ** Description      This function is called to put a connection out of sniff mode.
1775 **                  A check is made if the connection is already in sniff mode,
1776 **                  and if not, the cancel sniff mode is ignored.
1777 **
1778 ** Returns          status of the operation
1779 **
1780 *******************************************************************************/
BTM_CancelSniffMode(BD_ADDR remote_bda)1781 tBTM_STATUS BTM_CancelSniffMode (BD_ADDR remote_bda)
1782 {
1783     tACL_CONN   *p = btm_bda_to_acl(remote_bda);
1784     BTM_TRACE_DEBUG0 ("BTM_CancelSniffMode ");
1785     if (p == (tACL_CONN *)NULL)
1786         return(BTM_UNKNOWN_ADDR);
1787 
1788     /* If the connection is not in sniff mode, cannot cancel */
1789     if (p->mode != BTM_ACL_MODE_SNIFF)
1790         return(BTM_WRONG_MODE);
1791 
1792     if (!btsnd_hcic_exit_sniff_mode (p->hci_handle))
1793         return(BTM_NO_RESOURCES);
1794 
1795     return(BTM_CMD_STARTED);
1796 }
1797 
1798 
1799 /*******************************************************************************
1800 **
1801 ** Function         BTM_SetParkMode
1802 **
1803 ** Description      This function is called to set a connection into park mode.
1804 **                  A check is made if the connection is already in sniff or park
1805 **                  mode, and if yes, the park mode is ignored.
1806 **
1807 ** Returns          status of the operation
1808 **
1809 *******************************************************************************/
BTM_SetParkMode(BD_ADDR remote_bda,UINT16 beacon_min_period,UINT16 beacon_max_period)1810 tBTM_STATUS BTM_SetParkMode (BD_ADDR remote_bda, UINT16 beacon_min_period, UINT16 beacon_max_period)
1811 {
1812     tACL_CONN   *p;
1813 
1814     BTM_TRACE_DEBUG0 ("BTM_SetParkMode");
1815     /* First, check if park mode is supported */
1816     if (!HCI_PARK_MODE_SUPPORTED(BTM_ReadLocalFeatures()))
1817         return(BTM_MODE_UNSUPPORTED);
1818 
1819     p = btm_bda_to_acl(remote_bda);
1820     if (p != (tACL_CONN *)NULL)
1821     {
1822         /* If the connection is in sniff mode, forget about parking it */
1823         if (p->mode != BTM_ACL_MODE_NORMAL)
1824             return(BTM_WRONG_MODE);
1825 
1826         /* no park mode if SCO exists -- CR#1982, 1.1 errata 1124
1827            command status event should be returned /w error code 0x0C "Command Disallowed"
1828            Let LM do this.
1829         */
1830         if (!btsnd_hcic_park_mode (p->hci_handle,
1831                                    beacon_max_period, beacon_min_period))
1832             return(BTM_NO_RESOURCES);
1833 
1834         return(BTM_CMD_STARTED);
1835     }
1836 
1837     /* If here, no BD Addr found */
1838     return(BTM_UNKNOWN_ADDR);
1839 }
1840 
1841 /*******************************************************************************
1842 **
1843 ** Function         BTM_CancelParkMode
1844 **
1845 ** Description      This function is called to put a connection out of park mode.
1846 **                  A check is made if the connection is already in park mode,
1847 **                  and if not, the cancel sniff mode is ignored.
1848 **
1849 ** Returns          status of the operation
1850 **
1851 *******************************************************************************/
BTM_CancelParkMode(BD_ADDR remote_bda)1852 tBTM_STATUS BTM_CancelParkMode (BD_ADDR remote_bda)
1853 {
1854     tACL_CONN   *p;
1855 
1856     BTM_TRACE_DEBUG0 ("BTM_CancelParkMode");
1857     p = btm_bda_to_acl(remote_bda);
1858     if (p != (tACL_CONN *)NULL)
1859     {
1860         /* If the connection is not in park mode, cannot cancel */
1861         if (p->mode != BTM_ACL_MODE_PARK)
1862             return(BTM_WRONG_MODE);
1863 
1864         if (!btsnd_hcic_exit_park_mode (p->hci_handle))
1865             return(BTM_NO_RESOURCES);
1866 
1867         return(BTM_CMD_STARTED);
1868     }
1869 
1870     /* If here, no BD Addr found */
1871     return(BTM_UNKNOWN_ADDR);
1872 }
1873 #endif /* BTM_PWR_MGR_INCLUDED == FALSE */
1874 
1875 
1876 /*******************************************************************************
1877 **
1878 ** Function         BTM_SetPacketTypes
1879 **
1880 ** Description      This function is set the packet types used for a specific
1881 **                  ACL connection,
1882 **
1883 ** Returns          status of the operation
1884 **
1885 *******************************************************************************/
BTM_SetPacketTypes(BD_ADDR remote_bda,UINT16 pkt_types)1886 tBTM_STATUS BTM_SetPacketTypes (BD_ADDR remote_bda, UINT16 pkt_types)
1887 {
1888     tACL_CONN   *p;
1889     BTM_TRACE_DEBUG0 ("BTM_SetPacketTypes");
1890 
1891     if ((p = btm_bda_to_acl(remote_bda)) != NULL)
1892         return(btm_set_packet_types (p, pkt_types));
1893 
1894     /* If here, no BD Addr found */
1895     return(BTM_UNKNOWN_ADDR);
1896 }
1897 
1898 
1899 /*******************************************************************************
1900 **
1901 ** Function         BTM_ReadPacketTypes
1902 **
1903 ** Description      This function is set the packet types used for a specific
1904 **                  ACL connection,
1905 **
1906 ** Returns          packet types supported for the connection, or 0 if no BD address
1907 **
1908 *******************************************************************************/
BTM_ReadPacketTypes(BD_ADDR remote_bda)1909 UINT16 BTM_ReadPacketTypes (BD_ADDR remote_bda)
1910 {
1911     tACL_CONN   *p;
1912 
1913     BTM_TRACE_DEBUG0 ("BTM_ReadPacketTypes");
1914     p = btm_bda_to_acl(remote_bda);
1915     if (p != (tACL_CONN *)NULL)
1916     {
1917         return(p->pkt_types_mask);
1918     }
1919 
1920     /* If here, no BD Addr found */
1921     return(0);
1922 }
1923 
1924 
1925 /*******************************************************************************
1926 **
1927 ** Function         BTM_ReadAclMode
1928 **
1929 ** Description      This returns the current mode for a specific
1930 **                  ACL connection.
1931 **
1932 ** Input Param      remote_bda - device address of desired ACL connection
1933 **
1934 ** Output Param     p_mode - address where the current mode is copied into.
1935 **                          BTM_ACL_MODE_NORMAL
1936 **                          BTM_ACL_MODE_HOLD
1937 **                          BTM_ACL_MODE_SNIFF
1938 **                          BTM_ACL_MODE_PARK
1939 **                          (valid only if return code is BTM_SUCCESS)
1940 **
1941 ** Returns          BTM_SUCCESS if successful,
1942 **                  BTM_UNKNOWN_ADDR if bd addr is not active or bad
1943 **
1944 *******************************************************************************/
1945 #if BTM_PWR_MGR_INCLUDED == FALSE
BTM_ReadAclMode(BD_ADDR remote_bda,UINT8 * p_mode)1946 tBTM_STATUS BTM_ReadAclMode (BD_ADDR remote_bda, UINT8 *p_mode)
1947 {
1948     tACL_CONN   *p;
1949 
1950     BTM_TRACE_API6 ("BTM_ReadAclMode: RemBdAddr: %02x%02x%02x%02x%02x%02x",
1951                     remote_bda[0], remote_bda[1], remote_bda[2],
1952                     remote_bda[3], remote_bda[4], remote_bda[5]);
1953 
1954     p = btm_bda_to_acl(remote_bda);
1955     if (p != (tACL_CONN *)NULL)
1956     {
1957         *p_mode = p->mode;
1958         return(BTM_SUCCESS);
1959     }
1960 
1961     /* If here, no BD Addr found */
1962     return(BTM_UNKNOWN_ADDR);
1963 }
1964 #endif /* BTM_PWR_MGR_INCLUDED == FALSE */
1965 
1966 /*******************************************************************************
1967 **
1968 ** Function         BTM_ReadClockOffset
1969 **
1970 ** Description      This returns the clock offset for a specific
1971 **                  ACL connection.
1972 **
1973 ** Input Param      remote_bda - device address of desired ACL connection
1974 **
1975 ** Returns          clock-offset or 0 if unknown
1976 **
1977 *******************************************************************************/
BTM_ReadClockOffset(BD_ADDR remote_bda)1978 UINT16 BTM_ReadClockOffset (BD_ADDR remote_bda)
1979 {
1980     tACL_CONN   *p;
1981 
1982     BTM_TRACE_API6 ("BTM_ReadClockOffset: RemBdAddr: %02x%02x%02x%02x%02x%02x",
1983                     remote_bda[0], remote_bda[1], remote_bda[2],
1984                     remote_bda[3], remote_bda[4], remote_bda[5]);
1985 
1986     if ( (p = btm_bda_to_acl(remote_bda)) != NULL)
1987         return(p->clock_offset);
1988 
1989     /* If here, no BD Addr found */
1990     return(0);
1991 }
1992 
1993 /*******************************************************************************
1994 **
1995 ** Function         BTM_IsAclConnectionUp
1996 **
1997 ** Description      This function is called to check if an ACL connection exists
1998 **                  to a specific remote BD Address.
1999 **
2000 ** Returns          TRUE if connection is up, else FALSE.
2001 **
2002 *******************************************************************************/
BTM_IsAclConnectionUp(BD_ADDR remote_bda)2003 BOOLEAN BTM_IsAclConnectionUp (BD_ADDR remote_bda)
2004 {
2005     tACL_CONN   *p;
2006 
2007     BTM_TRACE_API6 ("BTM_IsAclConnectionUp: RemBdAddr: %02x%02x%02x%02x%02x%02x",
2008                     remote_bda[0], remote_bda[1], remote_bda[2],
2009                     remote_bda[3], remote_bda[4], remote_bda[5]);
2010 
2011     p = btm_bda_to_acl(remote_bda);
2012     if (p != (tACL_CONN *)NULL)
2013     {
2014         return(TRUE);
2015     }
2016 
2017     /* If here, no BD Addr found */
2018     return(FALSE);
2019 }
2020 
2021 /*******************************************************************************
2022 **
2023 ** Function         BTM_GetNumAclLinks
2024 **
2025 ** Description      This function is called to count the number of
2026 **                  ACL links that are active.
2027 **
2028 ** Returns          UINT16  Number of active ACL links
2029 **
2030 *******************************************************************************/
BTM_GetNumAclLinks(void)2031 UINT16 BTM_GetNumAclLinks (void)
2032 {
2033 #if (defined(BTM_BUSY_LEVEL_CHANGE_INCLUDED) && BTM_BUSY_LEVEL_CHANGE_INCLUDED == TRUE)
2034     return(UINT16)btm_cb.num_acl;
2035 #else
2036     tACL_CONN   *p = &btm_cb.acl_db[0];
2037     UINT16      xx, yy;
2038     BTM_TRACE_DEBUG0 ("BTM_GetNumAclLinks");
2039     for (xx = yy = 0; xx < MAX_L2CAP_LINKS; xx++, p++)
2040     {
2041         if (p->in_use)
2042             yy++;
2043     }
2044 
2045     return(yy);
2046 #endif
2047 }
2048 
2049 /*******************************************************************************
2050 **
2051 ** Function         btm_get_acl_disc_reason_code
2052 **
2053 ** Description      This function is called to get the disconnection reason code
2054 **                  returned by the HCI at disconnection complete event.
2055 **
2056 ** Returns          TRUE if connection is up, else FALSE.
2057 **
2058 *******************************************************************************/
btm_get_acl_disc_reason_code(void)2059 UINT16 btm_get_acl_disc_reason_code (void)
2060 {
2061     UINT8 res = btm_cb.acl_disc_reason;
2062     BTM_TRACE_DEBUG0 ("btm_get_acl_disc_reason_code");
2063     return(res);
2064 }
2065 
2066 
2067 /*******************************************************************************
2068 **
2069 ** Function         BTM_GetHCIConnHandle
2070 **
2071 ** Description      This function is called to get the handle for an ACL connection
2072 **                  to a specific remote BD Address.
2073 **
2074 ** Returns          the handle of the connection, or 0xFFFF if none.
2075 **
2076 *******************************************************************************/
BTM_GetHCIConnHandle(BD_ADDR remote_bda)2077 UINT16 BTM_GetHCIConnHandle (BD_ADDR remote_bda)
2078 {
2079     tACL_CONN   *p;
2080     BTM_TRACE_DEBUG0 ("BTM_GetHCIConnHandle");
2081     p = btm_bda_to_acl(remote_bda);
2082     if (p != (tACL_CONN *)NULL)
2083     {
2084         return(p->hci_handle);
2085     }
2086 
2087     /* If here, no BD Addr found */
2088     return(0xFFFF);
2089 }
2090 
2091 #if BTM_PWR_MGR_INCLUDED == FALSE
2092 /*******************************************************************************
2093 **
2094 ** Function         btm_process_mode_change
2095 **
2096 ** Description      This function is called when an HCI mode change event occurs.
2097 **
2098 ** Input Parms      hci_status - status of the event (HCI_SUCCESS if no errors)
2099 **                  hci_handle - connection handle associated with the change
2100 **                  mode - HCI_MODE_ACTIVE, HCI_MODE_HOLD, HCI_MODE_SNIFF, or HCI_MODE_PARK
2101 **                  interval - number of baseband slots (meaning depends on mode)
2102 **
2103 ** Returns          void
2104 **
2105 *******************************************************************************/
btm_process_mode_change(UINT8 hci_status,UINT16 hci_handle,UINT8 mode,UINT16 interval)2106 void btm_process_mode_change (UINT8 hci_status, UINT16 hci_handle, UINT8 mode, UINT16 interval)
2107 {
2108     tACL_CONN        *p;
2109     UINT8             xx;
2110     BTM_TRACE_DEBUG0 ("btm_process_mode_change");
2111     if (hci_status != HCI_SUCCESS)
2112     {
2113         BTM_TRACE_WARNING1 ("BTM: HCI Mode Change Error Status: 0x%02x", hci_status);
2114     }
2115 
2116     /* Look up the connection by handle and set the current mode */
2117     xx = btm_handle_to_acl_index(hci_handle);
2118 
2119     /* don't assume that we can never get a bad hci_handle */
2120     if (xx >= MAX_L2CAP_LINKS)
2121         return;
2122 
2123     p = &btm_cb.acl_db[xx];
2124 
2125     /* If status is not success mode does not mean anything */
2126     if (hci_status == HCI_SUCCESS)
2127         p->mode = mode;
2128 
2129     /* If mode change was because of an active role switch or change link key */
2130     btm_cont_rswitch_or_chglinkkey(p, btm_find_dev(p->remote_addr), hci_status);
2131 }
2132 #endif /* BTM_PWR_MGR_INCLUDED == FALSE */
2133 
2134 /*******************************************************************************
2135 **
2136 ** Function         btm_process_clk_off_comp_evt
2137 **
2138 ** Description      This function is called when clock offset command completes.
2139 **
2140 ** Input Parms      hci_handle - connection handle associated with the change
2141 **                  clock offset
2142 **
2143 ** Returns          void
2144 **
2145 *******************************************************************************/
btm_process_clk_off_comp_evt(UINT16 hci_handle,UINT16 clock_offset)2146 void btm_process_clk_off_comp_evt (UINT16 hci_handle, UINT16 clock_offset)
2147 {
2148     UINT8      xx;
2149     BTM_TRACE_DEBUG0 ("btm_process_clk_off_comp_evt");
2150     /* Look up the connection by handle and set the current mode */
2151     if ((xx = btm_handle_to_acl_index(hci_handle)) < MAX_L2CAP_LINKS)
2152         btm_cb.acl_db[xx].clock_offset = clock_offset;
2153 }
2154 
2155 /*******************************************************************************
2156 **
2157 ** Function         btm_acl_role_changed
2158 **
2159 ** Description      This function is called whan a link's master/slave role change
2160 **                  event or command status event (with error) is received.
2161 **                  It updates the link control block, and calls
2162 **                  the registered callback with status and role (if registered).
2163 **
2164 ** Returns          void
2165 **
2166 *******************************************************************************/
btm_acl_role_changed(UINT8 hci_status,BD_ADDR bd_addr,UINT8 new_role)2167 void btm_acl_role_changed (UINT8 hci_status, BD_ADDR bd_addr, UINT8 new_role)
2168 {
2169     UINT8                   *p_bda = (bd_addr) ? bd_addr :
2170                                         btm_cb.devcb.switch_role_ref_data.remote_bd_addr;
2171     tACL_CONN               *p = btm_bda_to_acl(p_bda);
2172     tBTM_ROLE_SWITCH_CMPL   *p_data = &btm_cb.devcb.switch_role_ref_data;
2173     tBTM_SEC_DEV_REC        *p_dev_rec;
2174 #if (defined(BTM_BUSY_LEVEL_CHANGE_INCLUDED) && BTM_BUSY_LEVEL_CHANGE_INCLUDED == TRUE)
2175     tBTM_BL_ROLE_CHG_DATA   evt;
2176 #endif
2177 
2178     BTM_TRACE_DEBUG0 ("btm_acl_role_changed");
2179     /* Ignore any stray events */
2180     if (p == NULL)
2181     {
2182         /* it could be a failure */
2183         if (hci_status != HCI_SUCCESS)
2184             btm_acl_report_role_change(hci_status, bd_addr);
2185         return;
2186     }
2187 
2188     p_data->hci_status = hci_status;
2189 
2190     if (hci_status == HCI_SUCCESS)
2191     {
2192         p_data->role = new_role;
2193         memcpy(p_data->remote_bd_addr, p_bda, BD_ADDR_LEN);
2194 
2195         /* Update cached value */
2196         p->link_role = new_role;
2197 
2198         /* Reload LSTO: link supervision timeout is reset in the LM after a role switch */
2199         if (new_role == BTM_ROLE_MASTER)
2200         {
2201             BTM_SetLinkSuperTout (p->remote_addr, p->link_super_tout);
2202         }
2203     }
2204     else
2205     {
2206         /* so the BTM_BL_ROLE_CHG_EVT uses the old role */
2207         new_role = p->link_role;
2208     }
2209 
2210     /* Check if any SCO req is pending for role change */
2211     btm_sco_chk_pend_rolechange (p->hci_handle);
2212 
2213     /* if switching state is switching we need to turn encryption on */
2214     /* if idle, we did not change encryption */
2215     if (p->switch_role_state == BTM_ACL_SWKEY_STATE_SWITCHING)
2216     {
2217         /* Make sure there's not also a change link key going on before re-enabling */
2218         if (p->change_key_state != BTM_ACL_SWKEY_STATE_SWITCHING)
2219         {
2220             if (btsnd_hcic_set_conn_encrypt (p->hci_handle, TRUE))
2221             {
2222                 p->encrypt_state = BTM_ACL_ENCRYPT_STATE_ENCRYPT_ON;
2223                 p->switch_role_state = BTM_ACL_SWKEY_STATE_ENCRYPTION_ON;
2224                 return;
2225             }
2226         }
2227         else    /* Set the state and wait for change link key */
2228         {
2229             p->switch_role_state = BTM_ACL_SWKEY_STATE_ENCRYPTION_ON;
2230             return;
2231         }
2232     }
2233 
2234     /* Set the switch_role_state to IDLE since the reply received from HCI */
2235     /* regardless of its result either success or failed. */
2236     if (p->switch_role_state == BTM_ACL_SWKEY_STATE_IN_PROGRESS)
2237     {
2238         p->switch_role_state = BTM_ACL_SWKEY_STATE_IDLE;
2239         p->encrypt_state = BTM_ACL_ENCRYPT_STATE_IDLE;
2240     }
2241 
2242     /* if role switch complete is needed, report it now */
2243     btm_acl_report_role_change(hci_status, bd_addr);
2244 
2245 #if (defined(BTM_BUSY_LEVEL_CHANGE_INCLUDED) && BTM_BUSY_LEVEL_CHANGE_INCLUDED == TRUE)
2246     /* if role change event is registered, report it now */
2247     if (btm_cb.p_bl_changed_cb && (btm_cb.bl_evt_mask & BTM_BL_ROLE_CHG_MASK))
2248     {
2249         evt.event       = BTM_BL_ROLE_CHG_EVT;
2250         evt.new_role    = new_role;
2251         evt.p_bda       = p_bda;
2252         evt.hci_status  = hci_status;
2253         (*btm_cb.p_bl_changed_cb)((tBTM_BL_EVENT_DATA *)&evt);
2254     }
2255 
2256     BTM_TRACE_DEBUG3("Role Switch Event: new_role 0x%02x, HCI Status 0x%02x, rs_st:%d",
2257                      p_data->role, p_data->hci_status, p->switch_role_state);
2258 #endif
2259 
2260 #if BTM_DISC_DURING_RS == TRUE
2261     /* If a disconnect is pending, issue it now that role switch has completed */
2262     if ((p_dev_rec = btm_find_dev (p_bda)) != NULL)
2263     {
2264         if (p_dev_rec->rs_disc_pending == BTM_SEC_DISC_PENDING)
2265         {
2266             BTM_TRACE_WARNING0("btm_acl_role_changed -> Issuing delayed HCI_Disconnect!!!");
2267             btsnd_hcic_disconnect(p_dev_rec->hci_handle, HCI_ERR_PEER_USER);
2268         }
2269         BTM_TRACE_ERROR2("tBTM_SEC_DEV:0x%x rs_disc_pending=%d",
2270                          (UINT32)p_dev_rec, p_dev_rec->rs_disc_pending);
2271         p_dev_rec->rs_disc_pending = BTM_SEC_RS_NOT_PENDING;     /* reset flag */
2272     }
2273 
2274 #endif
2275 
2276 }
2277 
2278 #if (RFCOMM_INCLUDED==TRUE)
2279 /*******************************************************************************
2280 **
2281 ** Function         BTM_AllocateSCN
2282 **
2283 ** Description      Look through the Server Channel Numbers for a free one.
2284 **
2285 ** Returns          Allocated SCN number or 0 if none.
2286 **
2287 *******************************************************************************/
2288 
BTM_AllocateSCN(void)2289 UINT8 BTM_AllocateSCN(void)
2290 {
2291     UINT8   x;
2292     BTM_TRACE_DEBUG0 ("BTM_AllocateSCN");
2293 
2294     // stack reserves scn 1 for HFP, HSP we still do the correct way
2295     for (x = 1; x < BTM_MAX_SCN; x++)
2296     {
2297         if (!btm_cb.btm_scn[x])
2298         {
2299             btm_cb.btm_scn[x] = TRUE;
2300             return(x+1);
2301         }
2302     }
2303 
2304     return(0);     /* No free ports */
2305 }
2306 
2307 /*******************************************************************************
2308 **
2309 ** Function         BTM_TryAllocateSCN
2310 **
2311 ** Description      Try to allocate a fixed server channel
2312 **
2313 ** Returns          Returns TRUE if server channel was available
2314 **
2315 *******************************************************************************/
2316 
BTM_TryAllocateSCN(UINT8 scn)2317 BOOLEAN BTM_TryAllocateSCN(UINT8 scn)
2318 {
2319     UINT8   x;
2320 
2321     /* Make sure we don't exceed max port range.
2322      * Stack reserves scn 1 for HFP, HSP we still do the correct way.
2323      */
2324     if ( (scn>=BTM_MAX_SCN) || (scn == 1) )
2325         return FALSE;
2326 
2327     /* check if this port is available */
2328     if (!btm_cb.btm_scn[scn-1])
2329     {
2330         btm_cb.btm_scn[scn-1] = TRUE;
2331         return TRUE;
2332     }
2333 
2334     return (FALSE);     /* Port was busy */
2335 }
2336 
2337 /*******************************************************************************
2338 **
2339 ** Function         BTM_FreeSCN
2340 **
2341 ** Description      Free the specified SCN.
2342 **
2343 ** Returns          TRUE or FALSE
2344 **
2345 *******************************************************************************/
BTM_FreeSCN(UINT8 scn)2346 BOOLEAN BTM_FreeSCN(UINT8 scn)
2347 {
2348     BTM_TRACE_DEBUG0 ("BTM_FreeSCN ");
2349     if (scn <= BTM_MAX_SCN)
2350     {
2351         btm_cb.btm_scn[scn-1] = FALSE;
2352         return(TRUE);
2353     }
2354     else
2355         return(FALSE);      /* Illegal SCN passed in */
2356 }
2357 
2358 #else
2359 
2360 /* Make dummy functions for the RPC to link against */
BTM_AllocateSCN(void)2361 UINT8 BTM_AllocateSCN(void)
2362 {
2363     return(0);
2364 }
2365 
BTM_FreeSCN(UINT8 scn)2366 BOOLEAN BTM_FreeSCN(UINT8 scn)
2367 {
2368     return(FALSE);
2369 }
2370 
2371 #endif
2372 
2373 
2374 /*******************************************************************************
2375 **
2376 ** Function         btm_acl_timeout
2377 **
2378 ** Description      This function is called when a timer list entry expires.
2379 **
2380 ** Returns          void
2381 **
2382 *******************************************************************************/
btm_acl_timeout(TIMER_LIST_ENT * p_tle)2383 void btm_acl_timeout (TIMER_LIST_ENT  *p_tle)
2384 {
2385     UINT32 timer_type = p_tle->param;
2386 
2387     BTM_TRACE_DEBUG0 ("btm_acl_timeout");
2388     if (timer_type == TT_DEV_RLNKP)
2389     {
2390         tBTM_CMPL_CB            *p_cb = btm_cb.devcb.p_rlinkp_cmpl_cb;
2391         tBTM_LNK_POLICY_RESULTS  lnkpol;
2392 
2393         lnkpol.status = BTM_ERR_PROCESSING;
2394         lnkpol.settings = 0;
2395 
2396         btm_cb.devcb.p_rlinkp_cmpl_cb = NULL;
2397 
2398         if (p_cb)
2399             (*p_cb)(&lnkpol);
2400     }
2401 }
2402 
2403 /*******************************************************************************
2404 **
2405 ** Function         btm_set_packet_types
2406 **
2407 ** Description      This function sets the packet types used for a specific
2408 **                  ACL connection. It is called internally by btm_acl_created
2409 **                  or by an application/profile by BTM_SetPacketTypes.
2410 **
2411 ** Returns          status of the operation
2412 **
2413 *******************************************************************************/
btm_set_packet_types(tACL_CONN * p,UINT16 pkt_types)2414 tBTM_STATUS btm_set_packet_types (tACL_CONN *p, UINT16 pkt_types)
2415 {
2416     UINT16 temp_pkt_types;
2417     BTM_TRACE_DEBUG0 ("btm_set_packet_types");
2418     /* Save in the ACL control blocks, types that we support */
2419     temp_pkt_types = (pkt_types & BTM_ACL_SUPPORTED_PKTS_MASK &
2420                       btm_cb.btm_acl_pkt_types_supported);
2421 
2422     /* OR in any exception packet types if at least 2.0 version of spec */
2423     if (btm_cb.devcb.local_version.hci_version >= HCI_PROTO_VERSION_2_0)
2424     {
2425         temp_pkt_types |= ((pkt_types & BTM_ACL_EXCEPTION_PKTS_MASK) |
2426                            (btm_cb.btm_acl_pkt_types_supported & BTM_ACL_EXCEPTION_PKTS_MASK));
2427     }
2428     else
2429     {
2430         temp_pkt_types &= (~BTM_ACL_EXCEPTION_PKTS_MASK);
2431     }
2432 
2433     /* Exclude packet types not supported by the peer */
2434     btm_acl_chk_peer_pkt_type_support (p, &temp_pkt_types);
2435 
2436     BTM_TRACE_DEBUG1 ("SetPacketType Mask -> 0x%04x", temp_pkt_types);
2437 
2438     if (!btsnd_hcic_change_conn_type (p->hci_handle, temp_pkt_types))
2439     {
2440         return(BTM_NO_RESOURCES);
2441     }
2442 
2443     p->pkt_types_mask = temp_pkt_types;
2444 
2445     return(BTM_CMD_STARTED);
2446 }
2447 
2448 /*******************************************************************************
2449 **
2450 ** Function         btm_get_max_packet_size
2451 **
2452 ** Returns          Returns maximum packet size that can be used for current
2453 **                  connection, 0 if connection is not established
2454 **
2455 *******************************************************************************/
btm_get_max_packet_size(BD_ADDR addr)2456 UINT16 btm_get_max_packet_size (BD_ADDR addr)
2457 {
2458     tACL_CONN   *p = btm_bda_to_acl(addr);
2459     UINT16      pkt_types = 0;
2460     UINT16      pkt_size = 0;
2461     BTM_TRACE_DEBUG0 ("btm_get_max_packet_size");
2462     if (p != NULL)
2463     {
2464         pkt_types = p->pkt_types_mask;
2465     }
2466     else
2467     {
2468         /* Special case for when info for the local device is requested */
2469         if (memcmp (btm_cb.devcb.local_addr, addr, BD_ADDR_LEN) == 0)
2470         {
2471             pkt_types = btm_cb.btm_acl_pkt_types_supported;
2472         }
2473     }
2474 
2475     if (pkt_types)
2476     {
2477         if (!(pkt_types & BTM_ACL_PKT_TYPES_MASK_NO_3_DH5))
2478             pkt_size = HCI_EDR3_DH5_PACKET_SIZE;
2479         else if (!(pkt_types & BTM_ACL_PKT_TYPES_MASK_NO_2_DH5))
2480             pkt_size = HCI_EDR2_DH5_PACKET_SIZE;
2481         else if (!(pkt_types & BTM_ACL_PKT_TYPES_MASK_NO_3_DH3))
2482             pkt_size = HCI_EDR3_DH3_PACKET_SIZE;
2483         else if (pkt_types & BTM_ACL_PKT_TYPES_MASK_DH5)
2484             pkt_size = HCI_DH5_PACKET_SIZE;
2485         else if (!(pkt_types & BTM_ACL_PKT_TYPES_MASK_NO_2_DH3))
2486             pkt_size = HCI_EDR2_DH3_PACKET_SIZE;
2487         else if (pkt_types & BTM_ACL_PKT_TYPES_MASK_DM5)
2488             pkt_size = HCI_DM5_PACKET_SIZE;
2489         else if (pkt_types & BTM_ACL_PKT_TYPES_MASK_DH3)
2490             pkt_size = HCI_DH3_PACKET_SIZE;
2491         else if (pkt_types & BTM_ACL_PKT_TYPES_MASK_DM3)
2492             pkt_size = HCI_DM3_PACKET_SIZE;
2493         else if (!(pkt_types & BTM_ACL_PKT_TYPES_MASK_NO_3_DH1))
2494             pkt_size = HCI_EDR3_DH1_PACKET_SIZE;
2495         else if (!(pkt_types & BTM_ACL_PKT_TYPES_MASK_NO_2_DH1))
2496             pkt_size = HCI_EDR2_DH1_PACKET_SIZE;
2497         else if (pkt_types & BTM_ACL_PKT_TYPES_MASK_DH1)
2498             pkt_size = HCI_DH1_PACKET_SIZE;
2499         else if (pkt_types & BTM_ACL_PKT_TYPES_MASK_DM1)
2500             pkt_size = HCI_DM1_PACKET_SIZE;
2501     }
2502 
2503    return(pkt_size);
2504 }
2505 
2506 /*******************************************************************************
2507 **
2508 ** Function         BTM_ReadRemoteVersion
2509 **
2510 ** Returns          If connected report peer device info
2511 **
2512 *******************************************************************************/
BTM_ReadRemoteVersion(BD_ADDR addr,UINT8 * lmp_version,UINT16 * manufacturer,UINT16 * lmp_sub_version)2513 tBTM_STATUS BTM_ReadRemoteVersion (BD_ADDR addr, UINT8 *lmp_version,
2514                                    UINT16 *manufacturer, UINT16 *lmp_sub_version)
2515 {
2516     tACL_CONN        *p = btm_bda_to_acl(addr);
2517     BTM_TRACE_DEBUG0 ("BTM_ReadRemoteVersion");
2518     if (p == NULL)
2519         return(BTM_UNKNOWN_ADDR);
2520 
2521     if (lmp_version)
2522         *lmp_version = p->lmp_version;
2523 
2524     if (manufacturer)
2525         *manufacturer = p->manufacturer;
2526 
2527     if (lmp_sub_version)
2528         *lmp_sub_version = p->lmp_subversion;
2529 
2530     return(BTM_SUCCESS);
2531 }
2532 
2533 /*******************************************************************************
2534 **
2535 ** Function         BTM_ReadRemoteFeatures
2536 **
2537 ** Returns          pointer to the remote supported features mask (8 bytes)
2538 **
2539 *******************************************************************************/
BTM_ReadRemoteFeatures(BD_ADDR addr)2540 UINT8 *BTM_ReadRemoteFeatures (BD_ADDR addr)
2541 {
2542     tACL_CONN        *p = btm_bda_to_acl(addr);
2543     BTM_TRACE_DEBUG0 ("BTM_ReadRemoteFeatures");
2544     if (p == NULL)
2545     {
2546         return(NULL);
2547     }
2548 
2549     return(p->peer_lmp_features[HCI_EXT_FEATURES_PAGE_0]);
2550 }
2551 
2552 /*******************************************************************************
2553 **
2554 ** Function         BTM_ReadRemoteExtendedFeatures
2555 **
2556 ** Returns          pointer to the remote extended features mask (8 bytes)
2557 **                  or NULL if bad page
2558 **
2559 *******************************************************************************/
BTM_ReadRemoteExtendedFeatures(BD_ADDR addr,UINT8 page_number)2560 UINT8 *BTM_ReadRemoteExtendedFeatures (BD_ADDR addr, UINT8 page_number)
2561 {
2562     tACL_CONN        *p = btm_bda_to_acl(addr);
2563     BTM_TRACE_DEBUG0 ("BTM_ReadRemoteExtendedFeatures");
2564     if (p == NULL)
2565     {
2566         return(NULL);
2567     }
2568 
2569     if (page_number > HCI_EXT_FEATURES_PAGE_MAX)
2570     {
2571         BTM_TRACE_ERROR1("Warning: BTM_ReadRemoteExtendedFeatures page %d unknown", page_number);
2572         return NULL;
2573     }
2574 
2575     return(p->peer_lmp_features[page_number]);
2576 }
2577 
2578 /*******************************************************************************
2579 **
2580 ** Function         BTM_ReadNumberRemoteFeaturesPages
2581 **
2582 ** Returns          number of features pages read from the remote device.
2583 **
2584 *******************************************************************************/
BTM_ReadNumberRemoteFeaturesPages(BD_ADDR addr)2585 UINT8 BTM_ReadNumberRemoteFeaturesPages (BD_ADDR addr)
2586 {
2587     tACL_CONN        *p = btm_bda_to_acl(addr);
2588     BTM_TRACE_DEBUG0 ("BTM_ReadNumberRemoteFeaturesPages");
2589     if (p == NULL)
2590     {
2591         return(0);
2592     }
2593 
2594     return(p->num_read_pages);
2595 }
2596 
2597 /*******************************************************************************
2598 **
2599 ** Function         BTM_ReadAllRemoteFeatures
2600 **
2601 ** Returns          pointer to all features of the remote (24 bytes).
2602 **
2603 *******************************************************************************/
BTM_ReadAllRemoteFeatures(BD_ADDR addr)2604 UINT8 *BTM_ReadAllRemoteFeatures (BD_ADDR addr)
2605 {
2606     tACL_CONN        *p = btm_bda_to_acl(addr);
2607     BTM_TRACE_DEBUG0 ("BTM_ReadAllRemoteFeatures");
2608     if (p == NULL)
2609     {
2610         return(NULL);
2611     }
2612 
2613     return(p->peer_lmp_features[HCI_EXT_FEATURES_PAGE_0]);
2614 }
2615 
2616 /*******************************************************************************
2617 **
2618 ** Function         BTM_RegBusyLevelNotif
2619 **
2620 ** Description      This function is called to register a callback to receive
2621 **                  busy level change events.
2622 **
2623 ** Returns          BTM_SUCCESS if successfully registered, otherwise error
2624 **
2625 *******************************************************************************/
2626 #if (defined(BTM_BUSY_LEVEL_CHANGE_INCLUDED) && BTM_BUSY_LEVEL_CHANGE_INCLUDED == TRUE)
BTM_RegBusyLevelNotif(tBTM_BL_CHANGE_CB * p_cb,UINT8 * p_level,tBTM_BL_EVENT_MASK evt_mask)2627 tBTM_STATUS BTM_RegBusyLevelNotif (tBTM_BL_CHANGE_CB *p_cb, UINT8 *p_level,
2628                                    tBTM_BL_EVENT_MASK evt_mask)
2629 {
2630     BTM_TRACE_DEBUG0 ("BTM_RegBusyLevelNotif");
2631     if (p_level)
2632         *p_level = btm_cb.busy_level;
2633 
2634     btm_cb.bl_evt_mask = evt_mask;
2635 
2636     if (!p_cb)
2637         btm_cb.p_bl_changed_cb = NULL;
2638     else if (btm_cb.p_bl_changed_cb)
2639         return(BTM_BUSY);
2640     else
2641         btm_cb.p_bl_changed_cb = p_cb;
2642 
2643     return(BTM_SUCCESS);
2644 }
2645 #else
2646 /*******************************************************************************
2647 **
2648 ** Function         BTM_AclRegisterForChanges
2649 **
2650 ** Returns          This function is called to register a callback for when the
2651 **                  ACL database changes, i.e. new entry or entry deleted.
2652 **
2653 *******************************************************************************/
BTM_AclRegisterForChanges(tBTM_ACL_DB_CHANGE_CB * p_cb)2654 tBTM_STATUS BTM_AclRegisterForChanges (tBTM_ACL_DB_CHANGE_CB *p_cb)
2655 {
2656     BTM_TRACE_DEBUG0 ("BTM_AclRegisterForChanges");
2657     if (!p_cb)
2658         btm_cb.p_acl_changed_cb = NULL;
2659     else if (btm_cb.p_acl_changed_cb)
2660         return(BTM_BUSY);
2661     else
2662         btm_cb.p_acl_changed_cb = p_cb;
2663 
2664     return(BTM_SUCCESS);
2665 }
2666 #endif
2667 
2668 /*******************************************************************************
2669 **
2670 ** Function         BTM_SetQoS
2671 **
2672 ** Description      This function is called to setup QoS
2673 **
2674 ** Returns          status of the operation
2675 **
2676 *******************************************************************************/
BTM_SetQoS(BD_ADDR bd,FLOW_SPEC * p_flow,tBTM_CMPL_CB * p_cb)2677 tBTM_STATUS BTM_SetQoS (BD_ADDR bd, FLOW_SPEC *p_flow, tBTM_CMPL_CB *p_cb)
2678 {
2679     tACL_CONN   *p = &btm_cb.acl_db[0];
2680 
2681     BTM_TRACE_API6 ("BTM_SetQoS: BdAddr: %02x%02x%02x%02x%02x%02x",
2682                     bd[0], bd[1], bd[2],
2683                     bd[3], bd[4], bd[5]);
2684 
2685     /* If someone already waiting on the version, do not allow another */
2686     if (btm_cb.devcb.p_qossu_cmpl_cb)
2687         return(BTM_BUSY);
2688 
2689     if ( (p = btm_bda_to_acl(bd)) != NULL)
2690     {
2691         btu_start_timer (&btm_cb.devcb.qossu_timer, BTU_TTYPE_BTM_ACL, BTM_DEV_REPLY_TIMEOUT);
2692         btm_cb.devcb.p_qossu_cmpl_cb = p_cb;
2693 
2694         if (!btsnd_hcic_qos_setup (p->hci_handle, p_flow->qos_flags, p_flow->service_type,
2695                                    p_flow->token_rate, p_flow->peak_bandwidth,
2696                                    p_flow->latency,p_flow->delay_variation))
2697         {
2698             btm_cb.devcb.p_qossu_cmpl_cb = NULL;
2699             btu_stop_timer(&btm_cb.devcb.qossu_timer);
2700             return(BTM_NO_RESOURCES);
2701         }
2702         else
2703             return(BTM_CMD_STARTED);
2704     }
2705 
2706     /* If here, no BD Addr found */
2707     return(BTM_UNKNOWN_ADDR);
2708 }
2709 
2710 /*******************************************************************************
2711 **
2712 ** Function         btm_qos_setup_complete
2713 **
2714 ** Description      This function is called when the command complete message
2715 **                  is received from the HCI for the qos setup request.
2716 **
2717 ** Returns          void
2718 **
2719 *******************************************************************************/
btm_qos_setup_complete(UINT8 status,UINT16 handle,FLOW_SPEC * p_flow)2720 void btm_qos_setup_complete (UINT8 status, UINT16 handle, FLOW_SPEC *p_flow)
2721 {
2722     tBTM_CMPL_CB            *p_cb = btm_cb.devcb.p_qossu_cmpl_cb;
2723     tBTM_QOS_SETUP_CMPL     qossu;
2724     BTM_TRACE_DEBUG0 ("btm_qos_setup_complete");
2725     btu_stop_timer (&btm_cb.devcb.qossu_timer);
2726 
2727     btm_cb.devcb.p_qossu_cmpl_cb = NULL;
2728 
2729     if (p_cb)
2730     {
2731         memset(&qossu, 0, sizeof(tBTM_QOS_SETUP_CMPL));
2732         qossu.status = status;
2733         qossu.handle = handle;
2734         if (p_flow != NULL)
2735         {
2736             qossu.flow.qos_flags = p_flow->qos_flags;
2737             qossu.flow.service_type = p_flow->service_type;
2738             qossu.flow.token_rate = p_flow->token_rate;
2739             qossu.flow.peak_bandwidth = p_flow->peak_bandwidth;
2740             qossu.flow.latency = p_flow->latency;
2741             qossu.flow.delay_variation = p_flow->delay_variation;
2742         }
2743         BTM_TRACE_DEBUG1 ("BTM: p_flow->delay_variation: 0x%02x",
2744                           qossu.flow.delay_variation);
2745         (*p_cb)(&qossu);
2746     }
2747 }
2748 
2749 
2750 /*******************************************************************************
2751 **
2752 ** Function         BTM_ReadRSSI
2753 **
2754 ** Description      This function is called to read the link policy settings.
2755 **                  The address of link policy results are returned in the callback.
2756 **                  (tBTM_RSSI_RESULTS)
2757 **
2758 ** Returns          BTM_CMD_STARTED if successfully initiated or error code
2759 **
2760 *******************************************************************************/
BTM_ReadRSSI(BD_ADDR remote_bda,tBTM_CMPL_CB * p_cb)2761 tBTM_STATUS BTM_ReadRSSI (BD_ADDR remote_bda, tBTM_CMPL_CB *p_cb)
2762 {
2763     tACL_CONN   *p;
2764 
2765     BTM_TRACE_API6 ("BTM_ReadRSSI: RemBdAddr: %02x%02x%02x%02x%02x%02x",
2766                     remote_bda[0], remote_bda[1], remote_bda[2],
2767                     remote_bda[3], remote_bda[4], remote_bda[5]);
2768 
2769     /* If someone already waiting on the version, do not allow another */
2770     if (btm_cb.devcb.p_rssi_cmpl_cb)
2771         return(BTM_BUSY);
2772 
2773     p = btm_bda_to_acl(remote_bda);
2774     if (p != (tACL_CONN *)NULL)
2775     {
2776         btu_start_timer (&btm_cb.devcb.rssi_timer, BTU_TTYPE_BTM_ACL,
2777                          BTM_DEV_REPLY_TIMEOUT);
2778 
2779         btm_cb.devcb.p_rssi_cmpl_cb = p_cb;
2780 
2781         if (!btsnd_hcic_read_rssi (p->hci_handle))
2782         {
2783             btm_cb.devcb.p_rssi_cmpl_cb = NULL;
2784             btu_stop_timer (&btm_cb.devcb.rssi_timer);
2785             return(BTM_NO_RESOURCES);
2786         }
2787         else
2788             return(BTM_CMD_STARTED);
2789     }
2790 
2791     /* If here, no BD Addr found */
2792     return(BTM_UNKNOWN_ADDR);
2793 }
2794 
2795 /*******************************************************************************
2796 **
2797 ** Function         BTM_ReadLinkQuality
2798 **
2799 ** Description      This function is called to read the link qulaity.
2800 **                  The value of the link quality is returned in the callback.
2801 **                  (tBTM_LINK_QUALITY_RESULTS)
2802 **
2803 ** Returns          BTM_CMD_STARTED if successfully initiated or error code
2804 **
2805 *******************************************************************************/
BTM_ReadLinkQuality(BD_ADDR remote_bda,tBTM_CMPL_CB * p_cb)2806 tBTM_STATUS BTM_ReadLinkQuality (BD_ADDR remote_bda, tBTM_CMPL_CB *p_cb)
2807 {
2808     tACL_CONN   *p;
2809 
2810     BTM_TRACE_API6 ("BTM_ReadLinkQuality: RemBdAddr: %02x%02x%02x%02x%02x%02x",
2811                     remote_bda[0], remote_bda[1], remote_bda[2],
2812                     remote_bda[3], remote_bda[4], remote_bda[5]);
2813 
2814     /* If someone already waiting on the version, do not allow another */
2815     if (btm_cb.devcb.p_lnk_qual_cmpl_cb)
2816         return(BTM_BUSY);
2817 
2818     p = btm_bda_to_acl(remote_bda);
2819     if (p != (tACL_CONN *)NULL)
2820     {
2821         btu_start_timer (&btm_cb.devcb.lnk_quality_timer, BTU_TTYPE_BTM_ACL,
2822                          BTM_DEV_REPLY_TIMEOUT);
2823         btm_cb.devcb.p_lnk_qual_cmpl_cb = p_cb;
2824 
2825         if (!btsnd_hcic_get_link_quality (p->hci_handle))
2826         {
2827             btu_stop_timer (&btm_cb.devcb.lnk_quality_timer);
2828             btm_cb.devcb.p_lnk_qual_cmpl_cb = NULL;
2829             return(BTM_NO_RESOURCES);
2830         }
2831         else
2832             return(BTM_CMD_STARTED);
2833     }
2834 
2835     /* If here, no BD Addr found */
2836     return(BTM_UNKNOWN_ADDR);
2837 }
2838 
2839 /*******************************************************************************
2840 **
2841 ** Function         BTM_ReadTxPower
2842 **
2843 ** Description      This function is called to read the current
2844 **                  TX power of the connection. The tx power level results
2845 **                  are returned in the callback.
2846 **                  (tBTM_RSSI_RESULTS)
2847 **
2848 ** Returns          BTM_CMD_STARTED if successfully initiated or error code
2849 **
2850 *******************************************************************************/
BTM_ReadTxPower(BD_ADDR remote_bda,tBTM_CMPL_CB * p_cb)2851 tBTM_STATUS BTM_ReadTxPower (BD_ADDR remote_bda, tBTM_CMPL_CB *p_cb)
2852 {
2853     tACL_CONN   *p;
2854     BOOLEAN     ret;
2855 #define BTM_READ_RSSI_TYPE_CUR  0x00
2856 #define BTM_READ_RSSI_TYPE_MAX  0X01
2857 
2858     BTM_TRACE_API6 ("BTM_ReadTxPower: RemBdAddr: %02x%02x%02x%02x%02x%02x",
2859                     remote_bda[0], remote_bda[1], remote_bda[2],
2860                     remote_bda[3], remote_bda[4], remote_bda[5]);
2861 
2862     /* If someone already waiting on the version, do not allow another */
2863     if (btm_cb.devcb.p_tx_power_cmpl_cb)
2864         return(BTM_BUSY);
2865 
2866     p = btm_bda_to_acl(remote_bda);
2867     if (p != (tACL_CONN *)NULL)
2868     {
2869         btu_start_timer (&btm_cb.devcb.tx_power_timer, BTU_TTYPE_BTM_ACL,
2870                          BTM_DEV_REPLY_TIMEOUT);
2871 
2872         btm_cb.devcb.p_tx_power_cmpl_cb = p_cb;
2873 
2874 #if BLE_INCLUDED == TRUE
2875         if (p->is_le_link)
2876         {
2877             memcpy(btm_cb.devcb.read_tx_pwr_addr, remote_bda, BD_ADDR_LEN);
2878             ret = btsnd_hcic_ble_read_adv_chnl_tx_power();
2879         }
2880         else
2881 #endif
2882         {
2883             ret = btsnd_hcic_read_tx_power (p->hci_handle, BTM_READ_RSSI_TYPE_CUR);
2884         }
2885         if (!ret)
2886         {
2887             btm_cb.devcb.p_tx_power_cmpl_cb = NULL;
2888             btu_stop_timer (&btm_cb.devcb.tx_power_timer);
2889             return(BTM_NO_RESOURCES);
2890         }
2891         else
2892             return(BTM_CMD_STARTED);
2893     }
2894 
2895     /* If here, no BD Addr found */
2896     return (BTM_UNKNOWN_ADDR);
2897 }
2898 /*******************************************************************************
2899 **
2900 ** Function         btm_read_tx_power_complete
2901 **
2902 ** Description      This function is called when the command complete message
2903 **                  is received from the HCI for the read tx power request.
2904 **
2905 ** Returns          void
2906 **
2907 *******************************************************************************/
btm_read_tx_power_complete(UINT8 * p,BOOLEAN is_ble)2908 void btm_read_tx_power_complete (UINT8 *p, BOOLEAN is_ble)
2909 {
2910     tBTM_CMPL_CB            *p_cb = btm_cb.devcb.p_tx_power_cmpl_cb;
2911     tBTM_TX_POWER_RESULTS   results;
2912     UINT16                   handle;
2913     tACL_CONN               *p_acl_cb = &btm_cb.acl_db[0];
2914     UINT16                   index;
2915     BTM_TRACE_DEBUG0 ("btm_read_tx_power_complete");
2916     btu_stop_timer (&btm_cb.devcb.tx_power_timer);
2917 
2918     /* If there was a callback registered for read rssi, call it */
2919     btm_cb.devcb.p_tx_power_cmpl_cb = NULL;
2920 
2921     if (p_cb)
2922     {
2923         STREAM_TO_UINT8  (results.hci_status, p);
2924 
2925         if (results.hci_status == HCI_SUCCESS)
2926         {
2927             results.status = BTM_SUCCESS;
2928 
2929             if (!is_ble)
2930             {
2931                 STREAM_TO_UINT16 (handle, p);
2932                 STREAM_TO_UINT8 (results.tx_power, p);
2933 
2934                 /* Search through the list of active channels for the correct BD Addr */
2935                 for (index = 0; index < MAX_L2CAP_LINKS; index++, p_acl_cb++)
2936                 {
2937                     if ((p_acl_cb->in_use) && (handle == p_acl_cb->hci_handle))
2938                     {
2939                         memcpy (results.rem_bda, p_acl_cb->remote_addr, BD_ADDR_LEN);
2940                         break;
2941                     }
2942                 }
2943             }
2944 #if BLE_INCLUDED == TRUE
2945             else
2946             {
2947                 STREAM_TO_UINT8 (results.tx_power, p);
2948                 memcpy(results.rem_bda, btm_cb.devcb.read_tx_pwr_addr, BD_ADDR_LEN);
2949             }
2950 #endif
2951             BTM_TRACE_DEBUG2 ("BTM TX power Complete: tx_power %d, hci status 0x%02x",
2952                                   results.tx_power, results.hci_status);
2953         }
2954         else
2955             results.status = BTM_ERR_PROCESSING;
2956 
2957         (*p_cb)(&results);
2958     }
2959 }
2960 
2961 /*******************************************************************************
2962 **
2963 ** Function         btm_read_rssi_complete
2964 **
2965 ** Description      This function is called when the command complete message
2966 **                  is received from the HCI for the read rssi request.
2967 **
2968 ** Returns          void
2969 **
2970 *******************************************************************************/
btm_read_rssi_complete(UINT8 * p)2971 void btm_read_rssi_complete (UINT8 *p)
2972 {
2973     tBTM_CMPL_CB            *p_cb = btm_cb.devcb.p_rssi_cmpl_cb;
2974     tBTM_RSSI_RESULTS        results;
2975     UINT16                   handle;
2976     tACL_CONN               *p_acl_cb = &btm_cb.acl_db[0];
2977     UINT16                   index;
2978     BTM_TRACE_DEBUG0 ("btm_read_rssi_complete");
2979     btu_stop_timer (&btm_cb.devcb.rssi_timer);
2980 
2981     /* If there was a callback registered for read rssi, call it */
2982     btm_cb.devcb.p_rssi_cmpl_cb = NULL;
2983 
2984     if (p_cb)
2985     {
2986         STREAM_TO_UINT8  (results.hci_status, p);
2987 
2988         if (results.hci_status == HCI_SUCCESS)
2989         {
2990             results.status = BTM_SUCCESS;
2991 
2992             STREAM_TO_UINT16 (handle, p);
2993 
2994             STREAM_TO_UINT8 (results.rssi, p);
2995             BTM_TRACE_DEBUG2 ("BTM RSSI Complete: rssi %d, hci status 0x%02x",
2996                               results.rssi, results.hci_status);
2997 
2998             /* Search through the list of active channels for the correct BD Addr */
2999             for (index = 0; index < MAX_L2CAP_LINKS; index++, p_acl_cb++)
3000             {
3001                 if ((p_acl_cb->in_use) && (handle == p_acl_cb->hci_handle))
3002                 {
3003                     memcpy (results.rem_bda, p_acl_cb->remote_addr, BD_ADDR_LEN);
3004                     break;
3005                 }
3006             }
3007         }
3008         else
3009             results.status = BTM_ERR_PROCESSING;
3010 
3011         (*p_cb)(&results);
3012     }
3013 }
3014 
3015 /*******************************************************************************
3016 **
3017 ** Function         btm_read_link_quality_complete
3018 **
3019 ** Description      This function is called when the command complete message
3020 **                  is received from the HCI for the read link quality.
3021 **
3022 ** Returns          void
3023 **
3024 *******************************************************************************/
btm_read_link_quality_complete(UINT8 * p)3025 void btm_read_link_quality_complete (UINT8 *p)
3026 {
3027     tBTM_CMPL_CB            *p_cb = btm_cb.devcb.p_lnk_qual_cmpl_cb;
3028     tBTM_LINK_QUALITY_RESULTS results;
3029     UINT16                   handle;
3030     tACL_CONN               *p_acl_cb = &btm_cb.acl_db[0];
3031     UINT16                   index;
3032     BTM_TRACE_DEBUG0 ("btm_read_link_quality_complete");
3033     btu_stop_timer (&btm_cb.devcb.lnk_quality_timer);
3034 
3035     /* If there was a callback registered for read rssi, call it */
3036     btm_cb.devcb.p_lnk_qual_cmpl_cb = NULL;
3037 
3038     if (p_cb)
3039     {
3040         STREAM_TO_UINT8  (results.hci_status, p);
3041 
3042         if (results.hci_status == HCI_SUCCESS)
3043         {
3044             results.status = BTM_SUCCESS;
3045 
3046             STREAM_TO_UINT16 (handle, p);
3047 
3048             STREAM_TO_UINT8 (results.link_quality, p);
3049             BTM_TRACE_DEBUG2 ("BTM Link Quality Complete: Link Quality %d, hci status 0x%02x",
3050                               results.link_quality, results.hci_status);
3051 
3052             /* Search through the list of active channels for the correct BD Addr */
3053             for (index = 0; index < MAX_L2CAP_LINKS; index++, p_acl_cb++)
3054             {
3055                 if ((p_acl_cb->in_use) && (handle == p_acl_cb->hci_handle))
3056                 {
3057                     memcpy (results.rem_bda, p_acl_cb->remote_addr, BD_ADDR_LEN);
3058                     break;
3059                 }
3060             }
3061         }
3062         else
3063             results.status = BTM_ERR_PROCESSING;
3064 
3065         (*p_cb)(&results);
3066     }
3067 }
3068 
3069 /*******************************************************************************
3070 **
3071 ** Function         btm_remove_acl
3072 **
3073 ** Description      This function is called to disconnect an ACL connection
3074 **
3075 ** Returns          BTM_SUCCESS if successfully initiated, otherwise BTM_NO_RESOURCES.
3076 **
3077 *******************************************************************************/
btm_remove_acl(BD_ADDR bd_addr)3078 tBTM_STATUS btm_remove_acl (BD_ADDR bd_addr)
3079 {
3080     UINT16  hci_handle = BTM_GetHCIConnHandle(bd_addr);
3081     tBTM_STATUS status = BTM_SUCCESS;
3082 
3083     BTM_TRACE_DEBUG0 ("btm_remove_acl");
3084 #if BTM_DISC_DURING_RS == TRUE
3085     tBTM_SEC_DEV_REC  *p_dev_rec = btm_find_dev (bd_addr);
3086 
3087     /* Role Switch is pending, postpone until completed */
3088     if (p_dev_rec && (p_dev_rec->rs_disc_pending == BTM_SEC_RS_PENDING))
3089     {
3090         p_dev_rec->rs_disc_pending = BTM_SEC_DISC_PENDING;
3091     }
3092     else    /* otherwise can disconnect right away */
3093 #endif
3094     {
3095         if (hci_handle != 0xFFFF)
3096         {
3097             if (!btsnd_hcic_disconnect (hci_handle, HCI_ERR_PEER_USER))
3098                 status = BTM_NO_RESOURCES;
3099         }
3100         else
3101             status = BTM_UNKNOWN_ADDR;
3102     }
3103 
3104     return status;
3105 }
3106 
3107 
3108 /*******************************************************************************
3109 **
3110 ** Function         BTM_SetTraceLevel
3111 **
3112 ** Description      This function sets the trace level for BTM.  If called with
3113 **                  a value of 0xFF, it simply returns the current trace level.
3114 **
3115 ** Returns          The new or current trace level
3116 **
3117 *******************************************************************************/
BTM_SetTraceLevel(UINT8 new_level)3118 UINT8 BTM_SetTraceLevel (UINT8 new_level)
3119 {
3120     BTM_TRACE_DEBUG0 ("BTM_SetTraceLevel");
3121     if (new_level != 0xFF)
3122         btm_cb.trace_level = new_level;
3123 
3124     return(btm_cb.trace_level);
3125 }
3126 
3127 /*******************************************************************************
3128 **
3129 ** Function         btm_cont_rswitch_or_chglinkkey
3130 **
3131 ** Description      This function is called to continue processing an active
3132 **                  role switch or change of link key procedure.  It first
3133 **                  disables encryption if enabled and EPR is not supported
3134 **
3135 ** Returns          void
3136 **
3137 *******************************************************************************/
btm_cont_rswitch_or_chglinkkey(tACL_CONN * p,tBTM_SEC_DEV_REC * p_dev_rec,UINT8 hci_status)3138 void btm_cont_rswitch_or_chglinkkey (tACL_CONN *p, tBTM_SEC_DEV_REC *p_dev_rec,
3139                                      UINT8 hci_status)
3140 {
3141     BOOLEAN sw_ok = TRUE;
3142     BOOLEAN chlk_ok = TRUE;
3143     BTM_TRACE_DEBUG0 ("btm_cont_rswitch_or_chglinkkey ");
3144     /* Check to see if encryption needs to be turned off if pending
3145        change of link key or role switch */
3146     if (p->switch_role_state == BTM_ACL_SWKEY_STATE_MODE_CHANGE ||
3147         p->change_key_state == BTM_ACL_SWKEY_STATE_MODE_CHANGE)
3148     {
3149         /* Must turn off Encryption first if necessary */
3150         /* Some devices do not support switch or change of link key while encryption is on */
3151         if (p_dev_rec != NULL && ((p_dev_rec->sec_flags & BTM_SEC_ENCRYPTED) != 0)
3152             && !BTM_EPR_AVAILABLE(p))
3153         {
3154             if (btsnd_hcic_set_conn_encrypt (p->hci_handle, FALSE))
3155             {
3156                 p->encrypt_state = BTM_ACL_ENCRYPT_STATE_ENCRYPT_OFF;
3157                 if (p->switch_role_state == BTM_ACL_SWKEY_STATE_MODE_CHANGE)
3158                     p->switch_role_state = BTM_ACL_SWKEY_STATE_ENCRYPTION_OFF;
3159 
3160                 if (p->change_key_state == BTM_ACL_SWKEY_STATE_MODE_CHANGE)
3161                     p->change_key_state = BTM_ACL_SWKEY_STATE_ENCRYPTION_OFF;
3162             }
3163             else
3164             {
3165                 /* Error occurred; set states back to Idle */
3166                 if (p->switch_role_state == BTM_ACL_SWKEY_STATE_MODE_CHANGE)
3167                     sw_ok = FALSE;
3168 
3169                 if (p->change_key_state == BTM_ACL_SWKEY_STATE_MODE_CHANGE)
3170                     chlk_ok = FALSE;
3171             }
3172         }
3173         else    /* Encryption not used or EPR supported, continue with switch
3174                    and/or change of link key */
3175         {
3176             if (p->switch_role_state == BTM_ACL_SWKEY_STATE_MODE_CHANGE)
3177             {
3178                 p->switch_role_state = BTM_ACL_SWKEY_STATE_IN_PROGRESS;
3179 #if BTM_DISC_DURING_RS == TRUE
3180                 if (p_dev_rec)
3181                     p_dev_rec->rs_disc_pending = BTM_SEC_RS_PENDING;
3182 #endif
3183                 sw_ok = btsnd_hcic_switch_role (p->remote_addr, (UINT8)!p->link_role);
3184             }
3185 
3186             if (p->change_key_state == BTM_ACL_SWKEY_STATE_MODE_CHANGE)
3187             {
3188                 p->switch_role_state = BTM_ACL_SWKEY_STATE_IN_PROGRESS;
3189                 chlk_ok = btsnd_hcic_change_link_key (p->hci_handle);
3190             }
3191         }
3192 
3193         if (!sw_ok)
3194         {
3195             p->switch_role_state = BTM_ACL_SWKEY_STATE_IDLE;
3196             btm_acl_report_role_change(hci_status, p->remote_addr);
3197         }
3198 
3199         if (!chlk_ok)
3200         {
3201             p->change_key_state = BTM_ACL_SWKEY_STATE_IDLE;
3202             if (btm_cb.devcb.p_chg_link_key_cb)
3203             {
3204                 btm_cb.devcb.chg_link_key_ref_data.hci_status = hci_status;
3205                 (*btm_cb.devcb.p_chg_link_key_cb)(&btm_cb.devcb.chg_link_key_ref_data);
3206                 btm_cb.devcb.p_chg_link_key_cb = NULL;
3207             }
3208         }
3209     }
3210 }
3211 
3212 /*******************************************************************************
3213 **
3214 ** Function         btm_acl_resubmit_page
3215 **
3216 ** Description      send pending page request
3217 **
3218 *******************************************************************************/
btm_acl_resubmit_page(void)3219 void btm_acl_resubmit_page (void)
3220 {
3221     tBTM_SEC_DEV_REC *p_dev_rec;
3222     BT_HDR  *p_buf;
3223     UINT8   *pp;
3224     BD_ADDR bda;
3225     BTM_TRACE_DEBUG0 ("btm_acl_resubmit_page");
3226     /* If there were other page request schedule can start the next one */
3227     if ((p_buf = (BT_HDR *)GKI_dequeue (&btm_cb.page_queue)) != NULL)
3228     {
3229         /* skip 3 (2 bytes opcode and 1 byte len) to get to the bd_addr
3230          * for both create_conn and rmt_name */
3231         pp = (UINT8 *)(p_buf + 1) + p_buf->offset + 3;
3232 
3233         STREAM_TO_BDADDR (bda, pp);
3234 
3235         p_dev_rec = btm_find_or_alloc_dev (bda);
3236 
3237         memcpy (btm_cb.connecting_bda, p_dev_rec->bd_addr,   BD_ADDR_LEN);
3238         memcpy (btm_cb.connecting_dc,  p_dev_rec->dev_class, DEV_CLASS_LEN);
3239 
3240         btu_hcif_send_cmd (LOCAL_BR_EDR_CONTROLLER_ID, p_buf);
3241     }
3242     else
3243         btm_cb.paging = FALSE;
3244 }
3245 
3246 /*******************************************************************************
3247 **
3248 ** Function         btm_acl_reset_paging
3249 **
3250 ** Description      set paging to FALSE and free the page queue - called at hci_reset
3251 **
3252 *******************************************************************************/
btm_acl_reset_paging(void)3253 void  btm_acl_reset_paging (void)
3254 {
3255     BT_HDR *p;
3256     BTM_TRACE_DEBUG0 ("btm_acl_reset_paging");
3257     /* If we sent reset we are definitely not paging any more */
3258     while ((p = (BT_HDR *)GKI_dequeue(&btm_cb.page_queue)) != NULL)
3259         GKI_freebuf (p);
3260 
3261     btm_cb.paging = FALSE;
3262 }
3263 
3264 /*******************************************************************************
3265 **
3266 ** Function         btm_acl_set_discing
3267 **
3268 ** Description      set discing to the given value
3269 **
3270 *******************************************************************************/
btm_acl_set_discing(BOOLEAN discing)3271 void  btm_acl_set_discing (BOOLEAN discing)
3272 {
3273     BTM_TRACE_DEBUG0 ("btm_acl_set_discing");
3274     btm_cb.discing = discing;
3275 }
3276 
3277 /*******************************************************************************
3278 **
3279 ** Function         btm_acl_paging
3280 **
3281 ** Description      send a paging command or queue it in btm_cb
3282 **
3283 *******************************************************************************/
btm_acl_paging(BT_HDR * p,BD_ADDR bda)3284 void  btm_acl_paging (BT_HDR *p, BD_ADDR bda)
3285 {
3286     tBTM_SEC_DEV_REC *p_dev_rec;
3287 
3288     BTM_TRACE_DEBUG4 ("btm_acl_paging discing:%d, paging:%d BDA: %06x%06x",
3289                       btm_cb.discing, btm_cb.paging,
3290                       (bda[0]<<16) + (bda[1]<<8) + bda[2], (bda[3]<<16) + (bda[4] << 8) + bda[5]);
3291     if (btm_cb.discing)
3292     {
3293         btm_cb.paging = TRUE;
3294         GKI_enqueue (&btm_cb.page_queue, p);
3295     }
3296     else
3297     {
3298         if (!BTM_ACL_IS_CONNECTED (bda))
3299         {
3300             BTM_TRACE_DEBUG2 ("connecting_bda: %06x%06x",
3301                               (btm_cb.connecting_bda[0]<<16) + (btm_cb.connecting_bda[1]<<8) +
3302                                btm_cb.connecting_bda[2],
3303                               (btm_cb.connecting_bda[3]<<16) + (btm_cb.connecting_bda[4] << 8) +
3304                                btm_cb.connecting_bda[5]);
3305             if (btm_cb.paging &&
3306                 memcmp (bda, btm_cb.connecting_bda, BD_ADDR_LEN) != 0)
3307             {
3308                 GKI_enqueue (&btm_cb.page_queue, p);
3309             }
3310             else
3311             {
3312                 p_dev_rec = btm_find_or_alloc_dev (bda);
3313                 memcpy (btm_cb.connecting_bda, p_dev_rec->bd_addr,   BD_ADDR_LEN);
3314                 memcpy (btm_cb.connecting_dc,  p_dev_rec->dev_class, DEV_CLASS_LEN);
3315 
3316                 btu_hcif_send_cmd (LOCAL_BR_EDR_CONTROLLER_ID, p);
3317             }
3318 
3319             btm_cb.paging = TRUE;
3320         }
3321         else /* ACL is already up */
3322         {
3323             btu_hcif_send_cmd (LOCAL_BR_EDR_CONTROLLER_ID, p);
3324         }
3325     }
3326 }
3327 
3328 /*******************************************************************************
3329 **
3330 ** Function         btm_acl_notif_conn_collision
3331 **
3332 ** Description      Send connection collision event to upper layer if registered
3333 **
3334 ** Returns          TRUE if sent out to upper layer,
3335 **                  FALSE if BTM_BUSY_LEVEL_CHANGE_INCLUDED == FALSE, or no one
3336 **                  needs the notification.
3337 **
3338 **          Note: Function only used if BTM_BUSY_LEVEL_CHANGE_INCLUDED == TRUE
3339 **
3340 *******************************************************************************/
btm_acl_notif_conn_collision(BD_ADDR bda)3341 BOOLEAN  btm_acl_notif_conn_collision (BD_ADDR bda)
3342 {
3343 #if (BTM_BUSY_LEVEL_CHANGE_INCLUDED == TRUE)
3344     tBTM_BL_EVENT_DATA  evt_data;
3345 
3346     /* Report possible collision to the upper layer. */
3347     if (btm_cb.p_bl_changed_cb)
3348     {
3349         BTM_TRACE_DEBUG6 ("btm_acl_notif_conn_collision: RemBdAddr: %02x%02x%02x%02x%02x%02x",
3350                           bda[0], bda[1], bda[2], bda[3], bda[4], bda[5]);
3351 
3352         evt_data.event = BTM_BL_COLLISION_EVT;
3353         evt_data.conn.p_bda = bda;
3354         (*btm_cb.p_bl_changed_cb)(&evt_data);
3355         return TRUE;
3356     }
3357     else
3358         return FALSE;
3359 #else
3360     return FALSE;
3361 #endif
3362 }
3363 
3364 
3365 /*******************************************************************************
3366 **
3367 ** Function         btm_acl_chk_peer_pkt_type_support
3368 **
3369 ** Description      Check if peer supports requested packets
3370 **
3371 *******************************************************************************/
btm_acl_chk_peer_pkt_type_support(tACL_CONN * p,UINT16 * p_pkt_type)3372 void btm_acl_chk_peer_pkt_type_support (tACL_CONN *p, UINT16 *p_pkt_type)
3373 {
3374     /* 3 and 5 slot packets? */
3375     if (!HCI_3_SLOT_PACKETS_SUPPORTED(p->peer_lmp_features[HCI_EXT_FEATURES_PAGE_0]))
3376         *p_pkt_type &= ~(BTM_ACL_PKT_TYPES_MASK_DH3 +BTM_ACL_PKT_TYPES_MASK_DM3);
3377 
3378     if (!HCI_5_SLOT_PACKETS_SUPPORTED(p->peer_lmp_features[HCI_EXT_FEATURES_PAGE_0]))
3379         *p_pkt_type &= ~(BTM_ACL_PKT_TYPES_MASK_DH5 + BTM_ACL_PKT_TYPES_MASK_DM5);
3380 
3381     /* If HCI version > 2.0, then also check EDR packet types */
3382     if (btm_cb.devcb.local_version.hci_version >= HCI_PROTO_VERSION_2_0)
3383     {
3384         /* 2 and 3 MPS support? */
3385         if (!HCI_EDR_ACL_2MPS_SUPPORTED(p->peer_lmp_features[HCI_EXT_FEATURES_PAGE_0]))
3386             /* Not supported. Add 'not_supported' mask for all 2MPS packet types */
3387             *p_pkt_type |= (BTM_ACL_PKT_TYPES_MASK_NO_2_DH1 + BTM_ACL_PKT_TYPES_MASK_NO_2_DH3 +
3388                                 BTM_ACL_PKT_TYPES_MASK_NO_2_DH5);
3389 
3390         if (!HCI_EDR_ACL_3MPS_SUPPORTED(p->peer_lmp_features[HCI_EXT_FEATURES_PAGE_0]))
3391             /* Not supported. Add 'not_supported' mask for all 3MPS packet types */
3392             *p_pkt_type |= (BTM_ACL_PKT_TYPES_MASK_NO_3_DH1 + BTM_ACL_PKT_TYPES_MASK_NO_3_DH3 +
3393                                 BTM_ACL_PKT_TYPES_MASK_NO_3_DH5);
3394 
3395         /* EDR 3 and 5 slot support? */
3396         if (HCI_EDR_ACL_2MPS_SUPPORTED(p->peer_lmp_features[HCI_EXT_FEATURES_PAGE_0])
3397          || HCI_EDR_ACL_3MPS_SUPPORTED(p->peer_lmp_features[HCI_EXT_FEATURES_PAGE_0]))
3398         {
3399             if (!HCI_3_SLOT_EDR_ACL_SUPPORTED(p->peer_lmp_features[HCI_EXT_FEATURES_PAGE_0]))
3400                 /* Not supported. Add 'not_supported' mask for all 3-slot EDR packet types */
3401                 *p_pkt_type |= (BTM_ACL_PKT_TYPES_MASK_NO_2_DH3 + BTM_ACL_PKT_TYPES_MASK_NO_3_DH3);
3402 
3403             if (!HCI_5_SLOT_EDR_ACL_SUPPORTED(p->peer_lmp_features[HCI_EXT_FEATURES_PAGE_0]))
3404                 /* Not supported. Add 'not_supported' mask for all 5-slot EDR packet types */
3405                 *p_pkt_type |= (BTM_ACL_PKT_TYPES_MASK_NO_2_DH5 + BTM_ACL_PKT_TYPES_MASK_NO_3_DH5);
3406         }
3407     }
3408 }
3409