From 8fe58875ce67c6e1099e7ba2339dcd2b979491b0 Mon Sep 17 00:00:00 2001 From: Ganesh Ganapathi Batta Date: Wed, 16 Apr 2014 16:50:09 -0700 Subject: [PATCH] Merge BT 4.1 features The features include: - LE Peripheral Mode - Link Layer topology (LE Central & Peripheral Concurrency) - Dual Mode Topology (Ability to choose LE transport when connecting with other Dual Mode devices) - Fast advertising Interval - Limited Discovery Time Changes - GAP Authentication and Lost Bond - Dual Mode Addressing - Common Profile and Service Error Code - 32 bit UUIDs Change-Id: Ic6701da4cf6aaa390ff2c8816b43157f36b7fb42 --- bta/dm/bta_dm_act.c | 350 ++++++++++--- bta/dm/bta_dm_api.c | 151 +++++- bta/dm/bta_dm_int.h | 38 +- bta/dm/bta_dm_main.c | 4 + bta/gatt/bta_gattc_act.c | 134 +++-- bta/gatt/bta_gattc_api.c | 5 +- bta/gatt/bta_gattc_cache.c | 52 +- bta/gatt/bta_gattc_int.h | 14 +- bta/gatt/bta_gattc_main.c | 16 +- bta/gatt/bta_gattc_utils.c | 211 ++------ bta/gatt/bta_gatts_act.c | 70 ++- bta/gatt/bta_gatts_api.c | 5 +- bta/gatt/bta_gatts_int.h | 10 +- bta/hh/bta_hh_le.c | 19 +- bta/include/bta_api.h | 97 +++- bta/include/bta_gatt_api.h | 60 ++- bta/jv/bta_jv_act.c | 23 +- bta/jv/bta_jv_api.c | 8 +- btif/include/btif_storage.h | 30 ++ btif/src/bluetooth.c | 2 +- btif/src/btif_dm.c | 6 + btif/src/btif_gatt_client.c | 50 +- btif/src/btif_gatt_server.c | 33 +- btif/src/btif_gatt_test.c | 5 +- btif/src/btif_gatt_util.c | 35 +- btif/src/btif_storage.c | 69 ++- hci/src/utils.c | 1 + include/bt_target.h | 132 +---- main/bte_main.c | 10 +- stack/avdt/avdt_l2c.c | 8 +- stack/bnep/bnep_int.h | 9 +- stack/bnep/bnep_utils.c | 4 +- stack/btm/btm_acl.c | 261 ++++++---- stack/btm/btm_ble.c | 153 +++--- stack/btm/btm_ble_bgconn.c | 57 ++- stack/btm/btm_ble_gap.c | 1132 ++++++++++++++++++++++++++++++------------- stack/btm/btm_ble_int.h | 90 +++- stack/btm/btm_dev.c | 24 +- stack/btm/btm_devctl.c | 53 ++ stack/btm/btm_inq.c | 30 +- stack/btm/btm_int.h | 53 +- stack/btm/btm_pm.c | 25 +- stack/btm/btm_sco.c | 8 +- stack/btm/btm_sec.c | 568 ++++++++++++++++------ stack/btu/btu_hcif.c | 41 +- stack/btu/btu_task.c | 5 + stack/gap/gap_api.c | 2 +- stack/gap/gap_ble.c | 251 +++------- stack/gap/gap_conn.c | 3 +- stack/gap/gap_utils.c | 4 +- stack/gatt/att_protocol.c | 4 +- stack/gatt/gatt_api.c | 61 ++- stack/gatt/gatt_attr.c | 16 +- stack/gatt/gatt_auth.c | 45 +- stack/gatt/gatt_cl.c | 46 +- stack/gatt/gatt_db.c | 136 ++++-- stack/gatt/gatt_int.h | 48 +- stack/gatt/gatt_main.c | 99 ++-- stack/gatt/gatt_sr.c | 41 +- stack/gatt/gatt_utils.c | 186 +++---- stack/hcic/hciblecmds.c | 79 ++- stack/hid/hidh_conn.c | 13 +- stack/include/bt_types.h | 4 + stack/include/btm_api.h | 350 ++++--------- stack/include/btm_ble_api.h | 115 +++-- stack/include/btu.h | 11 +- stack/include/gap_api.h | 11 +- stack/include/gatt_api.h | 125 ++--- stack/include/hcidefs.h | 305 +++++++++++- stack/include/hcimsgs.h | 16 +- stack/include/l2c_api.h | 23 +- stack/include/smp_api.h | 6 +- stack/include/uipc_msg.h | 318 +----------- stack/l2cap/l2c_api.c | 131 +++-- stack/l2cap/l2c_ble.c | 369 ++++++++------ stack/l2cap/l2c_fcr.c | 2 +- stack/l2cap/l2c_int.h | 38 +- stack/l2cap/l2c_link.c | 109 +++-- stack/l2cap/l2c_main.c | 35 +- stack/l2cap/l2c_ucd.c | 16 +- stack/l2cap/l2c_utils.c | 219 +++++++-- stack/mcap/mca_l2c.c | 7 +- stack/rfcomm/rfc_int.h | 2 +- stack/rfcomm/rfc_utils.c | 3 +- stack/smp/aes.c | 1 + stack/smp/smp_act.c | 27 +- stack/smp/smp_int.h | 5 + stack/smp/smp_l2c.c | 31 +- stack/smp/smp_main.c | 13 +- stack/smp/smp_utils.c | 29 ++ stack/srvc/srvc_dis.c | 4 +- stack/srvc/srvc_eng.c | 6 +- 92 files changed, 4653 insertions(+), 2873 deletions(-) diff --git a/bta/dm/bta_dm_act.c b/bta/dm/bta_dm_act.c index 86a7db22e..3a9dddefe 100644 --- a/bta/dm/bta_dm_act.c +++ b/bta/dm/bta_dm_act.c @@ -89,7 +89,7 @@ static void bta_dm_adjust_roles(BOOLEAN delay_role_switch); static char *bta_dm_get_remname(void); static void bta_dm_bond_cancel_complete_cback(tBTM_STATUS result); -static BOOLEAN bta_dm_read_remote_device_name (BD_ADDR bd_addr); +static BOOLEAN bta_dm_read_remote_device_name (BD_ADDR bd_addr,tBT_TRANSPORT transport); static void bta_dm_discover_device(BD_ADDR remote_bd_addr); static void bta_dm_sys_hw_cback( tBTA_SYS_HW_EVT status ); @@ -516,6 +516,8 @@ static void bta_dm_disable_timer_cback (TIMER_LIST_ENT *p_tle) { UNUSED(p_tle); UINT8 i; + tBT_TRANSPORT transport = BT_TRANSPORT_BR_EDR; + APPL_TRACE_EVENT0(" bta_dm_disable_timer_cback "); @@ -523,8 +525,10 @@ static void bta_dm_disable_timer_cback (TIMER_LIST_ENT *p_tle) { for(i=0; ibd_addr, FALSE); #endif - if (BTM_IsAclConnectionUp(p_dev->bd_addr)) + if ( BTM_IsAclConnectionUp(p_dev->bd_addr, BT_TRANSPORT_LE) || + BTM_IsAclConnectionUp(p_dev->bd_addr, BT_TRANSPORT_BR_EDR)) { + APPL_TRACE_DEBUG2("%s: ACL Up count %d", __FUNCTION__,bta_dm_cb.device_list.count); /* Take the link down first, and mark the device for removal when disconnected */ - btm_remove_acl( p_dev->bd_addr) ; for(i=0; ibd_addr)) - break; - } - - if(i < bta_dm_cb.device_list.count) - { - bta_dm_cb.device_list.peer_device[i].conn_state = BTA_DM_UNPAIRING; + { + bta_dm_cb.device_list.peer_device[i].conn_state = BTA_DM_UNPAIRING; + btm_remove_acl( p_dev->bd_addr,bta_dm_cb.device_list.peer_device[i].transport); + APPL_TRACE_DEBUG2("%s:transport = %d", __FUNCTION__, + bta_dm_cb.device_list.peer_device[i].transport); + break; + } } } + else /* Ok to remove the device in application layer */ { BTM_SecDeleteDevice(p_dev->bd_addr); @@ -789,15 +796,23 @@ void bta_dm_close_acl(tBTA_DM_MSG *p_data) { tBTA_DM_API_REMOVE_ACL *p_remove_acl = &p_data->remove_acl; UINT8 index; + tBT_TRANSPORT transport = BT_TRANSPORT_BR_EDR; APPL_TRACE_DEBUG0("bta_dm_close_acl"); - if (BTM_IsAclConnectionUp(p_remove_acl->bd_addr)) + if ( BTM_IsAclConnectionUp(p_remove_acl->bd_addr, BT_TRANSPORT_LE) || + BTM_IsAclConnectionUp(p_remove_acl->bd_addr, BT_TRANSPORT_BR_EDR)) + { for (index = 0; index < bta_dm_cb.device_list.count; index ++) { if (!bdcmp( bta_dm_cb.device_list.peer_device[index].peer_bdaddr, p_remove_acl->bd_addr)) + { +#if defined (BLE_INCLUDED) && (BLE_INCLUDED == TRUE) + transport = bta_dm_cb.device_list.peer_device[index].transport; +#endif break; + } } if (index != bta_dm_cb.device_list.count) { @@ -809,7 +824,7 @@ void bta_dm_close_acl(tBTA_DM_MSG *p_data) APPL_TRACE_ERROR0("unknown device, remove ACL failed"); } /* Disconnect the ACL link */ - btm_remove_acl(p_remove_acl->bd_addr); + btm_remove_acl(p_remove_acl->bd_addr, transport); } /* if to remove the device from security database ? do it now */ else if (p_remove_acl->remove_dev) @@ -844,7 +859,11 @@ void bta_dm_bond (tBTA_DM_MSG *p_data) tBTA_DM_SEC sec_event; char *p_name; - status = BTM_SecBond ( p_data->bond.bd_addr, 0, NULL, 0 ); + if (p_data->bond.transport == BTA_TRANSPORT_UNKNOWN) + status = BTM_SecBond ( p_data->bond.bd_addr, 0, NULL, 0 ); + else + status = BTM_SecBondByTransport ( p_data->bond.bd_addr, p_data->bond.transport, 0, NULL, 0 ); + if (bta_dm_cb.p_sec_cback && (status != BTM_CMD_STARTED)) { @@ -1334,6 +1353,7 @@ void bta_dm_discover (tBTA_DM_MSG *p_data) bta_dm_search_cb.peer_name[0] = 0; bta_dm_search_cb.sdp_search = p_data->discover.sdp_search; bta_dm_search_cb.p_btm_inq_info = BTM_InqDbRead (p_data->discover.bd_addr); + bta_dm_search_cb.transport = p_data->discover.transport; bta_dm_search_cb.name_discover_done = FALSE; memcpy(&bta_dm_search_cb.uuid, &p_data->discover.uuid, sizeof(tSDP_UUID)); @@ -1501,7 +1521,7 @@ void bta_dm_di_disc (tBTA_DM_MSG *p_data) ** Returns TRUE if started to get remote name ** *******************************************************************************/ -static BOOLEAN bta_dm_read_remote_device_name (BD_ADDR bd_addr) +static BOOLEAN bta_dm_read_remote_device_name (BD_ADDR bd_addr,tBT_TRANSPORT transport) { tBTM_STATUS btm_status; @@ -1511,7 +1531,8 @@ static BOOLEAN bta_dm_read_remote_device_name (BD_ADDR bd_addr) bta_dm_search_cb.peer_name[0] = 0; btm_status = BTM_ReadRemoteDeviceName (bta_dm_search_cb.peer_bdaddr, - (tBTM_CMPL_CB *) bta_dm_remname_cback); + (tBTM_CMPL_CB *) bta_dm_remname_cback, + transport); if ( btm_status == BTM_CMD_STARTED ) { @@ -2383,6 +2404,21 @@ static void bta_dm_discover_next_device(void) static void bta_dm_discover_device(BD_ADDR remote_bd_addr) { tBTA_DM_MSG * p_msg; + tBT_TRANSPORT transport = BT_TRANSPORT_BR_EDR; +#if BLE_INCLUDED == TRUE + tBT_DEVICE_TYPE dev_type; + tBLE_ADDR_TYPE addr_type; + + if (bta_dm_search_cb.transport == BTA_TRANSPORT_UNKNOWN) + { + BTM_ReadDevInfo(remote_bd_addr, &dev_type, &addr_type); + if (dev_type == BT_DEVICE_TYPE_BLE || addr_type == BLE_ADDR_RANDOM ) + transport = BT_TRANSPORT_LE; + } + else + transport = bta_dm_search_cb.transport; +#endif + APPL_TRACE_DEBUG6("bta_dm_discover_device, BDA:0x%02X%02X%02X%02X%02X%02X", remote_bd_addr[0],remote_bd_addr[1], @@ -2407,7 +2443,7 @@ static void bta_dm_discover_device(BD_ADDR remote_bd_addr) && (( bta_dm_search_cb.p_btm_inq_info == NULL ) ||(bta_dm_search_cb.p_btm_inq_info && (!bta_dm_search_cb.p_btm_inq_info->appl_knows_rem_name)))) { - if( bta_dm_read_remote_device_name(bta_dm_search_cb.peer_bdaddr) == TRUE ) + if(bta_dm_read_remote_device_name(bta_dm_search_cb.peer_bdaddr, transport) == TRUE) { return; } @@ -2446,7 +2482,7 @@ static void bta_dm_discover_device(BD_ADDR remote_bd_addr) /* check whether connection already exists to the device if connection exists, we don't have to wait for ACL link to go down to start search on next device */ - if(BTM_IsAclConnectionUp(bta_dm_search_cb.peer_bdaddr)) + if (BTM_IsAclConnectionUp(bta_dm_search_cb.peer_bdaddr, BT_TRANSPORT_BR_EDR)) bta_dm_search_cb.wait_disc = FALSE; else bta_dm_search_cb.wait_disc = TRUE; @@ -2460,8 +2496,7 @@ static void bta_dm_discover_device(BD_ADDR remote_bd_addr) bta_dm_search_cb.services_to_search ); } - if (BTM_UseLeLink(bta_dm_search_cb.peer_bdaddr)) - /* + if (transport == BT_TRANSPORT_LE) /* if ( bta_dm_search_cb.p_btm_inq_info != NULL && bta_dm_search_cb.p_btm_inq_info->results.device_type == BT_DEVICE_TYPE_BLE && (bta_dm_search_cb.services_to_search & BTA_BLE_SERVICE_MASK))*/ @@ -2559,7 +2594,7 @@ static void bta_dm_inq_results_cb (tBTM_INQ_RESULTS *p_inq, UINT8 *p_eir) result.inq_res.ble_addr_type = p_inq->ble_addr_type; result.inq_res.inq_result_type = p_inq->inq_result_type; result.inq_res.device_type = p_inq->device_type; - + result.inq_res.flag = p_inq->flag; #endif /* application will parse EIR to find out remote device name */ @@ -2649,7 +2684,8 @@ static void bta_dm_service_search_remname_cback (BD_ADDR bd_addr, DEV_CLASS dc, { /* get name of device */ btm_status = BTM_ReadRemoteDeviceName (bta_dm_search_cb.peer_bdaddr, - (tBTM_CMPL_CB *) bta_dm_remname_cback); + (tBTM_CMPL_CB *) bta_dm_remname_cback, + BT_TRANSPORT_BR_EDR); if ( btm_status == BTM_BUSY ) { /* wait for next chance(notification of remote name discovery done) */ @@ -2691,9 +2727,12 @@ static void bta_dm_remname_cback (tBTM_REMOTE_DEV_NAME *p_remote_name) bta_dm_search_cb.peer_name[BD_NAME_LEN]=0; BTM_SecDeleteRmtNameNotifyCallback(&bta_dm_service_search_remname_cback); + #if BLE_INCLUDED == TRUE - if (BTM_UseLeLink(bta_dm_search_cb.peer_bdaddr)) - GAP_BleReadPeerPrefConnParams (bta_dm_search_cb.peer_bdaddr); + if (bta_dm_search_cb.transport == BT_TRANSPORT_LE ) + { + GAP_BleReadPeerPrefConnParams (bta_dm_search_cb.peer_bdaddr); + } #endif if ((p_msg = (tBTA_DM_REM_NAME *) GKI_getbuf(sizeof(tBTA_DM_REM_NAME))) != NULL) { @@ -2856,7 +2895,7 @@ static UINT8 bta_dm_pin_cback (BD_ADDR bd_addr, DEV_CLASS dev_class, BD_NAME bd_ bta_dm_cb.pin_evt = BTA_DM_PIN_REQ_EVT; bdcpy(bta_dm_cb.pin_bd_addr, bd_addr); BTA_COPY_DEVICE_CLASS(bta_dm_cb.pin_dev_class, dev_class); - if ((BTM_ReadRemoteDeviceName(bd_addr, bta_dm_pinname_cback)) == BTM_CMD_STARTED) + if ((BTM_ReadRemoteDeviceName(bd_addr, bta_dm_pinname_cback, BT_TRANSPORT_BR_EDR)) == BTM_CMD_STARTED) return BTM_CMD_STARTED; APPL_TRACE_WARNING0(" bta_dm_pin_cback() -> Failed to start Remote Name Request "); @@ -3044,22 +3083,56 @@ static UINT8 bta_dm_sp_cback (tBTM_SP_EVT event, tBTM_SP_EVT_DATA *p_data) /*case BTM_SP_KEY_REQ_EVT: */ case BTM_SP_KEY_NOTIF_EVT: #endif + if(BTM_SP_CFM_REQ_EVT == event) + { + /* Due to the switch case falling through below to BTM_SP_KEY_NOTIF_EVT, + call remote name request using values from cfm_req */ + if(p_data->cfm_req.bd_name[0] == 0) + { + bta_dm_cb.pin_evt = pin_evt; + bdcpy(bta_dm_cb.pin_bd_addr, p_data->cfm_req.bd_addr); + BTA_COPY_DEVICE_CLASS(bta_dm_cb.pin_dev_class, p_data->cfm_req.dev_class); + if ((BTM_ReadRemoteDeviceName(p_data->cfm_req.bd_addr, bta_dm_pinname_cback, + BT_TRANSPORT_BR_EDR)) == BTM_CMD_STARTED) + return BTM_CMD_STARTED; + APPL_TRACE_WARNING0(" bta_dm_sp_cback() -> Failed to start Remote Name Request "); + } + else + { + /* Due to the switch case falling through below to BTM_SP_KEY_NOTIF_EVT, + copy these values into key_notif from cfm_req */ + bdcpy(sec_event.key_notif.bd_addr, p_data->cfm_req.bd_addr); + BTA_COPY_DEVICE_CLASS(sec_event.key_notif.dev_class, p_data->cfm_req.dev_class); + BCM_STRNCPY_S((char*)sec_event.key_notif.bd_name, sizeof(BD_NAME), + (char*)p_data->cfm_req.bd_name, (BD_NAME_LEN-1)); + sec_event.key_notif.bd_name[BD_NAME_LEN-1] = 0; + } + } + bta_dm_cb.num_val = sec_event.key_notif.passkey = p_data->key_notif.passkey; - /* If the device name is not known, save bdaddr and devclass and initiate a name request */ - if (p_data->key_notif.bd_name[0] == 0) + if (BTM_SP_KEY_NOTIF_EVT == event) { - bta_dm_cb.pin_evt = pin_evt; - bdcpy(bta_dm_cb.pin_bd_addr, p_data->key_notif.bd_addr); - BTA_COPY_DEVICE_CLASS(bta_dm_cb.pin_dev_class, p_data->key_notif.dev_class); - if ((BTM_ReadRemoteDeviceName(p_data->key_notif.bd_addr, bta_dm_pinname_cback)) == BTM_CMD_STARTED) + /* If the device name is not known, save bdaddr and devclass + and initiate a name request with values from key_notif */ + if(p_data->key_notif.bd_name[0] == 0) + { + bta_dm_cb.pin_evt = pin_evt; + bdcpy(bta_dm_cb.pin_bd_addr, p_data->key_notif.bd_addr); + BTA_COPY_DEVICE_CLASS(bta_dm_cb.pin_dev_class, p_data->key_notif.dev_class); + if ((BTM_ReadRemoteDeviceName(p_data->key_notif.bd_addr, bta_dm_pinname_cback, + BT_TRANSPORT_BR_EDR)) == BTM_CMD_STARTED) return BTM_CMD_STARTED; - - APPL_TRACE_WARNING0(" bta_dm_sp_cback() -> Failed to start Remote Name Request "); + APPL_TRACE_WARNING0(" bta_dm_sp_cback() -> Failed to start Remote Name Request "); + } + else + { + bdcpy(sec_event.key_notif.bd_addr, p_data->key_notif.bd_addr); + BTA_COPY_DEVICE_CLASS(sec_event.key_notif.dev_class, p_data->key_notif.dev_class); + BCM_STRNCPY_S((char*)sec_event.key_notif.bd_name, sizeof(BD_NAME), + (char*)p_data->key_notif.bd_name, (BD_NAME_LEN-1)); + sec_event.key_notif.bd_name[BD_NAME_LEN-1] = 0; + } } - bdcpy(sec_event.key_notif.bd_addr, p_data->key_notif.bd_addr); - BTA_COPY_DEVICE_CLASS(sec_event.key_notif.dev_class, p_data->key_notif.dev_class); - BCM_STRNCPY_S((char*)sec_event.key_notif.bd_name, sizeof(BD_NAME), (char*)p_data->key_notif.bd_name, (BD_NAME_LEN-1)); - sec_event.key_notif.bd_name[BD_NAME_LEN-1] = 0; bta_dm_cb.p_sec_cback(pin_evt, &sec_event); @@ -3075,17 +3148,18 @@ static UINT8 bta_dm_sp_cback (tBTM_SP_EVT event, tBTM_SP_EVT_DATA *p_data) /* If the device name is not known, save bdaddr and devclass and initiate a name request */ if (p_data->rmt_oob.bd_name[0] == 0) { - bta_dm_cb.pin_evt = BTA_DM_SP_RMT_OOB_EVT; - bdcpy(bta_dm_cb.pin_bd_addr, p_data->rmt_oob.bd_addr); - BTA_COPY_DEVICE_CLASS(bta_dm_cb.pin_dev_class, p_data->rmt_oob.dev_class); - if ((BTM_ReadRemoteDeviceName(p_data->rmt_oob.bd_addr, bta_dm_pinname_cback)) == BTM_CMD_STARTED) - return BTM_CMD_STARTED; + bta_dm_cb.pin_evt = BTA_DM_SP_RMT_OOB_EVT; + bdcpy(bta_dm_cb.pin_bd_addr, p_data->rmt_oob.bd_addr); + BTA_COPY_DEVICE_CLASS(bta_dm_cb.pin_dev_class, p_data->rmt_oob.dev_class); + if ((BTM_ReadRemoteDeviceName(p_data->rmt_oob.bd_addr, bta_dm_pinname_cback, + BT_TRANSPORT_BR_EDR)) == BTM_CMD_STARTED) + return BTM_CMD_STARTED; + APPL_TRACE_WARNING0(" bta_dm_sp_cback() -> Failed to start Remote Name Request "); + } - APPL_TRACE_WARNING0(" bta_dm_sp_cback() -> Failed to start Remote Name Request "); - } - bdcpy(sec_event.rmt_oob.bd_addr, p_data->rmt_oob.bd_addr); - BTA_COPY_DEVICE_CLASS(sec_event.rmt_oob.dev_class, p_data->rmt_oob.dev_class); - BCM_STRNCPY_S((char*)sec_event.rmt_oob.bd_name, sizeof(BD_NAME), (char*)p_data->rmt_oob.bd_name, (BD_NAME_LEN-1)); + bdcpy(sec_event.rmt_oob.bd_addr, p_data->rmt_oob.bd_addr); + BTA_COPY_DEVICE_CLASS(sec_event.rmt_oob.dev_class, p_data->rmt_oob.dev_class); + BCM_STRNCPY_S((char*)sec_event.rmt_oob.bd_name, sizeof(BD_NAME), (char*)p_data->rmt_oob.bd_name, (BD_NAME_LEN-1)); sec_event.rmt_oob.bd_name[BD_NAME_LEN-1] = 0; bta_dm_cb.p_sec_cback(BTA_DM_SP_RMT_OOB_EVT, &sec_event); @@ -3227,9 +3301,17 @@ static void bta_dm_bl_change_cback (tBTM_BL_EVENT_DATA *p_data) case BTM_BL_CONN_EVT: p_msg->is_new = TRUE; bdcpy(p_msg->bd_addr, p_data->conn.p_bda); +#if BLE_INCLUDED == TRUE + p_msg->transport = p_data->conn.transport; + p_msg->handle = p_data->conn.handle; +#endif break; case BTM_BL_DISCN_EVT: bdcpy(p_msg->bd_addr, p_data->discn.p_bda); +#if BLE_INCLUDED == TRUE + p_msg->transport = p_data->discn.transport; + p_msg->handle = p_data->discn.handle; +#endif break; case BTM_BL_UPDATE_EVT: p_msg->busy_level = p_data->update.busy_level; @@ -3240,9 +3322,9 @@ static void bta_dm_bl_change_cback (tBTM_BL_EVENT_DATA *p_data) p_msg->hci_status = p_data->role_chg.hci_status; bdcpy(p_msg->bd_addr, p_data->role_chg.p_bda); break; - case BTM_BL_COLLISION_EVT: - bdcpy(p_msg->bd_addr, p_data->conn.p_bda); - break;; + case BTM_BL_COLLISION_EVT: + bdcpy(p_msg->bd_addr, p_data->conn.p_bda); + break; } p_msg->hdr.event = BTA_DM_ACL_CHANGE_EVT; @@ -3264,7 +3346,8 @@ static void bta_dm_bl_change_cback (tBTM_BL_EVENT_DATA *p_data) ** *******************************************************************************/ static void bta_dm_acl_change_cback (BD_ADDR p_bda, DEV_CLASS p_dc, BD_NAME p_bdn, - UINT8 *features, BOOLEAN is_new) + UINT8 *features, BOOLEAN is_new,UINT16 handle, + tBT_TRANSPORT transport) { tBTA_DM_ACL_CHANGE * p_msg; @@ -3273,7 +3356,10 @@ static void bta_dm_acl_change_cback (BD_ADDR p_bda, DEV_CLASS p_dc, BD_NAME p_bd { bdcpy (p_msg->bd_addr, p_bda); p_msg->is_new = is_new; - +#if BLE_INCLUDED == TRUE + p_msg->handle = handle; + p_msg->transport = transport; +#endif /* This is collision case */ if (features != NULL) { @@ -3386,6 +3472,7 @@ void bta_dm_acl_change(tBTA_DM_MSG *p_data) #if (defined(BTM_BUSY_LEVEL_CHANGE_INCLUDED) && BTM_BUSY_LEVEL_CHANGE_INCLUDED == TRUE) tBTA_DM_PEER_DEVICE *p_dev; + memset(&conn, 0, sizeof(tBTA_DM_SEC)); switch(p_data->acl_change.event) { @@ -3437,7 +3524,7 @@ void bta_dm_acl_change(tBTA_DM_MSG *p_data) bdcpy(conn.role_chg.bd_addr, p_bda); conn.role_chg.new_role = (UINT8) p_data->acl_change.new_role; if( bta_dm_cb.p_sec_cback ) - bta_dm_cb.p_sec_cback(BTA_DM_ROLE_CHG_EVT, &conn); + bta_dm_cb.p_sec_cback(BTA_DM_ROLE_CHG_EVT, (tBTA_DM_SEC *)&conn); } return; } @@ -3454,7 +3541,11 @@ void bta_dm_acl_change(tBTA_DM_MSG *p_data) { for(i=0; iacl_change.handle +#endif + ) break; } @@ -3464,14 +3555,24 @@ void bta_dm_acl_change(tBTA_DM_MSG *p_data) bdcpy(bta_dm_cb.device_list.peer_device[bta_dm_cb.device_list.count].peer_bdaddr, p_bda); bta_dm_cb.device_list.peer_device[bta_dm_cb.device_list.count].link_policy = bta_dm_cb.cur_policy; bta_dm_cb.device_list.count++; +#if BLE_INCLUDED == TRUE + bta_dm_cb.device_list.peer_device[i].conn_handle = p_data->acl_change.handle; + if (p_data->acl_change.transport == BT_TRANSPORT_LE) + bta_dm_cb.device_list.le_count++; +#endif } bta_dm_cb.device_list.peer_device[i].conn_state = BTA_DM_CONNECTED; bta_dm_cb.device_list.peer_device[i].pref_role = BTA_ANY_ROLE; bdcpy(conn.link_up.bd_addr, p_bda); bta_dm_cb.device_list.peer_device[i].info = BTA_DM_DI_NONE; - if( ((NULL != (p = BTM_ReadLocalFeatures ())) && HCI_SNIFF_SUB_RATE_SUPPORTED(p)) && - ((NULL != (p = BTM_ReadRemoteFeatures (p_bda))) && HCI_SNIFF_SUB_RATE_SUPPORTED(p)) ) +#if BLE_INCLUDED == TRUE + conn.link_up.link_type = p_data->acl_change.transport; + bta_dm_cb.device_list.peer_device[i].transport = p_data->acl_change.transport; +#endif + + if (((NULL != (p = BTM_ReadLocalFeatures ())) && HCI_SNIFF_SUB_RATE_SUPPORTED(p)) && + ((NULL != (p = BTM_ReadRemoteFeatures (p_bda))) && HCI_SNIFF_SUB_RATE_SUPPORTED(p))) { /* both local and remote devices support SSR */ bta_dm_cb.device_list.peer_device[i].info = BTA_DM_DI_USE_SSR; @@ -3485,17 +3586,23 @@ void bta_dm_acl_change(tBTA_DM_MSG *p_data) { for(i=0; iacl_change.transport +#endif + ) continue; if( bta_dm_cb.device_list.peer_device[i].conn_state == BTA_DM_UNPAIRING ) { - BTM_SecDeleteDevice(bta_dm_cb.device_list.peer_device[i].peer_bdaddr); + if (BTM_SecDeleteDevice(bta_dm_cb.device_list.peer_device[i].peer_bdaddr)) + { #if (BLE_INCLUDED == TRUE && BTA_GATT_INCLUDED == TRUE) - /* remove all cached GATT information */ - BTA_GATTC_Refresh(p_bda); + /* remove all cached GATT information */ + BTA_GATTC_Refresh(p_bda); #endif - issue_unpair_cb = TRUE; + issue_unpair_cb = TRUE; + } } conn.link_down.is_removed = bta_dm_cb.device_list.peer_device[i].remove_dev_pending; @@ -3508,6 +3615,12 @@ void bta_dm_acl_change(tBTA_DM_MSG *p_data) } if(bta_dm_cb.device_list.count) bta_dm_cb.device_list.count--; +#if BLE_INCLUDED == TRUE + if ((p_data->acl_change.transport == BT_TRANSPORT_LE) && + (bta_dm_cb.device_list.le_count)) + bta_dm_cb.device_list.le_count--; + conn.link_down.link_type = p_data->acl_change.transport; +#endif if(bta_dm_search_cb.wait_disc && !bdcmp(bta_dm_search_cb.peer_bdaddr, p_bda)) { @@ -3785,7 +3898,8 @@ static void bta_dm_delay_role_switch_cback(TIMER_LIST_ENT *p_tle) static void bta_dm_remove_sec_dev_entry(BD_ADDR remote_bd_addr) { UINT16 index = 0; - if (BTM_IsAclConnectionUp(remote_bd_addr)) + if ( BTM_IsAclConnectionUp(remote_bd_addr, BT_TRANSPORT_LE) || + BTM_IsAclConnectionUp(remote_bd_addr, BT_TRANSPORT_BR_EDR)) { APPL_TRACE_DEBUG1("%s ACL is not down. Schedule for Dev Removal when ACL closes", __FUNCTION__); @@ -3831,14 +3945,18 @@ static void bta_dm_adjust_roles(BOOLEAN delay_role_switch) UINT8 i; BOOLEAN set_master_role = FALSE; - - if(bta_dm_cb.device_list.count) +#if BLE_INCLUDED == TRUE + UINT8 br_count = bta_dm_cb.device_list.count - bta_dm_cb.device_list.le_count; +#else + UINT8 br_count = bta_dm_cb.device_list.count; +#endif + if (br_count) { /* the configuration is no scatternet * or AV connection exists and there are more than one ACL link */ - if( (p_bta_dm_rm_cfg[0].cfg == BTA_DM_NO_SCATTERNET) || - (bta_dm_cb.cur_av_count && bta_dm_cb.device_list.count > 1) ) + if ( (p_bta_dm_rm_cfg[0].cfg == BTA_DM_NO_SCATTERNET) || + (bta_dm_cb.cur_av_count && br_count > 1) ) { L2CA_SetDesireRole (HCI_ROLE_MASTER); @@ -3848,7 +3966,11 @@ static void bta_dm_adjust_roles(BOOLEAN delay_role_switch) for(i=0; i 1)) + || (br_count > 1)) { /* Initiating immediate role switch with certain remote devices @@ -4508,13 +4630,26 @@ void bta_dm_execute_callback(tBTA_DM_MSG *p_data) ** Returns None ** *******************************************************************************/ -void bta_dm_encrypt_cback(BD_ADDR bd_addr, void *p_ref_data, tBTM_STATUS result) +void bta_dm_encrypt_cback(BD_ADDR bd_addr, tBT_TRANSPORT transport, void *p_ref_data, tBTM_STATUS result) { tBTA_STATUS bta_status = BTA_SUCCESS; - tBTA_DM_ENCRYPT_CBACK *p_callback = bta_dm_cb.p_encrypt_cback; + tBTA_DM_ENCRYPT_CBACK *p_callback = NULL; + UINT8 i ; UNUSED(p_ref_data); - bta_dm_cb.p_encrypt_cback = NULL; + for (i=0; iset_encryption.p_callback) @@ -4559,16 +4695,35 @@ void bta_dm_set_encryption (tBTA_DM_MSG *p_data) return; } - if (bta_dm_cb.p_encrypt_cback) + for (i=0; iset_encryption.p_callback)(p_data->set_encryption.bd_addr, BTA_BUSY); - return; + if (bdcmp( bta_dm_cb.device_list.peer_device[i].peer_bdaddr, p_data->set_encryption.bd_addr) == 0 && + bta_dm_cb.device_list.peer_device[i].conn_state == BTA_DM_CONNECTED) + break; } + if (i < bta_dm_cb.device_list.count) + { + if (bta_dm_cb.device_list.peer_device[i].p_encrypt_cback) + { + APPL_TRACE_ERROR0("earlier enc was not done for same device"); + (*p_data->set_encryption.p_callback)(p_data->set_encryption.bd_addr, + p_data->set_encryption.transport, BTA_BUSY); + return; + } - - bta_dm_cb.p_encrypt_cback = p_data->set_encryption.p_callback; - bta_dm_cb.sec_act = p_data->set_encryption.sec_act; - BTM_SetEncryption(p_data->set_encryption.bd_addr, bta_dm_encrypt_cback, &bta_dm_cb.sec_act); + if (BTM_SetEncryption(p_data->set_encryption.bd_addr, + p_data->set_encryption.transport, + bta_dm_encrypt_cback, + &p_data->set_encryption.sec_act) + == BTM_CMD_STARTED) + { + bta_dm_cb.device_list.peer_device[i].p_encrypt_cback = p_data->set_encryption.p_callback; + } + } + else + { + APPL_TRACE_ERROR1(" %s Device not found/not connected", __FUNCTION__); + } } /******************************************************************************* @@ -4991,7 +5146,42 @@ void bta_dm_ble_set_scan_params (tBTA_DM_MSG *p_data) BTM_BleSetConnScanParams(p_data->ble_set_scan_params.scan_int, p_data->ble_set_scan_params.scan_window); } +/******************************************************************************* +** +** Function bta_dm_ble_update_conn_params +** +** Description This function update LE connection parameters. +** +** Parameters: +** +*******************************************************************************/ +void bta_dm_ble_update_conn_params (tBTA_DM_MSG *p_data) +{ + if (!L2CA_UpdateBleConnParams(p_data->ble_update_conn_params.bd_addr, + p_data->ble_update_conn_params.min_int, + p_data-> ble_update_conn_params.max_int, + p_data->ble_update_conn_params.latency, + p_data->ble_update_conn_params.timeout)) + { + APPL_TRACE_ERROR0("Update connection parameters failed!"); + } +} +#if BLE_PRIVACY_SPT == TRUE +/******************************************************************************* +** +** Function bta_dm_ble_config_local_privacy +** +** Description This function set the local device LE privacy settings. +** +** Parameters: +** +*******************************************************************************/ +void bta_dm_ble_config_local_privacy (tBTA_DM_MSG *p_data) +{ + BTM_BleConfigPrivacy (p_data->ble_local_privacy.privacy_enable); +} +#endif /******************************************************************************* ** @@ -5310,7 +5500,7 @@ void btm_dm_start_gatt_discovery (BD_ADDR bd_addr) btm_dm_start_disc_gatt_services(bta_dm_search_cb.conn_id); } else - BTA_GATTC_Open(bta_dm_search_cb.client_if, bd_addr, TRUE); + BTA_GATTC_Open(bta_dm_search_cb.client_if, bd_addr, TRUE, BTA_GATT_TRANSPORT_LE); } /******************************************************************************* diff --git a/bta/dm/bta_dm_api.c b/bta/dm/bta_dm_api.c index 7db7f7bd9..89e2cce08 100644 --- a/bta/dm/bta_dm_api.c +++ b/bta/dm/bta_dm_api.c @@ -526,12 +526,29 @@ BOOLEAN BTA_DmIsMaster(BD_ADDR bd_addr) *******************************************************************************/ void BTA_DmBond(BD_ADDR bd_addr) { + BTA_DmBondByTransport (bd_addr, BTA_TRANSPORT_UNKNOWN); +} + +/******************************************************************************* +** +** Function BTA_DmBondByTransports +** +** Description This function initiates a bonding procedure with a peer +** device +** +** +** Returns void +** +*******************************************************************************/ +void BTA_DmBondByTransport(BD_ADDR bd_addr, tBTA_TRANSPORT transport) +{ tBTA_DM_API_BOND *p_msg; if ((p_msg = (tBTA_DM_API_BOND *) GKI_getbuf(sizeof(tBTA_DM_API_BOND))) != NULL) { p_msg->hdr.event = BTA_DM_API_BOND_EVT; bdcpy(p_msg->bd_addr, bd_addr); + p_msg->transport = transport; bta_sys_sendmsg(p_msg); } @@ -1487,6 +1504,9 @@ void BTA_DmSetBleAdvParams (UINT16 adv_int_min, UINT16 adv_int_max, } #endif } +/******************************************************************************* +** BLE ADV data management API +********************************************************************************/ #if BLE_INCLUDED == TRUE /******************************************************************************* @@ -1507,7 +1527,7 @@ void BTA_DmBleSetAdvConfig (tBTA_BLE_AD_MASK data_mask, tBTA_BLE_ADV_DATA *p_adv if ((p_msg = (tBTA_DM_API_SET_ADV_CONFIG *) GKI_getbuf(sizeof(tBTA_DM_API_SET_ADV_CONFIG))) != NULL) { p_msg->hdr.event = BTA_DM_API_BLE_SET_ADV_CONFIG_EVT; - p_msg->data_mask = data_mask; + p_msg->data_mask = data_mask; p_msg->p_adv_cfg = p_adv_cfg; bta_sys_sendmsg(p_msg); @@ -1532,7 +1552,7 @@ BTA_API extern void BTA_DmBleSetScanRsp (tBTA_BLE_AD_MASK data_mask, tBTA_BLE_AD if ((p_msg = (tBTA_DM_API_SET_ADV_CONFIG *) GKI_getbuf(sizeof(tBTA_DM_API_SET_ADV_CONFIG))) != NULL) { p_msg->hdr.event = BTA_DM_API_BLE_SET_SCAN_RSP_EVT; - p_msg->data_mask = data_mask; + p_msg->data_mask = data_mask; p_msg->p_adv_cfg = p_adv_cfg; bta_sys_sendmsg(p_msg); @@ -1599,28 +1619,24 @@ void BTA_DmBleSetBgConnType(tBTA_DM_BLE_CONN_TYPE bg_conn_type, tBTA_DM_BLE_SEL_ } #endif } + /******************************************************************************* ** -** Function BTA_DmDiscoverExt -** -** Description This function does service discovery for services of a -** peer device. When services.num_uuid is 0, it indicates all -** GATT based services are to be searched; other wise a list of -** UUID of interested services should be provided through -** p_services->p_uuid. -** +** Function bta_dm_discover_send_msg ** +** Description This function send discover message to BTA task. ** ** Returns void ** *******************************************************************************/ -void BTA_DmDiscoverExt(BD_ADDR bd_addr, tBTA_SERVICE_MASK_EXT *p_services, - tBTA_DM_SEARCH_CBACK *p_cback, BOOLEAN sdp_search) +static void bta_dm_discover_send_msg(BD_ADDR bd_addr, tBTA_SERVICE_MASK_EXT *p_services, + tBTA_DM_SEARCH_CBACK *p_cback, BOOLEAN sdp_search, + tBTA_TRANSPORT transport) { -#if BLE_INCLUDED == TRUE && BTA_GATT_INCLUDED == TRUE tBTA_DM_API_DISCOVER *p_msg; - UINT16 len = p_services ? (sizeof(tBTA_DM_API_DISCOVER) + sizeof(tBT_UUID) * p_services->num_uuid) : - sizeof(tBTA_DM_API_DISCOVER); + UINT16 len = p_services ? (sizeof(tBTA_DM_API_DISCOVER) + + sizeof(tBT_UUID) * p_services->num_uuid) : + sizeof(tBTA_DM_API_DISCOVER); if ((p_msg = (tBTA_DM_API_DISCOVER *) GKI_getbuf(len)) != NULL) { @@ -1630,6 +1646,7 @@ void BTA_DmDiscoverExt(BD_ADDR bd_addr, tBTA_SERVICE_MASK_EXT *p_services, bdcpy(p_msg->bd_addr, bd_addr); p_msg->p_cback = p_cback; p_msg->sdp_search = sdp_search; + p_msg->transport = transport; if (p_services != NULL) { @@ -1645,12 +1662,60 @@ void BTA_DmDiscoverExt(BD_ADDR bd_addr, tBTA_SERVICE_MASK_EXT *p_services, bta_sys_sendmsg(p_msg); } -#else - UNUSED(bd_addr); - UNUSED(p_services); - UNUSED(p_cback); - UNUSED(sdp_search); -#endif +} + +/******************************************************************************* +** +** Function BTA_DmDiscoverByTransport +** +** Description This function does service discovery on particular transport +** for services of a +** peer device. When services.num_uuid is 0, it indicates all +** GATT based services are to be searched; otherwise a list of +** UUID of interested services should be provided through +** p_services->p_uuid. +** +** Parameters bd_addr: Bluetooth address of remote device +** p_services :bit mask of the list of services to be discovered +** p_cback : Callback on which result will be received +** sdp_search: if TRUE SDP search will be initiated, else services present in +** EIR structure of remote device will be returned. +** transport : Physical transport BR/EDR or LE +** Returns void +** +*******************************************************************************/ + +void BTA_DmDiscoverByTransport(BD_ADDR bd_addr, tBTA_SERVICE_MASK_EXT *p_services, + tBTA_DM_SEARCH_CBACK *p_cback, BOOLEAN sdp_search, + tBTA_TRANSPORT transport) +{ + bta_dm_discover_send_msg(bd_addr, p_services, p_cback, sdp_search, transport); +} + + +/******************************************************************************* +** +** Function BTA_DmDiscoverExt +** +** Description This function does service discovery for services of a +** peer device. When services.num_uuid is 0, it indicates all +** GATT based services are to be searched; other wise a list of +** UUID of interested services should be provided through +** p_services->p_uuid. +** +** Parameters bd_addr: Bluetooth address of remote device +** p_services :bit mask of the list of services to be discovered +** p_cback : Callback on which result will be received +** sdp_search: if TRUE SDP search will be initiated, else services present in +** EIR structure of remote device will be returned. +** +** Returns void +** +*******************************************************************************/ +void BTA_DmDiscoverExt(BD_ADDR bd_addr, tBTA_SERVICE_MASK_EXT *p_services, + tBTA_DM_SEARCH_CBACK *p_cback, BOOLEAN sdp_search) +{ + bta_dm_discover_send_msg(bd_addr, p_services, p_cback, sdp_search, BTA_TRANSPORT_UNKNOWN); } @@ -1751,6 +1816,43 @@ void BTA_DmBleConfigLocalPrivacy(BOOLEAN privacy_enable) /******************************************************************************* ** +** Function BTA_DmBleUpdateConnectionParams +** +** Description Update connection parameters, can only be used when connection is up. +** +** Parameters: bd_addr - BD address of the peer +** min_int - minimum connection interval, [0x0004~ 0x4000] +** max_int - maximum connection interval, [0x0004~ 0x4000] +** latency - slave latency [0 ~ 500] +** timeout - supervision timeout [0x000a ~ 0xc80] +** +** Returns void +** +*******************************************************************************/ +void BTA_DmBleUpdateConnectionParams(BD_ADDR bd_addr, UINT16 min_int, UINT16 max_int, + UINT16 latency, UINT16 timeout) +{ +#if BLE_INCLUDED == TRUE + tBTA_DM_API_UPDATE_CONN_PARAM *p_msg; + + if ((p_msg = (tBTA_DM_API_UPDATE_CONN_PARAM *) GKI_getbuf(sizeof(tBTA_DM_API_UPDATE_CONN_PARAM))) != NULL) + { + memset (p_msg, 0, sizeof(tBTA_DM_API_UPDATE_CONN_PARAM)); + + p_msg->hdr.event = BTA_DM_API_UPDATE_CONN_PARAM_EVT; + bdcpy(p_msg->bd_addr, bd_addr); + p_msg->min_int = min_int; + p_msg->max_int = max_int; + p_msg->latency = latency; + p_msg->timeout = timeout; + + bta_sys_sendmsg(p_msg); + } +#endif +} + +/******************************************************************************* +** ** Function BTA_DmSetEncryption ** ** Description This function is called to ensure that connection is @@ -1759,6 +1861,7 @@ void BTA_DmBleConfigLocalPrivacy(BOOLEAN privacy_enable) ** bring up unencrypted links, then later encrypt them. ** ** Parameters: bd_addr - Address of the peer device +** transport - transport of the link to be encruypted ** p_callback - Pointer to callback function to indicat the ** link encryption status ** sec_act - This is the security action to indicate @@ -1770,7 +1873,7 @@ void BTA_DmBleConfigLocalPrivacy(BOOLEAN privacy_enable) ** Returns void ** *******************************************************************************/ -void BTA_DmSetEncryption(BD_ADDR bd_addr, tBTA_DM_ENCRYPT_CBACK *p_callback, +void BTA_DmSetEncryption(BD_ADDR bd_addr, tBTA_TRANSPORT transport, tBTA_DM_ENCRYPT_CBACK *p_callback, tBTA_DM_BLE_SEC_ACT sec_act) { tBTA_DM_API_SET_ENCRYPTION *p_msg; @@ -1783,6 +1886,7 @@ void BTA_DmSetEncryption(BD_ADDR bd_addr, tBTA_DM_ENCRYPT_CBACK *p_callback, p_msg->hdr.event = BTA_DM_API_SET_ENCRYPTION_EVT; memcpy(p_msg->bd_addr, bd_addr, BD_ADDR_LEN); + p_msg->transport = transport; p_msg->p_callback = p_callback; p_msg->sec_act = sec_act; @@ -1803,7 +1907,7 @@ void BTA_DmSetEncryption(BD_ADDR bd_addr, tBTA_DM_ENCRYPT_CBACK *p_callback, ** Returns void ** *******************************************************************************/ -void BTA_DmCloseACL(BD_ADDR bd_addr, BOOLEAN remove_dev) +void BTA_DmCloseACL(BD_ADDR bd_addr, BOOLEAN remove_dev, tBTA_TRANSPORT transport) { tBTA_DM_API_REMOVE_ACL *p_msg; @@ -1817,6 +1921,7 @@ void BTA_DmCloseACL(BD_ADDR bd_addr, BOOLEAN remove_dev) memcpy(p_msg->bd_addr, bd_addr, BD_ADDR_LEN); p_msg->remove_dev = remove_dev; + p_msg->transport = transport; bta_sys_sendmsg(p_msg); } diff --git a/bta/dm/bta_dm_int.h b/bta/dm/bta_dm_int.h index 784d49ec0..03cb45fdf 100644 --- a/bta/dm/bta_dm_int.h +++ b/bta/dm/bta_dm_int.h @@ -99,6 +99,7 @@ enum BTA_DM_API_BLE_CONN_PARAM_EVT, BTA_DM_API_BLE_SCAN_PARAM_EVT, BTA_DM_API_BLE_OBSERVE_EVT, + BTA_DM_API_UPDATE_CONN_PARAM_EVT, BTA_DM_API_BLE_ADV_PARAM_EVT, BTA_DM_API_BLE_SET_ADV_CONFIG_EVT, BTA_DM_API_BLE_SET_SCAN_RSP_EVT, @@ -214,6 +215,7 @@ typedef struct tBTA_SERVICE_MASK services; tBTA_DM_SEARCH_CBACK * p_cback; BOOLEAN sdp_search; + tBTA_TRANSPORT transport; #if BLE_INCLUDED == TRUE && BTA_GATT_INCLUDED == TRUE UINT8 num_uuid; tBT_UUID *p_uuid; @@ -236,6 +238,7 @@ typedef struct { BT_HDR hdr; BD_ADDR bd_addr; + tBTA_TRANSPORT transport; } tBTA_DM_API_BOND; /* data type for BTA_DM_API_BOND_CANCEL_EVT */ @@ -243,6 +246,7 @@ typedef struct { BT_HDR hdr; BD_ADDR bd_addr; + tBTA_TRANSPORT transport; } tBTA_DM_API_BOND_CANCEL; /* data type for BTA_DM_API_PIN_REPLY_EVT */ @@ -370,6 +374,10 @@ typedef struct UINT8 new_role; BD_ADDR bd_addr; UINT8 hci_status; +#if BLE_INCLUDED == TRUE + UINT16 handle; + tBT_TRANSPORT transport; +#endif } tBTA_DM_ACL_CHANGE; /* data type for BTA_DM_PM_BTM_STATUS_EVT */ @@ -429,6 +437,7 @@ typedef struct typedef struct { BT_HDR hdr; + tBTA_TRANSPORT transport; tBTA_DM_ENCRYPT_CBACK *p_callback; tBTA_DM_BLE_SEC_ACT sec_act; BD_ADDR bd_addr; @@ -568,7 +577,18 @@ typedef struct BT_HDR hdr; BD_ADDR bd_addr; BOOLEAN remove_dev; + tBTA_TRANSPORT transport; + }tBTA_DM_API_REMOVE_ACL; +typedef struct +{ + BT_HDR hdr; + BD_ADDR bd_addr; + UINT16 min_int; + UINT16 max_int; + UINT16 latency; + UINT16 timeout; +}tBTA_DM_API_UPDATE_CONN_PARAM; #if BLE_ANDROID_CONTROLLER_SCAN_FILTER == TRUE typedef struct @@ -668,6 +688,7 @@ typedef union tBTA_DM_API_ENABLE_SCAN_FILTER ble_enable_scan_filter; tBTA_DM_API_CFG_FILTER_COND ble_cfg_filter_cond; #endif + tBTA_DM_API_UPDATE_CONN_PARAM ble_update_conn_params; #endif tBTA_DM_API_SET_AFH_CHANNEL_ASSESSMENT set_afh_channel_assessment; @@ -707,13 +728,15 @@ typedef struct tBTA_PREF_ROLES pref_role; BOOLEAN in_use; tBTA_DM_DEV_INFO info; + tBTA_DM_ENCRYPT_CBACK *p_encrypt_cback; #if (BTM_SSR_INCLUDED == TRUE) tBTM_PM_STATUS prev_low; /* previous low power mode used */ #endif tBTA_DM_PM_ACTTION pm_mode_attempted; tBTA_DM_PM_ACTTION pm_mode_failed; BOOLEAN remove_dev_pending; - + UINT16 conn_handle; + tBT_TRANSPORT transport; } tBTA_DM_PEER_DEVICE; @@ -724,7 +747,9 @@ typedef struct { tBTA_DM_PEER_DEVICE peer_device[BTA_DM_NUM_PEER_DEVICE]; UINT8 count; - +#if BLE_INCLUDED == TRUE + UINT8 le_count; +#endif } tBTA_DM_ACTIVE_LINK; @@ -805,8 +830,6 @@ typedef struct #endif - tBTA_DM_ENCRYPT_CBACK *p_encrypt_cback; - tBTA_DM_BLE_SEC_ACT sec_act; TIMER_LIST_ENT switch_delay_timer; } tBTA_DM_CB; @@ -837,7 +860,7 @@ typedef struct tSDP_UUID uuid; UINT8 peer_scn; BOOLEAN sdp_search; - + tBTA_TRANSPORT transport; #if ((defined BLE_INCLUDED) && (BLE_INCLUDED == TRUE)) tBTA_DM_SEARCH_CBACK * p_scan_cback; #if ((defined BTA_GATT_INCLUDED) && (BTA_GATT_INCLUDED == TRUE)) @@ -1024,6 +1047,7 @@ extern void bta_dm_ble_set_conn_params (tBTA_DM_MSG *p_data); extern void bta_dm_ble_set_scan_params (tBTA_DM_MSG *p_data); extern void bta_dm_close_gatt_conn(tBTA_DM_MSG *p_data); extern void bta_dm_ble_observe (tBTA_DM_MSG *p_data); +extern void bta_dm_ble_update_conn_params (tBTA_DM_MSG *p_data); extern void bta_dm_ble_set_adv_params (tBTA_DM_MSG *p_data); extern void bta_dm_ble_set_adv_config (tBTA_DM_MSG *p_data); extern void bta_dm_ble_set_scan_rsp (tBTA_DM_MSG *p_data); @@ -1068,6 +1092,10 @@ extern void bta_dm_search_cancel_transac_cmpl(tBTA_DM_MSG *p_data); extern void bta_dm_disc_rmt_name (tBTA_DM_MSG *p_data); extern tBTA_DM_PEER_DEVICE * bta_dm_find_peer_device(BD_ADDR peer_addr); +#if BLE_PRIVACY_SPT == TRUE +extern void bta_dm_ble_config_local_privacy (tBTA_DM_MSG *p_data); +#endif + extern void bta_dm_pm_active(BD_ADDR peer_addr); #if ( BTM_EIR_SERVER_INCLUDED == TRUE ) diff --git a/bta/dm/bta_dm_main.c b/bta/dm/bta_dm_main.c index 74f4d829a..8f8c750d0 100644 --- a/bta/dm/bta_dm_main.c +++ b/bta/dm/bta_dm_main.c @@ -96,6 +96,10 @@ const tBTA_DM_ACTION bta_dm_action[] = bta_dm_ble_set_conn_params, /* BTA_DM_API_BLE_CONN_PARAM_EVT */ bta_dm_ble_set_scan_params, /* BTA_DM_API_BLE_SCAN_PARAM_EVT */ bta_dm_ble_observe, + bta_dm_ble_update_conn_params, /* BTA_DM_API_UPDATE_CONN_PARAM_EVT */ +#if BLE_PRIVACY_SPT == TRUE + bta_dm_ble_config_local_privacy, /* BTA_DM_API_LOCAL_PRIVACY_EVT */ +#endif bta_dm_ble_set_adv_params, /* BTA_DM_API_BLE_SCAN_PARAM_EVT */ bta_dm_ble_set_adv_config, /* BTA_DM_API_BLE_SET_ADV_CONFIG_EVT */ bta_dm_ble_set_scan_rsp, /* BTA_DM_API_BLE_SET_SCAN_RSP_EVT */ diff --git a/bta/gatt/bta_gattc_act.c b/bta/gatt/bta_gattc_act.c index f980c0b92..1b3261b4b 100644 --- a/bta/gatt/bta_gattc_act.c +++ b/bta/gatt/bta_gattc_act.c @@ -45,7 +45,8 @@ ** Constants *****************************************************************************/ static void bta_gattc_conn_cback(tGATT_IF gattc_if, BD_ADDR bda, UINT16 conn_id, - BOOLEAN connected, tGATT_DISCONN_REASON reason); + BOOLEAN connected, tGATT_DISCONN_REASON reason, + tBT_TRANSPORT transport); static void bta_gattc_cmpl_cback(UINT16 conn_id, tGATTC_OPTYPE op, tGATT_STATUS status, tGATT_CL_COMPLETE *p_data); @@ -339,7 +340,8 @@ void bta_gattc_process_api_open (tBTA_GATTC_CB *p_cb, tBTA_GATTC_DATA * p_msg) if (p_msg->api_conn.is_direct) { if ((p_clcb = bta_gattc_find_alloc_clcb(p_msg->api_conn.client_if, - p_msg->api_conn.remote_bda)) != NULL) + p_msg->api_conn.remote_bda, + p_msg->api_conn.transport)) != NULL) { bta_gattc_sm_execute(p_clcb, event, p_msg); } @@ -351,7 +353,7 @@ void bta_gattc_process_api_open (tBTA_GATTC_CB *p_cb, tBTA_GATTC_DATA * p_msg) BTA_GATT_NO_RESOURCES, p_msg->api_conn.remote_bda, BTA_GATT_INVALID_CONN_ID, - 0); + p_msg->api_conn.transport, 0); } } else @@ -385,7 +387,8 @@ void bta_gattc_process_api_open_cancel (tBTA_GATTC_CB *p_cb, tBTA_GATTC_DATA * p if (p_msg->api_cancel_conn.is_direct) { if ((p_clcb = bta_gattc_find_clcb_by_cif(p_msg->api_cancel_conn.client_if, - p_msg->api_cancel_conn.remote_bda)) != NULL) + p_msg->api_cancel_conn.remote_bda, + BTA_GATT_TRANSPORT_LE)) != NULL) { bta_gattc_sm_execute(p_clcb, event, p_msg); } @@ -476,6 +479,7 @@ void bta_gattc_open_error(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_DATA *p_data) BTA_GATT_OK, p_clcb->bda, p_clcb->bta_conn_id, + p_clcb->transport, 0); } /******************************************************************************* @@ -495,8 +499,8 @@ void bta_gattc_open_fail(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_DATA *p_data) BTA_GATT_ERROR, p_clcb->bda, p_clcb->bta_conn_id, + p_clcb->transport, 0); - /* open failure, remove clcb */ bta_gattc_clcb_dealloc(p_clcb); } @@ -515,7 +519,8 @@ void bta_gattc_open(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_DATA *p_data) tBTA_GATTC_DATA gattc_data; /* open/hold a connection */ - if (!GATT_Connect(p_clcb->p_rcb->client_if, p_data->api_conn.remote_bda, TRUE)) + if (!GATT_Connect(p_clcb->p_rcb->client_if, p_data->api_conn.remote_bda, + TRUE, p_data->api_conn.transport)) { APPL_TRACE_ERROR0("Connection open failure"); @@ -526,7 +531,8 @@ void bta_gattc_open(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_DATA *p_data) /* a connected remote device */ if (GATT_GetConnIdIfConnected(p_clcb->p_rcb->client_if, p_data->api_conn.remote_bda, - &p_clcb->bta_conn_id)) + &p_clcb->bta_conn_id, + p_data->api_conn.transport)) { gattc_data.int_conn.hdr.layer_specific = p_clcb->bta_conn_id; @@ -553,8 +559,8 @@ void bta_gattc_init_bk_conn(tBTA_GATTC_API_OPEN *p_data, tBTA_GATTC_RCB *p_clreg if (bta_gattc_mark_bg_conn(p_data->client_if, p_data->remote_bda, TRUE, FALSE)) { - /* alwaya call open to hold a connection */ - if (!GATT_Connect(p_data->client_if, p_data->remote_bda, FALSE)) + /* always call open to hold a connection */ + if (!GATT_Connect(p_data->client_if, p_data->remote_bda, FALSE, p_data->transport)) { status = BTA_GATT_ERROR; APPL_TRACE_ERROR0("bta_gattc_init_bk_conn failed"); @@ -566,9 +572,11 @@ void bta_gattc_init_bk_conn(tBTA_GATTC_API_OPEN *p_data, tBTA_GATTC_RCB *p_clreg /* if is a connected remote device */ if (GATT_GetConnIdIfConnected(p_data->client_if, p_data->remote_bda, - &conn_id)) + &conn_id, + p_data->transport)) { - if ((p_clcb = bta_gattc_find_alloc_clcb(p_data->client_if, p_data->remote_bda)) != NULL) + if ((p_clcb = bta_gattc_find_alloc_clcb(p_data->client_if, p_data->remote_bda, + BTA_GATT_TRANSPORT_LE)) != NULL) { gattc_data.hdr.layer_specific = p_clcb->bta_conn_id = conn_id; @@ -583,7 +591,8 @@ void bta_gattc_init_bk_conn(tBTA_GATTC_API_OPEN *p_data, tBTA_GATTC_RCB *p_clreg /* open failure, report OPEN_EVT */ if (status != BTA_GATT_OK) { - bta_gattc_send_open_cback(p_clreg, status, p_data->remote_bda, BTA_GATT_INVALID_CONN_ID, 0); + bta_gattc_send_open_cback(p_clreg, status, p_data->remote_bda, + BTA_GATT_INVALID_CONN_ID, BTA_GATT_TRANSPORT_LE, 0); } } /******************************************************************************* @@ -687,7 +696,9 @@ void bta_gattc_conn(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_DATA *p_data) { APPL_TRACE_DEBUG1("bta_gattc_conn conn_id=%d",p_data->hdr.layer_specific); p_clcb->bta_conn_id = p_data->int_conn.hdr.layer_specific; - GATT_GetConnectionInfor(p_data->int_conn.hdr.layer_specific, &gatt_if, p_clcb->bda); + + GATT_GetConnectionInfor(p_data->hdr.layer_specific, + &gatt_if, p_clcb->bda, &p_clcb->transport); } p_clcb->p_srcb->connected = TRUE; @@ -721,14 +732,16 @@ void bta_gattc_conn(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_DATA *p_data) if (p_clcb->p_rcb) { - /* there is no RM for GATT */ - if (!BTM_IsBleLink(p_clcb->bda)) - bta_sys_conn_open(BTA_ID_GATTC, BTA_ALL_APP_ID, p_clcb->bda); - bta_gattc_send_open_cback(p_clcb->p_rcb, - BTA_GATT_OK, - p_clcb->bda, - p_clcb->bta_conn_id, - p_clcb->p_srcb->mtu); + /* there is no RM for GATT */ + if (p_clcb->transport == BTA_TRANSPORT_BR_EDR) + bta_sys_conn_open(BTA_ID_GATTC, BTA_ALL_APP_ID, p_clcb->bda); + + bta_gattc_send_open_cback(p_clcb->p_rcb, + BTA_GATT_OK, + p_clcb->bda, + p_clcb->bta_conn_id, + p_clcb->transport, + p_clcb->p_srcb->mtu); } } /******************************************************************************* @@ -780,7 +793,7 @@ void bta_gattc_close(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_DATA *p_data) cb_data.close.status = p_clcb->status; bdcpy(cb_data.close.remote_bda, p_clcb->bda); - if (!BTM_IsBleLink(p_clcb->bda)) + if (p_clcb->transport == BTA_TRANSPORT_BR_EDR) bta_sys_conn_close( BTA_ID_GATTC ,BTA_ALL_APP_ID, p_clcb->bda); bta_gattc_clcb_dealloc(p_clcb); @@ -948,12 +961,16 @@ void bta_gattc_start_discover(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_DATA *p_data) p_clcb->p_srcb->update_count = 0; p_clcb->p_srcb->state = BTA_GATTC_SERV_DISC_ACT; + if (p_clcb->transport == BTA_TRANSPORT_LE) + L2CA_EnableUpdateBleConnParams(p_clcb->p_srcb->server_bda, FALSE); + /* set all srcb related clcb into discovery ST */ bta_gattc_set_discover_st(p_clcb->p_srcb); if ((p_clcb->status = bta_gattc_init_cache(p_clcb->p_srcb)) == BTA_GATT_OK) { - p_clcb->status = bta_gattc_discover_pri_service(p_clcb->bta_conn_id, p_clcb->p_srcb, GATT_DISC_SRVC_ALL); + p_clcb->status = bta_gattc_discover_pri_service(p_clcb->bta_conn_id, + p_clcb->p_srcb, GATT_DISC_SRVC_ALL); } if (p_clcb->status != BTA_GATT_OK) { @@ -993,7 +1010,8 @@ void bta_gattc_disc_cmpl(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_DATA *p_data) APPL_TRACE_DEBUG1("bta_gattc_disc_cmpl conn_id=%d",p_clcb->bta_conn_id); #if BLE_INCLUDED == TRUE - L2CA_EnableUpdateBleConnParams(p_clcb->p_srcb->server_bda, TRUE); + if(p_clcb->transport == BTA_TRANSPORT_LE) + L2CA_EnableUpdateBleConnParams(p_clcb->p_srcb->server_bda, TRUE); #endif p_clcb->p_srcb->state = BTA_GATTC_SERV_IDLE; @@ -1255,11 +1273,14 @@ void bta_gattc_confirm(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_DATA *p_data) { APPL_TRACE_ERROR1("bta_gattc_confirm to handle [0x%04x] failed", handle); } - /* if over BR_EDR, inform PM for mode change */ - else if (!BTM_IsBleLink(p_clcb->bda)) + else { - bta_sys_busy(BTA_ID_GATTC, BTA_ALL_APP_ID, p_clcb->bda); - bta_sys_idle(BTA_ID_GATTC, BTA_ALL_APP_ID, p_clcb->bda); + /* if over BR_EDR, inform PM for mode change */ + if (p_clcb->transport == BTA_TRANSPORT_BR_EDR) + { + bta_sys_busy(BTA_ID_GATTC, BTA_ALL_APP_ID, p_clcb->bda); + bta_sys_idle(BTA_ID_GATTC, BTA_ALL_APP_ID, p_clcb->bda); + } } } } @@ -1292,7 +1313,8 @@ void bta_gattc_read_cmpl(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_OP_CMPL *p_data) &cb_data.read.descr_type) == FALSE) { cb_data.read.status = BTA_GATT_INTERNAL_ERROR; - APPL_TRACE_ERROR1("can not map to GATT ID. handle = 0x%04x", p_data->p_cmpl->att_value.handle); + APPL_TRACE_ERROR1("can not map to GATT ID. handle = 0x%04x", + p_data->p_cmpl->att_value.handle); } else { @@ -1308,10 +1330,12 @@ void bta_gattc_read_cmpl(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_OP_CMPL *p_data) cb_data.read.srvc_id = p_clcb->p_q_cmd->api_read.srvc_id; cb_data.read.char_id = p_clcb->p_q_cmd->api_read.char_id; if (p_clcb->p_q_cmd->api_read.p_descr_type) - memcpy(&cb_data.read.descr_type, p_clcb->p_q_cmd->api_read.p_descr_type, sizeof(tBTA_GATT_ID)); + memcpy(&cb_data.read.descr_type, p_clcb->p_q_cmd->api_read.p_descr_type, + sizeof(tBTA_GATT_ID)); } - event = (p_clcb->p_q_cmd->api_read.p_descr_type == NULL) ? BTA_GATTC_READ_CHAR_EVT: BTA_GATTC_READ_DESCR_EVT; + event = (p_clcb->p_q_cmd->api_read.p_descr_type == NULL) ? + BTA_GATTC_READ_CHAR_EVT: BTA_GATTC_READ_DESCR_EVT; cb_data.read.conn_id = p_clcb->bta_conn_id; utl_freebuf((void **)&p_clcb->p_q_cmd); @@ -1345,10 +1369,13 @@ void bta_gattc_write_cmpl(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_OP_CMPL *p_data) } else { - memcpy(&cb_data.write.srvc_id, &p_clcb->p_q_cmd->api_write.srvc_id, sizeof(tBTA_GATT_SRVC_ID)); - memcpy(&cb_data.write.char_id, &p_clcb->p_q_cmd->api_write.char_id, sizeof(tBTA_GATT_ID)); + memcpy(&cb_data.write.srvc_id, &p_clcb->p_q_cmd->api_write.srvc_id, + sizeof(tBTA_GATT_SRVC_ID)); + memcpy(&cb_data.write.char_id, &p_clcb->p_q_cmd->api_write.char_id, + sizeof(tBTA_GATT_ID)); if (p_clcb->p_q_cmd->api_write.p_descr_type) - memcpy(&cb_data.write.descr_type, p_clcb->p_q_cmd->api_write.p_descr_type, sizeof(tBTA_GATT_ID)); + memcpy(&cb_data.write.descr_type, p_clcb->p_q_cmd->api_write.p_descr_type, + sizeof(tBTA_GATT_ID)); } if (p_clcb->p_q_cmd->api_write.hdr.event == BTA_GATTC_API_WRITE_EVT && @@ -1629,7 +1656,8 @@ void bta_gattc_ci_load(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_DATA *p_data) p_data->ci_load.status == BTA_GATT_MORE) && p_data->ci_load.num_attr > 0) { - bta_gattc_rebuild_cache(p_clcb->p_srcb, p_data->ci_load.num_attr, p_data->ci_load.attr, p_clcb->p_srcb->attr_index); + bta_gattc_rebuild_cache(p_clcb->p_srcb, p_data->ci_load.num_attr, + p_data->ci_load.attr, p_clcb->p_srcb->attr_index); if (p_data->ci_load.status == BTA_GATT_OK) { @@ -1741,7 +1769,8 @@ static void bta_gattc_deregister_cmpl(tBTA_GATTC_RCB *p_clreg) ** *******************************************************************************/ static void bta_gattc_conn_cback(tGATT_IF gattc_if, BD_ADDR bda, UINT16 conn_id, - BOOLEAN connected, tGATT_DISCONN_REASON reason) + BOOLEAN connected, tGATT_DISCONN_REASON reason, + tBT_TRANSPORT transport) { tBTA_GATTC_DATA *p_buf; @@ -1752,11 +1781,13 @@ static void bta_gattc_conn_cback(tGATT_IF gattc_if, BD_ADDR bda, UINT16 conn_id, { memset(p_buf, 0, sizeof(tBTA_GATTC_DATA)); - p_buf->int_conn.hdr.event = connected ? BTA_GATTC_INT_CONN_EVT: BTA_GATTC_INT_DISCONN_EVT; + p_buf->int_conn.hdr.event = connected ? BTA_GATTC_INT_CONN_EVT: + BTA_GATTC_INT_DISCONN_EVT; p_buf->int_conn.hdr.layer_specific = conn_id; p_buf->int_conn.client_if = gattc_if; p_buf->int_conn.role = L2CA_GetBleConnRole(bda); p_buf->int_conn.reason = reason; + p_buf->int_conn.transport = transport; bdcpy(p_buf->int_conn.remote_bda, bda); bta_sys_sendmsg(p_buf); @@ -1777,7 +1808,7 @@ static void bta_gattc_enc_cmpl_cback(tGATT_IF gattc_if, BD_ADDR bda) tBTA_GATTC_DATA *p_buf; tBTA_GATTC_CLCB *p_clcb = NULL; - if ((p_clcb = bta_gattc_find_clcb_by_cif(gattc_if, bda)) == NULL) + if ((p_clcb = bta_gattc_find_clcb_by_cif(gattc_if, bda, BTA_GATT_TRANSPORT_LE)) == NULL) { return; } @@ -1973,8 +2004,9 @@ void bta_gattc_process_indicate(UINT16 conn_id, tGATTC_OPTYPE op, tGATT_CL_COMPL tBTA_GATTC_NOTIFY notify; BD_ADDR remote_bda; tBTA_GATTC_IF gatt_if; + tBTA_TRANSPORT transport; - if (!GATT_GetConnectionInfor(conn_id, &gatt_if, remote_bda)) + if (!GATT_GetConnectionInfor(conn_id, &gatt_if, remote_bda, &transport)) { APPL_TRACE_ERROR0("indication/notif for unknown app"); return; @@ -2008,9 +2040,10 @@ void bta_gattc_process_indicate(UINT16 conn_id, tGATTC_OPTYPE op, tGATT_CL_COMPL /* connection not open yet */ if (p_clcb == NULL) { - if ((p_clcb = bta_gattc_clcb_alloc(gatt_if, remote_bda)) != NULL) + if ((p_clcb = bta_gattc_clcb_alloc(gatt_if, remote_bda, transport)) != NULL) { p_clcb->bta_conn_id = conn_id; + p_clcb->transport = transport; bta_gattc_sm_execute(p_clcb, BTA_GATTC_INT_CONN_EVT, NULL); } @@ -2033,7 +2066,8 @@ void bta_gattc_process_indicate(UINT16 conn_id, tGATTC_OPTYPE op, tGATT_CL_COMPL } else { - APPL_TRACE_ERROR1("Indi/Notif for Unknown handle[0x%04x], can not find in local cache.", handle); + APPL_TRACE_ERROR1("Indi/Notif for Unknown handle[0x%04x], can not find in local cache.", + handle); } } /******************************************************************************* @@ -2068,9 +2102,8 @@ static void bta_gattc_cmpl_cback(UINT16 conn_id, tGATTC_OPTYPE op, tGATT_STATUS return; } - -/* if over BR_EDR, inform PM for mode change */ - if (!BTM_IsBleLink(p_clcb->bda)) + /* if over BR_EDR, inform PM for mode change */ + if (p_clcb->transport == BTA_TRANSPORT_BR_EDR) { bta_sys_busy(BTA_ID_GATTC, BTA_ALL_APP_ID, p_clcb->bda); bta_sys_idle(BTA_ID_GATTC, BTA_ALL_APP_ID, p_clcb->bda); @@ -2112,14 +2145,14 @@ void bta_gattc_init_clcb_conn(UINT8 cif, BD_ADDR remote_bda) UINT16 conn_id; /* should always get the connection ID */ - if (GATT_GetConnIdIfConnected(cif, remote_bda,&conn_id) == FALSE) + if (GATT_GetConnIdIfConnected(cif, remote_bda, &conn_id, BTA_GATT_TRANSPORT_LE) == FALSE) { APPL_TRACE_ERROR0("bta_gattc_init_clcb_conn ERROR: not a connected device"); return; } /* initaite a new connection here */ - if ((p_clcb = bta_gattc_clcb_alloc(cif, remote_bda)) != NULL) + if ((p_clcb = bta_gattc_clcb_alloc(cif, remote_bda, BTA_GATT_TRANSPORT_LE)) != NULL) { gattc_data.hdr.layer_specific = p_clcb->bta_conn_id = conn_id; @@ -2153,7 +2186,7 @@ void bta_gattc_process_listen_all(UINT8 cif) { if (p_conn->in_use ) { - if (bta_gattc_find_clcb_by_cif(cif, p_conn->remote_bda) == NULL) + if (bta_gattc_find_clcb_by_cif(cif, p_conn->remote_bda, BTA_GATT_TRANSPORT_LE) == NULL) { bta_gattc_init_clcb_conn(cif, p_conn->remote_bda); } @@ -2212,7 +2245,9 @@ void bta_gattc_listen(tBTA_GATTC_CB *p_cb, tBTA_GATTC_DATA * p_msg) /* if is a connected remote device */ if (L2CA_GetBleConnRole(p_msg->api_listen.remote_bda) == HCI_ROLE_SLAVE && - bta_gattc_find_clcb_by_cif(p_msg->api_listen.client_if, p_msg->api_listen.remote_bda) == NULL) + bta_gattc_find_clcb_by_cif(p_msg->api_listen.client_if, + p_msg->api_listen.remote_bda, + BTA_GATT_TRANSPORT_LE) == NULL) { bta_gattc_init_clcb_conn(p_msg->api_listen.client_if, @@ -2223,7 +2258,8 @@ void bta_gattc_listen(tBTA_GATTC_CB *p_cb, tBTA_GATTC_DATA * p_msg) else { APPL_TRACE_ERROR0("Listen For All now"); - /* go through all connected device and send callback for all connected slave connection */ + /* go through all connected device and send + callback for all connected slave connection */ bta_gattc_process_listen_all(p_msg->api_listen.client_if); } } diff --git a/bta/gatt/bta_gattc_api.c b/bta/gatt/bta_gattc_api.c index 0bc87ec2a..bfbaf63d1 100644 --- a/bta/gatt/bta_gattc_api.c +++ b/bta/gatt/bta_gattc_api.c @@ -143,11 +143,13 @@ void BTA_GATTC_AppDeregister(tBTA_GATTC_IF client_if) ** Parameters client_if: server interface. ** remote_bda: remote device BD address. ** is_direct: direct connection or background auto connection +** transport: Transport to be used for GATT connection (BREDR/LE) ** ** Returns void ** *******************************************************************************/ -void BTA_GATTC_Open(tBTA_GATTC_IF client_if, BD_ADDR remote_bda, BOOLEAN is_direct) +void BTA_GATTC_Open(tBTA_GATTC_IF client_if, BD_ADDR remote_bda, + BOOLEAN is_direct, tBTA_GATT_TRANSPORT transport) { tBTA_GATTC_API_OPEN *p_buf; @@ -157,6 +159,7 @@ void BTA_GATTC_Open(tBTA_GATTC_IF client_if, BD_ADDR remote_bda, BOOLEAN is_dire p_buf->client_if = client_if; p_buf->is_direct = is_direct; + p_buf->transport = transport; memcpy(p_buf->remote_bda, remote_bda, BD_ADDR_LEN); diff --git a/bta/gatt/bta_gattc_cache.c b/bta/gatt/bta_gattc_cache.c index 3d603c372..64147e2df 100644 --- a/bta/gatt/bta_gattc_cache.c +++ b/bta/gatt/bta_gattc_cache.c @@ -460,12 +460,21 @@ void bta_gattc_get_disc_range(tBTA_GATTC_SERV *p_srvc_cb, UINT16 *p_s_hdl, UINT1 ** Returns status of the operation. ** *******************************************************************************/ -tBTA_GATT_STATUS bta_gattc_discover_pri_service(UINT16 conn_id, tBTA_GATTC_SERV *p_server_cb, UINT8 disc_type) +tBTA_GATT_STATUS bta_gattc_discover_pri_service(UINT16 conn_id, tBTA_GATTC_SERV *p_server_cb, + UINT8 disc_type) { - if (BTM_IsBleLink(p_server_cb->server_bda)) - return bta_gattc_discover_procedure(conn_id, p_server_cb, disc_type); - else - return bta_gattc_sdp_service_disc(conn_id, p_server_cb); + tBTA_GATTC_CLCB *p_clcb = bta_gattc_find_clcb_by_conn_id(conn_id); + tBTA_GATT_STATUS status = BTA_GATT_ERROR; + + if (p_clcb) + { + if (p_clcb->transport == BTA_TRANSPORT_LE) + status = bta_gattc_discover_procedure(conn_id, p_server_cb, disc_type); + else + status = bta_gattc_sdp_service_disc(conn_id, p_server_cb); + } + + return status; } /******************************************************************************* ** @@ -476,7 +485,8 @@ tBTA_GATT_STATUS bta_gattc_discover_pri_service(UINT16 conn_id, tBTA_GATTC_SERV ** Returns status of the operation. ** *******************************************************************************/ -tBTA_GATT_STATUS bta_gattc_discover_procedure(UINT16 conn_id, tBTA_GATTC_SERV *p_server_cb, UINT8 disc_type) +tBTA_GATT_STATUS bta_gattc_discover_procedure(UINT16 conn_id, tBTA_GATTC_SERV *p_server_cb, + UINT8 disc_type) { tGATT_DISC_PARAM param; BOOLEAN is_service = TRUE; @@ -844,7 +854,7 @@ void bta_gattc_sdp_callback (UINT16 sdp_status) service_uuid.uu.uuid16, start_handle, end_handle); #endif - if (GATT_HANDLE_IS_VALID(start_handle) && GATT_HANDLE_IS_VALID(end_handle) && + if (GATT_HANDLE_IS_VALID(start_handle) && GATT_HANDLE_IS_VALID(end_handle)&& p_srvc_cb != NULL) { /* discover services result, add services into a service list */ @@ -856,7 +866,8 @@ void bta_gattc_sdp_callback (UINT16 sdp_status) } else { - APPL_TRACE_ERROR2("invalid start_handle = %d end_handle = %d", start_handle, end_handle); + APPL_TRACE_ERROR2("invalid start_handle = %d end_handle = %d", + start_handle, end_handle); } } @@ -904,9 +915,11 @@ static tBTA_GATT_STATUS bta_gattc_sdp_service_disc(UINT16 conn_id, tBTA_GATTC_SE attr_list[0] = ATTR_ID_SERVICE_CLASS_ID_LIST; attr_list[1] = ATTR_ID_PROTOCOL_DESC_LIST; - SDP_InitDiscoveryDb (bta_gattc_cb.p_sdp_db, BTA_GATT_SDP_DB_SIZE, 1, &uuid, num_attrs, attr_list); + SDP_InitDiscoveryDb (bta_gattc_cb.p_sdp_db, BTA_GATT_SDP_DB_SIZE, 1, + &uuid, num_attrs, attr_list); - if(!SDP_ServiceSearchAttributeRequest (p_server_cb->server_bda, bta_gattc_cb.p_sdp_db, &bta_gattc_sdp_callback)) + if(!SDP_ServiceSearchAttributeRequest (p_server_cb->server_bda, + bta_gattc_cb.p_sdp_db, &bta_gattc_sdp_callback)) { GKI_freebuf(bta_gattc_cb.p_sdp_db); bta_gattc_cb.p_sdp_db = NULL; @@ -990,7 +1003,8 @@ void bta_gattc_disc_res_cback (UINT16 conn_id, tGATT_DISC_TYPE disc_type, tGATT_ break; case GATT_DISC_CHAR_DSCPT: - bta_gattc_add_attr_to_cache(p_srvc_cb, p_data->handle, &p_data->type, 0, BTA_GATTC_ATTR_TYPE_CHAR_DESCR); + bta_gattc_add_attr_to_cache(p_srvc_cb, p_data->handle, &p_data->type, 0, + BTA_GATTC_ATTR_TYPE_CHAR_DESCR); break; } } @@ -1073,7 +1087,8 @@ UINT16 bta_gattc_id2handle(tBTA_GATTC_SERV *p_srcb, tBTA_GATT_SRVC_ID *p_service { #if (defined BTA_GATT_DEBUG && BTA_GATT_DEBUG == TRUE) APPL_TRACE_DEBUG5("\t Attr[0x%04x] handle[0x%04x] uuid[0x%04x] inst[%d] type[%d]", - j + 1, p_attr->attr_handle, p_attr->p_uuid->uuid16, p_attr->inst_id, p_attr->attr_type); + j + 1, p_attr->attr_handle, p_attr->p_uuid->uuid16, + p_attr->inst_id, p_attr->attr_type); #endif bta_gattc_pack_attr_uuid(p_attr, &attr_uuid); @@ -1120,7 +1135,7 @@ UINT16 bta_gattc_id2handle(tBTA_GATTC_SERV *p_srcb, tBTA_GATT_SRVC_ID *p_service else /* another char */ { #if (defined BTA_GATT_DEBUG && BTA_GATT_DEBUG == TRUE) - APPL_TRACE_DEBUG0("no matching descriptor found!! start of next characteristic"); + APPL_TRACE_DEBUG0("no matching descptr found!!start of next characteristic"); #endif char_map = FALSE; done = TRUE; @@ -1178,7 +1193,8 @@ BOOLEAN bta_gattc_handle2id(tBTA_GATTC_SERV *p_srcb, UINT16 handle, tBTA_GATT_SR { #if (defined BTA_GATT_DEBUG && BTA_GATT_DEBUG == TRUE) APPL_TRACE_DEBUG5("\t Attr[0x%04x] handle[0x%04x] uuid[0x%04x] inst[%d] type[%d]", - j + 1, p_attr->attr_handle, p_attr->p_uuid->uuid16, p_attr->inst_id, p_attr->attr_type); + j + 1, p_attr->attr_handle, p_attr->p_uuid->uuid16, + p_attr->inst_id, p_attr->attr_type); #endif if (p_attr->attr_type == BTA_GATTC_ATTR_TYPE_CHAR) p_char = p_attr; @@ -1199,7 +1215,7 @@ BOOLEAN bta_gattc_handle2id(tBTA_GATTC_SERV *p_srcb, UINT16 handle, tBTA_GATT_SR } else { - APPL_TRACE_ERROR0("descriptor does not belong to any chracteristic, error"); + APPL_TRACE_ERROR0("descptr does not belong to any chracteristic"); } } else @@ -1249,7 +1265,8 @@ void bta_gattc_search_service(tBTA_GATTC_CLCB *p_clcb, tBT_UUID *p_uuid) memset(&cb_data, 0, sizeof(tBTA_GATTC)); cb_data.srvc_res.conn_id = p_clcb->bta_conn_id; - memcpy(&cb_data.srvc_res.service_uuid, &p_cache->service_uuid ,sizeof(tBTA_GATT_SRVC_ID)); + memcpy(&cb_data.srvc_res.service_uuid, &p_cache->service_uuid, + sizeof(tBTA_GATT_SRVC_ID)); (* p_clcb->p_rcb->p_cback)(BTA_GATTC_SEARCH_RES_EVT, &cb_data); } @@ -1533,7 +1550,8 @@ void bta_gattc_rebuild_cache(tBTA_GATTC_SERV *p_srvc_cb, UINT16 num_attr, ** *******************************************************************************/ void bta_gattc_fill_nv_attr(tBTA_GATTC_NV_ATTR *p_attr, UINT8 type, UINT16 s_handle, - UINT16 e_handle, UINT8 id, tBT_UUID uuid, UINT8 prop, BOOLEAN is_primary) + UINT16 e_handle, UINT8 id, tBT_UUID uuid, UINT8 prop, + BOOLEAN is_primary) { p_attr->s_handle = s_handle; p_attr->e_handle = e_handle; diff --git a/bta/gatt/bta_gattc_int.h b/bta/gatt/bta_gattc_int.h index 4f192cb1b..37a14c90f 100644 --- a/bta/gatt/bta_gattc_int.h +++ b/bta/gatt/bta_gattc_int.h @@ -118,6 +118,7 @@ typedef struct BD_ADDR remote_bda; tBTA_GATTC_IF client_if; BOOLEAN is_direct; + tBTA_TRANSPORT transport; } tBTA_GATTC_API_OPEN; typedef tBTA_GATTC_API_OPEN tBTA_GATTC_API_CANCEL_OPEN; @@ -202,6 +203,7 @@ typedef struct BD_ADDR remote_bda; tBTA_GATTC_IF client_if; UINT8 role; + tBT_TRANSPORT transport; tGATT_DISCONN_REASON reason; }tBTA_GATTC_INT_CONN; @@ -366,9 +368,11 @@ typedef struct { UINT16 bta_conn_id; /* client channel ID, unique for clcb */ BD_ADDR bda; + tBTA_TRANSPORT transport; /* channel transport */ tBTA_GATTC_RCB *p_rcb; /* pointer to the registration CB */ tBTA_GATTC_SERV *p_srcb; /* server cache CB */ tBTA_GATTC_DATA *p_q_cmd; /* command in queue waiting for execution */ + BOOLEAN buf_held; #define BTA_GATTC_NO_SCHEDULE 0 #define BTA_GATTC_DISC_WAITING 0x01 @@ -444,7 +448,7 @@ extern tBTA_GATTC_CB *bta_gattc_cb_ptr; ** Function prototypes *****************************************************************************/ extern BOOLEAN bta_gattc_hdl_event(BT_HDR *p_msg); -extern void bta_gattc_sm_execute(tBTA_GATTC_CLCB *p_clcb, UINT16 event, tBTA_GATTC_DATA *p_data); +extern BOOLEAN bta_gattc_sm_execute(tBTA_GATTC_CLCB *p_clcb, UINT16 event, tBTA_GATTC_DATA *p_data); /* function processed outside SM */ extern void bta_gattc_disable(tBTA_GATTC_CB *p_cb); @@ -491,7 +495,7 @@ extern void bta_gattc_restart_discover(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_DATA extern void bta_gattc_init_bk_conn(tBTA_GATTC_API_OPEN *p_data, tBTA_GATTC_RCB *p_clreg); extern void bta_gattc_cancel_bk_conn(tBTA_GATTC_API_CANCEL_OPEN *p_data); extern void bta_gattc_send_open_cback( tBTA_GATTC_RCB *p_clreg, tBTA_GATT_STATUS status, - BD_ADDR remote_bda, UINT16 conn_id, UINT16 mtu); + BD_ADDR remote_bda, UINT16 conn_id, tBTA_TRANSPORT transport, UINT16 mtu); extern void bta_gattc_process_api_refresh(tBTA_GATTC_CB *p_cb, tBTA_GATTC_DATA * p_msg); extern void bta_gattc_cfg_mtu(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_DATA *p_data); #if BLE_INCLUDED == TRUE @@ -499,11 +503,11 @@ extern void bta_gattc_listen(tBTA_GATTC_CB *p_cb, tBTA_GATTC_DATA * p_msg); extern void bta_gattc_broadcast(tBTA_GATTC_CB *p_cb, tBTA_GATTC_DATA * p_msg); #endif /* utility functions */ -extern tBTA_GATTC_CLCB * bta_gattc_find_clcb_by_cif (UINT8 client_if, BD_ADDR remote_bda); +extern tBTA_GATTC_CLCB * bta_gattc_find_clcb_by_cif (UINT8 client_if, BD_ADDR remote_bda, tBTA_TRANSPORT transport); extern tBTA_GATTC_CLCB * bta_gattc_find_clcb_by_conn_id (UINT16 conn_id); -extern tBTA_GATTC_CLCB * bta_gattc_clcb_alloc(tBTA_GATTC_IF client_if, BD_ADDR remote_bda); +extern tBTA_GATTC_CLCB * bta_gattc_clcb_alloc(tBTA_GATTC_IF client_if, BD_ADDR remote_bda, tBTA_TRANSPORT transport); extern void bta_gattc_clcb_dealloc(tBTA_GATTC_CLCB *p_clcb); -extern tBTA_GATTC_CLCB * bta_gattc_find_alloc_clcb(tBTA_GATTC_IF client_if, BD_ADDR remote_bda); +extern tBTA_GATTC_CLCB * bta_gattc_find_alloc_clcb(tBTA_GATTC_IF client_if, BD_ADDR remote_bda, tBTA_TRANSPORT transport); extern tBTA_GATTC_RCB * bta_gattc_cl_get_regcb(UINT8 client_if); extern tBTA_GATTC_SERV * bta_gattc_find_srcb(BD_ADDR bda); extern tBTA_GATTC_SERV * bta_gattc_srcb_alloc(BD_ADDR bda); diff --git a/bta/gatt/bta_gattc_main.c b/bta/gatt/bta_gattc_main.c index 932a1d76d..c917d4ae2 100644 --- a/bta/gatt/bta_gattc_main.c +++ b/bta/gatt/bta_gattc_main.c @@ -288,14 +288,16 @@ static char *gattc_state_code(tBTA_GATTC_STATE state_code); ** Description State machine event handling function for GATTC ** ** -** Returns void +** Returns BOOLEAN : TRUE if queued client request buffer can be immediately released +** else FALSE ** *******************************************************************************/ -void bta_gattc_sm_execute(tBTA_GATTC_CLCB *p_clcb, UINT16 event, tBTA_GATTC_DATA *p_data) +BOOLEAN bta_gattc_sm_execute(tBTA_GATTC_CLCB *p_clcb, UINT16 event, tBTA_GATTC_DATA *p_data) { tBTA_GATTC_ST_TBL state_table; UINT8 action; int i; + BOOLEAN rt = TRUE; #if BTA_GATT_DEBUG == TRUE tBTA_GATTC_STATE in_state = p_clcb->state; UINT16 in_event = event; @@ -320,6 +322,8 @@ void bta_gattc_sm_execute(tBTA_GATTC_CLCB *p_clcb, UINT16 event, tBTA_GATTC_DATA if ((action = state_table[event][i]) != BTA_GATTC_IGNORE) { (*bta_gattc_action[action])(p_clcb, p_data); + p_clcb->buf_held = FALSE; + rt = FALSE; } else { @@ -336,6 +340,7 @@ void bta_gattc_sm_execute(tBTA_GATTC_CLCB *p_clcb, UINT16 event, tBTA_GATTC_DATA gattc_evt_code(in_event)); } #endif +return rt; } /******************************************************************************* @@ -345,7 +350,7 @@ void bta_gattc_sm_execute(tBTA_GATTC_CLCB *p_clcb, UINT16 event, tBTA_GATTC_DATA ** Description GATT client main event handling function. ** ** -** Returns void +** Returns BOOLEAN ** *******************************************************************************/ BOOLEAN bta_gattc_hdl_event(BT_HDR *p_msg) @@ -353,6 +358,7 @@ BOOLEAN bta_gattc_hdl_event(BT_HDR *p_msg) tBTA_GATTC_CB *p_cb = &bta_gattc_cb; tBTA_GATTC_CLCB *p_clcb = NULL; tBTA_GATTC_RCB *p_clreg; + BOOLEAN rt = TRUE; #if BTA_GATT_DEBUG == TRUE APPL_TRACE_DEBUG1("bta_gattc_hdl_event: Event [%s]", gattc_evt_code(p_msg->event)); #endif @@ -410,7 +416,7 @@ BOOLEAN bta_gattc_hdl_event(BT_HDR *p_msg) if (p_clcb != NULL) { - bta_gattc_sm_execute(p_clcb, p_msg->event, (tBTA_GATTC_DATA *) p_msg); + rt = bta_gattc_sm_execute(p_clcb, p_msg->event, (tBTA_GATTC_DATA *) p_msg); } else { @@ -421,7 +427,7 @@ BOOLEAN bta_gattc_hdl_event(BT_HDR *p_msg) } - return(TRUE); + return rt; } diff --git a/bta/gatt/bta_gattc_utils.c b/bta/gatt/bta_gattc_utils.c index b52e52cfa..99b222a87 100644 --- a/bta/gatt/bta_gattc_utils.c +++ b/bta/gatt/bta_gattc_utils.c @@ -163,7 +163,8 @@ UINT8 bta_gattc_num_reg_app(void) ** Returns pointer to the clcb ** *******************************************************************************/ -tBTA_GATTC_CLCB * bta_gattc_find_clcb_by_cif (UINT8 client_if, BD_ADDR remote_bda) +tBTA_GATTC_CLCB * bta_gattc_find_clcb_by_cif (UINT8 client_if, BD_ADDR remote_bda, + tBTA_TRANSPORT transport) { tBTA_GATTC_CLCB *p_clcb = &bta_gattc_cb.clcb[0]; UINT8 i; @@ -172,6 +173,7 @@ tBTA_GATTC_CLCB * bta_gattc_find_clcb_by_cif (UINT8 client_if, BD_ADDR remote_bd { if (p_clcb->in_use && p_clcb->p_rcb->client_if == client_if && + p_clcb->transport == transport && bdcmp(p_clcb->bda, remote_bda) == 0) return p_clcb; } @@ -209,7 +211,8 @@ tBTA_GATTC_CLCB * bta_gattc_find_clcb_by_conn_id (UINT16 conn_id) ** Returns pointer to the clcb ** *******************************************************************************/ -tBTA_GATTC_CLCB * bta_gattc_clcb_alloc(tBTA_GATTC_IF client_if, BD_ADDR remote_bda) +tBTA_GATTC_CLCB * bta_gattc_clcb_alloc(tBTA_GATTC_IF client_if, BD_ADDR remote_bda, + tBTA_TRANSPORT transport) { UINT8 i_clcb = 0; tBTA_GATTC_CLCB *p_clcb = NULL; @@ -224,6 +227,7 @@ tBTA_GATTC_CLCB * bta_gattc_clcb_alloc(tBTA_GATTC_IF client_if, BD_ADDR remote_b p_clcb = &bta_gattc_cb.clcb[i_clcb]; p_clcb->in_use = TRUE; p_clcb->status = BTA_GATT_OK; + p_clcb->transport = transport; bdcpy(p_clcb->bda, remote_bda); p_clcb->p_rcb = bta_gattc_cl_get_regcb(client_if); @@ -256,13 +260,14 @@ tBTA_GATTC_CLCB * bta_gattc_clcb_alloc(tBTA_GATTC_IF client_if, BD_ADDR remote_b ** Returns pointer to the clcb ** *******************************************************************************/ -tBTA_GATTC_CLCB *bta_gattc_find_alloc_clcb(tBTA_GATTC_IF client_if, BD_ADDR remote_bda) +tBTA_GATTC_CLCB *bta_gattc_find_alloc_clcb(tBTA_GATTC_IF client_if, BD_ADDR remote_bda, + tBTA_TRANSPORT transport) { tBTA_GATTC_CLCB *p_clcb ; - if ((p_clcb = bta_gattc_find_clcb_by_cif(client_if, remote_bda)) == NULL) + if ((p_clcb = bta_gattc_find_clcb_by_cif(client_if, remote_bda, transport)) == NULL) { - p_clcb = bta_gattc_clcb_alloc(client_if, remote_bda); + p_clcb = bta_gattc_clcb_alloc(client_if, remote_bda, transport); } return p_clcb; } @@ -427,167 +432,19 @@ tBTA_GATTC_SERV * bta_gattc_srcb_alloc(BD_ADDR bda) *******************************************************************************/ BOOLEAN bta_gattc_enqueue(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_DATA *p_data) { - BOOLEAN in_q = FALSE; - if (p_clcb->p_q_cmd == NULL && p_data) - { - UINT16 len; - switch (p_data->hdr.event) - { - case BTA_GATTC_API_SEARCH_EVT: - { - if (p_data->api_search.p_srvc_uuid) - { - len = sizeof(tBTA_GATTC_API_SEARCH) + sizeof(tBT_UUID); - } - else - { - len = sizeof(tBTA_GATTC_API_SEARCH); - } - p_clcb->p_q_cmd = (tBTA_GATTC_DATA *)GKI_getbuf(len); - if (p_clcb->p_q_cmd == NULL) - { - APPL_TRACE_ERROR0("allocate buffer failed for p_q_cmd"); - return FALSE; - } - memcpy(p_clcb->p_q_cmd, p_data, sizeof(tBTA_GATTC_API_SEARCH)); - if (p_data->api_search.p_srvc_uuid) - { - tBTA_GATTC_API_SEARCH *p_buf; - p_buf = &(p_clcb->p_q_cmd->api_search); - p_buf->p_srvc_uuid = (tBT_UUID *)(p_buf + 1); - memcpy(p_buf->p_srvc_uuid, p_data->api_search.p_srvc_uuid, - sizeof(tBT_UUID)); - } - break; - } - case BTA_GATTC_API_READ_EVT: - { - if (p_data->api_read.p_descr_type) - { - len = sizeof(tBTA_GATT_ID) + sizeof(tBTA_GATTC_API_READ); - } - else - { - len = sizeof(tBTA_GATTC_API_READ); - } - p_clcb->p_q_cmd = (tBTA_GATTC_DATA *)GKI_getbuf(len); - if (p_clcb->p_q_cmd == NULL) - { - APPL_TRACE_ERROR0("allocate buffer failed for p_q_cmd"); - return FALSE; - } - memcpy(p_clcb->p_q_cmd, p_data, sizeof(tBTA_GATTC_API_READ)); - if (p_data->api_read.p_descr_type) - { - tBTA_GATTC_API_READ *p_buf; - p_buf = &(p_clcb->p_q_cmd->api_read); - p_buf->p_descr_type = (tBTA_GATT_ID *)(p_buf + 1); - memcpy(p_buf->p_descr_type, p_data->api_read.p_descr_type, - sizeof(tBTA_GATT_ID)); - } - break; - } - case BTA_GATTC_API_WRITE_EVT: - { - tBTA_GATTC_API_WRITE *p_buf; - len = sizeof(tBTA_GATTC_API_WRITE) + p_data->api_write.len; - if (p_data->api_write.p_descr_type) - { - len += sizeof(tBTA_GATT_ID); - } - p_clcb->p_q_cmd = (tBTA_GATTC_DATA *)GKI_getbuf(len); - if (p_clcb->p_q_cmd == NULL) - { - APPL_TRACE_ERROR0("allocate buffer failed for p_q_cmd"); - return FALSE; - } - memcpy(p_clcb->p_q_cmd, p_data, sizeof(tBTA_GATTC_API_WRITE)); - p_buf = &(p_clcb->p_q_cmd->api_write); - if (p_data->api_write.p_descr_type) - { - p_buf->p_descr_type = (tBTA_GATT_ID *)(p_buf + 1); - memcpy(p_buf->p_descr_type, p_data->api_write.p_descr_type, - sizeof(tBTA_GATT_ID)); - if (p_buf->len && p_buf->p_value) - { - p_buf->p_value = (UINT8 *)(p_buf->p_descr_type + 1); - memcpy(p_buf->p_value, p_data->api_write.p_value, - p_data->api_write.len); - } - } - else if (p_buf->len && p_buf->p_value) - { - p_buf->p_value = (UINT8 *)(p_buf + 1); - memcpy(p_buf->p_value, p_data->api_write.p_value, - p_data->api_write.len); - } - break; - } - case BTA_GATTC_API_EXEC_EVT: - { - len = sizeof(tBTA_GATTC_API_EXEC); - p_clcb->p_q_cmd = (tBTA_GATTC_DATA *)GKI_getbuf(len); - if (p_clcb->p_q_cmd == NULL) - { - APPL_TRACE_ERROR0("allocate buffer failed for p_q_cmd"); - return FALSE; - } - memcpy(p_clcb->p_q_cmd, p_data, len); - break; - } - case BTA_GATTC_API_READ_MULTI_EVT: - { - len = sizeof(tBTA_GATTC_API_READ_MULTI) + - p_data->api_read_multi.num_attr * sizeof(tBTA_GATTC_ATTR_ID); - p_clcb->p_q_cmd = (tBTA_GATTC_DATA *)GKI_getbuf(len); - if (p_clcb->p_q_cmd == NULL) - { - APPL_TRACE_ERROR0("allocate buffer failed for p_q_cmd"); - return FALSE; - } - memcpy(p_clcb->p_q_cmd, p_data, sizeof(tBTA_GATTC_API_READ_MULTI)); - if (p_data->api_read_multi.num_attr && - p_data->api_read_multi.p_id_list) - { - tBTA_GATTC_API_READ_MULTI *p_buf; - p_buf = &(p_clcb->p_q_cmd->api_read_multi); - p_buf->p_id_list = (tBTA_GATTC_ATTR_ID *)(p_buf + 1); - memcpy(p_buf->p_id_list, p_data->api_read_multi.p_id_list, - p_data->api_read_multi.num_attr * sizeof(tBTA_GATTC_ATTR_ID)); - } - break; - } - case BTA_GATTC_API_CFG_MTU_EVT: - { - len = sizeof(tBTA_GATTC_API_CFG_MTU); - p_clcb->p_q_cmd = (tBTA_GATTC_DATA *)GKI_getbuf(len); - if (p_clcb->p_q_cmd == NULL) - { - APPL_TRACE_ERROR0("allocate buffer failed for p_q_cmd"); - return FALSE; - } - memcpy(p_clcb->p_q_cmd, p_data, len); - break; - } - default: - APPL_TRACE_ERROR1("queue unsupported command %d", p_data->hdr.event); - return FALSE; - } - - in_q = TRUE; - } - else if (p_clcb->p_q_cmd) - { - APPL_TRACE_ERROR0("already has a pending command!!"); - /* skip the callback now. ----- need to send callback ? */ - } - else - { - APPL_TRACE_ERROR0("queue a null command"); - } + if (p_clcb->p_q_cmd == NULL) + { + p_clcb->p_q_cmd = p_data; + p_clcb->buf_held = TRUE; + } + else + { + APPL_TRACE_ERROR0("already has a pending command!!"); + /* skip the callback now. ----- need to send callback ? */ + } + return p_clcb->buf_held; - return in_q; } /******************************************************************************* ** @@ -738,14 +595,16 @@ void bta_gattc_clear_notif_registration(UINT16 conn_id) tBTA_GATTC_IF gatt_if; tBTA_GATTC_RCB *p_clrcb ; UINT8 i; + tGATT_TRANSPORT transport; - if (GATT_GetConnectionInfor(conn_id, &gatt_if, remote_bda)) + if (GATT_GetConnectionInfor(conn_id, &gatt_if, remote_bda, &transport)) { if ((p_clrcb = bta_gattc_cl_get_regcb(gatt_if)) != NULL) { for (i = 0 ; i < BTA_GATTC_NOTIF_REG_MAX; i ++) { - if (p_clrcb->notif_reg[i].in_use && !bdcmp(p_clrcb->notif_reg[i].remote_bda, remote_bda)) + if (p_clrcb->notif_reg[i].in_use && + !bdcmp(p_clrcb->notif_reg[i].remote_bda, remote_bda)) memset(&p_clrcb->notif_reg[i], 0, sizeof(tBTA_GATTC_NOTIF_REG)); } } @@ -919,7 +778,8 @@ BOOLEAN bta_gattc_check_bg_conn (tBTA_GATTC_IF client_if, BD_ADDR remote_bda, U ** *******************************************************************************/ void bta_gattc_send_open_cback( tBTA_GATTC_RCB *p_clreg, tBTA_GATT_STATUS status, - BD_ADDR remote_bda, UINT16 conn_id, UINT16 mtu) + BD_ADDR remote_bda, UINT16 conn_id, + tBTA_TRANSPORT transport, UINT16 mtu) { tBTA_GATTC cb_data; @@ -931,6 +791,7 @@ void bta_gattc_send_open_cback( tBTA_GATTC_RCB *p_clreg, tBTA_GATT_STATUS status cb_data.open.client_if = p_clreg->client_if; cb_data.open.conn_id = conn_id; cb_data.open.mtu = mtu; + cb_data.open.transport = transport; bdcpy(cb_data.open.remote_bda, remote_bda); (*p_clreg->p_cback)(BTA_GATTC_OPEN_EVT, &cb_data); @@ -1053,16 +914,19 @@ tBTA_GATTC_CLCB * bta_gattc_find_int_conn_clcb(tBTA_GATTC_DATA *p_msg) /* try to locate a logic channel */ if ((p_clcb = bta_gattc_find_clcb_by_cif(p_msg->int_conn.client_if, - p_msg->int_conn.remote_bda)) == NULL) + p_msg->int_conn.remote_bda, + p_msg->int_conn.transport)) == NULL) { /* for a background connection or listening connection */ - if (p_msg->int_conn.role == HCI_ROLE_SLAVE || + if (/*p_msg->int_conn.role == HCI_ROLE_SLAVE || */ bta_gattc_check_bg_conn(p_msg->int_conn.client_if, p_msg->int_conn.remote_bda, p_msg->int_conn.role)) { /* allocate a new channel */ - p_clcb = bta_gattc_clcb_alloc(p_msg->int_conn.client_if, p_msg->int_conn.remote_bda); + p_clcb = bta_gattc_clcb_alloc(p_msg->int_conn.client_if, + p_msg->int_conn.remote_bda, + p_msg->int_conn.transport); } } return p_clcb; @@ -1087,12 +951,13 @@ tBTA_GATTC_CLCB * bta_gattc_find_int_disconn_clcb(tBTA_GATTC_DATA *p_msg) if (reason == GATT_CONN_CANCEL || reason == GATT_CONN_L2C_FAILURE) { p_clcb = bta_gattc_find_clcb_by_cif(p_msg->int_conn.client_if, - p_msg->int_conn.remote_bda); + p_msg->int_conn.remote_bda, + p_msg->int_conn.transport); } else if ((p_clcb = bta_gattc_find_clcb_by_conn_id(p_msg->int_conn.hdr.layer_specific)) == NULL) { - APPL_TRACE_DEBUG1("disconnection ID: [%d] not used by BTA", - p_msg->int_conn.hdr.layer_specific); + APPL_TRACE_DEBUG1(" disconnection ID: [%d] not used by BTA", + p_msg->int_conn.hdr.layer_specific); } return p_clcb; } diff --git a/bta/gatt/bta_gatts_act.c b/bta/gatt/bta_gatts_act.c index be0365568..4a24d66ef 100644 --- a/bta/gatt/bta_gatts_act.c +++ b/bta/gatt/bta_gatts_act.c @@ -37,9 +37,12 @@ #include static void bta_gatts_nv_save_cback(BOOLEAN is_saved, tGATTS_HNDL_RANGE *p_hndl_range); -static BOOLEAN bta_gatts_nv_srv_chg_cback(tGATTS_SRV_CHG_CMD cmd, tGATTS_SRV_CHG_REQ *p_req, tGATTS_SRV_CHG_RSP *p_rsp); +static BOOLEAN bta_gatts_nv_srv_chg_cback(tGATTS_SRV_CHG_CMD cmd, tGATTS_SRV_CHG_REQ *p_req, + tGATTS_SRV_CHG_RSP *p_rsp); -static void bta_gatts_conn_cback (tGATT_IF gatt_if, BD_ADDR bda, UINT16 conn_id, BOOLEAN connected, tGATT_DISCONN_REASON reason); +static void bta_gatts_conn_cback (tGATT_IF gatt_if, BD_ADDR bda, UINT16 conn_id, + BOOLEAN connected, tGATT_DISCONN_REASON reason, + tGATT_TRANSPORT transport); static void bta_gatts_send_request_cback (UINT16 conn_id, UINT32 trans_id, tGATTS_REQ_TYPE req_type, tGATTS_DATA *p_data); @@ -85,7 +88,8 @@ static void bta_gatts_nv_save_cback(BOOLEAN is_add, tGATTS_HNDL_RANGE *p_hndl_ra ** Returns none. ** *******************************************************************************/ -static BOOLEAN bta_gatts_nv_srv_chg_cback(tGATTS_SRV_CHG_CMD cmd, tGATTS_SRV_CHG_REQ *p_req, tGATTS_SRV_CHG_RSP *p_rsp) +static BOOLEAN bta_gatts_nv_srv_chg_cback(tGATTS_SRV_CHG_CMD cmd, + tGATTS_SRV_CHG_REQ *p_req, tGATTS_SRV_CHG_RSP *p_rsp) { return bta_gatts_co_srv_chg((tBTA_GATTS_SRV_CHG_CMD) cmd, (tBTA_GATTS_SRV_CHG_REQ *) p_req, @@ -223,14 +227,16 @@ void bta_gatts_register(tBTA_GATTS_CB *p_cb, tBTA_GATTS_DATA *p_msg) p_cb->rcb[first_unuse].p_cback = p_msg->api_reg.p_cback; memcpy(&p_cb->rcb[first_unuse].app_uuid, &p_msg->api_reg.app_uuid, sizeof(tBT_UUID)); cb_data.reg_oper.server_if = - p_cb->rcb[first_unuse].gatt_if = GATT_Register(&p_msg->api_reg.app_uuid, &bta_gatts_cback); + p_cb->rcb[first_unuse].gatt_if = + GATT_Register(&p_msg->api_reg.app_uuid, &bta_gatts_cback); if ( !p_cb->rcb[first_unuse].gatt_if) { status = BTA_GATT_NO_RESOURCES; } else { - if ((p_buf = (tBTA_GATTS_INT_START_IF *) GKI_getbuf(sizeof(tBTA_GATTS_INT_START_IF))) != NULL) + if ((p_buf = + (tBTA_GATTS_INT_START_IF *) GKI_getbuf(sizeof(tBTA_GATTS_INT_START_IF))) != NULL) { p_buf->hdr.event = BTA_GATTS_INT_START_IF_EVT; p_buf->server_if = p_cb->rcb[first_unuse].gatt_if; @@ -275,7 +281,8 @@ void bta_gatts_start_if(tBTA_GATTS_CB *p_cb, tBTA_GATTS_DATA *p_msg) } else { - APPL_TRACE_ERROR1("Unable to start app.: Unknown interface =%d",p_msg->int_start_if.server_if ); + APPL_TRACE_ERROR1("Unable to start app.: Unknown interface =%d", + p_msg->int_start_if.server_if ); } } /******************************************************************************* @@ -358,7 +365,8 @@ void bta_gatts_create_srvc(tBTA_GATTS_CB *p_cb, tBTA_GATTS_DATA * p_msg) if (service_id != 0) { - memcpy(&p_cb->srvc_cb[srvc_idx].service_uuid, &p_msg->api_create_svc.service_uuid, sizeof(tBT_UUID)); + memcpy(&p_cb->srvc_cb[srvc_idx].service_uuid, + &p_msg->api_create_svc.service_uuid, sizeof(tBT_UUID)); p_cb->srvc_cb[srvc_idx].service_id = service_id; p_cb->srvc_cb[srvc_idx].inst_num = p_msg->api_create_svc.inst; p_cb->srvc_cb[srvc_idx].idx = srvc_idx; @@ -617,11 +625,7 @@ void bta_gatts_send_rsp (tBTA_GATTS_CB *p_cb, tBTA_GATTS_DATA * p_msg) ** ** Function bta_gatts_indicate_handle ** -<<<<<<< HEAD -** Description GATTS indicate handel value -======= ** Description GATTS send handle value indication or notification. ->>>>>>> 6ea30bf... LE: UPF 45 bug fixes ** ** Returns none. ** @@ -632,13 +636,14 @@ void bta_gatts_indicate_handle (tBTA_GATTS_CB *p_cb, tBTA_GATTS_DATA * p_msg) tBTA_GATT_STATUS status = BTA_GATT_ILLEGAL_PARAMETER; tGATT_IF gatt_if; BD_ADDR remote_bda; - + tBTA_TRANSPORT transport; p_srvc_cb = bta_gatts_find_srvc_cb_by_attr_id (p_cb, p_msg->api_indicate.attr_id); if (p_srvc_cb ) { - if (GATT_GetConnectionInfor(p_msg->api_indicate.hdr.layer_specific, &gatt_if, remote_bda)) + if (GATT_GetConnectionInfor(p_msg->api_indicate.hdr.layer_specific, + &gatt_if, remote_bda, &transport)) { if (p_msg->api_indicate.need_confirm) @@ -653,7 +658,7 @@ void bta_gatts_indicate_handle (tBTA_GATTS_CB *p_cb, tBTA_GATTS_DATA * p_msg) p_msg->api_indicate.value); /* if over BR_EDR, inform PM for mode change */ - if (!BTM_IsBleLink(remote_bda)) + if (transport == BTA_TRANSPORT_BR_EDR) { bta_sys_busy(BTA_ID_GATTS, BTA_ALL_APP_ID, remote_bda); bta_sys_idle(BTA_ID_GATTS, BTA_ALL_APP_ID, remote_bda); @@ -664,8 +669,7 @@ void bta_gatts_indicate_handle (tBTA_GATTS_CB *p_cb, tBTA_GATTS_DATA * p_msg) APPL_TRACE_ERROR1("Unknown connection ID: %d fail sending notification", p_msg->api_indicate.hdr.layer_specific); } - - if (status != GATT_SUCCESS && p_msg->api_indicate.need_confirm && + if ((status != GATT_SUCCESS || !p_msg->api_indicate.need_confirm) && p_cb->rcb[p_srvc_cb->rcb_idx].p_cback) { (*p_cb->rcb[p_srvc_cb->rcb_idx].p_cback)(BTA_GATTS_CONF_EVT, (tBTA_GATTS *)&status); @@ -692,13 +696,22 @@ void bta_gatts_open (tBTA_GATTS_CB *p_cb, tBTA_GATTS_DATA * p_msg) { tBTA_GATTS_RCB *p_rcb=NULL; tBTA_GATT_STATUS status= BTA_GATT_ERROR; + UINT16 conn_id; UNUSED(p_cb); if ((p_rcb = bta_gatts_find_app_rcb_by_app_if(p_msg->api_open.server_if)) != NULL) { - if (GATT_Connect(p_rcb->gatt_if, p_msg->api_open.remote_bda, p_msg->api_open.is_direct)) + /* should always get the connection ID */ + if (GATT_Connect(p_rcb->gatt_if, p_msg->api_open.remote_bda, + p_msg->api_open.is_direct, p_msg->api_open.transport)) { status = BTA_GATT_OK; + + if (GATT_GetConnIdIfConnected(p_rcb->gatt_if, p_msg->api_open.remote_bda, + &conn_id, p_msg->api_open.transport)) + { + status = BTA_GATT_ALREADY_OPEN; + } } } else @@ -727,7 +740,8 @@ void bta_gatts_cancel_open (tBTA_GATTS_CB *p_cb, tBTA_GATTS_DATA * p_msg) if ((p_rcb = bta_gatts_find_app_rcb_by_app_if(p_msg->api_cancel_open.server_if)) != NULL) { - if (!GATT_CancelConnect(p_rcb->gatt_if, p_msg->api_cancel_open.remote_bda, p_msg->api_cancel_open.is_direct)) + if (!GATT_CancelConnect(p_rcb->gatt_if, p_msg->api_cancel_open.remote_bda, + p_msg->api_cancel_open.is_direct)) { APPL_TRACE_ERROR0("bta_gatts_cancel_open failed for open request"); } @@ -759,9 +773,11 @@ void bta_gatts_close (tBTA_GATTS_CB *p_cb, tBTA_GATTS_DATA * p_msg) tBTA_GATT_STATUS status= BTA_GATT_ERROR; tGATT_IF gatt_if; BD_ADDR remote_bda; + tBTA_GATT_TRANSPORT transport; + UNUSED(p_cb); - if (GATT_GetConnectionInfor(p_msg->hdr.layer_specific, &gatt_if, remote_bda)) + if (GATT_GetConnectionInfor(p_msg->hdr.layer_specific, &gatt_if, remote_bda, &transport)) { if (GATT_Disconnect(p_msg->hdr.layer_specific) != GATT_SUCCESS) { @@ -776,7 +792,7 @@ void bta_gatts_close (tBTA_GATTS_CB *p_cb, tBTA_GATTS_DATA * p_msg) if (p_rcb && p_rcb->p_cback) { - if (!BTM_IsBleLink(remote_bda)) + if (transport == BTA_TRANSPORT_BR_EDR) bta_sys_conn_close( BTA_ID_GATTS ,BTA_ALL_APP_ID, remote_bda); (*p_rcb->p_cback)(BTA_GATTS_CLOSE_EVT, (tBTA_GATTS *)&status); @@ -840,19 +856,21 @@ static void bta_gatts_send_request_cback (UINT16 conn_id, tBTA_GATTS cb_data; tBTA_GATTS_RCB *p_rcb; tGATT_IF gatt_if; + tBTA_GATT_TRANSPORT transport; memset(&cb_data, 0 , sizeof(tBTA_GATTS)); - if (GATT_GetConnectionInfor(conn_id, &gatt_if, cb_data.req_data.remote_bda)) + if (GATT_GetConnectionInfor(conn_id, &gatt_if, cb_data.req_data.remote_bda, &transport)) { p_rcb = bta_gatts_find_app_rcb_by_app_if(gatt_if); - APPL_TRACE_DEBUG3 ("bta_gatts_send_request_cback conn_id=%d trans_id=%d req_type=%d", conn_id, trans_id, req_type); + APPL_TRACE_DEBUG3 ("bta_gatts_send_request_cback conn_id=%d trans_id=%d req_type=%d", + conn_id, trans_id, req_type); if (p_rcb && p_rcb->p_cback) { /* if over BR_EDR, inform PM for mode change */ - if (!BTM_IsBleLink(cb_data.req_data.remote_bda)) + if (transport == BTA_TRANSPORT_BR_EDR) { bta_sys_busy(BTA_ID_GATTS, BTA_ALL_APP_ID, cb_data.req_data.remote_bda); bta_sys_idle(BTA_ID_GATTS, BTA_ALL_APP_ID, cb_data.req_data.remote_bda); @@ -885,7 +903,8 @@ static void bta_gatts_send_request_cback (UINT16 conn_id, ** *******************************************************************************/ static void bta_gatts_conn_cback (tGATT_IF gatt_if, BD_ADDR bda, UINT16 conn_id, - BOOLEAN connected, tGATT_DISCONN_REASON reason) + BOOLEAN connected, tGATT_DISCONN_REASON reason, + tGATT_TRANSPORT transport) { tBTA_GATTS cb_data; UINT8 evt = connected ? BTA_GATTS_CONNECT_EVT: BTA_GATTS_DISCONNECT_EVT; @@ -901,7 +920,7 @@ static void bta_gatts_conn_cback (tGATT_IF gatt_if, BD_ADDR bda, UINT16 conn_id, if (p_reg && p_reg->p_cback) { /* there is no RM for GATT */ - if (!BTM_IsBleLink(bda)) + if (transport == BTA_TRANSPORT_BR_EDR) { if (connected) bta_sys_conn_open(BTA_ID_GATTS, BTA_ALL_APP_ID, bda); @@ -912,6 +931,7 @@ static void bta_gatts_conn_cback (tGATT_IF gatt_if, BD_ADDR bda, UINT16 conn_id, cb_data.conn.conn_id = conn_id; cb_data.conn.server_if = gatt_if; cb_data.conn.reason = reason; + cb_data.conn.transport = transport; memcpy(cb_data.conn.remote_bda, bda, BD_ADDR_LEN); (*p_reg->p_cback)(evt, &cb_data); } diff --git a/bta/gatt/bta_gatts_api.c b/bta/gatt/bta_gatts_api.c index ad30d73f8..79eb6f911 100644 --- a/bta/gatt/bta_gatts_api.c +++ b/bta/gatt/bta_gatts_api.c @@ -464,11 +464,13 @@ void BTA_GATTS_SendRsp (UINT16 conn_id, UINT32 trans_id, ** Parameters server_if: server interface. ** remote_bda: remote device BD address. ** is_direct: direct connection or background auto connection +** transport : Transport on which GATT connection to be opened (BR/EDR or LE) ** ** Returns void ** *******************************************************************************/ -void BTA_GATTS_Open(tBTA_GATTS_IF server_if, BD_ADDR remote_bda, BOOLEAN is_direct) +void BTA_GATTS_Open(tBTA_GATTS_IF server_if, BD_ADDR remote_bda, BOOLEAN is_direct, + tBTA_GATT_TRANSPORT transport) { tBTA_GATTS_API_OPEN *p_buf; @@ -477,6 +479,7 @@ void BTA_GATTS_Open(tBTA_GATTS_IF server_if, BD_ADDR remote_bda, BOOLEAN is_dire p_buf->hdr.event = BTA_GATTS_API_OPEN_EVT; p_buf->server_if = server_if; p_buf->is_direct = is_direct; + p_buf->transport = transport; memcpy(p_buf->remote_bda, remote_bda, BD_ADDR_LEN); bta_sys_sendmsg(p_buf); diff --git a/bta/gatt/bta_gatts_int.h b/bta/gatt/bta_gatts_int.h index ce9553a56..9a12dfd27 100644 --- a/bta/gatt/bta_gatts_int.h +++ b/bta/gatt/bta_gatts_int.h @@ -139,10 +139,12 @@ typedef struct typedef struct { - BT_HDR hdr; - BD_ADDR remote_bda; - tBTA_GATTS_IF server_if; - BOOLEAN is_direct; + BT_HDR hdr; + BD_ADDR remote_bda; + tBTA_GATTS_IF server_if; + BOOLEAN is_direct; + tBTA_GATT_TRANSPORT transport; + }tBTA_GATTS_API_OPEN; typedef tBTA_GATTS_API_OPEN tBTA_GATTS_API_CANCEL_OPEN; diff --git a/bta/hh/bta_hh_le.c b/bta/hh/bta_hh_le.c index 4f297eef7..f2bba4a6e 100644 --- a/bta/hh/bta_hh_le.c +++ b/bta/hh/bta_hh_le.c @@ -347,7 +347,7 @@ void bta_hh_le_open_conn(tBTA_HH_DEV_CB *p_cb, BD_ADDR remote_bda) bta_hh_cb.le_cb_index[BTA_HH_GET_LE_CB_IDX(p_cb->hid_handle)] = p_cb->index; p_cb->in_use = TRUE; - BTA_GATTC_Open(bta_hh_cb.gatt_if, remote_bda, TRUE); + BTA_GATTC_Open(bta_hh_cb.gatt_if, remote_bda, TRUE, BTA_GATT_TRANSPORT_LE); } /******************************************************************************* ** @@ -640,7 +640,8 @@ void bta_hh_le_read_rpt_ref_descr(tBTA_HH_DEV_CB *p_dev_cb, tBTA_HH_LE_RPT *p_rp while (p_rpt != NULL) { - if (!p_rpt->in_use) break; + if(!p_rpt->in_use) + break; if (p_rpt->rpt_type == BTA_HH_RPTT_INPUT) { @@ -674,8 +675,6 @@ void bta_hh_le_read_rpt_ref_descr(tBTA_HH_DEV_CB *p_dev_cb, tBTA_HH_LE_RPT *p_rp break; } } - else - break; if (p_rpt->index == BTA_HH_LE_RPT_MAX - 1) break; @@ -1210,11 +1209,13 @@ void bta_hh_le_pri_service_discovery(tBTA_HH_DEV_CB *p_cb) ** Returns None ** *******************************************************************************/ -void bta_hh_le_encrypt_cback(BD_ADDR bd_addr, void *p_ref_data, tBTM_STATUS result) +void bta_hh_le_encrypt_cback(BD_ADDR bd_addr, tBTA_GATT_TRANSPORT transport, + void *p_ref_data, tBTM_STATUS result) { UINT8 idx = bta_hh_find_cb(bd_addr); tBTA_HH_DEV_CB *p_dev_cb; UNUSED(p_ref_data); + UNUSED (transport); APPL_TRACE_ERROR0("bta_hh_le_encrypt_cback"); @@ -1315,7 +1316,7 @@ void bta_hh_start_security(tBTA_HH_DEV_CB *p_cb, tBTA_HH_DATA *p_buf) } /* verify bond */ - BTM_GetSecurityFlags(p_cb->addr, &sec_flag); + BTM_GetSecurityFlagsByTransport(p_cb->addr, &sec_flag, BT_TRANSPORT_LE); /* if link has been encrypted */ if (sec_flag & BTM_SEC_FLAG_ENCRYPTED) @@ -1327,14 +1328,14 @@ void bta_hh_start_security(tBTA_HH_DEV_CB *p_cb, tBTA_HH_DATA *p_buf) { sec_flag = BTM_BLE_SEC_ENCRYPT; p_cb->status = BTA_HH_ERR_AUTH_FAILED; - BTM_SetEncryption(p_cb->addr, bta_hh_le_encrypt_cback, &sec_flag); + BTM_SetEncryption(p_cb->addr, BTA_TRANSPORT_LE, bta_hh_le_encrypt_cback, &sec_flag); } /* unbonded device, report security error here */ else if (p_cb->sec_mask != BTA_SEC_NONE) { sec_flag = BTM_BLE_SEC_ENCRYPT_NO_MITM; p_cb->status = BTA_HH_ERR_AUTH_FAILED; - BTM_SetEncryption(p_cb->addr, bta_hh_le_encrypt_cback, &sec_flag); + BTM_SetEncryption(p_cb->addr, BTA_TRANSPORT_LE, bta_hh_le_encrypt_cback, &sec_flag); } /* otherwise let it go through */ else @@ -2620,7 +2621,7 @@ static void bta_hh_le_add_dev_bg_conn(tBTA_HH_DEV_CB *p_cb, BOOLEAN check_bond) !p_cb->in_bg_conn && to_add) { /* add device into BG connection to accept remote initiated connection */ - BTA_GATTC_Open(bta_hh_cb.gatt_if, p_cb->addr, FALSE); + BTA_GATTC_Open(bta_hh_cb.gatt_if, p_cb->addr, FALSE, BTA_GATT_TRANSPORT_LE); p_cb->in_bg_conn = TRUE; BTA_DmBleSetBgConnType(BTA_DM_BLE_CONN_AUTO, NULL); diff --git a/bta/include/bta_api.h b/bta/include/bta_api.h index 86d91826c..b8fcddc15 100644 --- a/bta/include/bta_api.h +++ b/bta/include/bta_api.h @@ -200,7 +200,11 @@ typedef UINT16 tBTA_DM_DISC; /* this discoverability mode is a bit mask a // btla-specific ++ typedef UINT16 tBTA_DM_CONN; -// btla-specific -- + +#define BTA_TRANSPORT_UNKNOWN 0 +#define BTA_TRANSPORT_BR_EDR BT_TRANSPORT_BR_EDR +#define BTA_TRANSPORT_LE BT_TRANSPORT_LE +typedef tBT_TRANSPORT tBTA_TRANSPORT; /* Pairable Modes */ #define BTA_DM_PAIRABLE 1 @@ -311,6 +315,8 @@ typedef struct #define BTA_BLE_LIMIT_DISC_FLAG BTM_BLE_LIMIT_DISC_FLAG #define BTA_BLE_GEN_DISC_FLAG BTM_BLE_GEN_DISC_FLAG #define BTA_BLE_BREDR_NOT_SPT BTM_BLE_BREDR_NOT_SPT +#define BTA_BLE_DMT_CONTROLLER_SPT BTM_BLE_DMT_CONTROLLER_SPT +#define BTA_BLE_DMT_HOST_SPT BTM_BLE_DMT_HOST_SPT #define BTA_BLE_NON_LIMIT_DISC_FLAG BTM_BLE_NON_LIMIT_DISC_FLAG #define BTA_BLE_ADV_FLAG_MASK BTM_BLE_ADV_FLAG_MASK #define BTA_BLE_LIMIT_DISC_MASK BTM_BLE_LIMIT_DISC_MASK @@ -439,7 +445,9 @@ typedef UINT8 tBTA_DM_BLE_SCAN_COND_OP; #define BTA_DM_BLE_PF_MANU_DATA BTM_BLE_PF_MANU_DATA #define BTA_DM_BLE_PF_SRVC_DATA_PATTERN BTM_BLE_PF_SRVC_DATA_PATTERN #define BTA_DM_BLE_PF_TYPE_MAX BTM_BLE_PF_TYPE_MAX +#define BTA_DM_BLE_PF_SRVC_DATA BTM_BLE_PF_SRVC_DATA #define BTA_DM_BLE_PF_TYPE_ALL BTM_BLE_PF_TYPE_ALL +#define BTA_DM_BLE_PF_TYPE_MAX BTM_BLE_PF_TYPE_MAX typedef UINT8 tBTA_DM_BLE_PF_COND_TYPE; typedef union @@ -541,6 +549,7 @@ typedef struct /* Structure associated with BTA_DM_PIN_REQ_EVT */ typedef struct { + /* Note: First 3 data members must be, bd_addr, dev_class, and bd_name in order */ BD_ADDR bd_addr; /* BD address peer device. */ DEV_CLASS dev_class; /* Class of Device */ BD_NAME bd_name; /* Name of peer device. */ @@ -674,6 +683,9 @@ typedef struct typedef struct { BD_ADDR bd_addr; /* BD address peer device. */ +#if BLE_INCLUDED == TRUE + tBTA_TRANSPORT link_type; +#endif } tBTA_DM_LINK_UP; /* Structure associated with BTA_DM_LINK_DOWN_EVT */ @@ -682,6 +694,9 @@ typedef struct BD_ADDR bd_addr; /* BD address peer device. */ UINT8 status; /* connection open/closed */ BOOLEAN is_removed; /* TRUE if device is removed when link is down */ +#if BLE_INCLUDED == TRUE + tBTA_TRANSPORT link_type; +#endif } tBTA_DM_LINK_DOWN; /* Structure associated with BTA_DM_ROLE_CHG_EVT */ @@ -859,6 +874,7 @@ typedef struct UINT8 ble_addr_type; tBTM_BLE_EVT_TYPE ble_evt_type; tBT_DEVICE_TYPE device_type; + UINT8 flag; #endif } tBTA_DM_INQ_RES; @@ -920,7 +936,7 @@ typedef void (tBTA_DM_SEARCH_CBACK)(tBTA_DM_SEARCH_EVT event, tBTA_DM_SEARCH *p_ typedef void (tBTA_DM_EXEC_CBACK) (void * p_param); /* Encryption callback*/ -typedef void (tBTA_DM_ENCRYPT_CBACK) (BD_ADDR bd_addr, tBTA_STATUS result); +typedef void (tBTA_DM_ENCRYPT_CBACK) (BD_ADDR bd_addr, tBTA_TRANSPORT transport, tBTA_STATUS result); #if BLE_INCLUDED == TRUE #define BTA_DM_BLE_SEC_NONE BTM_BLE_SEC_NONE @@ -980,13 +996,6 @@ typedef UINT8 tBTA_DM_PM_ACTTION; #define BTA_DM_PM_PARK_IDX 5 /* the actual index to bta_dm_pm_md[] for PARK mode */ #endif -#define BTA_DM_SW_BB_TO_MM BTM_SW_BB_TO_MM -#define BTA_DM_SW_MM_TO_BB BTM_SW_MM_TO_BB -#define BTA_DM_SW_BB_TO_BTC BTM_SW_BB_TO_BTC -#define BTA_DM_SW_BTC_TO_BB BTM_SW_BTC_TO_BB - -typedef tBTM_SW_DIR tBTA_DM_SW_DIR; - /* Switch callback events */ #define BTA_DM_SWITCH_CMPL_EVT 0 /* Completion of the Switch API */ @@ -1023,6 +1032,12 @@ typedef tSDP_DISCOVERY_DB tBTA_DISCOVERY_DB; /* Device features mask definitions */ #define BTA_FEATURE_BYTES_PER_PAGE BTM_FEATURE_BYTES_PER_PAGE #define BTA_EXT_FEATURES_PAGE_MAX BTM_EXT_FEATURES_PAGE_MAX +/* ACL type +*/ +#define BTA_DM_LINK_TYPE_BR_EDR 0x01 +#define BTA_DM_LINK_TYPE_LE 0x02 +#define BTA_DM_LINK_TYPE_ALL 0xFF +typedef UINT8 tBTA_DM_LINK_TYPE; /***************************************************************************** ** External Function Declarations @@ -1274,6 +1289,21 @@ BTA_API extern void BTA_DmBond(BD_ADDR bd_addr); /******************************************************************************* ** +** Function BTA_DmBondByTransport +** +** Description This function initiates a bonding procedure with a peer +** device by designated transport. The bonding procedure enables +** authentication and optionally encryption on the Bluetooth link. +** +** +** Returns void +** +*******************************************************************************/ +BTA_API extern void BTA_DmBondByTransport(BD_ADDR bd_addr, tBTA_TRANSPORT transport); + + +/******************************************************************************* +** ** Function BTA_DmBondCancel ** ** Description This function cancels a bonding procedure with a peer @@ -1596,11 +1626,13 @@ BTA_API extern tBTA_STATUS BTA_DmGetDiRecord( UINT8 get_record_index, tBTA_DI_GE ** ** Parameters: bd_addr - Address of the peer device ** remove_dev - remove device or not after link down +** transport - which transport to close + ** ** Returns void. ** *******************************************************************************/ -BTA_API extern void BTA_DmCloseACL(BD_ADDR bd_addr, BOOLEAN remove_dev); +BTA_API extern void BTA_DmCloseACL(BD_ADDR bd_addr, BOOLEAN remove_dev, tBTA_TRANSPORT transport); /******************************************************************************* ** @@ -1746,7 +1778,8 @@ BTA_API extern void BTA_DmAddBleDevice(BD_ADDR bd_addr, tBLE_ADDR_TYPE addr_type ** Returns void ** *******************************************************************************/ -BTA_API extern void BTA_DmAddBleKey (BD_ADDR bd_addr, tBTA_LE_KEY_VALUE *p_le_key, +BTA_API extern void BTA_DmAddBleKey (BD_ADDR bd_addr, + tBTA_LE_KEY_VALUE *p_le_key, tBTA_LE_KEY_TYPE key_type); /******************************************************************************* @@ -1844,6 +1877,25 @@ BTA_API extern void BTA_DmSearchExt(tBTA_DM_INQ *p_dm_inq, tBTA_SERVICE_MASK_EXT BTA_API extern void BTA_DmDiscoverExt(BD_ADDR bd_addr, tBTA_SERVICE_MASK_EXT *p_services, tBTA_DM_SEARCH_CBACK *p_cback, BOOLEAN sdp_search); +/******************************************************************************* +** +** Function BTA_DmDiscoverByTransport +** +** Description This function does service discovery on particular transport +** for services of a +** peer device. When services.num_uuid is 0, it indicates all +** GATT based services are to be searched; other wise a list of +** UUID of interested services should be provided through +** p_services->p_uuid. +** +** +** +** Returns void +** +*******************************************************************************/ +BTA_API extern void BTA_DmDiscoverByTransport(BD_ADDR bd_addr, tBTA_SERVICE_MASK_EXT *p_services, + tBTA_DM_SEARCH_CBACK *p_cback, BOOLEAN sdp_search, + tBTA_TRANSPORT transport); /******************************************************************************* ** @@ -1855,6 +1907,7 @@ BTA_API extern void BTA_DmDiscoverExt(BD_ADDR bd_addr, tBTA_SERVICE_MASK_EXT *p_ ** bring up unencrypted links, then later encrypt them. ** ** Parameters: bd_addr - Address of the peer device +** transport - transport of the link to be encruypted ** p_callback - Pointer to callback function to indicat the ** link encryption status ** sec_act - This is the security action to indicate @@ -1867,8 +1920,9 @@ BTA_API extern void BTA_DmDiscoverExt(BD_ADDR bd_addr, tBTA_SERVICE_MASK_EXT *p_ ** ** *******************************************************************************/ -BTA_API extern void BTA_DmSetEncryption(BD_ADDR bd_addr, tBTA_DM_ENCRYPT_CBACK *p_callback, - tBTA_DM_BLE_SEC_ACT sec_act); +BTA_API extern void BTA_DmSetEncryption(BD_ADDR bd_addr, tBTA_TRANSPORT transport, + tBTA_DM_ENCRYPT_CBACK *p_callback, + tBTA_DM_BLE_SEC_ACT sec_act); /******************************************************************************* @@ -1974,6 +2028,23 @@ BTA_API extern void BTA_DmBleSetScanRsp (tBTA_BLE_AD_MASK data_mask, *******************************************************************************/ BTA_API extern void BTA_DmBleBroadcast (BOOLEAN start); +/******************************************************************************* +** +** Function BTA_DmBleUpdateConnectionParams +** +** Description Update connection parameters, can only be used when connection is up. +** +** Parameters: bd_addr - BD address of the peer +** min_int - minimum connection interval, [0x0004~ 0x4000] +** max_int - maximum connection interval, [0x0004~ 0x4000] +** latency - slave latency [0 ~ 500] +** timeout - supervision timeout [0x000a ~ 0xc80] +** +** Returns void +** +*******************************************************************************/ +BTA_API extern void BTA_DmBleUpdateConnectionParams(BD_ADDR bd_addr, UINT16 min_int, + UINT16 max_int, UINT16 latency, UINT16 timeout); #endif #ifdef __cplusplus diff --git a/bta/include/bta_gatt_api.h b/bta/include/bta_gatt_api.h index b53b1802a..3fec4a078 100644 --- a/bta/include/bta_gatt_api.h +++ b/bta/include/bta_gatt_api.h @@ -77,21 +77,32 @@ typedef struct #define BTA_GATT_INSUF_RESOURCE GATT_INSUF_RESOURCE /* 0x0011 */ -#define BTA_GATT_ILLEGAL_PARAMETER GATT_ILLEGAL_PARAMETER /* 0x0087 */ -#define BTA_GATT_NO_RESOURCES GATT_NO_RESOURCES /* 0x0080 */ -#define BTA_GATT_INTERNAL_ERROR GATT_INTERNAL_ERROR /* 0x0081 */ -#define BTA_GATT_WRONG_STATE GATT_WRONG_STATE /* 0x0082 */ -#define BTA_GATT_DB_FULL GATT_DB_FULL /* 0x0083 */ -#define BTA_GATT_BUSY GATT_BUSY /* 0x0084 */ -#define BTA_GATT_ERROR GATT_ERROR /* 0x0085 */ -#define BTA_GATT_CMD_STARTED GATT_CMD_STARTED /* 0x0086 */ -#define BTA_GATT_PENDING GATT_PENDING /* 0x0088 */ -#define BTA_GATT_AUTH_FAIL GATT_AUTH_FAIL /* 0x0089 */ -#define BTA_GATT_MORE GATT_MORE /* 0x008a */ -#define BTA_GATT_INVALID_CFG GATT_INVALID_CFG /* 0x008b */ -#define BTA_GATT_DUP_REG 0x008c -#define BTA_GATT_ALREADY_OPEN 0x008d /* 0x008d */ -#define BTA_GATT_CANCEL 0x008e /* 0x008e */ +#define BTA_GATT_NO_RESOURCES GATT_NO_RESOURCES /* 0x80 */ +#define BTA_GATT_INTERNAL_ERROR GATT_INTERNAL_ERROR /* 0x81 */ +#define BTA_GATT_WRONG_STATE GATT_WRONG_STATE /* 0x82 */ +#define BTA_GATT_DB_FULL GATT_DB_FULL /* 0x83 */ +#define BTA_GATT_BUSY GATT_BUSY /* 0x84 */ +#define BTA_GATT_ERROR GATT_ERROR /* 0x85 */ +#define BTA_GATT_CMD_STARTED GATT_CMD_STARTED /* 0x86 */ +#define BTA_GATT_ILLEGAL_PARAMETER GATT_ILLEGAL_PARAMETER /* 0x87 */ +#define BTA_GATT_PENDING GATT_PENDING /* 0x88 */ +#define BTA_GATT_AUTH_FAIL GATT_AUTH_FAIL /* 0x89 */ +#define BTA_GATT_MORE GATT_MORE /* 0x8a */ +#define BTA_GATT_INVALID_CFG GATT_INVALID_CFG /* 0x8b */ +#define BTA_GATT_SERVICE_STARTED GATT_SERVICE_STARTED /* 0x8c */ +#define BTA_GATT_ENCRYPED_MITM GATT_ENCRYPED_MITM /* GATT_SUCCESS */ +#define BTA_GATT_ENCRYPED_NO_MITM GATT_ENCRYPED_NO_MITM /* 0x8d */ +#define BTA_GATT_NOT_ENCRYPTED GATT_NOT_ENCRYPTED /* 0x8e */ + +#define BTA_GATT_DUP_REG 0x8f /* 0x8f */ +#define BTA_GATT_ALREADY_OPEN 0x90 /* 0x90 */ +#define BTA_GATT_CANCEL 0x91 /* 0x91 */ + + /* 0xE0 ~ 0xFC reserved for future use */ +#define BTA_GATT_CCC_CFG_ERR GATT_CCC_CFG_ERR /* 0xFD Client Characteristic Configuration Descriptor Improperly Configured */ +#define BTA_GATT_PRC_IN_PROGRESS GATT_PRC_IN_PROGRESS /* 0xFE Procedure Already in progress */ +#define BTA_GATT_OUT_OF_RANGE GATT_OUT_OF_RANGE /* 0xFFAttribute value out of range */ + typedef UINT8 tBTA_GATT_STATUS; #define BTA_GATT_INVALID_CONN_ID GATT_INVALID_CONN_ID @@ -325,6 +336,7 @@ typedef struct UINT16 conn_id; tBTA_GATTC_IF client_if; BD_ADDR remote_bda; + tBTA_TRANSPORT transport; UINT16 mtu; }tBTA_GATTC_OPEN; @@ -469,12 +481,9 @@ typedef tGATTS_SRV_CHG tBTA_GATTS_SRV_CHG; typedef tGATTS_SRV_CHG_REQ tBTA_GATTS_SRV_CHG_REQ; typedef tGATTS_SRV_CHG_RSP tBTA_GATTS_SRV_CHG_RSP; -enum -{ - BTA_GATT_TRANSPORT_LE, - BTA_GATT_TRANSPORT_BR_EDR, - BTA_GATT_TRANSPORT_LE_BR_EDR -}; +#define BTA_GATT_TRANSPORT_LE GATT_TRANSPORT_LE +#define BTA_GATT_TRANSPORT_BR_EDR GATT_TRANSPORT_BR_EDR +#define BTA_GATT_TRANSPORT_LE_BR_EDR GATT_TRANSPORT_LE_BR_EDR typedef UINT8 tBTA_GATT_TRANSPORT; /* attribute value */ @@ -552,6 +561,7 @@ typedef struct BD_ADDR remote_bda; UINT16 conn_id; tBTA_GATT_REASON reason; /* report disconnect reason */ + tBTA_GATT_TRANSPORT transport; }tBTA_GATTS_CONN; /* GATTS callback data */ @@ -560,7 +570,7 @@ typedef union tBTA_GATTS_REG_OPER reg_oper; tBTA_GATTS_CREATE create; tBTA_GATTS_SRVC_OPER srvc_oper; - tBTA_GATT_STATUS status; /* BTA_GATTS_CONF_EVT */ + tBTA_GATT_STATUS status; /* BTA_GATTS_CONF_EVT or BTA_GATTS_LISTEN_EVT */ tBTA_GATTS_ADD_RESULT add_result; /* add included service: BTA_GATTS_ADD_INCL_SRVC_EVT add char : BTA_GATTS_ADD_CHAR_EVT add char descriptor: BTA_GATTS_ADD_CHAR_DESCR_EVT */ @@ -644,7 +654,8 @@ BTA_API extern void BTA_GATTC_AppDeregister (tBTA_GATTC_IF client_if); ** Returns void ** *******************************************************************************/ -BTA_API extern void BTA_GATTC_Open(tBTA_GATTC_IF client_if, BD_ADDR remote_bda, BOOLEAN is_direct); +BTA_API extern void BTA_GATTC_Open(tBTA_GATTC_IF client_if, BD_ADDR remote_bda, + BOOLEAN is_direct, tBTA_GATT_TRANSPORT transport); /******************************************************************************* ** @@ -1301,7 +1312,8 @@ BTA_API extern void BTA_GATTC_ConfigureMTU (UINT16 conn_id, UINT16 mtu); ** Returns void ** *******************************************************************************/ - BTA_API extern void BTA_GATTS_Open(tBTA_GATTS_IF server_if, BD_ADDR remote_bda, BOOLEAN is_direct); + BTA_API extern void BTA_GATTS_Open(tBTA_GATTS_IF server_if, BD_ADDR remote_bda, + BOOLEAN is_direct, tBTA_GATT_TRANSPORT transport); /******************************************************************************* diff --git a/bta/jv/bta_jv_act.c b/bta/jv/bta_jv_act.c index afbd111bc..f9569b3e7 100644 --- a/bta/jv/bta_jv_act.c +++ b/bta/jv/bta_jv_act.c @@ -886,7 +886,7 @@ void bta_jv_get_remote_device_name(tBTA_JV_MSG *p_data) { BTM_ReadRemoteDeviceName(p_data->get_rmt_name.bd_addr, - (tBTM_CMPL_CB *)bta_jv_get_remote_device_name_cback); + (tBTM_CMPL_CB *)bta_jv_get_remote_device_name_cback, BT_TRANSPORT_BR_EDR); } /******************************************************************************* @@ -903,11 +903,16 @@ void bta_jv_set_service_class (tBTA_JV_MSG *p_data) tBTA_UTL_COD cod; /* set class of device */ - /* BTA_JvSetServiceClass(UINT32 service) assumes that the service class passed to the API function as defined in the assigned number page. - For example: the object transfer bit is bit 20 of the 24-bit Class of device; the value of this bit is 0x00100000 (value 1) - Our btm_api.h defines this bit as #define BTM_COD_SERVICE_OBJ_TRANSFER 0x1000 // (value 2) - This reflects that the service class defined at btm is UINT16, which starts at bit 8 of the 24 bit Class of Device - The following statement converts from (value 1) into (value 2) */ + /* + BTA_JvSetServiceClass(UINT32 service) assumes that the service class passed to the + API function as defined in the assigned number page. + For example: the object transfer bit is bit 20 of the 24-bit Class of device; + the value of this bit is 0x00100000 (value 1) + Our btm_api.h defines this bit as #define BTM_COD_SERVICE_OBJ_TRANSFER 0x1000 (value 2) + This reflects that the service class defined at btm is UINT16, + which starts at bit 8 of the 24 bit Class of Device + The following statement converts from (value 1) into (value 2) + */ cod.service = (p_data->set_service.service >> 8); utl_set_device_class(&cod, BTA_UTL_SET_COD_SERVICE_CLASS); } @@ -921,9 +926,11 @@ void bta_jv_set_service_class (tBTA_JV_MSG *p_data) ** Returns void ** *******************************************************************************/ -static void bta_jv_sec_cback (BD_ADDR bd_addr, void *p_ref_data, tBTM_STATUS result) +static void bta_jv_sec_cback (BD_ADDR bd_addr, tBTA_TRANSPORT transport, + void *p_ref_data, tBTM_STATUS result) { UNUSED(p_ref_data); + UNUSED(transport); tBTA_JV_SET_ENCRYPTION set_enc; if(bta_jv_cb.p_dm_cback) @@ -947,7 +954,7 @@ static void bta_jv_sec_cback (BD_ADDR bd_addr, void *p_ref_data, tBTM_STATUS res *******************************************************************************/ void bta_jv_set_encryption(tBTA_JV_MSG *p_data) { - BTM_SetEncryption(p_data->set_encrypt.bd_addr, bta_jv_sec_cback, NULL); + BTM_SetEncryption(p_data->set_encrypt.bd_addr, BTA_TRANSPORT_BR_EDR, bta_jv_sec_cback, NULL); } /******************************************************************************* diff --git a/bta/jv/bta_jv_api.c b/bta/jv/bta_jv_api.c index 16ab2d5bf..ad0b694e0 100644 --- a/bta/jv/bta_jv_api.c +++ b/bta/jv/bta_jv_api.c @@ -495,11 +495,13 @@ BOOLEAN BTA_JvIsAuthorized(BD_ADDR bd_addr) BOOLEAN BTA_JvIsEncrypted(BD_ADDR bd_addr) { BOOLEAN is_encrypted = FALSE; - UINT8 sec_flags; + UINT8 sec_flags, le_flags; - if(BTM_GetSecurityFlags(bd_addr, &sec_flags)) + if (BTM_GetSecurityFlags(bd_addr, &sec_flags) && + BTM_GetSecurityFlagsByTransport(bd_addr, &le_flags, BT_TRANSPORT_LE)) { - if(sec_flags&BTM_SEC_FLAG_ENCRYPTED) + if(sec_flags & BTM_SEC_FLAG_ENCRYPTED || + le_flags & BTM_SEC_FLAG_ENCRYPTED) is_encrypted = TRUE; } return is_encrypted; diff --git a/btif/include/btif_storage.h b/btif/include/btif_storage.h index 9a69b0053..f64c695d1 100644 --- a/btif/include/btif_storage.h +++ b/btif/include/btif_storage.h @@ -353,4 +353,34 @@ bt_status_t btif_storage_set_remote_addr_type(bt_bdaddr_t *remote_bd_addr, bt_status_t btif_storage_get_remote_version(const bt_bdaddr_t *remote_bd_addr, bt_remote_version_t *p_ver); + +/******************************************************************************* +** +** Function btif_storage_set_dmt_support_type +** +** Description Sets DMT support status for a remote device +** +** Returns BT_STATUS_SUCCESS if config update is successful +** BT_STATUS_FAIL otherwise +** +*******************************************************************************/ + +bt_status_t btif_storage_set_dmt_support_type(const bt_bdaddr_t *remote_bd_addr, + BOOLEAN dmt_supported); + + + +/******************************************************************************* +** +** Function btif_storage_is_dmt_supported_device +** +** Description checks if a device supports Dual mode topology +** +** Returns TRUE if remote supports DMT else FALSE +** +*******************************************************************************/ + +BOOLEAN btif_storage_is_dmt_supported_device(const bt_bdaddr_t *remote_bd_addr); + + #endif /* BTIF_STORAGE_H */ diff --git a/btif/src/bluetooth.c b/btif/src/bluetooth.c index 44644de2d..fe4182f5c 100644 --- a/btif/src/bluetooth.c +++ b/btif/src/bluetooth.c @@ -327,7 +327,7 @@ static const void* get_profile_interface (const char *profile_id) if (is_profile(profile_id, BT_PROFILE_HEALTH_ID)) return btif_hl_get_interface(); -#if BTA_GATT_INCLUDED == TRUE +#if ( BTA_GATT_INCLUDED == TRUE &&BLE_INCLUDED == TRUE) if (is_profile(profile_id, BT_PROFILE_GATT_ID)) return btif_gatt_get_interface(); #endif diff --git a/btif/src/btif_dm.c b/btif/src/btif_dm.c index e72a95e45..40d21fdfa 100644 --- a/btif/src/btif_dm.c +++ b/btif/src/btif_dm.c @@ -1073,6 +1073,12 @@ static void btif_dm_search_devices_evt (UINT16 event, char *p_param) ASSERTC(status == BT_STATUS_SUCCESS, "failed to save remote device (inquiry)", status); #if (defined(BLE_INCLUDED) && (BLE_INCLUDED == TRUE)) status = btif_storage_set_remote_addr_type(&bdaddr, addr_type); + if (( dev_type == BT_DEVICE_TYPE_DUMO)&& + (p_search_data->inq_res.flag & BTA_BLE_DMT_CONTROLLER_SPT) && + (p_search_data->inq_res.flag & BTA_BLE_DMT_HOST_SPT)) + { + btif_storage_set_dmt_support_type (&bdaddr, TRUE); + } ASSERTC(status == BT_STATUS_SUCCESS, "failed to save remote addr type (inquiry)", status); #endif /* Callback to notify upper layer of device */ diff --git a/btif/src/btif_gatt_client.c b/btif/src/btif_gatt_client.c index 59840af05..3d6d09780 100644 --- a/btif/src/btif_gatt_client.c +++ b/btif/src/btif_gatt_client.c @@ -141,7 +141,9 @@ typedef struct uint8_t start; uint8_t has_mask; int8_t rssi; + uint8_t flag; tBT_DEVICE_TYPE device_type; + btgatt_transport_t transport; } __attribute__((packed)) btif_gattc_cb_t; typedef struct @@ -153,8 +155,8 @@ typedef struct typedef struct { btif_gattc_dev_t remote_dev[BTIF_GATT_MAX_OBSERVED_DEV]; - uint8_t addr_type; - uint8_t next_storage_idx; + uint8_t addr_type; + uint8_t next_storage_idx; }__attribute__((packed)) btif_gattc_dev_cb_t; /******************************************************************************* @@ -482,6 +484,8 @@ static void btif_gattc_upstreams_evt(uint16_t event, char* p_param) btif_gattc_cb_t *p_btif_cb = (btif_gattc_cb_t*)p_param; uint8_t remote_name_len; uint8_t *p_eir_remote_name=NULL; + bt_device_type_t dev_type; + bt_property_t properties; p_eir_remote_name = BTA_CheckEirData(p_btif_cb->value, BTM_EIR_COMPLETE_LOCAL_NAME_TYPE, &remote_name_len); @@ -506,6 +510,19 @@ static void btif_gattc_upstreams_evt(uint16_t event, char* p_param) } } + + if (( p_btif_cb->device_type == BT_DEVICE_TYPE_DUMO)&& + (p_btif_cb->flag & BTA_BLE_DMT_CONTROLLER_SPT) && + (p_btif_cb->flag & BTA_BLE_DMT_HOST_SPT)) + { + btif_storage_set_dmt_support_type (&(p_btif_cb->bd_addr), TRUE); + } + + dev_type = p_btif_cb->device_type; + BTIF_STORAGE_FILL_PROPERTY(&properties, + BT_PROPERTY_TYPE_OF_DEVICE, sizeof(dev_type), &dev_type); + btif_storage_set_remote_device_property(&(p_btif_cb->bd_addr), &properties); + HAL_CBACK(bt_gatt_callbacks, client->scan_result_cb, &p_btif_cb->bd_addr, p_btif_cb->rssi, p_btif_cb->value); break; @@ -570,6 +587,7 @@ static void bta_scan_results_cb (tBTA_DM_SEARCH_EVT event, tBTA_DM_SEARCH *p_dat btif_cb.device_type = p_data->inq_res.device_type; btif_cb.rssi = p_data->inq_res.rssi; btif_cb.addr_type = p_data->inq_res.ble_addr_type; + btif_cb.flag = p_data->inq_res.flag; if (p_data->inq_res.p_eir) { memcpy(btif_cb.value, p_data->inq_res.p_eir, 62); @@ -663,6 +681,7 @@ static void btgattc_handle_event(uint16_t event, char* p_param) // Ensure device is in inquiry database int addr_type = 0; int device_type = 0; + tBTA_GATT_TRANSPORT transport = BTA_GATT_TRANSPORT_LE; if (btif_get_device_type(p_cb->bd_addr.address, &addr_type, &device_type) == TRUE && device_type != BT_DEVICE_TYPE_BREDR) @@ -672,8 +691,29 @@ static void btgattc_handle_event(uint16_t event, char* p_param) if (!p_cb->is_direct) BTA_DmBleSetBgConnType(BTM_BLE_CONN_AUTO, NULL); + switch(device_type) + { + case BT_DEVICE_TYPE_BREDR: + transport = BTA_GATT_TRANSPORT_BR_EDR; + break; + + case BT_DEVICE_TYPE_BLE: + transport = BTA_GATT_TRANSPORT_LE; + break; + + case BT_DEVICE_TYPE_DUMO: + if ((p_cb->transport == GATT_TRANSPORT_LE) && + (btif_storage_is_dmt_supported_device(&(p_cb->bd_addr)) == TRUE)) + transport = BTA_GATT_TRANSPORT_LE; + else + transport = BTA_GATT_TRANSPORT_BR_EDR; + break; + } + // Connect! - BTA_GATTC_Open(p_cb->client_if, p_cb->bd_addr.address, p_cb->is_direct); + BTIF_TRACE_DEBUG2 ("BTA_GATTC_Open Transport = %d, dev type = %d", + transport, device_type); + BTA_GATTC_Open(p_cb->client_if, p_cb->bd_addr.address, p_cb->is_direct, transport); break; } @@ -1057,12 +1097,14 @@ static bt_status_t btif_gattc_scan( int client_if, bool start ) (char*) &btif_cb, sizeof(btif_gattc_cb_t), NULL); } -static bt_status_t btif_gattc_open(int client_if, const bt_bdaddr_t *bd_addr, bool is_direct ) +static bt_status_t btif_gattc_open(int client_if, const bt_bdaddr_t *bd_addr, + bool is_direct,int transport) { CHECK_BTGATT_INIT(); btif_gattc_cb_t btif_cb; btif_cb.client_if = (uint8_t) client_if; btif_cb.is_direct = is_direct ? 1 : 0; + btif_cb.transport = (btgatt_transport_t)transport; bdcpy(btif_cb.bd_addr.address, bd_addr->address); return btif_transfer_context(btgattc_handle_event, BTIF_GATTC_OPEN, (char*) &btif_cb, sizeof(btif_gattc_cb_t), NULL); diff --git a/btif/src/btif_gatt_server.c b/btif/src/btif_gatt_server.c index 9fc4fad17..f5ad0f5b1 100644 --- a/btif/src/btif_gatt_server.c +++ b/btif/src/btif_gatt_server.c @@ -100,9 +100,10 @@ typedef struct uint8_t is_direct; uint8_t num_handles; uint8_t properties; - uint8_t transport; uint8_t confirm; uint8_t status; + btgatt_transport_t transport; + } __attribute__((packed)) btif_gatts_cb_t; @@ -369,6 +370,7 @@ static void btgatts_handle_event(uint16_t event, char* p_param) // Ensure device is in inquiry database int addr_type = 0; int device_type = 0; + tBTA_GATT_TRANSPORT transport = BTA_GATT_TRANSPORT_LE; if (btif_get_device_type(p_cb->bd_addr.address, &addr_type, &device_type) == TRUE && device_type != BT_DEVICE_TYPE_BREDR) @@ -378,9 +380,32 @@ static void btgatts_handle_event(uint16_t event, char* p_param) if (!p_cb->is_direct) BTA_DmBleSetBgConnType(BTM_BLE_CONN_AUTO, NULL); + switch(device_type) + { + case BT_DEVICE_TYPE_BREDR: + transport = BTA_GATT_TRANSPORT_BR_EDR; + break; + + case BT_DEVICE_TYPE_BLE: + transport = BTA_GATT_TRANSPORT_LE; + break; + + case BT_DEVICE_TYPE_DUMO: + if ((p_cb->transport == GATT_TRANSPORT_LE) && + (btif_storage_is_dmt_supported_device(&(p_cb->bd_addr)) == TRUE)) + transport = BTA_GATT_TRANSPORT_LE; + else + transport = BTA_GATT_TRANSPORT_BR_EDR; + break; + + default: + BTIF_TRACE_ERROR1 (" GATT Open :Invalid device type %d",device_type); + return; + } + // Connect! BTA_GATTS_Open(p_cb->server_if, p_cb->bd_addr.address, - p_cb->is_direct); + p_cb->is_direct, transport); break; } @@ -489,12 +514,14 @@ static bt_status_t btif_gatts_unregister_app( int server_if ) (char*) &btif_cb, sizeof(btif_gatts_cb_t), NULL); } -static bt_status_t btif_gatts_open( int server_if, const bt_bdaddr_t *bd_addr, bool is_direct ) +static bt_status_t btif_gatts_open( int server_if, const bt_bdaddr_t *bd_addr, + bool is_direct, int transport ) { CHECK_BTGATT_INIT(); btif_gatts_cb_t btif_cb; btif_cb.server_if = (uint8_t) server_if; btif_cb.is_direct = is_direct ? 1 : 0; + btif_cb.transport = (btgatt_transport_t)transport; bdcpy(btif_cb.bd_addr.address, bd_addr->address); return btif_transfer_context(btgatts_handle_event, BTIF_GATTS_OPEN, (char*) &btif_cb, sizeof(btif_gatts_cb_t), NULL); diff --git a/btif/src/btif_gatt_test.c b/btif/src/btif_gatt_test.c index a2cca6a7b..def27533e 100644 --- a/btif/src/btif_gatt_test.c +++ b/btif/src/btif_gatt_test.c @@ -101,11 +101,12 @@ static char * format_uuid(tBT_UUID bt_uuid, char *str_buf) } static void btif_test_connect_cback(tGATT_IF gatt_if, BD_ADDR bda, UINT16 conn_id, - BOOLEAN connected, tGATT_DISCONN_REASON reason) + BOOLEAN connected, tGATT_DISCONN_REASON reason, tBT_TRANSPORT transport) { UNUSED(gatt_if); UNUSED(bda); UNUSED(reason); + UNUSED (transport); ALOGD("%s: conn_id=%d, connected=%d", __FUNCTION__, conn_id, connected); test_cb.conn_id = connected ? conn_id : 0; @@ -242,7 +243,7 @@ bt_status_t btif_gattc_test_command_impl(uint16_t command, btgatt_test_params_t* if (params->u1 == BT_DEVICE_TYPE_BLE) BTM_SecAddBleDevice(params->bda1->address, NULL, BT_DEVICE_TYPE_BLE, 0); - if ( !GATT_Connect(test_cb.gatt_if, params->bda1->address, TRUE) ) + if ( !GATT_Connect(test_cb.gatt_if, params->bda1->address, TRUE, BT_TRANSPORT_LE) ) { ALOGE("%s: GATT_Connect failed!", __FUNCTION__); } diff --git a/btif/src/btif_gatt_util.c b/btif/src/btif_gatt_util.c index 91cf004da..4facdefec 100644 --- a/btif/src/btif_gatt_util.c +++ b/btif/src/btif_gatt_util.c @@ -285,7 +285,7 @@ uint16_t set_read_value(btgatt_read_params_t *p_dest, tBTA_GATTC_READ *p_src) * Encrypted link map handling *******************************************************************************/ -static void btif_gatt_set_encryption_cb (BD_ADDR bd_addr, tBTA_STATUS result); +static void btif_gatt_set_encryption_cb (BD_ADDR bd_addr, tBTA_TRANSPORT transport, tBTA_STATUS result); static BOOLEAN btif_gatt_is_link_encrypted (BD_ADDR bd_addr) { @@ -295,8 +295,10 @@ static BOOLEAN btif_gatt_is_link_encrypted (BD_ADDR bd_addr) return BTA_JvIsEncrypted(bd_addr); } -static void btif_gatt_set_encryption_cb (BD_ADDR bd_addr, tBTA_STATUS result) +static void btif_gatt_set_encryption_cb (BD_ADDR bd_addr, tBTA_TRANSPORT transport, tBTA_STATUS result) { + UNUSED(transport); + if (result != BTA_SUCCESS && result != BTA_BUSY) { bt_bdaddr_t bda; @@ -312,16 +314,39 @@ void btif_gatt_check_encrypted_link (BD_ADDR bd_addr) bt_bdaddr_t bda; bdcpy(bda.address, bd_addr); + int device_type = 0; + int addr_type = 0; +#if (!defined(BLE_DELAY_REQUEST_ENC) || (BLE_DELAY_REQUEST_ENC == FALSE)) if ((btif_storage_get_ble_bonding_key(&bda, BTIF_DM_LE_KEY_PENC, buf, sizeof(btif_dm_ble_penc_keys_t)) == BT_STATUS_SUCCESS) && !btif_gatt_is_link_encrypted(bd_addr)) { -#if (!defined(BLE_DELAY_REQUEST_ENC) || (BLE_DELAY_REQUEST_ENC == FALSE)) - BTA_DmSetEncryption(bd_addr, + tBTA_GATT_TRANSPORT transport = BTA_GATT_TRANSPORT_LE; + + btif_get_device_type(bd_addr, &addr_type, &device_type); + switch(device_type) + { + case BT_DEVICE_TYPE_BREDR: + transport = BTA_GATT_TRANSPORT_BR_EDR; + break; + + case BT_DEVICE_TYPE_BLE: + transport = BTA_GATT_TRANSPORT_LE; + break; + + case BT_DEVICE_TYPE_DUMO: + transport = BTA_GATT_TRANSPORT_LE_BR_EDR; + break; + + default: + BTIF_TRACE_ERROR1 (" GATT Encrypt :Invalid device type %d",device_type); + return; + } + BTA_DmSetEncryption(bd_addr,transport, &btif_gatt_set_encryption_cb, BTM_BLE_SEC_ENCRYPT); -#endif } +#endif } /******************************************************************************* diff --git a/btif/src/btif_storage.c b/btif/src/btif_storage.c index a8499382f..f364701db 100644 --- a/btif/src/btif_storage.c +++ b/btif/src/btif_storage.c @@ -1744,8 +1744,8 @@ BOOLEAN btif_storage_is_fixed_pin_zeros_keyboard(bt_bdaddr_t *remote_bd_addr) bd2str(remote_bd_addr, &bdstr); - /*consider on LAP part of BDA string*/ - bdstr[8] = '\0'; + /*consider on LAP part of BDA string*/ + bdstr[8] = '\0'; int line_size = sizeof(linebuf); if(btif_config_get_str("Local", BTIF_STORAGE_PATH_AUTOPAIR_BLACKLIST, @@ -1757,3 +1757,68 @@ BOOLEAN btif_storage_is_fixed_pin_zeros_keyboard(bt_bdaddr_t *remote_bd_addr) return FALSE; } + +/******************************************************************************* +** +** Function btif_storage_set_dmt_support_type +** +** Description Sets DMT support status for a remote device +** +** Returns BT_STATUS_SUCCESS if config update is successful +** BT_STATUS_FAIL otherwise +** +*******************************************************************************/ + +bt_status_t btif_storage_set_dmt_support_type(const bt_bdaddr_t *remote_bd_addr, + BOOLEAN dmt_supported) +{ + int ret; + bdstr_t bdstr = {0}; + if(remote_bd_addr) + { + bd2str(remote_bd_addr, &bdstr); + } + else + { + BTIF_TRACE_ERROR1("%s NULL BD Address", __FUNCTION__); + return BT_STATUS_FAIL; + } + + ret = btif_config_set_int("Remote", bdstr,"DMTSupported", (int)dmt_supported); + return ret ? BT_STATUS_SUCCESS:BT_STATUS_FAIL; + +} + +/******************************************************************************* +** +** Function btif_storage_is_dmt_supported_device +** +** Description checks if a device supports Dual mode topology +** +** Returns TRUE if remote address is valid and supports DMT else FALSE +** +*******************************************************************************/ + +BOOLEAN btif_storage_is_dmt_supported_device(const bt_bdaddr_t *remote_bd_addr) +{ + int dmt_supported = 0; + bdstr_t bdstr = {0}; + if(remote_bd_addr) + bd2str(remote_bd_addr, &bdstr); + + if(remote_bd_addr) + { + bd2str(remote_bd_addr, &bdstr); + } + else + { + BTIF_TRACE_ERROR1("%s NULL BD Address", __FUNCTION__); + return FALSE; + } + + btif_config_get_int("Remote", bdstr,"DMTSupported", &dmt_supported); + + return dmt_supported == 1 ? TRUE:FALSE; +} + + diff --git a/hci/src/utils.c b/hci/src/utils.c index bfcf72481..85304fa81 100644 --- a/hci/src/utils.c +++ b/hci/src/utils.c @@ -65,6 +65,7 @@ void utils_init (void) *******************************************************************************/ void utils_cleanup (void) { + pthread_mutex_destroy(&utils_mutex); } /******************************************************************************* diff --git a/include/bt_target.h b/include/bt_target.h index c81cbe529..e6b3bb530 100644 --- a/include/bt_target.h +++ b/include/bt_target.h @@ -102,10 +102,6 @@ #define SMP_HOST_ENCRYPT_INCLUDED FALSE #endif -#ifndef SAP_INCLUDED -#define SAP_INCLUDED FALSE -#endif - #ifndef SBC_NO_PCM_CPY_OPTION #define SBC_NO_PCM_CPY_OPTION FALSE #endif @@ -118,34 +114,6 @@ #define BTA_AG_INCLUDED TRUE #endif -#ifndef BTA_CT_INCLUDED -#define BTA_CT_INCLUDED FALSE -#endif - -#ifndef BTA_CG_INCLUDED -#define BTA_CG_INCLUDED FALSE -#endif - -#ifndef BTA_DG_INCLUDED -#define BTA_DG_INCLUDED FALSE -#endif - -#ifndef BTA_FT_INCLUDED -#define BTA_FT_INCLUDED FALSE -#endif - -#ifndef BTA_OP_INCLUDED -#define BTA_OP_INCLUDED FALSE -#endif - -#ifndef BTA_PR_INCLUDED -#define BTA_PR_INCLUDED FALSE -#endif - -#ifndef BTA_SS_INCLUDED -#define BTA_SS_INCLUDED FALSE -#endif - #ifndef BTA_DM_INCLUDED #define BTA_DM_INCLUDED TRUE #endif @@ -171,14 +139,6 @@ #define BTA_FS_INCLUDED TRUE #endif -#ifndef BTA_AC_INCLUDED -#define BTA_AC_INCLUDED FALSE -#endif - -#ifndef BTA_HD_INCLUDED -#define BTA_HD_INCLUDED FALSE -#endif - #ifndef BTA_HH_INCLUDED #define BTA_HH_INCLUDED TRUE #endif @@ -199,68 +159,8 @@ #define BTA_AV_INCLUDED TRUE #endif -#ifndef BTA_AV_VDP_INCLUDED -#define BTA_AV_VDP_INCLUDED FALSE -#endif - -#ifndef BTA_AVK_INCLUDED -#define BTA_AVK_INCLUDED FALSE -#endif - -#ifndef BTA_PBS_INCLUDED -#define BTA_PBS_INCLUDED FALSE -#endif - -#ifndef BTA_PBC_INCLUDED -#define BTA_PBC_INCLUDED FALSE -#endif - -#ifndef BTA_FM_INCLUDED -#define BTA_FM_INCLUDED FALSE -#endif - -#ifndef BTA_FM_DEBUG -#define BTA_FM_DEBUG FALSE -#endif - -#ifndef BTA_FMTX_INCLUDED -#define BTA_FMTX_INCLUDED FALSE -#endif - -#ifndef BTA_FMTX_DEBUG -#define BTA_FMTX_DEBUG FALSE -#endif - -#ifndef BTA_FMTX_FMRX_SWITCH_WORKAROUND -#define BTA_FMTX_FMRX_SWITCH_WORKAROUND FALSE -#endif - -#ifndef BTA_FMTX_US_FCC_RULES -#define BTA_FMTX_US_FCC_RULES FALSE -#endif - -#ifndef BTA_HS_INCLUDED -#define BTA_HS_INCLUDED FALSE -#endif - -#ifndef BTA_MSE_INCLUDED -#define BTA_MSE_INCLUDED FALSE -#endif - -#ifndef BTA_MCE_INCLUDED -#define BTA_MCE_INCLUDED FALSE -#endif - -#ifndef BTA_PLAYBACK_INCLUDED -#define BTA_PLAYBACK_INCLUDED FALSE -#endif - -#ifndef BTA_SSR_INCLUDED -#define BTA_SSR_INCLUDED FALSE -#endif - -#ifndef BTA_JV_INCLUDED -#define BTA_JV_INCLUDED FALSE +#ifndef BTA_GATT_INCLUDED +#define BTA_GATT_INCLUDED TRUE #endif #ifndef BTA_DISABLE_DELAY @@ -397,10 +297,6 @@ #define BTA_DM_SDP_DB_SIZE 8000 #endif -#ifndef FTS_REJECT_INVALID_OBEX_SET_PATH_REQ -#define FTS_REJECT_INVALID_OBEX_SET_PATH_REQ FALSE -#endif - #ifndef HL_INCLUDED #define HL_INCLUDED TRUE #endif @@ -421,8 +317,6 @@ -/* #define BYPASS_AVDATATRACE */ - /****************************************************************************** ** ** Platform-Specific @@ -1130,16 +1024,6 @@ and USER_HW_DISABLE_API macros */ #define BTM_MAX_VSE_CALLBACKS 3 #endif -/* Number of streams for dual stack */ -#ifndef BTM_SYNC_INFO_NUM_STR -#define BTM_SYNC_INFO_NUM_STR 2 -#endif - -/* Number of streams for dual stack in BT Controller */ -#ifndef BTM_SYNC_INFO_NUM_STR_BTC -#define BTM_SYNC_INFO_NUM_STR_BTC 2 -#endif - /****************************************** ** Lisbon Features *******************************************/ @@ -1412,8 +1296,8 @@ and USER_HW_DISABLE_API macros */ #define LOCAL_BLE_CONTROLLER_ID (1) #endif -#ifndef BTM_BLE_PRIVACY_SPT -#define BTM_BLE_PRIVACY_SPT TRUE +#ifndef BLE_PRIVACY_SPT +#define BLE_PRIVACY_SPT TRUE #endif /****************************************************************************** @@ -1433,6 +1317,12 @@ and USER_HW_DISABLE_API macros */ #error "can't have GATT without BLE" #endif +#ifndef BLE_LLT_INCLUDED +#define BLE_LLT_INCLUDED TRUE +#endif +#ifndef BTM_DUMO_ADDR_CENTRAL_ENABLED +#define BTM_DUMO_ADDR_CENTRAL_ENABLED FALSE +#endif #ifndef ATT_INCLUDED #define ATT_INCLUDED TRUE #endif @@ -1450,7 +1340,7 @@ and USER_HW_DISABLE_API macros */ #endif #ifndef BLE_PERIPHERAL_MODE_SUPPORT -#define BLE_PERIPHERAL_MODE_SUPPORT FALSE +#define BLE_PERIPHERAL_MODE_SUPPORT TRUE #endif #ifndef BLE_PERIPHERAL_DISPLAYONLY diff --git a/main/bte_main.c b/main/bte_main.c index b9cbf91da..739548118 100644 --- a/main/bte_main.c +++ b/main/bte_main.c @@ -641,11 +641,19 @@ static char *alloc(int size) APPL_TRACE_DEBUG1("HC alloc size=%d", size); */ + /* Requested buffer size cannot exceed GKI_MAX_BUF_SIZE. */ + if (size > GKI_MAX_BUF_SIZE) + { + APPL_TRACE_ERROR2("HCI DATA SIZE %d greater than MAX %d", + size, GKI_MAX_BUF_SIZE); + return NULL; + } + p_hdr = (BT_HDR *) GKI_getbuf ((UINT16) size); if (p_hdr == NULL) { - APPL_TRACE_WARNING0("alloc returns NO BUFFER!"); + APPL_TRACE_WARNING1("alloc returns NO BUFFER! (sz %d)", size); } return ((char *) p_hdr); diff --git a/stack/avdt/avdt_l2c.c b/stack/avdt/avdt_l2c.c index 2256a90b5..943a3cf87 100644 --- a/stack/avdt/avdt_l2c.c +++ b/stack/avdt/avdt_l2c.c @@ -70,7 +70,8 @@ const tL2CAP_APPL_INFO avdt_l2c_appl = { ** Returns void ** *******************************************************************************/ -static void avdt_sec_check_complete_term (BD_ADDR bd_addr, void *p_ref_data, UINT8 res) +static void avdt_sec_check_complete_term (BD_ADDR bd_addr, tBT_TRANSPORT transport, + void *p_ref_data, UINT8 res) { tAVDT_CCB *p_ccb = NULL; tL2CAP_CFG_INFO cfg; @@ -92,7 +93,7 @@ static void avdt_sec_check_complete_term (BD_ADDR bd_addr, void *p_ref_data, UIN if (res == BTM_SUCCESS) { - /* Send response to the L2CAP layer. */ + /* Send response to the L2CAP layer. */ L2CA_ConnectRsp (bd_addr, p_tbl->id, p_tbl->lcid, L2CAP_CONN_OK, L2CAP_CONN_OK); /* store idx in LCID table, store LCID in routing table */ @@ -127,7 +128,8 @@ static void avdt_sec_check_complete_term (BD_ADDR bd_addr, void *p_ref_data, UIN ** Returns void ** *******************************************************************************/ -static void avdt_sec_check_complete_orig (BD_ADDR bd_addr, void *p_ref_data, UINT8 res) +static void avdt_sec_check_complete_orig (BD_ADDR bd_addr, tBT_TRANSPORT trasnport, + void *p_ref_data, UINT8 res) { tAVDT_CCB *p_ccb = NULL; tL2CAP_CFG_INFO cfg; diff --git a/stack/bnep/bnep_int.h b/stack/bnep/bnep_int.h index 528c80969..0c435efc7 100644 --- a/stack/bnep/bnep_int.h +++ b/stack/bnep/bnep_int.h @@ -234,9 +234,12 @@ extern void bnep_send_conn_req (tBNEP_CONN *p_bcb); extern void bnep_send_conn_responce (tBNEP_CONN *p_bcb, UINT16 resp_code); extern void bnep_process_setup_conn_req (tBNEP_CONN *p_bcb, UINT8 *p_setup, UINT8 len); extern void bnep_process_setup_conn_responce (tBNEP_CONN *p_bcb, UINT8 *p_setup); -extern UINT8 *bnep_process_control_packet (tBNEP_CONN *p_bcb, UINT8 *p, UINT16 *len, BOOLEAN is_ext); -extern void bnep_sec_check_complete (BD_ADDR bd_addr, void *p_ref_data, UINT8 result); -extern tBNEP_RESULT bnep_is_packet_allowed (tBNEP_CONN *p_bcb, BD_ADDR p_dest_addr, UINT16 protocol, BOOLEAN fw_ext_present, UINT8 *p_data); +extern UINT8 *bnep_process_control_packet (tBNEP_CONN *p_bcb, UINT8 *p, UINT16 *len, + BOOLEAN is_ext); +extern void bnep_sec_check_complete (BD_ADDR bd_addr, tBT_TRANSPORT trasnport, + void *p_ref_data, UINT8 result); +extern tBNEP_RESULT bnep_is_packet_allowed (tBNEP_CONN *p_bcb, BD_ADDR p_dest_addr, UINT16 protocol, + BOOLEAN fw_ext_present, UINT8 *p_data); extern UINT32 bnep_get_uuid32 (tBT_UUID *src_uuid); extern void bnep_dump_status (void); diff --git a/stack/bnep/bnep_utils.c b/stack/bnep/bnep_utils.c index 0a8fd6d33..faf808b29 100644 --- a/stack/bnep/bnep_utils.c +++ b/stack/bnep/bnep_utils.c @@ -1209,12 +1209,14 @@ void bnepu_send_peer_multicast_filter_rsp (tBNEP_CONN *p_bcb, UINT16 response_co ** Returns void ** *******************************************************************************/ -void bnep_sec_check_complete (BD_ADDR bd_addr, void *p_ref_data, UINT8 result) +void bnep_sec_check_complete (BD_ADDR bd_addr, tBT_TRANSPORT trasnport, + void *p_ref_data, UINT8 result) { tBNEP_CONN *p_bcb = (tBNEP_CONN *)p_ref_data; UINT16 resp_code = BNEP_SETUP_CONN_OK; BOOLEAN is_role_change; UNUSED(bd_addr); + UNUSED(trasnport); BNEP_TRACE_EVENT1 ("BNEP security callback returned result %d", result); if (p_bcb->con_flags & BNEP_FLAGS_CONN_COMPLETED) diff --git a/stack/btm/btm_acl.c b/stack/btm/btm_acl.c index 0a4ed1a08..ee3088769 100644 --- a/stack/btm/btm_acl.c +++ b/stack/btm/btm_acl.c @@ -130,11 +130,14 @@ void btm_acl_init (void) ** ** Description This function returns the FIRST acl_db entry for the passed BDA. ** +** Parameters bda : BD address of the remote device +** transport : Physical transport used for ACL connection (BR/EDR or LE) +** ** Returns Returns pointer to the ACL DB for the requested BDA if found. ** NULL if not found. ** *******************************************************************************/ -tACL_CONN *btm_bda_to_acl (BD_ADDR bda) +tACL_CONN *btm_bda_to_acl (BD_ADDR bda, tBT_TRANSPORT transport) { tACL_CONN *p = &btm_cb.acl_db[0]; UINT16 xx; @@ -142,7 +145,11 @@ tACL_CONN *btm_bda_to_acl (BD_ADDR bda) { for (xx = 0; xx < MAX_L2CAP_LINKS; xx++, p++) { - if ((p->in_use) && (!memcmp (p->remote_addr, bda, BD_ADDR_LEN))) + if ((p->in_use) && (!memcmp (p->remote_addr, bda, BD_ADDR_LEN)) +#if BLE_INCLUDED == TRUE + && p->transport == transport +#endif + ) { BTM_TRACE_DEBUG0 ("btm_bda_to_acl found"); return(p); @@ -180,7 +187,7 @@ UINT8 btm_handle_to_acl_index (UINT16 hci_handle) return(xx); } -#if BTM_BLE_PRIVACY_SPT == TRUE +#if BLE_PRIVACY_SPT == TRUE /******************************************************************************* ** ** Function btm_ble_get_acl_remote_addr @@ -243,24 +250,24 @@ BOOLEAN btm_ble_get_acl_remote_addr(tBTM_SEC_DEV_REC *p_dev_rec, BD_ADDR conn_ad ** *******************************************************************************/ void btm_acl_created (BD_ADDR bda, DEV_CLASS dc, BD_NAME bdn, - UINT16 hci_handle, UINT8 link_role, UINT8 is_le_link) + UINT16 hci_handle, UINT8 link_role, tBT_TRANSPORT transport) { tBTM_SEC_DEV_REC *p_dev_rec = NULL; UINT8 yy; tACL_CONN *p; UINT8 xx; - BTM_TRACE_DEBUG3 ("btm_acl_created hci_handle=%d link_role=%d is_le_link=%d", - hci_handle,link_role, is_le_link); + BTM_TRACE_DEBUG3 ("btm_acl_created hci_handle=%d link_role=%d transport=%d", + hci_handle,link_role, transport); /* Ensure we don't have duplicates */ - p = btm_bda_to_acl(bda); + p = btm_bda_to_acl(bda, transport); if (p != (tACL_CONN *)NULL) { p->hci_handle = hci_handle; p->link_role = link_role; btm_save_remote_device_role(bda, link_role); #if BLE_INCLUDED == TRUE - p->is_le_link = is_le_link; + p->transport = transport; #endif BTM_TRACE_DEBUG6 ("Duplicate btm_acl_created: RemBdAddr: %02x%02x%02x%02x%02x%02x", bda[0], bda[1], bda[2], bda[3], bda[4], bda[5]); @@ -280,14 +287,23 @@ void btm_acl_created (BD_ADDR bda, DEV_CLASS dc, BD_NAME bdn, p->link_up_issued = FALSE; #if BLE_INCLUDED == TRUE - p->is_le_link = is_le_link; - - if (is_le_link) + p->transport = transport; + if (transport == BT_TRANSPORT_LE) { - p->conn_addr_type = BLE_ADDR_PUBLIC; - BTM_GetLocalDeviceAddr(p->conn_addr); +#if ( BLE_PRIVACY_SPT == TRUE ) + /*allow central device to use random address for now by skipping the role check */ + if (btm_cb.ble_ctr_cb.privacy /* && p->link_role == HCI_ROLE_SLAVE */) + { + p->conn_addr_type = btm_cb.ble_ctr_cb.addr_mgnt_cb.own_addr_type; + memcpy(p->conn_addr, btm_cb.ble_ctr_cb.addr_mgnt_cb.private_addr, BD_ADDR_LEN); + } + else +#endif + { + p->conn_addr_type = BLE_ADDR_PUBLIC; + BTM_GetLocalDeviceAddr(p->conn_addr); + } } - #endif p->restore_pkt_types = 0; /* Only exists while SCO is active */ p->switch_role_state = BTM_ACL_SWKEY_STATE_IDLE; @@ -307,7 +323,7 @@ void btm_acl_created (BD_ADDR bda, DEV_CLASS dc, BD_NAME bdn, memcpy (p->remote_name, bdn, BTM_MAX_REM_BD_NAME_LEN); /* if BR/EDR do something more */ - if (!is_le_link) + if (transport == BT_TRANSPORT_BR_EDR) { btsnd_hcic_read_rmt_clk_offset (p->hci_handle); btsnd_hcic_rmt_ver_req (p->hci_handle); @@ -321,7 +337,7 @@ void btm_acl_created (BD_ADDR bda, DEV_CLASS dc, BD_NAME bdn, } #endif - if (p_dev_rec && !is_le_link) + if (p_dev_rec && !(transport == BT_TRANSPORT_LE)) { /* If remote features already known, copy them and continue connection setup */ if ((p_dev_rec->num_read_pages) && @@ -349,9 +365,9 @@ void btm_acl_created (BD_ADDR bda, DEV_CLASS dc, BD_NAME bdn, #if (BLE_INCLUDED == TRUE) /* If here, features are not known yet */ - if (p_dev_rec && is_le_link) + if (p_dev_rec && transport == BT_TRANSPORT_LE) { -#if BTM_BLE_PRIVACY_SPT == TRUE +#if BLE_PRIVACY_SPT == TRUE btm_ble_get_acl_remote_addr (p_dev_rec, p->active_remote_addr, &p->active_remote_addr_type); #endif @@ -413,7 +429,7 @@ void btm_acl_report_role_change (UINT8 hci_status, BD_ADDR bda) ** Returns void ** *******************************************************************************/ -void btm_acl_removed (BD_ADDR bda) +void btm_acl_removed (BD_ADDR bda, tBT_TRANSPORT transport) { tACL_CONN *p; #if (defined(BTM_BUSY_LEVEL_CHANGE_INCLUDED) && BTM_BUSY_LEVEL_CHANGE_INCLUDED == TRUE) @@ -424,7 +440,7 @@ void btm_acl_removed (BD_ADDR bda) #endif BTM_TRACE_DEBUG0 ("btm_acl_removed"); - p = btm_bda_to_acl(bda); + p = btm_bda_to_acl(bda, transport); if (p != (tACL_CONN *)NULL) { p->in_use = FALSE; @@ -443,22 +459,29 @@ void btm_acl_removed (BD_ADDR bda) { evt_data.event = BTM_BL_DISCN_EVT; evt_data.discn.p_bda = bda; - +#if BLE_INCLUDED == TRUE + evt_data.discn.handle = p->hci_handle; + evt_data.discn.transport = p->transport; +#endif (*btm_cb.p_bl_changed_cb)(&evt_data); } btm_acl_update_busy_level (BTM_BLI_ACL_DOWN_EVT); #else if (btm_cb.p_acl_changed_cb) +#if BLE_INCLUDED == TRUE + (*btm_cb.p_acl_changed_cb) (bda, NULL, NULL, NULL, FALSE, p->hci_handle, p->transport); +#else (*btm_cb.p_acl_changed_cb) (bda, NULL, NULL, NULL, FALSE); #endif +#endif } #if (defined BLE_INCLUDED && BLE_INCLUDED == TRUE) - BTM_TRACE_DEBUG4 ("acl hci_handle=%d is_le_link=%d connectable_mode=0x%0x link_role=%d", + BTM_TRACE_DEBUG4 ("acl hci_handle=%d transport=%d connectable_mode=0x%0x link_role=%d", p->hci_handle, - p->is_le_link, + p->transport, btm_cb.ble_ctr_cb.inq_var.connectable_mode, p->link_role); @@ -466,14 +489,14 @@ void btm_acl_removed (BD_ADDR bda) if ( p_dev_rec) { BTM_TRACE_DEBUG1("before update p_dev_rec->sec_flags=0x%x", p_dev_rec->sec_flags); - if (p->is_le_link) + if (p->transport == BT_TRANSPORT_LE) { BTM_TRACE_DEBUG0("LE link down"); - p_dev_rec->sec_flags &= ~(BTM_SEC_ENCRYPTED | BTM_SEC_ROLE_SWITCHED); - if ( (p_dev_rec->sec_flags & BTM_SEC_LINK_KEY_KNOWN) == 0) + p_dev_rec->sec_flags &= ~(BTM_SEC_LE_ENCRYPTED | BTM_SEC_ROLE_SWITCHED); + if ( (p_dev_rec->sec_flags & BTM_SEC_LE_LINK_KEY_KNOWN) == 0) { BTM_TRACE_DEBUG0("Not Bonded"); - p_dev_rec->sec_flags &= ~(BTM_SEC_AUTHENTICATED | BTM_SEC_LINK_KEY_AUTHED); + p_dev_rec->sec_flags &= ~(BTM_SEC_LE_LINK_KEY_AUTHED | BTM_SEC_LE_AUTHENTICATED); } else { @@ -541,6 +564,7 @@ void btm_acl_update_busy_level (tBTM_BLI_EVENT event) tBTM_BL_UPDATE_DATA evt; UINT8 busy_level; BTM_TRACE_DEBUG0 ("btm_acl_update_busy_level"); + BOOLEAN old_inquiry_state = btm_cb.is_inquiry; switch (event) { case BTM_BLI_ACL_UP_EVT: @@ -590,7 +614,7 @@ void btm_acl_update_busy_level (tBTM_BLI_EVENT event) else busy_level = (UINT8)btm_cb.num_acl; - if (busy_level != btm_cb.busy_level) + if ((busy_level != btm_cb.busy_level) ||(old_inquiry_state != btm_cb.is_inquiry)) { evt.event = BTM_BL_UPDATE_EVT; evt.busy_level = busy_level; @@ -619,7 +643,7 @@ tBTM_STATUS BTM_GetRole (BD_ADDR remote_bd_addr, UINT8 *p_role) { tACL_CONN *p; BTM_TRACE_DEBUG0 ("BTM_GetRole"); - if ((p = btm_bda_to_acl(remote_bd_addr)) == NULL) + if ((p = btm_bda_to_acl(remote_bd_addr, BT_TRANSPORT_BR_EDR)) == NULL) { *p_role = BTM_ROLE_UNDEFINED; return(BTM_UNKNOWN_ADDR); @@ -682,7 +706,7 @@ tBTM_STATUS BTM_SwitchRole (BD_ADDR remote_bd_addr, UINT8 new_role, tBTM_CMPL_CB return(BTM_BUSY); } - if ((p = btm_bda_to_acl(remote_bd_addr)) == NULL) + if ((p = btm_bda_to_acl(remote_bd_addr, BT_TRANSPORT_BR_EDR)) == NULL) return(BTM_UNKNOWN_ADDR); /* Finished if already in desired role */ @@ -807,7 +831,7 @@ tBTM_STATUS BTM_ChangeLinkKey (BD_ADDR remote_bd_addr, tBTM_CMPL_CB *p_cb) tBTM_PM_PWR_MD settings; #endif BTM_TRACE_DEBUG0 ("BTM_ChangeLinkKey"); - if ((p = btm_bda_to_acl(remote_bd_addr)) == NULL) + if ((p = btm_bda_to_acl(remote_bd_addr, BT_TRANSPORT_BR_EDR)) == NULL) return(BTM_UNKNOWN_ADDR); /* Ignore change link key request if the previsous request has not completed */ @@ -1119,9 +1143,8 @@ tBTM_STATUS BTM_SetLinkPolicy (BD_ADDR remote_bda, UINT16 *settings) } } - if ((p = btm_bda_to_acl(remote_bda)) != NULL) - return(btsnd_hcic_write_policy_set (p->hci_handle, *settings) ? - BTM_CMD_STARTED : BTM_NO_RESOURCES); + if ((p = btm_bda_to_acl(remote_bda, BT_TRANSPORT_BR_EDR)) != NULL) + return(btsnd_hcic_write_policy_set (p->hci_handle, *settings) ? BTM_CMD_STARTED : BTM_NO_RESOURCES); /* If here, no BD Addr found */ return(BTM_UNKNOWN_ADDR); @@ -1195,7 +1218,7 @@ tBTM_STATUS BTM_ReadLinkPolicy (BD_ADDR remote_bda, tBTM_CMPL_CB *p_cb) if (btm_cb.devcb.p_rlinkp_cmpl_cb) return(BTM_BUSY); - p = btm_bda_to_acl(remote_bda); + p = btm_bda_to_acl(remote_bda, BT_TRANSPORT_BR_EDR); if (p != (tACL_CONN *)NULL) { btu_start_timer (&btm_cb.devcb.rlinkp_timer, BTU_TTYPE_BTM_ACL, BTM_DEV_REPLY_TIMEOUT); @@ -1634,47 +1657,62 @@ void btm_read_remote_ext_features_failed (UINT8 status, UINT16 handle) static void btm_establish_continue (tACL_CONN *p_acl_cb) { #if (defined(BTM_BUSY_LEVEL_CHANGE_INCLUDED) && BTM_BUSY_LEVEL_CHANGE_INCLUDED == TRUE) - tBTM_BL_EVENT_DATA evt_data; + tBTM_BL_EVENT_DATA evt_data; #endif - BTM_TRACE_DEBUG0 ("btm_establish_continue"); + BTM_TRACE_DEBUG0 ("btm_establish_continue"); #if (!defined(BTM_BYPASS_EXTRA_ACL_SETUP) || BTM_BYPASS_EXTRA_ACL_SETUP == FALSE) #if (defined BLE_INCLUDED && BLE_INCLUDED == TRUE) - if (!p_acl_cb->is_le_link) + if (p_acl_cb->transport == BT_TRANSPORT_BR_EDR) #endif - { - /* For now there are a some devices that do not like sending */ - /* commands events and data at the same time. */ - /* Set the packet types to the default allowed by the device */ - btm_set_packet_types (p_acl_cb, btm_cb.btm_acl_pkt_types_supported); + { + /* For now there are a some devices that do not like sending */ + /* commands events and data at the same time. */ + /* Set the packet types to the default allowed by the device */ + btm_set_packet_types (p_acl_cb, btm_cb.btm_acl_pkt_types_supported); - if (btm_cb.btm_def_link_policy) - BTM_SetLinkPolicy (p_acl_cb->remote_addr, &btm_cb.btm_def_link_policy); - } + if (btm_cb.btm_def_link_policy) + BTM_SetLinkPolicy (p_acl_cb->remote_addr, &btm_cb.btm_def_link_policy); + } #endif - p_acl_cb->link_up_issued = TRUE; + p_acl_cb->link_up_issued = TRUE; - /* If anyone cares, tell him database changed */ + /* If anyone cares, tell him database changed */ #if (defined(BTM_BUSY_LEVEL_CHANGE_INCLUDED) && BTM_BUSY_LEVEL_CHANGE_INCLUDED == TRUE) - if (btm_cb.p_bl_changed_cb) - { - evt_data.event = BTM_BL_CONN_EVT; - evt_data.conn.p_bda = p_acl_cb->remote_addr; - evt_data.conn.p_bdn = p_acl_cb->remote_name; - evt_data.conn.p_dc = p_acl_cb->remote_dc; - evt_data.conn.p_features = p_acl_cb->peer_lmp_features[HCI_EXT_FEATURES_PAGE_0]; - + if (btm_cb.p_bl_changed_cb) + { + evt_data.event = BTM_BL_CONN_EVT; + evt_data.conn.p_bda = p_acl_cb->remote_addr; + evt_data.conn.p_bdn = p_acl_cb->remote_name; + evt_data.conn.p_dc = p_acl_cb->remote_dc; + evt_data.conn.p_features = p_acl_cb->peer_lmp_features[HCI_EXT_FEATURES_PAGE_0]; +#if BLE_INCLUDED == TRUE + evt_data.conn.handle = p_acl_cb->hci_handle; + evt_data.conn.transport = p_acl_cb->transport; +#endif - (*btm_cb.p_bl_changed_cb)(&evt_data); - } - btm_acl_update_busy_level (BTM_BLI_ACL_UP_EVT); + (*btm_cb.p_bl_changed_cb)(&evt_data); + } + btm_acl_update_busy_level (BTM_BLI_ACL_UP_EVT); +#else + if (btm_cb.p_acl_changed_cb) +#if BLE_INCLUDED == TRUE + (*btm_cb.p_acl_changed_cb) (p_acl_cb->remote_addr, + p_acl_cb->remote_dc, + p_acl_cb->remote_name, + p_acl_cb->peer_lmp_features[HCI_EXT_FEATURES_PAGE_0], + TRUE, + p_acl_cb->hci_handle, + p_acl_cb->transport); #else - if (btm_cb.p_acl_changed_cb) - (*btm_cb.p_acl_changed_cb) (p_acl_cb->remote_addr, - p_acl_cb->remote_dc, - p_acl_cb->remote_name, - p_acl_cb->peer_lmp_features[HCI_EXT_FEATURES_PAGE_0], - TRUE); + (*btm_cb.p_acl_changed_cb) (p_acl_cb->remote_addr, + p_acl_cb->remote_dc, + p_acl_cb->remote_name, + p_acl_cb->peer_lmp_features[HCI_EXT_FEATURES_PAGE_0], + TRUE); +#endif + #endif + } @@ -1705,7 +1743,7 @@ void BTM_SetDefaultLinkSuperTout (UINT16 timeout) *******************************************************************************/ tBTM_STATUS BTM_GetLinkSuperTout (BD_ADDR remote_bda, UINT16 *p_timeout) { - tACL_CONN *p = btm_bda_to_acl(remote_bda); + tACL_CONN *p = btm_bda_to_acl(remote_bda, BT_TRANSPORT_BR_EDR); BTM_TRACE_DEBUG0 ("BTM_GetLinkSuperTout"); if (p != (tACL_CONN *)NULL) @@ -1729,7 +1767,7 @@ tBTM_STATUS BTM_GetLinkSuperTout (BD_ADDR remote_bda, UINT16 *p_timeout) *******************************************************************************/ tBTM_STATUS BTM_SetLinkSuperTout (BD_ADDR remote_bda, UINT16 timeout) { - tACL_CONN *p = btm_bda_to_acl(remote_bda); + tACL_CONN *p = btm_bda_to_acl(remote_bda, BT_TRANSPORT_BR_EDR); BTM_TRACE_DEBUG0 ("BTM_SetLinkSuperTout"); if (p != (tACL_CONN *)NULL) @@ -1816,7 +1854,7 @@ tBTM_STATUS BTM_SetHoldMode (BD_ADDR remote_bda, UINT16 min_interval, UINT16 max if (!HCI_HOLD_MODE_SUPPORTED(BTM_ReadLocalFeatures())) return(BTM_MODE_UNSUPPORTED); - p = btm_bda_to_acl(remote_bda); + p = btm_bda_to_acl(remote_bda, BT_TRANSPORT_BR_EDR); if (p != (tACL_CONN *)NULL) { /* If the connection is in park or sniff mode, forget about holding it */ @@ -1854,7 +1892,7 @@ tBTM_STATUS BTM_SetSniffMode (BD_ADDR remote_bda, UINT16 min_period, UINT16 max_ if (!HCI_SNIFF_MODE_SUPPORTED(BTM_ReadLocalFeatures())) return(BTM_MODE_UNSUPPORTED); - p = btm_bda_to_acl(remote_bda); + p = btm_bda_to_acl(remote_bda, BT_TRANSPORT_BR_EDR); if (p != (tACL_CONN *)NULL) { /* If the connection is in park mode, forget about sniffing it */ @@ -1888,7 +1926,7 @@ tBTM_STATUS BTM_SetSniffMode (BD_ADDR remote_bda, UINT16 min_period, UINT16 max_ *******************************************************************************/ tBTM_STATUS BTM_CancelSniffMode (BD_ADDR remote_bda) { - tACL_CONN *p = btm_bda_to_acl(remote_bda); + tACL_CONN *p = btm_bda_to_acl(remote_bda, BT_TRANSPORT_BR_EDR); BTM_TRACE_DEBUG0 ("BTM_CancelSniffMode "); if (p == (tACL_CONN *)NULL) return(BTM_UNKNOWN_ADDR); @@ -1924,7 +1962,7 @@ tBTM_STATUS BTM_SetParkMode (BD_ADDR remote_bda, UINT16 beacon_min_period, UINT1 if (!HCI_PARK_MODE_SUPPORTED(BTM_ReadLocalFeatures())) return(BTM_MODE_UNSUPPORTED); - p = btm_bda_to_acl(remote_bda); + p = btm_bda_to_acl(remote_bda, BT_TRANSPORT_BR_EDR); if (p != (tACL_CONN *)NULL) { /* If the connection is in sniff mode, forget about parking it */ @@ -1962,7 +2000,7 @@ tBTM_STATUS BTM_CancelParkMode (BD_ADDR remote_bda) tACL_CONN *p; BTM_TRACE_DEBUG0 ("BTM_CancelParkMode"); - p = btm_bda_to_acl(remote_bda); + p = btm_bda_to_acl(remote_bda, BT_TRANSPORT_BR_EDR); if (p != (tACL_CONN *)NULL) { /* If the connection is not in park mode, cannot cancel */ @@ -1996,7 +2034,7 @@ tBTM_STATUS BTM_SetPacketTypes (BD_ADDR remote_bda, UINT16 pkt_types) tACL_CONN *p; BTM_TRACE_DEBUG0 ("BTM_SetPacketTypes"); - if ((p = btm_bda_to_acl(remote_bda)) != NULL) + if ((p = btm_bda_to_acl(remote_bda, BT_TRANSPORT_BR_EDR)) != NULL) return(btm_set_packet_types (p, pkt_types)); /* If here, no BD Addr found */ @@ -2019,7 +2057,7 @@ UINT16 BTM_ReadPacketTypes (BD_ADDR remote_bda) tACL_CONN *p; BTM_TRACE_DEBUG0 ("BTM_ReadPacketTypes"); - p = btm_bda_to_acl(remote_bda); + p = btm_bda_to_acl(remote_bda, BT_TRANSPORT_BR_EDR); if (p != (tACL_CONN *)NULL) { return(p->pkt_types_mask); @@ -2059,7 +2097,7 @@ tBTM_STATUS BTM_ReadAclMode (BD_ADDR remote_bda, UINT8 *p_mode) remote_bda[0], remote_bda[1], remote_bda[2], remote_bda[3], remote_bda[4], remote_bda[5]); - p = btm_bda_to_acl(remote_bda); + p = btm_bda_to_acl(remote_bda, BT_TRANSPORT_BR_EDR); if (p != (tACL_CONN *)NULL) { *p_mode = p->mode; @@ -2091,7 +2129,7 @@ UINT16 BTM_ReadClockOffset (BD_ADDR remote_bda) remote_bda[0], remote_bda[1], remote_bda[2], remote_bda[3], remote_bda[4], remote_bda[5]); - if ( (p = btm_bda_to_acl(remote_bda)) != NULL) + if ( (p = btm_bda_to_acl(remote_bda, BT_TRANSPORT_BR_EDR)) != NULL) return(p->clock_offset); /* If here, no BD Addr found */ @@ -2108,7 +2146,7 @@ UINT16 BTM_ReadClockOffset (BD_ADDR remote_bda) ** Returns TRUE if connection is up, else FALSE. ** *******************************************************************************/ -BOOLEAN BTM_IsAclConnectionUp (BD_ADDR remote_bda) +BOOLEAN BTM_IsAclConnectionUp (BD_ADDR remote_bda, tBT_TRANSPORT transport) { tACL_CONN *p; @@ -2116,7 +2154,7 @@ BOOLEAN BTM_IsAclConnectionUp (BD_ADDR remote_bda) remote_bda[0], remote_bda[1], remote_bda[2], remote_bda[3], remote_bda[4], remote_bda[5]); - p = btm_bda_to_acl(remote_bda); + p = btm_bda_to_acl(remote_bda, transport); if (p != (tACL_CONN *)NULL) { return(TRUE); @@ -2156,6 +2194,34 @@ UINT16 BTM_GetNumAclLinks (void) /******************************************************************************* ** +** Function BTM_GetNumLeLinks +** +** Description This function is called to count the number of +** LE ACL links that are active. +** +** Returns UINT16 Number of active LE links +** +*******************************************************************************/ +UINT16 BTM_GetNumLeLinks (void) +{ + UINT16 yy = 0; + +#if BLE_INCLUDED == TRUE + tACL_CONN *p = &btm_cb.acl_db[0]; + UINT16 xx; + BTM_TRACE_DEBUG0 ("BTM_GetNumLeLinks"); + for (xx = yy = 0; xx < MAX_L2CAP_LINKS; xx++, p++) + { + if ((p->in_use) &&(p->transport == BT_TRANSPORT_LE)) + yy++; + } +#endif + + return(yy); +} + +/******************************************************************************* +** ** Function btm_get_acl_disc_reason_code ** ** Description This function is called to get the disconnection reason code @@ -2182,11 +2248,11 @@ UINT16 btm_get_acl_disc_reason_code (void) ** Returns the handle of the connection, or 0xFFFF if none. ** *******************************************************************************/ -UINT16 BTM_GetHCIConnHandle (BD_ADDR remote_bda) +UINT16 BTM_GetHCIConnHandle (BD_ADDR remote_bda, tBT_TRANSPORT transport) { tACL_CONN *p; BTM_TRACE_DEBUG0 ("BTM_GetHCIConnHandle"); - p = btm_bda_to_acl(remote_bda); + p = btm_bda_to_acl(remote_bda, transport); if (p != (tACL_CONN *)NULL) { return(p->hci_handle); @@ -2276,7 +2342,7 @@ void btm_acl_role_changed (UINT8 hci_status, BD_ADDR bd_addr, UINT8 new_role) { UINT8 *p_bda = (bd_addr) ? bd_addr : btm_cb.devcb.switch_role_ref_data.remote_bd_addr; - tACL_CONN *p = btm_bda_to_acl(p_bda); + tACL_CONN *p = btm_bda_to_acl(p_bda, BT_TRANSPORT_BR_EDR); tBTM_ROLE_SWITCH_CMPL *p_data = &btm_cb.devcb.switch_role_ref_data; tBTM_SEC_DEV_REC *p_dev_rec; #if (defined(BTM_BUSY_LEVEL_CHANGE_INCLUDED) && BTM_BUSY_LEVEL_CHANGE_INCLUDED == TRUE) @@ -2563,7 +2629,7 @@ tBTM_STATUS btm_set_packet_types (tACL_CONN *p, UINT16 pkt_types) *******************************************************************************/ UINT16 btm_get_max_packet_size (BD_ADDR addr) { - tACL_CONN *p = btm_bda_to_acl(addr); + tACL_CONN *p = btm_bda_to_acl(addr, BT_TRANSPORT_BR_EDR); UINT16 pkt_types = 0; UINT16 pkt_size = 0; BTM_TRACE_DEBUG0 ("btm_get_max_packet_size"); @@ -2621,7 +2687,7 @@ UINT16 btm_get_max_packet_size (BD_ADDR addr) tBTM_STATUS BTM_ReadRemoteVersion (BD_ADDR addr, UINT8 *lmp_version, UINT16 *manufacturer, UINT16 *lmp_sub_version) { - tACL_CONN *p = btm_bda_to_acl(addr); + tACL_CONN *p = btm_bda_to_acl(addr, BT_TRANSPORT_BR_EDR); BTM_TRACE_DEBUG0 ("BTM_ReadRemoteVersion"); if (p == NULL) return(BTM_UNKNOWN_ADDR); @@ -2647,7 +2713,7 @@ tBTM_STATUS BTM_ReadRemoteVersion (BD_ADDR addr, UINT8 *lmp_version, *******************************************************************************/ UINT8 *BTM_ReadRemoteFeatures (BD_ADDR addr) { - tACL_CONN *p = btm_bda_to_acl(addr); + tACL_CONN *p = btm_bda_to_acl(addr, BT_TRANSPORT_BR_EDR); BTM_TRACE_DEBUG0 ("BTM_ReadRemoteFeatures"); if (p == NULL) { @@ -2667,7 +2733,7 @@ UINT8 *BTM_ReadRemoteFeatures (BD_ADDR addr) *******************************************************************************/ UINT8 *BTM_ReadRemoteExtendedFeatures (BD_ADDR addr, UINT8 page_number) { - tACL_CONN *p = btm_bda_to_acl(addr); + tACL_CONN *p = btm_bda_to_acl(addr, BT_TRANSPORT_BR_EDR); BTM_TRACE_DEBUG0 ("BTM_ReadRemoteExtendedFeatures"); if (p == NULL) { @@ -2692,7 +2758,7 @@ UINT8 *BTM_ReadRemoteExtendedFeatures (BD_ADDR addr, UINT8 page_number) *******************************************************************************/ UINT8 BTM_ReadNumberRemoteFeaturesPages (BD_ADDR addr) { - tACL_CONN *p = btm_bda_to_acl(addr); + tACL_CONN *p = btm_bda_to_acl(addr, BT_TRANSPORT_BR_EDR); BTM_TRACE_DEBUG0 ("BTM_ReadNumberRemoteFeaturesPages"); if (p == NULL) { @@ -2711,7 +2777,7 @@ UINT8 BTM_ReadNumberRemoteFeaturesPages (BD_ADDR addr) *******************************************************************************/ UINT8 *BTM_ReadAllRemoteFeatures (BD_ADDR addr) { - tACL_CONN *p = btm_bda_to_acl(addr); + tACL_CONN *p = btm_bda_to_acl(addr, BT_TRANSPORT_BR_EDR); BTM_TRACE_DEBUG0 ("BTM_ReadAllRemoteFeatures"); if (p == NULL) { @@ -2794,7 +2860,7 @@ tBTM_STATUS BTM_SetQoS (BD_ADDR bd, FLOW_SPEC *p_flow, tBTM_CMPL_CB *p_cb) if (btm_cb.devcb.p_qossu_cmpl_cb) return(BTM_BUSY); - if ( (p = btm_bda_to_acl(bd)) != NULL) + if ( (p = btm_bda_to_acl(bd, BT_TRANSPORT_BR_EDR)) != NULL) { btu_start_timer (&btm_cb.devcb.qossu_timer, BTU_TTYPE_BTM_ACL, BTM_DEV_REPLY_TIMEOUT); btm_cb.devcb.p_qossu_cmpl_cb = p_cb; @@ -2878,7 +2944,7 @@ tBTM_STATUS BTM_ReadRSSI (BD_ADDR remote_bda, tBTM_CMPL_CB *p_cb) if (btm_cb.devcb.p_rssi_cmpl_cb) return(BTM_BUSY); - p = btm_bda_to_acl(remote_bda); + p = btm_bda_to_acl(remote_bda, BT_TRANSPORT_BR_EDR); if (p != (tACL_CONN *)NULL) { btu_start_timer (&btm_cb.devcb.rssi_timer, BTU_TTYPE_BTM_ACL, @@ -2923,7 +2989,7 @@ tBTM_STATUS BTM_ReadLinkQuality (BD_ADDR remote_bda, tBTM_CMPL_CB *p_cb) if (btm_cb.devcb.p_lnk_qual_cmpl_cb) return(BTM_BUSY); - p = btm_bda_to_acl(remote_bda); + p = btm_bda_to_acl(remote_bda, BT_TRANSPORT_BR_EDR); if (p != (tACL_CONN *)NULL) { btu_start_timer (&btm_cb.devcb.lnk_quality_timer, BTU_TTYPE_BTM_ACL, @@ -2956,7 +3022,7 @@ tBTM_STATUS BTM_ReadLinkQuality (BD_ADDR remote_bda, tBTM_CMPL_CB *p_cb) ** Returns BTM_CMD_STARTED if successfully initiated or error code ** *******************************************************************************/ -tBTM_STATUS BTM_ReadTxPower (BD_ADDR remote_bda, tBTM_CMPL_CB *p_cb) +tBTM_STATUS BTM_ReadTxPower (BD_ADDR remote_bda, tBT_TRANSPORT transport, tBTM_CMPL_CB *p_cb) { tACL_CONN *p; BOOLEAN ret; @@ -2971,7 +3037,7 @@ tBTM_STATUS BTM_ReadTxPower (BD_ADDR remote_bda, tBTM_CMPL_CB *p_cb) if (btm_cb.devcb.p_tx_power_cmpl_cb) return(BTM_BUSY); - p = btm_bda_to_acl(remote_bda); + p = btm_bda_to_acl(remote_bda, transport); if (p != (tACL_CONN *)NULL) { btu_start_timer (&btm_cb.devcb.tx_power_timer, BTU_TTYPE_BTM_ACL, @@ -2980,7 +3046,7 @@ tBTM_STATUS BTM_ReadTxPower (BD_ADDR remote_bda, tBTM_CMPL_CB *p_cb) btm_cb.devcb.p_tx_power_cmpl_cb = p_cb; #if BLE_INCLUDED == TRUE - if (p->is_le_link) + if (p->transport == BT_TRANSPORT_LE) { memcpy(btm_cb.devcb.read_tx_pwr_addr, remote_bda, BD_ADDR_LEN); ret = btsnd_hcic_ble_read_adv_chnl_tx_power(); @@ -3183,9 +3249,9 @@ void btm_read_link_quality_complete (UINT8 *p) ** Returns BTM_SUCCESS if successfully initiated, otherwise BTM_NO_RESOURCES. ** *******************************************************************************/ -tBTM_STATUS btm_remove_acl (BD_ADDR bd_addr) +tBTM_STATUS btm_remove_acl (BD_ADDR bd_addr, tBT_TRANSPORT transport) { - UINT16 hci_handle = BTM_GetHCIConnHandle(bd_addr); + UINT16 hci_handle = BTM_GetHCIConnHandle(bd_addr, transport); tBTM_STATUS status = BTM_SUCCESS; BTM_TRACE_DEBUG0 ("btm_remove_acl"); @@ -3459,6 +3525,11 @@ BOOLEAN btm_acl_notif_conn_collision (BD_ADDR bda) evt_data.event = BTM_BL_COLLISION_EVT; evt_data.conn.p_bda = bda; + +#if BLE_INCLUDED == TRUE + evt_data.conn.transport = BT_TRANSPORT_BR_EDR; + evt_data.conn.handle = BTM_INVALID_HCI_HANDLE; +#endif (*btm_cb.p_bl_changed_cb)(&evt_data); return TRUE; } diff --git a/stack/btm/btm_ble.c b/stack/btm/btm_ble.c index 5b61b76f4..9bd771a71 100644 --- a/stack/btm/btm_ble.c +++ b/stack/btm/btm_ble.c @@ -35,9 +35,6 @@ #include "btm_ble_api.h" #include "smp_api.h" #include "l2c_int.h" -#if (defined BLE_BRCM_INCLUDED && BLE_BRCM_INCLUDED == TRUE) -#include "brcm_ble.h" -#endif #include "gap_api.h" #include "bt_utils.h" @@ -94,7 +91,8 @@ BOOLEAN BTM_SecAddBleDevice (BD_ADDR bd_addr, BD_NAME bd_name, tBT_DEVICE_TYPE d memset (p_dev_rec, 0, sizeof (tBTM_SEC_DEV_REC)); p_dev_rec->sec_flags = BTM_SEC_IN_USE; memcpy (p_dev_rec->bd_addr, bd_addr, BD_ADDR_LEN); - p_dev_rec->hci_handle = BTM_GetHCIConnHandle (bd_addr); + p_dev_rec->hci_handle = BTM_GetHCIConnHandle (bd_addr, BT_TRANSPORT_BR_EDR); + p_dev_rec->ble_hci_handle = BTM_GetHCIConnHandle (bd_addr, BT_TRANSPORT_LE); /* update conn params, use default value for background connection params */ p_dev_rec->conn_params.min_conn_int = @@ -102,7 +100,7 @@ BOOLEAN BTM_SecAddBleDevice (BD_ADDR bd_addr, BD_NAME bd_name, tBT_DEVICE_TYPE d p_dev_rec->conn_params.supervision_tout = p_dev_rec->conn_params.slave_latency = BTM_BLE_CONN_PARAM_UNDEF; - BTM_TRACE_DEBUG1 ("hci_handl=0x%x ", p_dev_rec->hci_handle ); + BTM_TRACE_DEBUG1 ("hci_handl=0x%x ", p_dev_rec->ble_hci_handle ); break; } } @@ -290,7 +288,7 @@ void BTM_GetDeviceDHK (BT_OCTET16 dhk) *******************************************************************************/ void BTM_ReadConnectionAddr (BD_ADDR remote_bda, BD_ADDR local_conn_addr, tBLE_ADDR_TYPE *p_addr_type) { - tACL_CONN *p_acl = btm_bda_to_acl(remote_bda); + tACL_CONN *p_acl = btm_bda_to_acl(remote_bda, BT_TRANSPORT_LE); if (p_acl == NULL) { @@ -316,6 +314,7 @@ void BTM_ReadConnectionAddr (BD_ADDR remote_bda, BD_ADDR local_conn_addr, tBLE_A *******************************************************************************/ BOOLEAN BTM_IsBleConnection (UINT16 conn_handle) { +#if (BLE_INCLUDED == TRUE) UINT8 xx; tACL_CONN *p; @@ -327,7 +326,10 @@ BOOLEAN BTM_IsBleConnection (UINT16 conn_handle) p = &btm_cb.acl_db[xx]; - return(p->is_le_link); + return (p->transport == BT_TRANSPORT_LE); +#else + return FALSE; +#endif } /******************************************************************************* @@ -335,27 +337,33 @@ BOOLEAN BTM_IsBleConnection (UINT16 conn_handle) ** Function BTM_ReadRemoteConnectionAddr ** ** Description This function is read the remote device address currently used -** . ** -** Returns void +** Parameters pseudo_addr: pseudo random address available +** conn_addr:connection address used +** p_addr_type : BD Address type, Public or Random of the address used +** +** Returns BOOLEAN , TRUE if connection to remote device exists, else FALSE ** *******************************************************************************/ -BOOLEAN BTM_ReadRemoteConnectionAddr(BD_ADDR pseudo_addr, BD_ADDR conn_addr, tBLE_ADDR_TYPE *p_addr_type) +BOOLEAN BTM_ReadRemoteConnectionAddr(BD_ADDR pseudo_addr, BD_ADDR conn_addr, + tBLE_ADDR_TYPE *p_addr_type) { - BOOLEAN st = TRUE; - tBTM_SEC_DEV_REC *p_dev_rec = btm_find_dev(pseudo_addr); -#if BTM_BLE_PRIVACY_SPT == TRUE - tACL_CONN *p = btm_bda_to_acl (pseudo_addr); + BOOLEAN st = TRUE; +#if (BLE_PRIVACY_SPT == TRUE) + tACL_CONN *p = btm_bda_to_acl (pseudo_addr, BT_TRANSPORT_LE); if (p == NULL) { - BTM_TRACE_ERROR0("BTM_ReadRemoteConnectionAddr can not find matching address"); + BTM_TRACE_ERROR0("BTM_ReadRemoteConnectionAddr can not find connection" + " with matching address"); return FALSE; } memcpy(conn_addr, p->active_remote_addr, BD_ADDR_LEN); *p_addr_type = p->active_remote_addr_type; #else + tBTM_SEC_DEV_REC *p_dev_rec = btm_find_dev(pseudo_addr); + memcpy(conn_addr, pseudo_addr, BD_ADDR_LEN); if (p_dev_rec != NULL) { @@ -363,6 +371,7 @@ BOOLEAN BTM_ReadRemoteConnectionAddr(BD_ADDR pseudo_addr, BD_ADDR conn_addr, tBL } #endif return st; + } /******************************************************************************* ** @@ -412,7 +421,7 @@ void BTM_BlePasskeyReply (BD_ADDR bd_addr, UINT8 res, UINT32 passkey) return; } - p_dev_rec->sec_flags |= BTM_SEC_LINK_KEY_AUTHED; + p_dev_rec->sec_flags |= BTM_SEC_LE_LINK_KEY_AUTHED; BTM_TRACE_DEBUG0 ("BTM_BlePasskeyReply"); SMP_PasskeyReply(bd_addr, res_smp, passkey); #endif @@ -444,7 +453,7 @@ void BTM_BleOobDataReply(BD_ADDR bd_addr, UINT8 res, UINT8 len, UINT8 *p_data) return; } - p_dev_rec->sec_flags |= BTM_SEC_LINK_KEY_AUTHED; + p_dev_rec->sec_flags |= BTM_SEC_LE_LINK_KEY_AUTHED; SMP_OobDataReply(bd_addr, res_smp, len, p_data); #endif } @@ -694,24 +703,6 @@ void btm_ble_test_command_complete(UINT8 *p) /******************************************************************************* ** -** Function BTM_IsBleLink -** -** Description This function is to check the link type is BLE or BR/EDR. -** -** Returns TRUE if BLE link; FALSE if BR/EDR. -** -*******************************************************************************/ -BOOLEAN BTM_IsBleLink (BD_ADDR bd_addr) -{ - tACL_CONN *p; - BTM_TRACE_DEBUG0 ("BTM_IsBleLink"); - if ((p = btm_bda_to_acl(bd_addr)) != NULL) - return p->is_le_link; - else - return FALSE; -} -/******************************************************************************* -** ** Function BTM_UseLeLink ** ** Description This function is to select the underneath physical link to use. @@ -726,9 +717,13 @@ BOOLEAN BTM_UseLeLink (BD_ADDR bd_addr) tBLE_ADDR_TYPE addr_type; BOOLEAN use_le = FALSE; - if ((p = btm_bda_to_acl(bd_addr)) != NULL) + if ((p = btm_bda_to_acl(bd_addr, BT_TRANSPORT_BR_EDR)) != NULL) { - use_le = (p->is_le_link); + return use_le; + } + else if ((p = btm_bda_to_acl(bd_addr, BT_TRANSPORT_LE)) != NULL) + { + use_le = TRUE; } else { @@ -902,11 +897,11 @@ void btm_sec_save_le_key(BD_ADDR bd_addr, tBTM_LE_KEY_TYPE key_type, tBTM_LE_KEY p_rec->ble.keys.ediv = p_keys->penc_key.ediv; p_rec->ble.keys.key_size = p_keys->penc_key.key_size; p_rec->ble.key_type |= BTM_LE_KEY_PENC; - p_rec->sec_flags |= BTM_SEC_LINK_KEY_KNOWN; + p_rec->sec_flags |= BTM_SEC_LE_LINK_KEY_KNOWN; if (p_keys->penc_key.sec_level == SMP_SEC_AUTHENTICATED) - p_rec->sec_flags |= BTM_SEC_LINK_KEY_AUTHED; + p_rec->sec_flags |= BTM_SEC_LE_LINK_KEY_AUTHED; else - p_rec->sec_flags &= ~BTM_SEC_LINK_KEY_AUTHED; + p_rec->sec_flags &= ~BTM_SEC_LE_LINK_KEY_AUTHED; BTM_TRACE_DEBUG3("BTM_LE_KEY_PENC key_type=0x%x sec_flags=0x%x sec_leve=0x%x", p_rec->ble.key_type, p_rec->sec_flags, @@ -931,11 +926,11 @@ void btm_sec_save_le_key(BD_ADDR bd_addr, tBTM_LE_KEY_TYPE key_type, tBTM_LE_KEY p_rec->ble.keys.srk_sec_level = p_keys->pcsrk_key.sec_level; p_rec->ble.keys.counter = p_keys->pcsrk_key.counter; p_rec->ble.key_type |= BTM_LE_KEY_PCSRK; - p_rec->sec_flags |= BTM_SEC_LINK_KEY_KNOWN; + p_rec->sec_flags |= BTM_SEC_LE_LINK_KEY_KNOWN; if ( p_keys->pcsrk_key.sec_level== SMP_SEC_AUTHENTICATED) - p_rec->sec_flags |= BTM_SEC_LINK_KEY_AUTHED; + p_rec->sec_flags |= BTM_SEC_LE_LINK_KEY_AUTHED; else - p_rec->sec_flags &= ~BTM_SEC_LINK_KEY_AUTHED; + p_rec->sec_flags &= ~BTM_SEC_LE_LINK_KEY_AUTHED; BTM_TRACE_DEBUG4("BTM_LE_KEY_PCSRK key_type=0x%x sec_flags=0x%x sec_level=0x%x peer_counter=%d", p_rec->ble.key_type, @@ -1081,9 +1076,9 @@ void btm_ble_link_sec_check(BD_ADDR bd_addr, tBTM_LE_AUTH_REQ auth_req, tBTM_BLE BTM_TRACE_DEBUG1 ("dev_rec sec_flags=0x%x", p_dev_rec->sec_flags); /* currently encrpted */ - if (p_dev_rec->sec_flags & BTM_SEC_ENCRYPTED) + if (p_dev_rec->sec_flags & BTM_SEC_LE_ENCRYPTED) { - if (p_dev_rec->sec_flags & BTM_SEC_LINK_KEY_AUTHED) + if (p_dev_rec->sec_flags & BTM_SEC_LE_LINK_KEY_AUTHED) cur_sec_level = BTM_LE_SEC_AUTHENTICATED; else cur_sec_level = BTM_LE_SEC_UNAUTHENTICATE; @@ -1191,7 +1186,7 @@ tBTM_STATUS btm_ble_set_encryption (BD_ADDR bd_addr, void *p_ref_data, UINT8 lin break; default: - cmd = BTM_SUCCESS; + cmd = BTM_WRONG_MODE; break; } return cmd; @@ -1235,40 +1230,48 @@ void btm_ble_ltk_request(UINT16 handle, UINT8 rand[8], UINT16 ediv) ** Description This function is called to start LE encryption. ** ** -** Returns void +** Returns BTM_SUCCESS if encryption was started successfully ** *******************************************************************************/ -BOOLEAN btm_ble_start_encrypt(BD_ADDR bda, BOOLEAN use_stk, BT_OCTET16 stk) +tBTM_STATUS btm_ble_start_encrypt(BD_ADDR bda, BOOLEAN use_stk, BT_OCTET16 stk) { tBTM_CB *p_cb = &btm_cb; tBTM_SEC_DEV_REC *p_rec = btm_find_dev (bda); BT_OCTET8 dummy_rand = {0}; - BOOLEAN rt = FALSE; + tBTM_STATUS rt = BTM_NO_RESOURCES; BTM_TRACE_DEBUG0 ("btm_ble_start_encrypt"); - if (!p_rec || - (p_rec && p_rec->sec_state == BTM_SEC_STATE_ENCRYPTING)) - return FALSE; + if (!p_rec ) + { + BTM_TRACE_ERROR0("Link is not active, can not encrypt!"); + return BTM_WRONG_MODE; + } + + if (p_rec->sec_state == BTM_SEC_STATE_ENCRYPTING) + { + BTM_TRACE_WARNING0("Link Encryption is active, Busy!"); + return BTM_BUSY; + } - p_cb->enc_handle = p_rec->hci_handle; + p_cb->enc_handle = p_rec->ble_hci_handle; if (use_stk) { - if (btsnd_hcic_ble_start_enc(p_rec->hci_handle, dummy_rand, 0, stk)) - rt = TRUE; + if (btsnd_hcic_ble_start_enc(p_rec->ble_hci_handle, dummy_rand, 0, stk)) + rt = BTM_CMD_STARTED; } else if (p_rec->ble.key_type & BTM_LE_KEY_PENC) { - if (btsnd_hcic_ble_start_enc(p_rec->hci_handle, p_rec->ble.keys.rand, + if (btsnd_hcic_ble_start_enc(p_rec->ble_hci_handle, p_rec->ble.keys.rand, p_rec->ble.keys.ediv, p_rec->ble.keys.ltk)) - rt = TRUE; + rt = BTM_CMD_STARTED; } else { BTM_TRACE_ERROR0("No key available to encrypt the link"); } - if (rt) + if (rt == BTM_CMD_STARTED) { if (p_rec->sec_state == BTM_SEC_STATE_IDLE) p_rec->sec_state = BTM_SEC_STATE_ENCRYPTING; @@ -1312,9 +1315,9 @@ void btm_ble_link_encrypted(BD_ADDR bd_addr, UINT8 encr_enable) if (p_dev_rec->p_callback && enc_cback) { if (encr_enable) - btm_sec_dev_rec_cback_event(p_dev_rec, BTM_SUCCESS); + btm_sec_dev_rec_cback_event(p_dev_rec, BTM_SUCCESS, TRUE); else if (p_dev_rec->role_master) - btm_sec_dev_rec_cback_event(p_dev_rec, BTM_ERR_PROCESSING); + btm_sec_dev_rec_cback_event(p_dev_rec, BTM_ERR_PROCESSING, TRUE); } /* to notify GATT to send data if any request is pending */ @@ -1399,7 +1402,7 @@ void btm_ble_ltk_request_reply(BD_ADDR bda, BOOLEAN use_stk, BT_OCTET16 stk) } BTM_TRACE_DEBUG0 ("btm_ble_ltk_request_reply"); - p_cb->enc_handle = p_rec->hci_handle; + p_cb->enc_handle = p_rec->ble_hci_handle; p_cb->key_size = p_rec->ble.keys.key_size; BTM_TRACE_ERROR1("key size = %d", p_rec->ble.keys.key_size); @@ -1477,7 +1480,7 @@ UINT8 btm_ble_io_capabilities_req(tBTM_SEC_DEV_REC *p_dev_rec, tBTM_LE_IO_REQ *p return callback_rc; } -#if (BTM_BLE_PRIVACY_SPT == TRUE ) +#if (BLE_PRIVACY_SPT == TRUE ) /******************************************************************************* ** ** Function btm_ble_resolve_random_addr_on_conn_cmpl @@ -1556,7 +1559,7 @@ void btm_ble_connected (UINT8 *bda, UINT16 handle, UINT8 enc_mode, UINT8 role, #if (BT_USE_TRACES == TRUE) if (p_dev_rec) { - BTM_TRACE_EVENT4 ("Security Manager: btm_sec_connected : handle:%d enc_mode:%d bda:%x RName:%s", + BTM_TRACE_EVENT4 ("Security Manager: btm_ble_connected : handle:%d enc_mode:%d bda:%x RName:%s", handle, enc_mode, (bda[2]<<24)+(bda[3]<<16)+(bda[4]<<8)+bda[5], p_dev_rec->sec_bd_name); @@ -1565,7 +1568,7 @@ void btm_ble_connected (UINT8 *bda, UINT16 handle, UINT8 enc_mode, UINT8 role, } else { - BTM_TRACE_EVENT3 ("Security Manager: btm_sec_connected: handle:%d enc_mode:%d bda:%x ", + BTM_TRACE_EVENT3 ("Security Manager: btm_ble_connected: handle:%d enc_mode:%d bda:%x ", handle, enc_mode, (bda[2]<<24)+(bda[3]<<16)+(bda[4]<<8)+bda[5]); } @@ -1583,14 +1586,14 @@ void btm_ble_connected (UINT8 *bda, UINT16 handle, UINT8 enc_mode, UINT8 role, /* update device information */ p_dev_rec->device_type |= BT_DEVICE_TYPE_BLE; - p_dev_rec->hci_handle = handle; + p_dev_rec->ble_hci_handle = handle; p_dev_rec->ble.ble_addr_type = addr_type; p_dev_rec->role_master = FALSE; if (role == HCI_ROLE_MASTER) p_dev_rec->role_master = TRUE; -#if (defined BTM_BLE_PRIVACY_SPT && BTM_BLE_PRIVACY_SPT == TRUE) +#if (defined BLE_PRIVACY_SPT && BLE_PRIVACY_SPT == TRUE) if (!addr_matched) p_dev_rec->ble.active_addr_type = BTM_BLE_ADDR_PSEUDO; @@ -1613,7 +1616,7 @@ void btm_ble_connected (UINT8 *bda, UINT16 handle, UINT8 enc_mode, UINT8 role, ******************************************************************************/ void btm_ble_conn_complete(UINT8 *p, UINT16 evt_len) { -#if (BTM_BLE_PRIVACY_SPT == TRUE ) +#if (BLE_PRIVACY_SPT == TRUE ) UINT8 *p_data = p; #endif UINT8 role, status, bda_type; @@ -1631,10 +1634,10 @@ void btm_ble_conn_complete(UINT8 *p, UINT16 evt_len) if (status == 0) { -#if (BTM_BLE_PRIVACY_SPT == TRUE ) +#if (BLE_PRIVACY_SPT == TRUE ) /* possiblly receive connection complete with resolvable random on slave role while the device has been paired */ - if (!match && BTM_BLE_IS_RESOLVE_BDA(bda)) + if (!match && role == HCI_ROLE_SLAVE && BTM_BLE_IS_RESOLVE_BDA(bda)) { btm_ble_resolve_random_addr(bda, btm_ble_resolve_random_addr_on_conn_cmpl, p_data); } @@ -1679,9 +1682,7 @@ void btm_ble_conn_complete(UINT8 *p, UINT16 evt_len) } } } - btm_ble_set_conn_st(BLE_CONN_IDLE); - btm_ble_update_mode_operation(role, bda, TRUE); } @@ -1709,10 +1710,12 @@ UINT8 btm_proc_smp_cback(tSMP_EVT event, BD_ADDR bd_addr, tSMP_EVT_DATA *p_data) case SMP_PASSKEY_REQ_EVT: case SMP_PASSKEY_NOTIF_EVT: case SMP_OOB_REQ_EVT: - p_dev_rec->sec_flags |= BTM_SEC_LINK_KEY_AUTHED; + p_dev_rec->sec_flags |= BTM_SEC_LE_AUTHENTICATED; + case SMP_SEC_REQUEST_EVT: memcpy (btm_cb.pairing_bda, bd_addr, BD_ADDR_LEN); p_dev_rec->sec_state = BTM_SEC_STATE_AUTHENTICATING; + btm_cb.pairing_flags |= BTM_PAIR_FLAGS_LE_ACTIVE; /* fall through */ case SMP_COMPLT_EVT: if (btm_cb.api.p_le_callback) @@ -1731,7 +1734,7 @@ UINT8 btm_proc_smp_cback(tSMP_EVT event, BD_ADDR bd_addr, tSMP_EVT_DATA *p_data) BTM_TRACE_DEBUG3 ("after update result=%d sec_level=0x%x sec_flags=0x%x", res, p_data->cmplt.sec_level , p_dev_rec->sec_flags ); - btm_sec_dev_rec_cback_event(p_dev_rec, res); + btm_sec_dev_rec_cback_event(p_dev_rec, res, TRUE); if (p_data->cmplt.is_pair_cancel && btm_cb.api.p_bond_cancel_cmpl_callback ) { @@ -1744,7 +1747,7 @@ UINT8 btm_proc_smp_cback(tSMP_EVT event, BD_ADDR bd_addr, tSMP_EVT_DATA *p_data) if (!btm_cb.devcb.no_disc_if_pair_fail && p_data->cmplt.reason != SMP_CONN_TOUT) { BTM_TRACE_DEBUG0 ("Pairing failed - Remove ACL"); - btm_remove_acl(bd_addr); + btm_remove_acl(bd_addr, BT_TRANSPORT_LE); } else { @@ -1754,7 +1757,7 @@ UINT8 btm_proc_smp_cback(tSMP_EVT event, BD_ADDR bd_addr, tSMP_EVT_DATA *p_data) } #else if (res != BTM_SUCCESS && p_data->cmplt.reason != SMP_CONN_TOUT) - btm_remove_acl(bd_addr); + btm_remove_acl(bd_addr, BT_TRANSPORT_LE); #endif BTM_TRACE_DEBUG3 ("btm_cb pairing_state=%x pairing_flags=%x pin_code_len=%x", diff --git a/stack/btm/btm_ble_bgconn.c b/stack/btm/btm_ble_bgconn.c index 96d35c4c5..7341cd25a 100644 --- a/stack/btm/btm_ble_bgconn.c +++ b/stack/btm/btm_ble_bgconn.c @@ -57,7 +57,7 @@ void btm_update_scanner_filter_policy(tBTM_BLE_SFP scan_policy) btsnd_hcic_ble_set_scan_params (p_inq->scan_type, (UINT16)(!p_inq->scan_interval ? BTM_BLE_GAP_DISC_SCAN_INT : p_inq->scan_interval), (UINT16)(!p_inq->scan_window ? BTM_BLE_GAP_DISC_SCAN_WIN : p_inq->scan_window), - BLE_ADDR_PUBLIC, + btm_cb.ble_ctr_cb.addr_mgnt_cb.own_addr_type, scan_policy); } /******************************************************************************* @@ -88,12 +88,13 @@ BOOLEAN btm_add_dev_to_controller (BOOLEAN to_add, BD_ADDR bd_addr, UINT8 attr) if (memcmp(p_dev_rec->ble.static_addr, bd_addr, BD_ADDR_LEN) != 0 && memcmp(p_dev_rec->ble.static_addr, dummy_bda, BD_ADDR_LEN) != 0) { - started = btsnd_hcic_ble_add_white_list (p_dev_rec->ble.static_addr_type, p_dev_rec->ble.static_addr); + started = btsnd_hcic_ble_add_white_list (p_dev_rec->ble.static_addr_type, + p_dev_rec->ble.static_addr); } } else { - if (!BTM_BLE_IS_RESOLVE_BDA(bd_addr)) + if (p_dev_rec->ble.ble_addr_type == BLE_ADDR_PUBLIC || !BTM_BLE_IS_RESOLVE_BDA(bd_addr)) { started = btsnd_hcic_ble_remove_from_white_list (p_dev_rec->ble.ble_addr_type, bd_addr); } @@ -255,9 +256,9 @@ void btm_ble_add_2_white_list_complete(UINT8 status) } /******************************************************************************* ** -** Function btm_ble_add_2_white_list_complete +** Function btm_ble_remove_from_white_list_complete ** -** Description This function read the current white list size. +** Description This function remove the white list element complete. *******************************************************************************/ void btm_ble_remove_from_white_list_complete(UINT8 *p, UINT16 evt_len) { @@ -284,7 +285,7 @@ UINT8 btm_ble_count_unconn_dev_in_whitelist(void) for (i = 0; i < BTM_BLE_MAX_BG_CONN_DEV_NUM; i ++) { if (p_cb->bg_dev_list[i].in_use && - !BTM_IsAclConnectionUp(p_cb->bg_dev_list[i].bd_addr)) + !BTM_IsAclConnectionUp(p_cb->bg_dev_list[i].bd_addr, BT_TRANSPORT_LE)) { count ++; } @@ -363,12 +364,12 @@ BOOLEAN btm_ble_start_auto_conn(BOOLEAN start) tBTM_BLE_CB *p_cb = &btm_cb.ble_ctr_cb; BD_ADDR dummy_bda = {0}; BOOLEAN exec = TRUE; - UINT8 own_addr_type = BLE_ADDR_PUBLIC; UINT16 scan_int, scan_win; if (start) { - if (p_cb->conn_state == BLE_CONN_IDLE && btm_ble_count_unconn_dev_in_whitelist() > 0) + if ((p_cb->conn_state == BLE_CONN_IDLE && btm_ble_count_unconn_dev_in_whitelist() > 0) + && btm_ble_topology_check(BTM_BLE_STATE_INIT)) { btm_execute_wl_dev_operation(); @@ -380,7 +381,9 @@ BOOLEAN btm_ble_start_auto_conn(BOOLEAN start) 0x01, /* UINT8 white_list */ BLE_ADDR_PUBLIC, /* UINT8 addr_type_peer */ dummy_bda, /* BD_ADDR bda_peer */ - own_addr_type, /* UINT8 addr_type_own, not allow random address for central */ + p_cb->addr_mgnt_cb.own_addr_type, + /* UINT8 addr_type_own, + not allow random address for central */ BTM_BLE_CONN_INT_MIN_DEF, /* UINT16 conn_int_min */ BTM_BLE_CONN_INT_MAX_DEF, /* UINT16 conn_int_max */ BTM_BLE_CONN_SLAVE_LATENCY_DEF, /* UINT16 conn_latency */ @@ -407,7 +410,7 @@ BOOLEAN btm_ble_start_auto_conn(BOOLEAN start) if (p_cb->conn_state == BLE_BG_CONN) { btsnd_hcic_ble_create_conn_cancel(); - btm_ble_set_conn_st (BLE_CONN_CANCEL); + btm_ble_set_conn_st (BLE_CONN_CANCEL); } else @@ -446,26 +449,27 @@ BOOLEAN btm_ble_start_select_conn(BOOLEAN start,tBTM_BLE_SEL_CBACK *p_select_c if (start) { - if (btm_cb.btm_inq_vars.inq_active == BTM_INQUIRY_INACTIVE) + if (!BTM_BLE_IS_SCAN_ACTIVE(p_cb->scan_activity)) { if (p_select_cback != NULL) btm_cb.ble_ctr_cb.p_select_cback = p_select_cback; + btm_execute_wl_dev_operation(); + btm_update_scanner_filter_policy(SP_ADV_WL); btm_cb.ble_ctr_cb.inq_var.scan_type = BTM_BLE_SCAN_MODE_PASS; if (!btsnd_hcic_ble_set_scan_params(BTM_BLE_SCAN_MODE_PASS, /* use passive scan by default */ scan_int, /* scan interval */ scan_win, /* scan window */ - BLE_ADDR_PUBLIC, /* own device, DUMO always use public */ + p_cb->addr_mgnt_cb.own_addr_type, SP_ADV_WL) /* process advertising packets only from devices in the White List */ ) return FALSE; - if (p_cb->inq_var.adv_mode == BTM_BLE_ADV_ENABLE - ) + if (!btm_ble_topology_check(BTM_BLE_STATE_PASSIVE_SCAN)) { - BTM_TRACE_ERROR0("peripheral device cannot initiate a selective connection"); + BTM_TRACE_ERROR0("peripheral device cannot initiate passive scan for a selective connection"); return FALSE; } else if (p_cb->bg_dev_num > 0 && btm_ble_count_unconn_dev_in_whitelist() > 0 ) @@ -475,9 +479,7 @@ BOOLEAN btm_ble_start_select_conn(BOOLEAN start,tBTM_BLE_SEL_CBACK *p_select_c return FALSE; /* mark up inquiry status flag */ - btm_cb.btm_inq_vars.inq_active |= BTM_LE_SELECT_CONN_ACTIVE; - p_cb->inq_var.proc_mode = BTM_BLE_SELECT_SCAN; - p_cb->conn_state = BLE_BG_CONN; + p_cb->scan_activity |= BTM_LE_SELECT_CONN_ACTIVE; } } else @@ -488,13 +490,13 @@ BOOLEAN btm_ble_start_select_conn(BOOLEAN start,tBTM_BLE_SEL_CBACK *p_select_c } else /* disable selective connection mode */ { - btm_cb.btm_inq_vars.inq_active &= ~BTM_LE_SELECT_CONN_ACTIVE; - btm_cb.ble_ctr_cb.inq_var.proc_mode = BTM_BLE_INQUIRY_NONE; + p_cb->scan_activity &= ~BTM_LE_SELECT_CONN_ACTIVE; + p_cb->p_select_cback = NULL; + - btm_update_scanner_filter_policy(SP_ADV_ALL); /* stop scanning */ - if (!btsnd_hcic_ble_set_scan_enable(FALSE, TRUE)) /* duplicate filtering enabled */ - return FALSE; + if (!BTM_BLE_IS_SCAN_ACTIVE(p_cb->scan_activity)) + btm_ble_stop_scan(); /* duplicate filtering enabled */ btm_update_scanner_filter_policy(SP_ADV_ALL); } return TRUE; @@ -569,7 +571,7 @@ static void btm_suspend_wl_activity(tBTM_BLE_WL_STATE wl_state) } if (wl_state & BTM_BLE_WL_ADV) { - btsnd_hcic_ble_set_adv_enable(BTM_BLE_ADV_DISABLE); + btm_ble_stop_adv(); } } @@ -588,7 +590,7 @@ static void btm_resume_wl_activity(tBTM_BLE_WL_STATE wl_state) if (wl_state & BTM_BLE_WL_ADV) { - btsnd_hcic_ble_set_adv_enable(BTM_BLE_ADV_ENABLE); + btm_ble_start_adv(); } } @@ -645,6 +647,10 @@ tBTM_BLE_CONN_ST btm_ble_get_conn_st(void) void btm_ble_set_conn_st(tBTM_BLE_CONN_ST new_st) { btm_cb.ble_ctr_cb.conn_state = new_st; + if (new_st == BLE_BG_CONN || new_st == BLE_DIR_CONN) + btm_ble_set_topology_mask(BTM_BLE_STATE_INIT_BIT); + else + btm_ble_clear_topology_mask(BTM_BLE_STATE_INIT_BIT); } /******************************************************************************* @@ -689,6 +695,7 @@ BOOLEAN btm_send_pending_direct_conn(void ) return rt; } + #endif diff --git a/stack/btm/btm_ble_gap.c b/stack/btm/btm_ble_gap.c index 39f344cfc..f9bd1aa82 100644 --- a/stack/btm/btm_ble_gap.c +++ b/stack/btm/btm_ble_gap.c @@ -37,6 +37,8 @@ #if (BLE_INCLUDED == TRUE) #include "gattdefs.h" +#include "btm_ble_int.h" + #define BTM_BLE_NAME_SHORT 0x01 #define BTM_BLE_NAME_CMPL 0x02 @@ -55,26 +57,156 @@ static UINT8 btm_set_conn_mode_adv_init_addr(tBTM_BLE_INQ_CB *p_cb, BD_ADDR_PTR p_addr_ptr, tBLE_ADDR_TYPE *p_init_addr_type, tBLE_ADDR_TYPE *p_own_addr_type); -static tBTM_STATUS btm_ble_start_adv(void); -static tBTM_STATUS btm_ble_stop_adv(void); - +static void btm_ble_stop_observe(void); +#define BTM_BLE_INQ_RESULT 0x01 +#define BTM_BLE_OBS_RESULT 0x02 +#define BTM_BLE_SEL_CONN_RESULT 0x04 -/******************************************************************************* -** -** Function BTM_BleReset -** -** Description This function is called to reset ULP controller. -** -** Parameters None. -** -** Returns void -** -*******************************************************************************/ -void BTM_BleReset(void) +/* LE states combo bit to check */ +const UINT8 btm_le_state_combo_tbl[BTM_BLE_STATE_MAX][BTM_BLE_STATE_MAX][2] = { - btsnd_hcic_ble_reset(); -} + {/* single state support */ + {HCI_SUPP_LE_STATES_CONN_ADV_MASK, HCI_SUPP_LE_STATES_CONN_ADV_OFF}, /* conn_adv */ + {HCI_SUPP_LE_STATES_INIT_MASK, HCI_SUPP_LE_STATES_INIT_OFF}, /* init */ + {HCI_SUPP_LE_STATES_INIT_MASK, HCI_SUPP_LE_STATES_INIT_OFF}, /* master */ + {HCI_SUPP_LE_STATES_SLAVE_MASK, HCI_SUPP_LE_STATES_SLAVE_OFF}, /* slave */ + {0, 0}, /* todo: lo du dir adv, not covered ? */ + {HCI_SUPP_LE_STATES_HI_DUTY_DIR_ADV_MASK, HCI_SUPP_LE_STATES_HI_DUTY_DIR_ADV_OFF}, /* hi duty dir adv */ + {HCI_SUPP_LE_STATES_NON_CONN_ADV_MASK, HCI_SUPP_LE_STATES_NON_CONN_ADV_OFF}, /* non connectable adv */ + {HCI_SUPP_LE_STATES_PASS_SCAN_MASK, HCI_SUPP_LE_STATES_PASS_SCAN_OFF}, /* passive scan */ + {HCI_SUPP_LE_STATES_ACTIVE_SCAN_MASK, HCI_SUPP_LE_STATES_ACTIVE_SCAN_OFF}, /* active scan */ + {HCI_SUPP_LE_STATES_SCAN_ADV_MASK, HCI_SUPP_LE_STATESSCAN_ADV_OFF} /* scanable adv */ + }, + { /* conn_adv =0 */ + {0, 0}, /* conn_adv */ + {HCI_SUPP_LE_STATES_CONN_ADV_INIT_MASK, HCI_SUPP_LE_STATES_CONN_ADV_INIT_OFF}, /* init: 32 */ + {HCI_SUPP_LE_STATES_CONN_ADV_MASTER_MASK, HCI_SUPP_LE_STATES_CONN_ADV_MASTER_OFF}, /* master: 35 */ + {HCI_SUPP_LE_STATES_CONN_ADV_SLAVE_MASK, HCI_SUPP_LE_STATES_CONN_ADV_SLAVE_OFF}, /* slave: 38,*/ + {0, 0}, /* lo du dir adv */ + {0, 0}, /* hi duty dir adv */ + {0, 0}, /* non connectable adv */ + {HCI_SUPP_LE_STATES_CONN_ADV_PASS_SCAN_MASK, HCI_SUPP_LE_STATES_CONN_ADV_PASS_SCAN_OFF}, /* passive scan */ + {HCI_SUPP_LE_STATES_CONN_ADV_ACTIVE_SCAN_MASK, HCI_SUPP_LE_STATES_CONN_ADV_ACTIVE_SCAN_OFF}, /* active scan */ + {0, 0} /* scanable adv */ + }, + { /* init */ + {HCI_SUPP_LE_STATES_CONN_ADV_INIT_MASK, HCI_SUPP_LE_STATES_CONN_ADV_INIT_OFF}, /* conn_adv: 32 */ + {0, 0}, /* init */ + {HCI_SUPP_LE_STATES_INIT_MASTER_MASK, HCI_SUPP_LE_STATES_INIT_MASTER_OFF}, /* master 28 */ + {HCI_SUPP_LE_STATES_INIT_MASTER_SLAVE_MASK, HCI_SUPP_LE_STATES_INIT_MASTER_SLAVE_OFF}, /* slave 41 */ + {HCI_SUPP_LE_STATES_LO_DUTY_DIR_ADV_INIT_MASK, HCI_SUPP_LE_STATES_LO_DUTY_DIR_ADV_INIT_OFF} ,/* lo du dir adv 34 */ + {HCI_SUPP_LE_STATES_HI_DUTY_DIR_ADV_INIT_MASK, HCI_SUPP_LE_STATES_HI_DUTY_DIR_ADV_INIT_OFF}, /* hi duty dir adv 33 */ + {HCI_SUPP_LE_STATES_NON_CONN_INIT_MASK, HCI_SUPP_LE_STATES_NON_CONN_INIT_OFF}, /* non connectable adv */ + {HCI_SUPP_LE_STATES_PASS_SCAN_INIT_MASK, HCI_SUPP_LE_STATES_PASS_SCAN_INIT_OFF}, /* passive scan */ + {HCI_SUPP_LE_STATES_ACTIVE_SCAN_INIT_MASK, HCI_SUPP_LE_STATES_ACTIVE_SCAN_INIT_OFF}, /* active scan */ + {HCI_SUPP_LE_STATES_SCAN_ADV_INIT_MASK, HCI_SUPP_LE_STATES_SCAN_ADV_INIT_OFF} /* scanable adv */ + + }, + { /* master */ + {HCI_SUPP_LE_STATES_CONN_ADV_MASTER_MASK, HCI_SUPP_LE_STATES_CONN_ADV_MASTER_OFF}, /* conn_adv: 35 */ + {HCI_SUPP_LE_STATES_INIT_MASTER_MASK, HCI_SUPP_LE_STATES_INIT_MASTER_OFF}, /* init 28 */ + {HCI_SUPP_LE_STATES_INIT_MASTER_MASK, HCI_SUPP_LE_STATES_INIT_MASTER_OFF}, /* master 28 */ + {HCI_SUPP_LE_STATES_CONN_ADV_INIT_MASK, HCI_SUPP_LE_STATES_CONN_ADV_INIT_OFF}, /* slave: 32 */ + {HCI_SUPP_LE_STATES_LO_DUTY_DIR_ADV_MASTER_MASK, HCI_SUPP_LE_STATES_LO_DUTY_DIR_ADV_MASTER_OFF}, /* lo duty cycle adv 37 */ + {HCI_SUPP_LE_STATES_HI_DUTY_DIR_ADV_MASTER_MASK, HCI_SUPP_LE_STATES_HI_DUTY_DIR_ADV_MASTER_OFF}, /* hi duty cycle adv 36 */ + {HCI_SUPP_LE_STATES_NON_CONN_ADV_MASTER_MASK, HCI_SUPP_LE_STATES_NON_CONN_ADV_MASTER_OFF}, /* non connectable adv */ + {HCI_SUPP_LE_STATES_PASS_SCAN_MASTER_MASK, HCI_SUPP_LE_STATES_PASS_SCAN_MASTER_OFF}, /* passive scan */ + {HCI_SUPP_LE_STATES_ACTIVE_SCAN_MASTER_MASK, HCI_SUPP_LE_STATES_ACTIVE_SCAN_MASTER_OFF}, /* active scan */ + {HCI_SUPP_LE_STATES_SCAN_ADV_MASTER_MASK, HCI_SUPP_LE_STATES_SCAN_ADV_MASTER_OFF} /* scanable adv */ + + }, + { /* slave */ + {HCI_SUPP_LE_STATES_CONN_ADV_SLAVE_MASK, HCI_SUPP_LE_STATES_CONN_ADV_SLAVE_OFF}, /* conn_adv: 38,*/ + {HCI_SUPP_LE_STATES_INIT_MASTER_SLAVE_MASK, HCI_SUPP_LE_STATES_INIT_MASTER_SLAVE_OFF}, /* init 41 */ + {HCI_SUPP_LE_STATES_INIT_MASTER_SLAVE_MASK, HCI_SUPP_LE_STATES_INIT_MASTER_SLAVE_OFF}, /* master 41 */ + {HCI_SUPP_LE_STATES_CONN_ADV_SLAVE_MASK, HCI_SUPP_LE_STATES_CONN_ADV_SLAVE_OFF}, /* slave: 38,*/ + {HCI_SUPP_LE_STATES_LO_DUTY_DIR_ADV_SLAVE_MASK, HCI_SUPP_LE_STATES_LO_DUTY_DIR_ADV_SLAVE_OFF}, /* lo duty cycle adv 40 */ + {HCI_SUPP_LE_STATES_HI_DUTY_DIR_ADV_SLAVE_MASK, HCI_SUPP_LE_STATES_HI_DUTY_DIR_ADV_SLAVE_OFF}, /* hi duty cycle adv 39 */ + {HCI_SUPP_LE_STATES_NON_CONN_ADV_SLAVE_MASK, HCI_SUPP_LE_STATES_NON_CONN_ADV_SLAVE_OFF}, /* non connectable adv */ + {HCI_SUPP_LE_STATES_PASS_SCAN_SLAVE_MASK, HCI_SUPP_LE_STATES_PASS_SCAN_SLAVE_OFF}, /* passive scan */ + {HCI_SUPP_LE_STATES_ACTIVE_SCAN_SLAVE_MASK, HCI_SUPP_LE_STATES_ACTIVE_SCAN_SLAVE_OFF}, /* active scan */ + {HCI_SUPP_LE_STATES_SCAN_ADV_SLAVE_MASK, HCI_SUPP_LE_STATES_SCAN_ADV_SLAVE_OFF} /* scanable adv */ + + }, + { /* lo duty cycle adv */ + {0, 0}, /* conn_adv: 38,*/ + {HCI_SUPP_LE_STATES_LO_DUTY_DIR_ADV_INIT_MASK, HCI_SUPP_LE_STATES_LO_DUTY_DIR_ADV_INIT_OFF} ,/* init 34 */ + {HCI_SUPP_LE_STATES_LO_DUTY_DIR_ADV_MASTER_MASK, HCI_SUPP_LE_STATES_LO_DUTY_DIR_ADV_MASTER_OFF}, /* master 37 */ + {HCI_SUPP_LE_STATES_LO_DUTY_DIR_ADV_SLAVE_MASK, HCI_SUPP_LE_STATES_LO_DUTY_DIR_ADV_SLAVE_OFF}, /* slave: 40 */ + {0, 0}, /* lo duty cycle adv 40 */ + {0, 0}, /* hi duty cycle adv 39 */ + {0, 0}, /* non connectable adv */ + {0, 0}, /* TODO: passive scan, not covered? */ + {0, 0}, /* TODO: active scan, not covered? */ + {0, 0} /* scanable adv */ + }, + { /* hi duty cycle adv */ + {0, 0}, /* conn_adv: 38,*/ + {HCI_SUPP_LE_STATES_HI_DUTY_DIR_ADV_INIT_MASK, HCI_SUPP_LE_STATES_HI_DUTY_DIR_ADV_INIT_OFF}, /* init 33 */ + {HCI_SUPP_LE_STATES_HI_DUTY_DIR_ADV_MASTER_MASK, HCI_SUPP_LE_STATES_HI_DUTY_DIR_ADV_MASTER_OFF}, /* master 36 */ + {HCI_SUPP_LE_STATES_HI_DUTY_DIR_ADV_SLAVE_MASK, HCI_SUPP_LE_STATES_HI_DUTY_DIR_ADV_SLAVE_OFF}, /* slave: 39*/ + {0, 0}, /* lo duty cycle adv 40 */ + {0, 0}, /* hi duty cycle adv 39 */ + {0, 0}, /* non connectable adv */ + {HCI_SUPP_LE_STATES_HI_DUTY_DIR_ADV_PASS_SCAN_MASK, HCI_SUPP_LE_STATES_HI_DUTY_DIR_ADV_PASS_SCAN_OFF}, /* passive scan */ + {HCI_SUPP_LE_STATES_HI_DUTY_DIR_ADV_ACTIVE_SCAN_MASK, HCI_SUPP_LE_STATES_HI_DUTY_DIR_ADV_ACTIVE_SCAN_OFF}, /* active scan */ + {0, 0} /* scanable adv */ + }, + { /* non connectable adv */ + {0, 0}, /* conn_adv: */ + {HCI_SUPP_LE_STATES_NON_CONN_INIT_MASK, HCI_SUPP_LE_STATES_NON_CONN_INIT_OFF}, /* init */ + {HCI_SUPP_LE_STATES_NON_CONN_ADV_MASTER_MASK, HCI_SUPP_LE_STATES_NON_CONN_ADV_MASTER_OFF}, /* master */ + {HCI_SUPP_LE_STATES_NON_CONN_ADV_SLAVE_MASK, HCI_SUPP_LE_STATES_NON_CONN_ADV_SLAVE_OFF}, /* slave: */ + {0, 0}, /* lo duty cycle adv */ + {0, 0}, /* hi duty cycle adv */ + {0, 0}, /* non connectable adv */ + {HCI_SUPP_LE_STATES_NON_CONN_ADV_PASS_SCAN_MASK, HCI_SUPP_LE_STATES_NON_CONN_ADV_PASS_SCAN_OFF}, /* passive scan */ + {HCI_SUPP_LE_STATES_NON_CONN_ADV_ACTIVE_SCAN_MASK, HCI_SUPP_LE_STATES_NON_CONN_ADV_ACTIVE_SCAN_OFF}, /* active scan */ + {0, 0} /* scanable adv */ + }, + { /* passive scan */ + {HCI_SUPP_LE_STATES_CONN_ADV_PASS_SCAN_MASK, HCI_SUPP_LE_STATES_CONN_ADV_PASS_SCAN_OFF}, /* conn_adv: */ + {HCI_SUPP_LE_STATES_PASS_SCAN_INIT_MASK, HCI_SUPP_LE_STATES_PASS_SCAN_INIT_OFF}, /* init */ + {HCI_SUPP_LE_STATES_PASS_SCAN_MASTER_MASK, HCI_SUPP_LE_STATES_PASS_SCAN_MASTER_OFF}, /* master */ + {HCI_SUPP_LE_STATES_PASS_SCAN_SLAVE_MASK, HCI_SUPP_LE_STATES_PASS_SCAN_SLAVE_OFF}, /* slave: */ + {0, 0}, /* lo duty cycle adv */ + {HCI_SUPP_LE_STATES_HI_DUTY_DIR_ADV_PASS_SCAN_MASK, HCI_SUPP_LE_STATES_HI_DUTY_DIR_ADV_PASS_SCAN_OFF}, /* hi duty cycle adv */ + {HCI_SUPP_LE_STATES_NON_CONN_ADV_PASS_SCAN_MASK, HCI_SUPP_LE_STATES_NON_CONN_ADV_PASS_SCAN_OFF}, /* non connectable adv */ + {0, 0}, /* passive scan */ + {0, 0}, /* active scan */ + {HCI_SUPP_LE_STATES_SCAN_ADV_PASS_SCAN_MASK, HCI_SUPP_LE_STATES_SCAN_ADV_PASS_SCAN_OFF} /* scanable adv */ + }, + { /* active scan */ + {HCI_SUPP_LE_STATES_CONN_ADV_ACTIVE_SCAN_MASK, HCI_SUPP_LE_STATES_CONN_ADV_ACTIVE_SCAN_OFF}, /* conn_adv: */ + {HCI_SUPP_LE_STATES_ACTIVE_SCAN_INIT_MASK, HCI_SUPP_LE_STATES_ACTIVE_SCAN_INIT_OFF}, /* init */ + {HCI_SUPP_LE_STATES_ACTIVE_SCAN_MASTER_MASK, HCI_SUPP_LE_STATES_ACTIVE_SCAN_MASTER_OFF}, /* master */ + {HCI_SUPP_LE_STATES_ACTIVE_SCAN_SLAVE_MASK, HCI_SUPP_LE_STATES_ACTIVE_SCAN_SLAVE_OFF}, /* slave: */ + {0, 0}, /* lo duty cycle adv */ + {HCI_SUPP_LE_STATES_HI_DUTY_DIR_ADV_ACTIVE_SCAN_MASK, HCI_SUPP_LE_STATES_HI_DUTY_DIR_ADV_ACTIVE_SCAN_OFF}, /* hi duty cycle adv */ + {HCI_SUPP_LE_STATES_NON_CONN_ADV_ACTIVE_SCAN_MASK, HCI_SUPP_LE_STATES_NON_CONN_ADV_ACTIVE_SCAN_OFF}, /* non connectable adv */ + {0, 0}, /* TODO: passive scan */ + {0, 0}, /* TODO: active scan */ + {HCI_SUPP_LE_STATES_SCAN_ADV_ACTIVE_SCAN_MASK, HCI_SUPP_LE_STATES_SCAN_ADV_ACTIVE_SCAN_OFF} /* scanable adv */ + }, + { /* scanable adv */ + {0, 0}, /* conn_adv: */ + {HCI_SUPP_LE_STATES_SCAN_ADV_INIT_MASK, HCI_SUPP_LE_STATES_SCAN_ADV_INIT_OFF}, /* init */ + {HCI_SUPP_LE_STATES_SCAN_ADV_MASTER_MASK, HCI_SUPP_LE_STATES_SCAN_ADV_MASTER_OFF}, /* master */ + {HCI_SUPP_LE_STATES_SCAN_ADV_SLAVE_MASK, HCI_SUPP_LE_STATES_SCAN_ADV_SLAVE_OFF}, /* slave: */ + {0, 0}, /* lo duty cycle adv */ + {0, 0}, /* hi duty cycle adv */ + {0, 0}, /* non connectable adv */ + {HCI_SUPP_LE_STATES_SCAN_ADV_PASS_SCAN_MASK, HCI_SUPP_LE_STATES_SCAN_ADV_PASS_SCAN_OFF}, /* passive scan */ + {HCI_SUPP_LE_STATES_SCAN_ADV_ACTIVE_SCAN_MASK, HCI_SUPP_LE_STATES_SCAN_ADV_ACTIVE_SCAN_OFF}, /* active scan */ + {0, 0} /* scanable adv */ + } + +}; +/* check LE combo state supported */ +#define BTM_LE_STATES_SUPPORTED(x, y, z) ((x)[(z)] & (y)) + + /******************************************************************************* ** ** Function BTM_BleUpdateAdvWhitelist @@ -122,10 +254,13 @@ void BTM_BleUpdateAdvFilterPolicy(tBTM_BLE_AFP adv_policy) btm_ble_stop_adv (); if (p_cb->connectable_mode & BTM_BLE_CONNECTABLE) - p_cb->evt_type = btm_set_conn_mode_adv_init_addr(p_cb, p_addr_ptr, &init_addr_type, &p_cb->adv_addr_type); + p_cb->evt_type = btm_set_conn_mode_adv_init_addr(p_cb, p_addr_ptr, &init_addr_type, + &p_cb->adv_addr_type); - btsnd_hcic_ble_write_adv_params (p_cb->adv_interval_min, - p_cb->adv_interval_max, + btsnd_hcic_ble_write_adv_params ((UINT16)(p_cb->adv_interval_min ? p_cb->adv_interval_min : + BTM_BLE_GAP_ADV_SLOW_INT), + (UINT16)(p_cb->adv_interval_max ? p_cb->adv_interval_max : + BTM_BLE_GAP_ADV_SLOW_INT), p_cb->evt_type, p_cb->adv_addr_type, init_addr_type, @@ -155,7 +290,7 @@ tBTM_STATUS BTM_BleObserve(BOOLEAN start, UINT8 duration, tBTM_INQ_RESULTS_CB *p_results_cb, tBTM_CMPL_CB *p_cmpl_cb) { tBTM_BLE_INQ_CB *p_inq = &btm_cb.ble_ctr_cb.inq_var; - tBTM_STATUS status = BTM_NO_RESOURCES; + tBTM_STATUS status = BTM_WRONG_MODE; BTM_TRACE_EVENT1 ("BTM_BleObserve : scan_type:%d",btm_cb.btm_inq_vars.scan_type); @@ -165,63 +300,50 @@ tBTM_STATUS BTM_BleObserve(BOOLEAN start, UINT8 duration, if (start) { /* shared inquiry database, do not allow observe if any inquiry is active */ - if (btm_cb.btm_inq_vars.inq_active || p_inq->proc_mode != BTM_BLE_INQUIRY_NONE) + if (BTM_BLE_IS_OBS_ACTIVE(btm_cb.ble_ctr_cb.scan_activity)) { - /*check if an interleave scan is already in progress*/ - if(btm_cb.btm_inq_vars.scan_type == INQ_GENERAL - && btm_cb.btm_inq_vars.p_inq_results_cb != NULL) - { - BTM_TRACE_EVENT0 ("BTM_BleObserve general inq in progress, redirecting the results"); - btm_cb.btm_inq_vars.p_inq_ble_results_cb = p_results_cb; - btm_cb.btm_inq_vars.p_inq_ble_cmpl_cb = p_cmpl_cb; - return BTM_SUCCESS; - } - else - return BTM_BUSY; + BTM_TRACE_ERROR0("Observe Already Active"); + return status; } - btm_cb.btm_inq_vars.scan_type = INQ_LE_OBSERVE; - btm_cb.btm_inq_vars.p_inq_ble_results_cb = p_results_cb; - btm_cb.btm_inq_vars.p_inq_ble_cmpl_cb = p_cmpl_cb; - p_inq->scan_type = (p_inq->scan_type == BTM_BLE_SCAN_MODE_NONE) ? BTM_BLE_SCAN_MODE_ACTI: p_inq->scan_type; - /* allow config scanning type */ - if (btsnd_hcic_ble_set_scan_params (p_inq->scan_type, + btm_cb.ble_ctr_cb.p_obs_results_cb = p_results_cb; + btm_cb.ble_ctr_cb.p_obs_cmpl_cb = p_cmpl_cb; + status = BTM_CMD_STARTED; + + /* scan is not started */ + if (!BTM_BLE_IS_SCAN_ACTIVE(btm_cb.ble_ctr_cb.scan_activity)) + { + p_inq->scan_type = (p_inq->scan_type == BTM_BLE_SCAN_MODE_NONE) ? BTM_BLE_SCAN_MODE_ACTI: p_inq->scan_type; + /* allow config scanning type */ + btsnd_hcic_ble_set_scan_params (p_inq->scan_type, (UINT16)(!p_inq->scan_interval ? BTM_BLE_GAP_DISC_SCAN_INT : p_inq->scan_interval), (UINT16)(!p_inq->scan_window ? BTM_BLE_GAP_DISC_SCAN_WIN : p_inq->scan_window), - BLE_ADDR_PUBLIC, - BTM_BLE_DEFAULT_SFP)) /* assume observe always not using white list */ + btm_cb.ble_ctr_cb.addr_mgnt_cb.own_addr_type, + BTM_BLE_DEFAULT_SFP); /* assume observe always not using white list */ + + status = btm_ble_start_scan(BTM_BLE_DUPLICATE_DISABLE); + } + if (status == BTM_CMD_STARTED) { - /* start scan, disable duplicate filtering */ - if (btsnd_hcic_ble_set_scan_enable (BTM_BLE_SCAN_ENABLE, BTM_BLE_DUPLICATE_DISABLE)) - { - status = BTM_SUCCESS; - p_inq->proc_mode = BTM_BLE_OBSERVE; - btm_cb.btm_inq_vars.inq_active |= BTM_LE_OBSERVE_ACTIVE; + btm_cb.ble_ctr_cb.scan_activity |= BTM_LE_OBSERVE_ACTIVE; - if (duration != 0) - { - /* start inquiry timer */ - btu_start_timer (&p_inq->inq_timer_ent, BTU_TTYPE_BLE_INQUIRY, duration); - } - } + if (duration != 0) + /* start observer timer */ + btu_start_timer (&btm_cb.ble_ctr_cb.obs_timer_ent, BTU_TTYPE_BLE_OBSERVE, duration); } } - else/*start = 0*/ + else if (BTM_BLE_IS_OBS_ACTIVE(btm_cb.ble_ctr_cb.scan_activity)) { - if(btm_cb.btm_inq_vars.scan_type == INQ_GENERAL) - { - //Dont stop the scan. Just nullify the cbs - btm_cb.btm_inq_vars.p_inq_ble_results_cb = NULL; - btm_cb.btm_inq_vars.p_inq_ble_cmpl_cb = NULL; - } - else if (p_inq->proc_mode == BTM_BLE_OBSERVE) - { - btm_cb.btm_inq_vars.inq_active &= ~BTM_LE_OBSERVE_ACTIVE; - btm_ble_stop_scan(); - } + status = BTM_CMD_STARTED; + btm_ble_stop_observe(); + } + else + { + BTM_TRACE_ERROR0("Observe not active"); } return status; + } /******************************************************************************* @@ -255,8 +377,10 @@ tBTM_STATUS BTM_BleBroadcast(BOOLEAN start) if (start && p_cb->adv_mode == BTM_BLE_ADV_DISABLE) { /* update adv params */ - if (!btsnd_hcic_ble_write_adv_params ((UINT16)(p_cb->adv_interval_min ? p_cb->adv_interval_min : BTM_BLE_GAP_ADV_INT), - (UINT16)(p_cb->adv_interval_max ? p_cb->adv_interval_max : BTM_BLE_GAP_ADV_INT), + if (!btsnd_hcic_ble_write_adv_params ((UINT16)(p_cb->adv_interval_min ? p_cb->adv_interval_min : + BTM_BLE_GAP_ADV_INT), + (UINT16)(p_cb->adv_interval_max ? p_cb->adv_interval_max : + BTM_BLE_GAP_ADV_INT), evt_type, p_addr_cb->own_addr_type, p_cb->direct_bda.type, @@ -270,7 +394,7 @@ tBTM_STATUS BTM_BleBroadcast(BOOLEAN start) status = btm_ble_start_adv (); } - else if (!start && p_cb->adv_mode == BTM_BLE_ADV_ENABLE) + else if (!start) { status = btm_ble_stop_adv(); } @@ -278,7 +402,7 @@ tBTM_STATUS BTM_BleBroadcast(BOOLEAN start) { status = BTM_WRONG_MODE; BTM_TRACE_ERROR2("Can not %s Broadcast, device %s in Broadcast mode", - (start ? "Start" : "Stop"), (start ? "alerady" :"not")); + (start ? "Start" : "Stop"), (start ? "already" :"not")); } return status; } @@ -309,7 +433,42 @@ void BTM_RegisterScanReqEvt(tBTM_BLE_SCAN_REQ_CBACK *p_scan_req_cback) #endif } -#if BTM_BLE_PRIVACY_SPT == TRUE +#if BLE_PRIVACY_SPT == TRUE +/******************************************************************************* +** +** Function BTM_BleConfigPrivacy +** +** Description This function is called to enable or disable the privacy in +** LE channel of the local device. +** +** Parameters enable: TRUE to enable it; FALSE to disable it. +** +** Returns void +** +*******************************************************************************/ +void BTM_BleConfigPrivacy(BOOLEAN enable) +{ + tBTM_BLE_CB *p_cb = &btm_cb.ble_ctr_cb; + + BTM_TRACE_EVENT0 (" BTM_BleConfigPrivacy"); + + if (p_cb->privacy != enable) + { + p_cb->privacy = enable; + + if (p_cb->privacy) + { + /* generate resolvable private address */ + btm_gen_resolvable_private_addr(); + } + else /* if privacy disabled, always use public address */ + { + p_cb->addr_mgnt_cb.own_addr_type = BLE_ADDR_PUBLIC; + } + } +} + + /******************************************************************************* ** ** Function btm_ble_resolve_random_addr_on_adv @@ -486,11 +645,13 @@ static UINT8 btm_set_conn_mode_adv_init_addr(tBTM_BLE_INQ_CB *p_cb, { UINT8 evt_type; + UNUSED(p_own_addr_type); + if ( p_cb->directed_conn) { /* direct adv mode does not have privacy if privacy - is not enabled or no reconn addr config */ - *p_own_addr_type = BLE_ADDR_PUBLIC; + is not enabled or no reconn addr config */ + *p_init_addr_type = p_cb->direct_bda.type; memcpy(p_addr_ptr, p_cb->direct_bda.bda, BD_ADDR_LEN); evt_type = BTM_BLE_CONNECT_DIR_EVT; @@ -498,6 +659,16 @@ static UINT8 btm_set_conn_mode_adv_init_addr(tBTM_BLE_INQ_CB *p_cb, else /* undirect adv mode */ { evt_type = BTM_BLE_CONNECT_EVT; + +#if BLE_PRIVACY_SPT == TRUE + /* may need to reset random address if privacy is enabled */ + if (btm_cb.ble_ctr_cb.privacy && /* own addr_type is random */ + !BTM_BLE_IS_RESOLVE_BDA(btm_cb.ble_ctr_cb.addr_mgnt_cb.private_addr)) + { + /* need to generate RRA and update random addresss in controller */ + btm_gen_resolvable_private_addr(); + } +#endif } return evt_type; @@ -704,7 +875,7 @@ tBTM_STATUS BTM_BleWriteAdvData(tBTM_BLE_AD_MASK data_mask, tBTM_BLE_ADV_DATA *p { tBTM_BLE_LOCAL_ADV_DATA *p_cb_data = &btm_cb.ble_ctr_cb.inq_var.adv_data; UINT8 *p; - UINT16 mask = data_mask; + tBTM_BLE_AD_MASK mask = data_mask; BTM_TRACE_EVENT0 ("BTM_BleWriteAdvData "); @@ -930,7 +1101,99 @@ static UINT8 *btm_ble_build_adv_data(tBTM_BLE_AD_MASK *p_data_mask, UINT8 **p_ds return p_flag; } +/******************************************************************************* +** +** Function btm_ble_select_adv_interval +** +** Description select adv interval based on device mode +** +** Returns void +** +*******************************************************************************/ +void btm_ble_select_adv_interval(tBTM_BLE_INQ_CB *p_cb, UINT8 evt_type, UINT16 *p_adv_int_min, UINT16 *p_adv_int_max) +{ + if (p_cb->adv_interval_min && p_cb->adv_interval_max) + { + *p_adv_int_min = p_cb->adv_interval_min; + *p_adv_int_max = p_cb->adv_interval_max; + } + else + { + switch (evt_type) + { + case BTM_BLE_CONNECT_EVT: + *p_adv_int_min = *p_adv_int_max = BTM_BLE_GAP_ADV_FAST_INT_1; + break; + + case BTM_BLE_NON_CONNECT_EVT: + case BTM_BLE_DISCOVER_EVT: + *p_adv_int_min = *p_adv_int_max = BTM_BLE_GAP_ADV_FAST_INT_2; + break; + /* connectable directed event */ + case BTM_BLE_CONNECT_DIR_EVT: + *p_adv_int_min = BTM_BLE_GAP_ADV_DIR_MIN_INT; + *p_adv_int_max = BTM_BLE_GAP_ADV_DIR_MAX_INT; + break; + + default: + *p_adv_int_min = *p_adv_int_max = BTM_BLE_GAP_ADV_SLOW_INT; + break; + } + } + return; +} +/******************************************************************************* +** +** Function btm_ble_set_adv_flag +** +** Description Set adv flag in adv data. +** +** Returns void +** +*******************************************************************************/ +void btm_ble_set_adv_flag(UINT16 connect_mode, UINT16 disc_mode) +{ + UINT8 flag = 0, old_flag = 0; + tBTM_BLE_LOCAL_ADV_DATA *p_adv_data = &btm_cb.ble_ctr_cb.inq_var.adv_data; + + if (p_adv_data->p_flags != NULL) + flag = old_flag = *(p_adv_data->p_flags); + + /* BR/EDR non-discoverable , non-connectable */ + if ((disc_mode & BTM_DISCOVERABLE_MASK) == 0 && + (connect_mode & BTM_CONNECTABLE_MASK) == 0) + flag |= BTM_BLE_BREDR_NOT_SPT; + else + flag &= ~BTM_BLE_BREDR_NOT_SPT; + + /* if local controller support, mark both controller and host support in flag */ + if (HCI_SIMUL_LE_BREDR_SUPPORTED(btm_cb.devcb.local_lmp_features[HCI_EXT_FEATURES_PAGE_0])) + flag |= (BTM_BLE_DMT_CONTROLLER_SPT|BTM_BLE_DMT_HOST_SPT); + else + flag &= ~(BTM_BLE_DMT_CONTROLLER_SPT|BTM_BLE_DMT_HOST_SPT); + + BTM_TRACE_ERROR1("disc_mode %04x", disc_mode); + /* update discoverable flag */ + if (disc_mode & BTM_BLE_LIMITED_DISCOVERABLE) + { + flag &= ~BTM_BLE_GEN_DISC_FLAG; + flag |= BTM_BLE_LIMIT_DISC_FLAG ; + } + else if (disc_mode & BTM_BLE_GENERAL_DISCOVERABLE) + { + flag |= BTM_BLE_GEN_DISC_FLAG; + flag &= ~BTM_BLE_LIMIT_DISC_FLAG; + } + else /* remove all discoverable flags */ + { + flag &= ~(BTM_BLE_LIMIT_DISC_FLAG|BTM_BLE_GEN_DISC_FLAG); + } + if (flag != old_flag) + { + btm_ble_update_adv_flag(flag); + } +} /******************************************************************************* ** ** Function btm_ble_set_discoverability @@ -947,7 +1210,6 @@ tBTM_STATUS btm_ble_set_discoverability(UINT16 combined_mode) tBTM_LE_RANDOM_CB *p_addr_cb = &btm_cb.ble_ctr_cb.addr_mgnt_cb; tBTM_BLE_INQ_CB *p_cb = &btm_cb.ble_ctr_cb.inq_var; UINT16 mode = (combined_mode & BTM_BLE_DISCOVERABLE_MASK); - UINT8 flag = 0; UINT8 new_mode = BTM_BLE_ADV_ENABLE; UINT8 evt_type = (p_cb->connectable_mode == BTM_BLE_NON_CONNECTABLE) ? \ ((p_cb->scan_rsp) ? BTM_BLE_DISCOVER_EVT : BTM_BLE_NON_CONNECT_EVT )\ @@ -955,7 +1217,8 @@ tBTM_STATUS btm_ble_set_discoverability(UINT16 combined_mode) tBTM_STATUS status = BTM_SUCCESS; BD_ADDR p_addr_ptr= {0}; tBLE_ADDR_TYPE init_addr_type = BLE_ADDR_PUBLIC, - own_addr_type = p_addr_cb->own_addr_type;; + own_addr_type = p_addr_cb->own_addr_type; + UINT16 adv_int_min, adv_int_max; BTM_TRACE_EVENT2 ("btm_ble_set_discoverability mode=0x%0x combined_mode=0x%x", mode, combined_mode); @@ -963,56 +1226,28 @@ tBTM_STATUS btm_ble_set_discoverability(UINT16 combined_mode) if (mode > BTM_BLE_MAX_DISCOVERABLE) return(BTM_ILLEGAL_VALUE); - p_cb->br_edr_supported_flag |= (combined_mode & BTM_DISCOVERABLE_MASK); - p_cb->discoverable_mode = mode; + btm_ble_set_adv_flag (btm_cb.btm_inq_vars.connectable_mode, combined_mode); - if (!p_cb->br_edr_supported_flag) - { - flag = BTM_BLE_BREDR_NOT_SPT; - BTM_TRACE_DEBUG1("btm_ble_set_discoverability (BREDR not sup)flag=0x%x",flag); - } + evt_type = btm_set_conn_mode_adv_init_addr(p_cb, p_addr_ptr, &init_addr_type, &own_addr_type); - BTM_TRACE_DEBUG1 ("br_edr_supported=0x%x", p_cb->br_edr_supported_flag); + if (p_cb->connectable_mode == BTM_BLE_NON_CONNECTABLE && mode == BTM_BLE_NON_DISCOVERABLE) + new_mode = BTM_BLE_ADV_DISABLE; - if (mode == BTM_BLE_LIMITED_DISCOVERABLE || mode == BTM_BLE_GENERAL_DISCOVERABLE) - { - BTM_TRACE_EVENT0 ("mode == BTM_BLE_LIMITED_DISCOVERABLE "); - /* write ADV data with limited disc flag */ - if (mode == BTM_BLE_LIMITED_DISCOVERABLE) - flag |= BTM_BLE_LIMIT_DISC_FLAG ; - else - flag |= BTM_BLE_GEN_DISC_FLAG; - } - else /* non-discoverable */ - { - BTM_TRACE_EVENT0 ("mode == BTM_BLE_NON_DISCOVERABLE "); + btm_ble_select_adv_interval(p_cb, evt_type, &adv_int_min, &adv_int_max); - if (p_cb->connectable_mode == BTM_BLE_NON_CONNECTABLE) - { - p_cb->br_edr_supported_flag = 0; - - BTM_TRACE_EVENT0 ("always disable adv in non-discoverable non-connectable mode if no scan rsp "); - if (!p_cb->scan_rsp ) - new_mode = BTM_BLE_ADV_DISABLE; - - } - else - { - p_cb->evt_type = btm_set_conn_mode_adv_init_addr(p_cb, p_addr_ptr, &init_addr_type, &own_addr_type); - } - } - btm_ble_update_adv_flag(flag); + btu_stop_timer(&p_cb->fast_adv_timer); /* update adv params if start advertising */ BTM_TRACE_EVENT2 ("evt_type=0x%x p-cb->evt_type=0x%x ", evt_type, p_cb->evt_type); + if (new_mode == BTM_BLE_ADV_ENABLE && - (evt_type != p_cb->evt_type ||p_cb->adv_addr_type != own_addr_type)) + (evt_type != p_cb->evt_type ||p_cb->adv_addr_type != own_addr_type || !p_cb->fast_adv_on)) { btm_ble_stop_adv(); /* update adv params */ - if (!btsnd_hcic_ble_write_adv_params ((UINT16)(p_cb->adv_interval_min ? p_cb->adv_interval_min : BTM_BLE_GAP_ADV_INT), - (UINT16)(p_cb->adv_interval_max ? p_cb->adv_interval_max : BTM_BLE_GAP_ADV_INT), + if (!btsnd_hcic_ble_write_adv_params (adv_int_min, + adv_int_max, evt_type, own_addr_type, init_addr_type, @@ -1036,11 +1271,18 @@ tBTM_STATUS btm_ble_set_discoverability(UINT16 combined_mode) else status = btm_ble_stop_adv(); } + if (p_cb->adv_mode == BTM_BLE_ADV_ENABLE) + { + p_cb->fast_adv_on = TRUE; + /* start initial GAP mode adv timer */ + btu_start_timer (&p_cb->fast_adv_timer, BTU_TTYPE_BLE_GAP_FAST_ADV, + BTM_BLE_GAP_FAST_ADV_TOUT); + } /* set up stop advertising timer */ if (status == BTM_SUCCESS && mode == BTM_BLE_LIMITED_DISCOVERABLE) { - BTM_TRACE_EVENT1 ("start timer for limited disc mode duration=%d (30 secs)", BTM_BLE_GAP_LIM_TOUT); + BTM_TRACE_EVENT1 ("start timer for limited disc mode duration=%d (180 secs)", BTM_BLE_GAP_LIM_TOUT); /* start Tgap(lim_timeout) */ btu_start_timer (&p_cb->inq_timer_ent, BTU_TTYPE_BLE_GAP_LIM_DISC, BTM_BLE_GAP_LIM_TOUT); @@ -1064,57 +1306,39 @@ tBTM_STATUS btm_ble_set_connectability(UINT16 combined_mode) tBTM_LE_RANDOM_CB *p_addr_cb = &btm_cb.ble_ctr_cb.addr_mgnt_cb; tBTM_BLE_INQ_CB *p_cb = &btm_cb.ble_ctr_cb.inq_var; UINT16 mode = (combined_mode & BTM_BLE_CONNECTABLE_MASK); - UINT8 cur_flag = 0; - UINT8 cur_br_edr_not_sup_flag; - UINT8 new_flag; UINT8 new_mode = BTM_BLE_ADV_ENABLE; UINT8 evt_type = (p_cb->scan_rsp) ? BTM_BLE_DISCOVER_EVT: BTM_BLE_NON_CONNECT_EVT; tBTM_STATUS status = BTM_SUCCESS; BD_ADDR p_addr_ptr = {0}; tBLE_ADDR_TYPE init_addr_type = BLE_ADDR_PUBLIC, own_addr_type = p_addr_cb->own_addr_type; + UINT16 adv_int_min, adv_int_max; BTM_TRACE_EVENT2 ("btm_ble_set_connectability mode=0x%0x combined_mode=0x%x", mode, combined_mode); + /*** Check mode parameter ***/ if (mode > BTM_BLE_MAX_CONNECTABLE) return(BTM_ILLEGAL_VALUE); - if (btm_cb.ble_ctr_cb.inq_var.adv_data.p_flags) - cur_flag = *btm_cb.ble_ctr_cb.inq_var.adv_data.p_flags ; - cur_br_edr_not_sup_flag = (cur_flag & ((UINT8) BTM_BLE_BREDR_NOT_SPT)); - p_cb->br_edr_supported_flag |= ((combined_mode & BTM_CONNECTABLE_MASK) << 4); - if (p_cb->br_edr_supported_flag && cur_br_edr_not_sup_flag) - { - new_flag = cur_flag & ((UINT8) (~BTM_BLE_BREDR_NOT_SPT)); - BTM_TRACE_EVENT2 ("new flag=0x%x cur flag=0x%x",new_flag, cur_flag); - btm_ble_update_adv_flag(new_flag); - } p_cb->connectable_mode = mode; - if (mode == BTM_BLE_NON_CONNECTABLE) - { - if (p_cb->discoverable_mode == BTM_BLE_NON_DISCOVERABLE) - { - p_cb->br_edr_supported_flag = 0; - BTM_TRACE_EVENT0 ("always disable adv in non-discoverable non-connectable mode with no scan rsp"); - if(!p_cb->scan_rsp) - new_mode = BTM_BLE_ADV_DISABLE; + btm_ble_set_adv_flag (combined_mode, btm_cb.btm_inq_vars.discoverable_mode); - } - } - else /* connectable */ - { - evt_type = btm_set_conn_mode_adv_init_addr(p_cb, p_addr_ptr, &init_addr_type, &own_addr_type); - } + evt_type = btm_set_conn_mode_adv_init_addr(p_cb, p_addr_ptr, &init_addr_type, &own_addr_type); + + if (mode == BTM_BLE_NON_CONNECTABLE && p_cb->discoverable_mode == BTM_BLE_NON_DISCOVERABLE) + new_mode = BTM_BLE_ADV_DISABLE; + btm_ble_select_adv_interval(p_cb, evt_type, &adv_int_min, &adv_int_max); + + btu_stop_timer(&p_cb->fast_adv_timer); /* update adv params if needed */ - if ((p_cb->evt_type != evt_type || p_cb->adv_addr_type != p_addr_cb->own_addr_type) - && new_mode == BTM_BLE_ADV_ENABLE) + if ((p_cb->evt_type != evt_type || p_cb->adv_addr_type != p_addr_cb->own_addr_type || !p_cb->fast_adv_on)) { btm_ble_stop_adv(); - if (!btsnd_hcic_ble_write_adv_params ((UINT16)(p_cb->adv_interval_min ? p_cb->adv_interval_min : BTM_BLE_GAP_ADV_INT), - (UINT16)(p_cb->adv_interval_max ? p_cb->adv_interval_max : BTM_BLE_GAP_ADV_INT), + if (!btsnd_hcic_ble_write_adv_params (adv_int_min, + adv_int_max, evt_type, own_addr_type, init_addr_type, @@ -1132,24 +1356,22 @@ tBTM_STATUS btm_ble_set_connectability(UINT16 combined_mode) /* update advertising mode */ if (status == BTM_SUCCESS && new_mode != p_cb->adv_mode) { - if (btsnd_hcic_ble_set_adv_enable (new_mode)) - { - status = BTM_SUCCESS; - - p_cb->adv_mode = new_mode; - - if (p_cb->adv_mode == BTM_BLE_ADV_ENABLE && - p_cb->afp != AP_SCAN_CONN_ALL) - btm_cb.ble_ctr_cb.wl_state |= BTM_BLE_WL_ADV; - else - btm_cb.ble_ctr_cb.wl_state &= ~BTM_BLE_WL_ADV; - - } + if (new_mode == BTM_BLE_ADV_ENABLE) + status = btm_ble_start_adv(); + else + status = btm_ble_stop_adv(); + } + if (p_cb->adv_mode == BTM_BLE_ADV_ENABLE) + { + p_cb->fast_adv_on = TRUE; + /* start initial GAP mode adv timer */ + btu_start_timer (&p_cb->fast_adv_timer, BTU_TTYPE_BLE_GAP_FAST_ADV, + BTM_BLE_GAP_FAST_ADV_TOUT); } - return status; } + /******************************************************************************* ** ** Function btm_ble_start_inquiry @@ -1171,24 +1393,32 @@ tBTM_STATUS btm_ble_set_connectability(UINT16 combined_mode) *******************************************************************************/ tBTM_STATUS btm_ble_start_inquiry (UINT8 mode, UINT8 duration) { - tBTM_STATUS status = BTM_NO_RESOURCES; - tBTM_BLE_INQ_CB *p_inq = &btm_cb.ble_ctr_cb.inq_var; + tBTM_STATUS status = BTM_CMD_STARTED; + tBTM_BLE_CB *p_ble_cb = &btm_cb.ble_ctr_cb; + tBTM_INQUIRY_VAR_ST *p_inq = &btm_cb.btm_inq_vars; - BTM_TRACE_DEBUG2("btm_ble_start_inquiry: mode = %02x inq_active = %d", mode, btm_cb.btm_inq_vars.inq_active); + BTM_TRACE_DEBUG2("btm_ble_start_inquiry: mode = %02x inq_active = 0x%02x", mode, btm_cb.btm_inq_vars.inq_active); - if (p_inq->proc_mode != BTM_BLE_INQUIRY_NONE) + /* if selective connection is active, or inquiry is already active, reject it */ + if (BTM_BLE_IS_INQ_ACTIVE(p_ble_cb->scan_activity) || + BTM_BLE_IS_SEL_CONN_ACTIVE (p_ble_cb->scan_activity)) { - BTM_TRACE_ERROR0("LE scan is active, can not start inquiry"); + BTM_TRACE_ERROR0("LE Inquiry is active, can not start inquiry"); return(BTM_BUSY); } - btm_update_scanner_filter_policy(SP_ADV_ALL); + if (!BTM_BLE_IS_SCAN_ACTIVE(p_ble_cb->scan_activity)) + { + btm_update_scanner_filter_policy(SP_ADV_ALL); + status = btm_ble_start_scan(BTM_BLE_DUPLICATE_DISABLE); + } - /* start scan, already enable duplicate filtering */ - if (btsnd_hcic_ble_set_scan_enable (BTM_BLE_SCAN_ENABLE, BTM_BLE_DUPLICATE_DISABLE)) + if (status == BTM_CMD_STARTED) { - status = BTM_CMD_STARTED; - p_inq->proc_mode = mode; + p_inq->inq_active |= mode; + p_ble_cb->scan_activity |= mode; + + BTM_TRACE_DEBUG1("btm_ble_start_inquiry inq_active = 0x%02x", p_inq->inq_active); if (duration != 0) { @@ -1198,6 +1428,7 @@ tBTM_STATUS btm_ble_start_inquiry (UINT8 mode, UINT8 duration) } return status; + } /******************************************************************************* @@ -1508,68 +1739,54 @@ void btm_ble_cache_adv_data(tBTM_INQ_RESULTS *p_cur, UINT8 data_len, UINT8 *p, U ** Returns void ** *******************************************************************************/ -BOOLEAN btm_ble_is_discoverable(BD_ADDR bda, UINT8 evt_type, UINT8 *p) +UINT8 btm_ble_is_discoverable(BD_ADDR bda, UINT8 evt_type, UINT8 *p) { - BOOLEAN is_discoverable = FALSE; - UINT8 *p_flag, flag = 0; + UINT8 *p_flag, flag = 0, rt = 0; UINT8 data_len; tBTM_INQ_PARMS *p_cond = &btm_cb.btm_inq_vars.inqparms; + tBTM_BLE_INQ_CB *p_le_inq_cb = &btm_cb.ble_ctr_cb.inq_var; - STREAM_TO_UINT8 (data_len, p); + UNUSED(p); /* for observer, always "discoverable */ - if (btm_cb.ble_ctr_cb.inq_var.proc_mode == BTM_BLE_OBSERVE || - (btm_cb.ble_ctr_cb.inq_var.proc_mode == BTM_BLE_SELECT_SCAN && - btm_cb.ble_ctr_cb.bg_conn_type == BTM_BLE_CONN_SELECTIVE)) - return TRUE; + if (BTM_BLE_IS_OBS_ACTIVE(btm_cb.ble_ctr_cb.scan_activity)) + rt |= BTM_BLE_OBS_RESULT; + + if (BTM_BLE_IS_SEL_CONN_ACTIVE(btm_cb.ble_ctr_cb.scan_activity) && + (evt_type == BTM_BLE_CONNECT_EVT || evt_type == BTM_BLE_CONNECT_DIR_EVT)) + rt |= BTM_BLE_SEL_CONN_RESULT; /* does not match filter condition */ if (p_cond->filter_cond_type == BTM_FILTER_COND_BD_ADDR && memcmp(bda, p_cond->filter_cond.bdaddr_cond, BD_ADDR_LEN) != 0) { BTM_TRACE_DEBUG0("BD ADDR does not meet filter condition"); - return FALSE; - } - - /* scan response does not include the flag */ - if (evt_type == BTM_BLE_SCAN_RSP_EVT) - return FALSE; - - if (data_len > BTM_BLE_ADV_DATA_LEN_MAX) - { - BTM_TRACE_WARNING1("ADV data too long %d. discard", data_len); - return FALSE; + return rt; } - if (data_len != 0) + if (p_le_inq_cb->adv_len != 0) { - if ((p_flag = BTM_CheckAdvData(p, BTM_BLE_AD_TYPE_FLAG, &data_len)) != NULL) + if ((p_flag = BTM_CheckAdvData(p_le_inq_cb->adv_data_cache, + BTM_BLE_AD_TYPE_FLAG, &data_len)) != NULL) { flag = * p_flag; - if ((btm_cb.ble_ctr_cb.inq_var.proc_mode == BTM_BLE_GENERAL_INQUIRY) && + if ((btm_cb.btm_inq_vars.inq_active & BTM_BLE_GENERAL_INQUIRY) && (flag & (BTM_BLE_LIMIT_DISC_FLAG|BTM_BLE_GEN_DISC_FLAG)) != 0) { BTM_TRACE_DEBUG0("Find Generable Discoverable device"); - is_discoverable = TRUE; + rt |= BTM_BLE_INQ_RESULT; } - else if (btm_cb.ble_ctr_cb.inq_var.proc_mode == BTM_BLE_LIMITED_INQUIRY && + else if (btm_cb.btm_inq_vars.inq_active & BTM_BLE_LIMITED_INQUIRY && (flag & BTM_BLE_LIMIT_DISC_FLAG) != 0) { BTM_TRACE_DEBUG0("Find limited discoverable device"); - is_discoverable = TRUE; + rt |= BTM_BLE_INQ_RESULT; } - } } - - if (!is_discoverable) - { - BTM_TRACE_ERROR1("discoverable flag not desired: %d", flag); - } - - return is_discoverable; + return rt; } /******************************************************************************* @@ -1742,7 +1959,7 @@ void btm_ble_process_adv_pkt (UINT8 *p_data) BD_ADDR bda; UINT8 evt_type = 0, *p = p_data; UINT8 addr_type = 0; -#if (defined BTM_BLE_PRIVACY_SPT && BTM_BLE_PRIVACY_SPT == TRUE) +#if (defined BLE_PRIVACY_SPT && BLE_PRIVACY_SPT == TRUE) BOOLEAN match = FALSE; #endif @@ -1765,15 +1982,12 @@ void btm_ble_process_adv_pkt (UINT8 *p_data) /* Only process the results if the inquiry is still active */ - if ((btm_cb.btm_inq_vars.inq_active & BTM_LE_SCAN_ACTIVE_MASK) == 0 && - (btm_cb.ble_ctr_cb.bg_conn_type != BTM_BLE_CONN_SELECTIVE || - /* or selective auto connection is active */ - btm_cb.ble_ctr_cb.p_select_cback == NULL)) + if (!BTM_BLE_IS_SCAN_ACTIVE(btm_cb.ble_ctr_cb.scan_activity)) return; BTM_TRACE_DEBUG6("btm_ble_process_adv_pkt:bda= %0x:%0x:%0x:%0x:%0x:%0x", bda[0],bda[1],bda[2],bda[3],bda[4],bda[5]); -#if (defined BTM_BLE_PRIVACY_SPT && BTM_BLE_PRIVACY_SPT == TRUE) +#if (defined BLE_PRIVACY_SPT && BLE_PRIVACY_SPT == TRUE) #if SMP_INCLUDED == TRUE /* always do RRA resolution on host */ if (!match && BTM_BLE_IS_RESOLVE_BDA(bda)) @@ -1803,13 +2017,12 @@ void btm_ble_process_adv_pkt (UINT8 *p_data) static void btm_ble_process_adv_pkt_cont(BD_ADDR bda, UINT8 addr_type, UINT8 evt_type, UINT8 *p) { tINQ_DB_ENT *p_i; - BOOLEAN to_report = FALSE; - BOOLEAN to_report_LE = TRUE; //var for reporting to LE observe tBTM_INQUIRY_VAR_ST *p_inq = &btm_cb.btm_inq_vars; tBTM_INQ_RESULTS_CB *p_inq_results_cb = p_inq->p_inq_results_cb; - tBTM_INQ_RESULTS_CB *p_inq_ble_results_cb = p_inq->p_inq_ble_results_cb; + tBTM_INQ_RESULTS_CB *p_obs_results_cb = btm_cb.ble_ctr_cb.p_obs_results_cb; tBTM_BLE_INQ_CB *p_le_inq_cb = &btm_cb.ble_ctr_cb.inq_var; - BTM_TRACE_DEBUG2("btm_ble_process_adv_pkt_cont: addr_type: %d, evt_type: %d", addr_type, evt_type); + BOOLEAN update = TRUE; + UINT8 result = 0; p_i = btm_inq_db_find (bda); @@ -1817,26 +2030,23 @@ static void btm_ble_process_adv_pkt_cont(BD_ADDR bda, UINT8 addr_type, UINT8 evt if (btm_inq_find_bdaddr(bda)) { /* never been report as an LE device */ - if ((p_i && + if (p_i && (!(p_i->inq_info.results.device_type & BT_DEVICE_TYPE_BLE) || /* scan repsonse to be updated */ (!p_i->scan_rsp))) - || - btm_cb.ble_ctr_cb.inq_var.proc_mode == BTM_BLE_OBSERVE) { - BTM_TRACE_DEBUG0("update new BLE information "); - to_report = TRUE; + update = TRUE; + } + else if (BTM_BLE_IS_OBS_ACTIVE(btm_cb.ble_ctr_cb.scan_activity)) + { + update = FALSE; } else { - to_report = FALSE; + /* if yes, skip it */ + return; /* assumption: one result per event */ } } - else /* not been processed in this round */ - { - to_report = TRUE; - } - /* If existing entry, use that, else get a new one (possibly reusing the oldest) */ if (p_i == NULL) { @@ -1846,25 +2056,22 @@ static void btm_ble_process_adv_pkt_cont(BD_ADDR bda, UINT8 addr_type, UINT8 evt } else return; - - if (to_report && btm_ble_is_discoverable(bda, evt_type, p)) - { - to_report = TRUE; - } - else - { - BTM_TRACE_ERROR0("discard adv pkt"); - to_report = FALSE; - } } else if (p_i->inq_count != p_inq->inq_counter) /* first time seen in this inquiry */ { p_inq->inq_cmpl_info.num_resp++; } /* update the LE device information in inquiry database */ - to_report_LE = btm_ble_update_inq_result(p_i, addr_type, evt_type, p); - if (to_report) - to_report = to_report_LE; + if (!btm_ble_update_inq_result(p_i, addr_type, evt_type, p)) + return; + + if ((result = btm_ble_is_discoverable(bda, evt_type, p)) == 0) + { + BTM_TRACE_ERROR0("discard adv pkt"); + return; + } + if (!update) + result &= ~BTM_BLE_INQ_RESULT; #if BTM_USE_INQ_RESULTS_FILTER == TRUE /* If the number of responses found and limited, issue a cancel inquiry */ if (p_inq->inqparms.max_resps && @@ -1882,8 +2089,7 @@ static void btm_ble_process_adv_pkt_cont(BD_ADDR bda, UINT8 addr_type, UINT8 evt (p_inq->inq_active & BTM_PERIODIC_INQUIRY_ACTIVE) == 0) btsnd_hcic_inq_cancel(); - /* stop LE scan now */ - btm_ble_stop_scan(); + btm_ble_stop_inquiry(); #if BTM_BUSY_LEVEL_CHANGE_INCLUDED == TRUE btm_acl_update_busy_level (BTM_BLI_INQ_DONE_EVT); @@ -1891,28 +2097,54 @@ static void btm_ble_process_adv_pkt_cont(BD_ADDR bda, UINT8 addr_type, UINT8 evt } } #endif - - BTM_TRACE_DEBUG2("btm_ble_process_adv_pkt_cont: to_report =%d, to_report_le=%d", - to_report, to_report_LE); /* background connection in selective connection mode */ if (btm_cb.ble_ctr_cb.bg_conn_type == BTM_BLE_CONN_SELECTIVE) { - if (p_i->inq_info.results.device_type == BT_DEVICE_TYPE_BLE && - (evt_type == BTM_BLE_CONNECT_EVT || evt_type == BTM_BLE_CONNECT_DIR_EVT)) + if (result & BTM_BLE_SEL_CONN_RESULT) btm_send_sel_conn_callback(bda, evt_type, p, addr_type); else { BTM_TRACE_DEBUG0("None LE device, can not initiate selective connection"); } } - else if (to_report || to_report_LE) + else { - if(p_inq_results_cb && to_report) + if (p_inq_results_cb && (result & BTM_BLE_INQ_RESULT)) + { (p_inq_results_cb)((tBTM_INQ_RESULTS *) &p_i->inq_info.results, p_le_inq_cb->adv_data_cache); - if(p_inq_ble_results_cb && to_report_LE) - (p_inq_ble_results_cb)((tBTM_INQ_RESULTS *) &p_i->inq_info.results, - p_le_inq_cb->adv_data_cache); + } + if (p_obs_results_cb && (result & BTM_BLE_OBS_RESULT)) + { + (p_obs_results_cb)((tBTM_INQ_RESULTS *) &p_i->inq_info.results, p_le_inq_cb->adv_data_cache); + } + } +} + +/******************************************************************************* +** +** Function btm_ble_start_scan +** +** Description Start the BLE scan. +** +** Returns void +** +*******************************************************************************/ +tBTM_STATUS btm_ble_start_scan (UINT8 filter_enable) +{ + tBTM_BLE_INQ_CB *p_inq = &btm_cb.ble_ctr_cb.inq_var; + tBTM_STATUS status = BTM_CMD_STARTED; + + /* start scan, disable duplicate filtering */ + if (!btsnd_hcic_ble_set_scan_enable (BTM_BLE_SCAN_ENABLE, filter_enable)) + status = BTM_NO_RESOURCES; + else + { + if (p_inq->scan_type == BTM_BLE_SCAN_MODE_ACTI) + btm_ble_set_topology_mask(BTM_BLE_STATE_ACTIVE_SCAN_BIT); + else + btm_ble_set_topology_mask(BTM_BLE_STATE_PASSIVE_SCAN_BIT); } + return status; } /******************************************************************************* @@ -1926,44 +2158,135 @@ static void btm_ble_process_adv_pkt_cont(BD_ADDR bda, UINT8 addr_type, UINT8 evt *******************************************************************************/ void btm_ble_stop_scan(void) { - tBTM_BLE_INQ_CB *p_cb = &btm_cb.ble_ctr_cb.inq_var; - tBTM_INQUIRY_VAR_ST *p_inq = &btm_cb.btm_inq_vars; - BTM_TRACE_EVENT0 ("btm_ble_stop_scan "); - btu_stop_timer (&p_cb->inq_timer_ent); - /* Clear the inquiry callback if set */ - p_cb->scan_type = BTM_BLE_SCAN_MODE_NONE; - p_cb->proc_mode = BTM_BLE_INQUIRY_NONE; + btm_cb.ble_ctr_cb.inq_var.scan_type = BTM_BLE_SCAN_MODE_NONE; /* stop discovery now */ btsnd_hcic_ble_set_scan_enable (BTM_BLE_SCAN_DISABLE, BTM_BLE_DUPLICATE_ENABLE); + btm_update_scanner_filter_policy(SP_ADV_ALL); +} +/******************************************************************************* +** +** Function btm_ble_stop_inquiry +** +** Description Stop the BLE Inquiry. +** +** Returns void +** +*******************************************************************************/ +void btm_ble_stop_inquiry(void) +{ + tBTM_INQUIRY_VAR_ST *p_inq = &btm_cb.btm_inq_vars; + tBTM_BLE_CB *p_ble_cb = &btm_cb.ble_ctr_cb; + + btu_stop_timer (&p_ble_cb->inq_var.inq_timer_ent); + + p_ble_cb->scan_activity &= ~BTM_BLE_INQUIRY_MASK; + + /* If no more scan activity, stop LE scan now */ + if (!BTM_BLE_IS_SCAN_ACTIVE(p_ble_cb->scan_activity)) + btm_ble_stop_scan(); + /* If we have a callback registered for inquiry complete, call it */ BTM_TRACE_DEBUG2 ("BTM Inq Compl Callback: status 0x%02x, num results %d", p_inq->inq_cmpl_info.status, p_inq->inq_cmpl_info.num_resp); - btm_update_scanner_filter_policy(SP_ADV_ALL); - btm_process_inq_complete(HCI_SUCCESS, (UINT8)(p_inq->inqparms.mode & BTM_BLE_INQUIRY_MASK)); +} + +/******************************************************************************* +** +** Function btm_ble_stop_observe +** +** Description Stop the BLE Observe. +** +** Returns void +** +*******************************************************************************/ +static void btm_ble_stop_observe(void) +{ + tBTM_BLE_CB *p_ble_cb = & btm_cb.ble_ctr_cb; + tBTM_CMPL_CB *p_obs_cb = p_ble_cb->p_obs_cmpl_cb; + + btu_stop_timer (&p_ble_cb->obs_timer_ent); + p_ble_cb->scan_activity &= ~BTM_LE_OBSERVE_ACTIVE; + + p_ble_cb->p_obs_results_cb = NULL; + p_ble_cb->p_obs_cmpl_cb = NULL; + + if (!BTM_BLE_IS_SCAN_ACTIVE(p_ble_cb->scan_activity)) + btm_ble_stop_scan(); + + if (p_obs_cb) + (p_obs_cb)((tBTM_INQUIRY_CMPL *) &btm_cb.btm_inq_vars.inq_cmpl_info); +} +/******************************************************************************* +** +** Function btm_ble_adv_states_operation +** +** Description Set or clear adv states in topology mask +** +** Returns operation status. TRUE if sucessful, FALSE otherwise. +** +*******************************************************************************/ +typedef BOOLEAN (BTM_TOPOLOGY_FUNC_PTR)(tBTM_BLE_STATE_MASK); +static BOOLEAN btm_ble_adv_states_operation(BTM_TOPOLOGY_FUNC_PTR *p_handler, UINT8 adv_evt) +{ + BOOLEAN rt = FALSE; + + switch (adv_evt) + { + case BTM_BLE_CONNECT_EVT: + rt = (*p_handler)(BTM_BLE_STATE_CONN_ADV_BIT); + break; + + case BTM_BLE_NON_CONNECT_EVT: + rt = (*p_handler) (BTM_BLE_STATE_NON_CONN_ADV_BIT); + break; + case BTM_BLE_CONNECT_DIR_EVT: + rt = (*p_handler) (BTM_BLE_STATE_HI_DUTY_DIR_ADV_BIT); + break; + + case BTM_BLE_DISCOVER_EVT: + rt = (*p_handler) (BTM_BLE_STATE_SCAN_ADV_BIT); + break; + + default: + BTM_TRACE_ERROR1("unknown adv event : %d", adv_evt); + break; + } + + return rt; } + /******************************************************************************* ** ** Function btm_ble_start_adv ** -** Description Stop the BLE advertising. +** Description start the BLE advertising. ** ** Returns void ** *******************************************************************************/ -static tBTM_STATUS btm_ble_start_adv(void) +tBTM_STATUS btm_ble_start_adv(void) { tBTM_BLE_INQ_CB *p_cb = &btm_cb.ble_ctr_cb.inq_var; tBTM_STATUS rt = BTM_NO_RESOURCES; + if (!btm_ble_adv_states_operation (btm_ble_topology_check, p_cb->evt_type)) + return BTM_WRONG_MODE; + + if (p_cb->afp != AP_SCAN_CONN_ALL) + { + btm_execute_wl_dev_operation(); + btm_cb.ble_ctr_cb.wl_state |= BTM_BLE_WL_ADV; + } + if (btsnd_hcic_ble_set_adv_enable (BTM_BLE_ADV_ENABLE)) { if (p_cb->afp != AP_SCAN_CONN_ALL) @@ -1972,13 +2295,13 @@ static tBTM_STATUS btm_ble_start_adv(void) p_cb->adv_mode = BTM_BLE_ADV_ENABLE; rt = BTM_SUCCESS; - } - else - { - p_cb->adv_mode = BTM_BLE_ADV_DISABLE; - btm_cb.ble_ctr_cb.wl_state &= ~BTM_BLE_WL_ADV; - } - return rt; + } + else + { + p_cb->adv_mode = BTM_BLE_ADV_DISABLE; + btm_cb.ble_ctr_cb.wl_state &= ~BTM_BLE_WL_ADV; + } + return rt; } /******************************************************************************* ** @@ -1989,7 +2312,7 @@ static tBTM_STATUS btm_ble_start_adv(void) ** Returns void ** *******************************************************************************/ -static tBTM_STATUS btm_ble_stop_adv(void) +tBTM_STATUS btm_ble_stop_adv(void) { tBTM_BLE_INQ_CB *p_cb = &btm_cb.ble_ctr_cb.inq_var; tBTM_STATUS rt = BTM_SUCCESS; @@ -1998,18 +2321,143 @@ static tBTM_STATUS btm_ble_stop_adv(void) { if (btsnd_hcic_ble_set_adv_enable (BTM_BLE_ADV_DISABLE)) { + p_cb->fast_adv_on = FALSE; p_cb->adv_mode = BTM_BLE_ADV_DISABLE; btm_cb.ble_ctr_cb.wl_state &= ~BTM_BLE_WL_ADV; + + /* clear all adv states */ + btm_ble_clear_topology_mask (BTM_BLE_STATE_ALL_ADV_MASK); } else rt = BTM_NO_RESOURCES; } return rt; +} + + +/******************************************************************************* +** +** Function btm_ble_set_topology_mask +** +** Description set BLE topology mask +** +** Returns TRUE is request is allowed, FALSE otherwise. +** +*******************************************************************************/ +BOOLEAN btm_ble_set_topology_mask(tBTM_BLE_STATE_MASK request_state_mask) +{ + BOOLEAN rt = TRUE; + + request_state_mask &= BTM_BLE_STATE_ALL_MASK; + + btm_cb.ble_ctr_cb.cur_states |= request_state_mask; + + return rt; +} +/******************************************************************************* +** +** Function btm_ble_clear_topology_mask +** +** Description Clear BLE topology bit mask +** +** Returns TRUE is request is allowed, FALSE otherwise. +** +*******************************************************************************/ +BOOLEAN btm_ble_clear_topology_mask (tBTM_BLE_STATE_MASK request_state_mask) +{ + request_state_mask &= BTM_BLE_STATE_ALL_MASK; + + btm_cb.ble_ctr_cb.cur_states &= ~request_state_mask; + + return TRUE; +} +/******************************************************************************* +** +** Function btm_ble_update_mode_operation +** +** Description This function update the GAP role operation when a link status +** is updated. +** +** Returns void +** +*******************************************************************************/ +void btm_ble_update_mode_operation(UINT8 link_role, BD_ADDR bd_addr, BOOLEAN conn_cancel) +{ + tACL_CONN *pa = &btm_cb.acl_db[0]; + UINT16 xx; + UINT16 mask = BTM_BLE_STATE_ALL_CONN_MASK; + + UNUSED(bd_addr); + UNUSED (conn_cancel); + + if (link_role == HCI_ROLE_SLAVE) + { + btm_cb.ble_ctr_cb.inq_var.adv_mode = BTM_BLE_ADV_DISABLE; + /* clear all adv states */ + mask |= BTM_BLE_STATE_ALL_ADV_MASK; + } + + btm_ble_clear_topology_mask (mask); + + /* check the device link role maps */ + for (xx = 0; xx < MAX_L2CAP_LINKS; xx++, pa++) + { + if (pa->in_use && pa->transport == BT_TRANSPORT_LE) + { + if (pa->link_role == HCI_ROLE_MASTER) + btm_ble_set_topology_mask (BTM_BLE_STATE_MASTER_BIT); + else + btm_ble_set_topology_mask (BTM_BLE_STATE_SLAVE_BIT); + } + } + + if (btm_cb.ble_ctr_cb.inq_var.connectable_mode == BTM_BLE_CONNECTABLE) + { + btm_ble_set_connectability ( btm_cb.ble_ctr_cb.inq_var.connectable_mode ); + } + if (btm_ble_get_conn_st() == BLE_CONN_IDLE) + { + if (!btm_send_pending_direct_conn()) + { + btm_ble_resume_bg_conn(); + } + } } /******************************************************************************* ** +** Function btm_ble_start_slow_adv +** +** Description Restart adv with slow adv interval +** +** Returns void +** +*******************************************************************************/ +static void btm_ble_start_slow_adv (void) +{ + tBTM_BLE_INQ_CB *p_cb = &btm_cb.ble_ctr_cb.inq_var; + BD_ADDR p_addr_ptr= {0}; + + if (p_cb->adv_mode == BTM_BLE_ADV_ENABLE) + { + btm_ble_stop_adv(); + + btsnd_hcic_ble_write_adv_params (BTM_BLE_GAP_ADV_SLOW_INT, + BTM_BLE_GAP_ADV_SLOW_INT, + p_cb->evt_type, + p_cb->adv_addr_type, + btm_cb.ble_ctr_cb.addr_mgnt_cb.own_addr_type,/* slow adv + mode never goes into directed adv */ + p_addr_ptr, + p_cb->adv_chnl_map, + p_cb->afp); + + btm_ble_start_adv(); + } +} +/******************************************************************************* +** ** Function btm_ble_timeout ** ** Description Called when BTM BLE inquiry timer expires @@ -2019,17 +2467,23 @@ static tBTM_STATUS btm_ble_stop_adv(void) *******************************************************************************/ void btm_ble_timeout(TIMER_LIST_ENT *p_tle) { + BTM_TRACE_EVENT0 ("btm_ble_timeout"); + switch (p_tle->event) { + case BTU_TTYPE_BLE_OBSERVE: + btm_ble_stop_observe(); + break; + case BTU_TTYPE_BLE_INQUIRY: - btm_ble_stop_scan(); + btm_ble_stop_inquiry(); break; case BTU_TTYPE_BLE_GAP_LIM_DISC: /* lim_timeout expiried, limited discovery should exit now */ - btm_ble_update_adv_flag(BTM_BLE_NON_LIMIT_DISC_FLAG); + btm_cb.btm_inq_vars.discoverable_mode &= ~BTM_BLE_LIMITED_DISCOVERABLE; - btm_ble_stop_adv(); + btm_ble_set_adv_flag(btm_cb.btm_inq_vars.connectable_mode, btm_cb.btm_inq_vars.discoverable_mode); break; case BTU_TTYPE_BLE_RANDOM_ADDR: @@ -2040,6 +2494,14 @@ void btm_ble_timeout(TIMER_LIST_ENT *p_tle) } break; + case BTU_TTYPE_BLE_GAP_FAST_ADV: + /* fast adv is completed, fall back to slow adv interval */ + btm_ble_start_slow_adv(); + break; + + default: + break; + } } @@ -2058,13 +2520,13 @@ void btm_ble_timeout(TIMER_LIST_ENT *p_tle) void btm_ble_read_remote_features_complete(UINT8 *p) { tACL_CONN *p_acl_cb = &btm_cb.acl_db[0]; - UINT8 status; UINT16 handle; int xx; BTM_TRACE_EVENT0 ("btm_ble_read_remote_features_complete "); - STREAM_TO_UINT8 (status, p); + /* Skip status */ + p++; STREAM_TO_UINT16 (handle, p); /* Look up the connection by handle and copy features */ @@ -2076,6 +2538,7 @@ void btm_ble_read_remote_features_complete(UINT8 *p) break; } } + } /******************************************************************************* @@ -2120,58 +2583,6 @@ void btm_ble_dir_adv_tout(void) /******************************************************************************* ** -** Function btm_ble_update_mode_operation -** -** Description This function update the GAP role operation when a link status -** is updated. -** -** Returns void -** -*******************************************************************************/ -void btm_ble_update_mode_operation(UINT8 link_role, BD_ADDR bd_addr, BOOLEAN conn_cancel) -{ - tACL_CONN *pa = &btm_cb.acl_db[0]; - UINT16 xx; - UINT8 dev_role = link_role; - UNUSED(bd_addr); - UNUSED(conn_cancel); - - BTM_TRACE_DEBUG1("btm_ble_update_mode_operation adv_mode = %d", btm_cb.ble_ctr_cb.inq_var.adv_mode ); - - /* update periphera role operation */ - /* If we are LE connectable, check if we need to start advertising again */ - if (link_role == HCI_ROLE_UNKNOWN) - /* && btm_cb.ble_ctr_cb.inq_var.connectable_mode != BTM_BLE_NON_CONNECTABLE) */ - { - for (xx = 0; xx < MAX_L2CAP_LINKS; xx++, pa++) - { - /* If any other LE link is up, we are still not connectable */ - if (pa->in_use && pa->is_le_link) - { - dev_role = pa->link_role; - break; - } - } - } - - if (btm_cb.ble_ctr_cb.inq_var.connectable_mode == BTM_BLE_CONNECTABLE && - (dev_role == HCI_ROLE_UNKNOWN )) /* when device has no connection, update adv here */ - /* if already in connection, no connectable adv is allowed unless scatternet is enabled */ - { - btm_ble_set_connectability ( btm_cb.ble_ctr_cb.inq_var.connectable_mode ); - } - - if (btm_ble_get_conn_st() == BLE_CONN_IDLE) - { - if (!btm_send_pending_direct_conn()) - { - btm_ble_resume_bg_conn(); - } - } -} - -/******************************************************************************* -** ** Function btm_ble_init ** ** Description Initialize the control block variable values. @@ -2186,6 +2597,7 @@ void btm_ble_init (void) BTM_TRACE_EVENT0 ("btm_ble_init "); memset(p_cb, 0, sizeof(tBTM_BLE_CB)); + p_cb->cur_states = 0; p_cb->inq_var.adv_mode = BTM_BLE_ADV_DISABLE; p_cb->inq_var.scan_type = BTM_BLE_SCAN_MODE_NONE; @@ -2201,4 +2613,76 @@ void btm_ble_init (void) p_cb->inq_var.evt_type = BTM_BLE_NON_CONNECT_EVT; } +/******************************************************************************* +** +** Function btm_ble_topology_check +** +** Description check to see requested state is supported. One state check at +** a time is supported +** +** Returns TRUE is request is allowed, FALSE otherwise. +** +*******************************************************************************/ +BOOLEAN btm_ble_topology_check(tBTM_BLE_STATE_MASK request_state_mask) +{ + BOOLEAN rt = FALSE; + UINT32 llt_mask = 0; + UINT8 *p; + + UINT8 state_offset = 0; + UINT16 cur_states = btm_cb.ble_ctr_cb.cur_states; + UINT8 mask, offset; + UINT8 request_state = 0; + + /* check only one bit is set and within valid range */ + if (request_state_mask == BTM_BLE_STATE_INVALID || + request_state_mask > BTM_BLE_STATE_SCAN_ADV_BIT || + (request_state_mask & (request_state_mask -1 )) != 0) + { + BTM_TRACE_ERROR1("illegal state requested: %d", request_state_mask); + return rt; + } + + while (request_state_mask) + { + request_state_mask >>= 1; + request_state ++; + } + + /* check if the requested state is supported or not */ + mask = btm_le_state_combo_tbl[0][request_state - 1][0]; + offset = btm_le_state_combo_tbl[0][request_state-1][1]; + + if (!BTM_LE_STATES_SUPPORTED(btm_cb.devcb.le_supported_states, mask, offset)) + { + BTM_TRACE_ERROR1("state requested not supported: %d", request_state); + return rt; + } + + rt = TRUE; + /* make sure currently active states are all supported in conjunction with the requested + state. If the bit in table is not set, the combination is not supported */ + while (cur_states != 0) + { + if (cur_states & 0x01) + { + mask = btm_le_state_combo_tbl[request_state][state_offset][0]; + offset = btm_le_state_combo_tbl[request_state][state_offset][1]; + + if (mask != 0 && offset != 0) + { + if (!BTM_LE_STATES_SUPPORTED(btm_cb.devcb.le_supported_states, mask, offset)) + { + rt = FALSE; + break; + } + } + } + cur_states >>= 1; + state_offset ++; + } + return rt; +} + + #endif /* BLE_INCLUDED */ diff --git a/stack/btm/btm_ble_int.h b/stack/btm/btm_ble_int.h index 7a0550767..f3cb77135 100644 --- a/stack/btm/btm_ble_int.h +++ b/stack/btm/btm_ble_int.h @@ -61,9 +61,17 @@ #define BTM_BLE_GAP_DISC_SCAN_INT 18 /* Interval(scan_int) = 11.25 ms= 0x0010 * 0.625 ms */ #define BTM_BLE_GAP_DISC_SCAN_WIN 18 /* scan_window = 11.25 ms= 0x0010 * 0.625 ms */ #define BTM_BLE_GAP_ADV_INT 512 /* Tgap(gen_disc) = 1.28 s= 512 * 0.625 ms */ -#define BTM_BLE_GAP_LIM_TOUT 30 /* Tgap(lim_timeout) = 30.72 s max, round down to 30 */ +#define BTM_BLE_GAP_LIM_TOUT 180 /* Tgap(lim_timeout) = 180s max */ +#define BTM_BLE_GAP_ADV_FAST_INT_1 48 /* TGAP(adv_fast_interval1) = 30(used) ~ 60 ms = 48 *0.625 */ +#define BTM_BLE_GAP_ADV_FAST_INT_2 160 /* TGAP(adv_fast_interval2) = 100(used) ~ 150 ms = 160 * 0.625 ms */ +#define BTM_BLE_GAP_ADV_SLOW_INT 2048 /* Tgap(adv_slow_interval) = 1.28 s= 512 * 0.625 ms */ +#define BTM_BLE_GAP_ADV_DIR_MAX_INT 800 /* Tgap(dir_conn_adv_int_max) = 500 ms = 800 * 0.625 ms */ +#define BTM_BLE_GAP_ADV_DIR_MIN_INT 400 /* Tgap(dir_conn_adv_int_min) = 250 ms = 400 * 0.625 ms */ + +#define BTM_BLE_GAP_FAST_ADV_TOUT 30 + #define BTM_BLE_SEC_REQ_ACT_NONE 0 #define BTM_BLE_SEC_REQ_ACT_ENCRYPT 1 /* encrypt the link using current key or key refresh */ #define BTM_BLE_SEC_REQ_ACT_PAIR 2 @@ -75,6 +83,16 @@ typedef UINT8 tBTM_BLE_SEC_REQ_ACT; #define BLE_RESOLVE_ADDR_MASK 0xc0 /* bit 6, and bit7 */ #define BTM_BLE_IS_RESOLVE_BDA(x) ((x[0] & BLE_RESOLVE_ADDR_MASK) == BLE_RESOLVE_ADDR_MSB) +/* LE scan activity bit mask, continue with LE inquiry bits */ +#define BTM_LE_SELECT_CONN_ACTIVE 0x40 /* selection connection is in progress */ +#define BTM_LE_OBSERVE_ACTIVE 0x80 /* observe is in progress */ + +/* BLE scan activity mask checking */ +#define BTM_BLE_IS_SCAN_ACTIVE(x) ((x) & BTM_BLE_SCAN_ACTIVE_MASK) +#define BTM_BLE_IS_INQ_ACTIVE(x) ((x) & BTM_BLE_INQUIRY_MASK) +#define BTM_BLE_IS_OBS_ACTIVE(x) ((x) & BTM_LE_OBSERVE_ACTIVE) +#define BTM_BLE_IS_SEL_CONN_ACTIVE(x) ((x) & BTM_LE_SELECT_CONN_ACTIVE) + typedef struct { UINT16 data_mask; @@ -103,11 +121,6 @@ typedef struct UINT16 discoverable_mode; UINT16 connectable_mode; - UINT16 br_edr_supported_flag; /* combined BR EDR discoverable and connectable mode */ - /* only meaningful when it is zero. This means - BR EDR is not supported*/ - UINT8 proc_mode; /* current procedure mode : inquiry or discovery */ - UINT16 scan_window; UINT16 scan_interval; UINT8 scan_type; /* current scan type: active or passive */ @@ -121,6 +134,8 @@ typedef struct UINT8 adv_mode; tBLE_BD_ADDR direct_bda; BOOLEAN directed_conn; + BOOLEAN fast_adv_on; + TIMER_LIST_ENT fast_adv_timer; UINT8 adv_len; UINT8 adv_data_cache[BTM_BLE_CACHE_ADV_DATA_MAX]; @@ -148,8 +163,8 @@ typedef void (tBTM_BLE_ADDR_CBACK) (BD_ADDR_PTR static_random, void *p); /* random address management control block */ typedef struct { - tBLE_ADDR_TYPE own_addr_type; /* local device LE address type */ - BD_ADDR private_addr; + tBLE_ADDR_TYPE own_addr_type; /* local device LE address type */ + BD_ADDR private_addr; BD_ADDR random_bda; BOOLEAN busy; UINT16 index; @@ -198,6 +213,37 @@ typedef struct void *p_param; }tBTM_BLE_CONN_REQ; +/* LE state request */ +#define BTM_BLE_STATE_INVALID 0 +#define BTM_BLE_STATE_CONN_ADV 1 +#define BTM_BLE_STATE_INIT 2 +#define BTM_BLE_STATE_MASTER 3 +#define BTM_BLE_STATE_SLAVE 4 +#define BTM_BLE_STATE_LO_DUTY_DIR_ADV 5 +#define BTM_BLE_STATE_HI_DUTY_DIR_ADV 6 +#define BTM_BLE_STATE_NON_CONN_ADV 7 +#define BTM_BLE_STATE_PASSIVE_SCAN 8 +#define BTM_BLE_STATE_ACTIVE_SCAN 9 +#define BTM_BLE_STATE_SCAN_ADV 10 +#define BTM_BLE_STATE_MAX 11 +typedef UINT8 tBTM_BLE_STATE; + +#define BTM_BLE_STATE_CONN_ADV_BIT 0x0001 +#define BTM_BLE_STATE_INIT_BIT 0x0002 +#define BTM_BLE_STATE_MASTER_BIT 0x0004 +#define BTM_BLE_STATE_SLAVE_BIT 0x0008 +#define BTM_BLE_STATE_LO_DUTY_DIR_ADV_BIT 0x0010 +#define BTM_BLE_STATE_HI_DUTY_DIR_ADV_BIT 0x0020 +#define BTM_BLE_STATE_NON_CONN_ADV_BIT 0x0040 +#define BTM_BLE_STATE_PASSIVE_SCAN_BIT 0x0080 +#define BTM_BLE_STATE_ACTIVE_SCAN_BIT 0x0100 +#define BTM_BLE_STATE_SCAN_ADV_BIT 0x0200 +typedef UINT16 tBTM_BLE_STATE_MASK; + +#define BTM_BLE_STATE_ALL_MASK 0x03ff +#define BTM_BLE_STATE_ALL_ADV_MASK (BTM_BLE_STATE_CONN_ADV_BIT|BTM_BLE_STATE_LO_DUTY_DIR_ADV_BIT|BTM_BLE_STATE_HI_DUTY_DIR_ADV_BIT|BTM_BLE_STATE_SCAN_ADV_BIT) +#define BTM_BLE_STATE_ALL_SCAN_MASK (BTM_BLE_STATE_PASSIVE_SCAN_BIT|BTM_BLE_STATE_ACTIVE_SCAN_BIT) +#define BTM_BLE_STATE_ALL_CONN_MASK (BTM_BLE_STATE_MASTER_BIT|BTM_BLE_STATE_SLAVE_BIT) typedef struct { @@ -210,11 +256,18 @@ typedef struct */ typedef struct { + UINT8 scan_activity; /* LE scan activity mask */ + /***************************************************** ** BLE Inquiry *****************************************************/ tBTM_BLE_INQ_CB inq_var; + /* observer callback and timer */ + tBTM_INQ_RESULTS_CB *p_obs_results_cb; + tBTM_CMPL_CB *p_obs_cmpl_cb; + TIMER_LIST_ENT obs_timer_ent; + /* background connection procedure cb value */ tBTM_BLE_CONN_TYPE bg_conn_type; UINT16 scan_int; @@ -236,12 +289,18 @@ typedef struct tBTM_LE_RANDOM_CB addr_mgnt_cb; BOOLEAN enabled; +#if BLE_PRIVACY_SPT == TRUE + BOOLEAN privacy; /* privacy enabled or disabled */ +#endif tBTM_BLE_WL_OP wl_op_q[BTM_BLE_MAX_BG_CONN_DEV_NUM]; #ifdef BTM_BLE_PC_ADV_TEST_MODE tBTM_BLE_SCAN_REQ_CBACK *p_scan_req_cback; #endif + /* current BLE link state */ + tBTM_BLE_STATE_MASK cur_states; /* bit mask of tBTM_BLE_STATE */ + } tBTM_BLE_CB; #ifdef __cplusplus @@ -259,15 +318,20 @@ extern tBTM_STATUS btm_ble_set_connectability(UINT16 combined_mode); extern tBTM_STATUS btm_ble_start_inquiry (UINT8 mode, UINT8 duration); extern void btm_ble_dir_adv_tout(void); -extern void btm_ble_stop_scan(void); -extern void btm_ble_att_db_init(void); +extern void btm_ble_stop_scan(); +extern void btm_ble_stop_inquiry(void); extern void btm_ble_init (void); extern void btm_ble_connected (UINT8 *bda, UINT16 handle, UINT8 enc_mode, UINT8 role, tBLE_ADDR_TYPE addr_type, BOOLEAN addr_matched); extern void btm_ble_read_remote_features_complete(UINT8 *p); extern void btm_ble_write_adv_enable_complete(UINT8 * p); extern void btm_ble_conn_complete(UINT8 *p, UINT16 evt_len); +extern void btm_read_ble_local_supported_states_complete(UINT8 *p, UINT16 evt_len); extern tBTM_BLE_CONN_ST btm_ble_get_conn_st(void); extern void btm_ble_set_conn_st(tBTM_BLE_CONN_ST new_st); +extern tBTM_STATUS btm_ble_start_adv(void); +extern tBTM_STATUS btm_ble_stop_adv(void); +extern tBTM_STATUS btm_ble_start_scan (UINT8 filter_enb); + /* LE security function from btm_sec.c */ @@ -277,7 +341,7 @@ extern void btm_ble_ltk_request_reply(BD_ADDR bda, BOOLEAN use_stk, BT_OCTET16 extern UINT8 btm_proc_smp_cback(tSMP_EVT event, BD_ADDR bd_addr, tSMP_EVT_DATA *p_data); extern tBTM_STATUS btm_ble_set_encryption (BD_ADDR bd_addr, void *p_ref_data, UINT8 link_role); extern void btm_ble_ltk_request(UINT16 handle, UINT8 rand[8], UINT16 ediv); -extern BOOLEAN btm_ble_start_encrypt(BD_ADDR bda, BOOLEAN use_stk, BT_OCTET16 stk); +extern tBTM_STATUS btm_ble_start_encrypt(BD_ADDR bda, BOOLEAN use_stk, BT_OCTET16 stk); extern void btm_ble_link_encrypted(BD_ADDR bd_addr, UINT8 encr_enable); #endif @@ -312,6 +376,7 @@ extern BOOLEAN btm_ble_renew_bg_conn_params(BOOLEAN add, BD_ADDR bd_addr); extern UINT8 btm_ble_count_unconn_dev_in_whitelist(void); extern void btm_write_dir_conn_wl(BD_ADDR target_addr); extern void btm_ble_update_mode_operation(UINT8 link_role, BD_ADDR bda, BOOLEAN conn_ccancel); +extern BOOLEAN btm_execute_wl_dev_operation(void); /* direct connection utility */ extern BOOLEAN btm_send_pending_direct_conn(void); @@ -322,6 +387,9 @@ extern void btm_gen_resolvable_private_addr (void); extern void btm_gen_non_resolvable_private_addr (tBTM_BLE_ADDR_CBACK *p_cback, void *p); extern void btm_ble_resolve_random_addr(BD_ADDR random_bda, tBTM_BLE_RESOLVE_CBACK * p_cback, void *p); extern void btm_ble_update_reconnect_address(BD_ADDR bd_addr); +extern BOOLEAN btm_ble_topology_check(tBTM_BLE_STATE_MASK request); +extern BOOLEAN btm_ble_clear_topology_mask(tBTM_BLE_STATE_MASK request_state); +extern BOOLEAN btm_ble_set_topology_mask(tBTM_BLE_STATE_MASK request_state); #if BTM_BLE_CONFORMANCE_TESTING == TRUE BT_API extern void btm_ble_set_no_disc_if_pair_fail (BOOLEAN disble_disc); diff --git a/stack/btm/btm_dev.c b/stack/btm/btm_dev.c index 0dd534cfb..fbf4df13b 100644 --- a/stack/btm/btm_dev.c +++ b/stack/btm/btm_dev.c @@ -64,6 +64,7 @@ BOOLEAN BTM_SecAddDevice (BD_ADDR bd_addr, DEV_CLASS dev_class, BD_NAME bd_name, int i, j; BOOLEAN found = FALSE; + BTM_TRACE_API2("%s, link key type:%x", __FUNCTION__,key_type); p_dev_rec = btm_find_dev (bd_addr); if (!p_dev_rec) { @@ -79,7 +80,7 @@ BOOLEAN BTM_SecAddDevice (BD_ADDR bd_addr, DEV_CLASS dev_class, BD_NAME bd_name, memset (p_dev_rec, 0, sizeof (tBTM_SEC_DEV_REC)); p_dev_rec->sec_flags = BTM_SEC_IN_USE; memcpy (p_dev_rec->bd_addr, bd_addr, BD_ADDR_LEN); - p_dev_rec->hci_handle = BTM_GetHCIConnHandle (bd_addr); + p_dev_rec->hci_handle = BTM_GetHCIConnHandle (bd_addr, BT_TRANSPORT_BR_EDR); #if BLE_INCLUDED == TRUE /* use default value for background connection params */ @@ -172,7 +173,7 @@ BOOLEAN BTM_SecDeleteDevice (BD_ADDR bd_addr) { tBTM_SEC_DEV_REC *p_dev_rec; - if (BTM_IsAclConnectionUp(bd_addr)) + if (BTM_IsAclConnectionUp(bd_addr, BT_TRANSPORT_LE) || BTM_IsAclConnectionUp(bd_addr, BT_TRANSPORT_BR_EDR)) { BTM_TRACE_WARNING0("BTM_SecDeleteDevice FAILED: Cannot Delete when connection is active"); return(FALSE); @@ -215,9 +216,9 @@ char *BTM_SecReadDevName (BD_ADDR bd_addr) ** Function btm_sec_alloc_dev ** ** Description Look for the record in the device database for the record -** with specified handle +** with specified address ** -** Returns Pointer to the record +** Returns Pointer to the record or NULL ** *******************************************************************************/ tBTM_SEC_DEV_REC *btm_sec_alloc_dev (BD_ADDR bd_addr) @@ -278,7 +279,10 @@ tBTM_SEC_DEV_REC *btm_sec_alloc_dev (BD_ADDR bd_addr) memcpy (p_dev_rec->bd_addr, bd_addr, BD_ADDR_LEN); - p_dev_rec->hci_handle = BTM_GetHCIConnHandle (bd_addr); +#if BLE_INCLUDED == TRUE + p_dev_rec->ble_hci_handle = BTM_GetHCIConnHandle (bd_addr, BT_TRANSPORT_LE); +#endif + p_dev_rec->hci_handle = BTM_GetHCIConnHandle (bd_addr, BT_TRANSPORT_BR_EDR); p_dev_rec->timestamp = btm_cb.dev_rec_count++; return(p_dev_rec); @@ -376,7 +380,11 @@ tBTM_SEC_DEV_REC *btm_find_dev_by_handle (UINT16 handle) for (i = 0; i < BTM_SEC_MAX_DEVICE_RECORDS; i++, p_dev_rec++) { if ((p_dev_rec->sec_flags & BTM_SEC_IN_USE) - && (p_dev_rec->hci_handle == handle)) + && ((p_dev_rec->hci_handle == handle) +#if BLE_INCLUDED == TRUE + ||(p_dev_rec->ble_hci_handle == handle) +#endif + )) return(p_dev_rec); } return(NULL); @@ -440,7 +448,7 @@ tBTM_SEC_DEV_REC *btm_find_or_alloc_dev (BD_ADDR bd_addr) ** the oldest non-paired device. If all devices are paired it ** deletes the oldest paired device. ** -** Returns Pointer to the record +** Returns Pointer to the record or NULL ** *******************************************************************************/ tBTM_SEC_DEV_REC *btm_find_oldest_dev (void) @@ -454,7 +462,7 @@ tBTM_SEC_DEV_REC *btm_find_oldest_dev (void) for (i = 0; i < BTM_SEC_MAX_DEVICE_RECORDS; i++, p_dev_rec++) { if (((p_dev_rec->sec_flags & BTM_SEC_IN_USE) == 0) - || ((p_dev_rec->sec_flags & BTM_SEC_LINK_KEY_KNOWN) != 0)) + || ((p_dev_rec->sec_flags & (BTM_SEC_LINK_KEY_KNOWN |BTM_SEC_LE_LINK_KEY_KNOWN)) != 0)) continue; /* Device is paired so skip it */ if (p_dev_rec->timestamp < ot) diff --git a/stack/btm/btm_devctl.c b/stack/btm/btm_devctl.c index 240bd2fed..8117c458d 100644 --- a/stack/btm/btm_devctl.c +++ b/stack/btm/btm_devctl.c @@ -483,6 +483,25 @@ static void btm_read_ble_local_supported_features(void) /* Send a Read Local Supported Features message to the Host Controller. */ btsnd_hcic_ble_read_local_spt_feat (); } + +/******************************************************************************* +** +** Function btm_read_ble_local_supported_states +** +** Description Local function called to send a read BLE local supported +** features command +** +** Returns void +** +*******************************************************************************/ +static void btm_read_ble_local_supported_states(void) +{ + BTM_TRACE_DEBUG0("btm_read_ble_local_supported_states "); + btu_start_timer (&btm_cb.devcb.reset_timer, BTU_TTYPE_BTM_DEV_CTL, BTM_DEV_REPLY_TIMEOUT); + + /* Send a Read Local Supported states message to the Host Controller. */ + btsnd_hcic_ble_read_supported_states (); +} #endif /******************************************************************************* ** @@ -808,6 +827,36 @@ void btm_read_ble_buf_size_complete (UINT8 *p, UINT16 evt_len) l2c_link_processs_ble_num_bufs (lm_num_le_bufs); } + btm_read_ble_local_supported_states(); +} +/******************************************************************************* +** +** Function btm_read_ble_local_supported_states_complete +** +** Description This function is called when command complete for +** Read LE Local Supported states complete is received. +** +** Returns void +** +*******************************************************************************/ +void btm_read_ble_local_supported_states_complete (UINT8 *p, UINT16 evt_len) +{ + UINT8 status; + + UNUSED(evt_len); + BTM_TRACE_DEBUG0("btm_read_ble_local_supported_states_complete "); + + btu_stop_timer (&btm_cb.devcb.reset_timer); + + STREAM_TO_UINT8 (status, p); + if (status == HCI_SUCCESS) + { + STREAM_TO_ARRAY(&btm_cb.devcb.le_supported_states, p, BTM_LE_SUPPORT_STATE_SIZE); + } + else + { + BTM_TRACE_WARNING1 ("btm_read_ble_local_supported_features_complete status = %d", status); + } btm_read_ble_local_supported_features(); } @@ -842,6 +891,8 @@ void btm_read_ble_local_supported_features_complete (UINT8 *p, UINT16 evt_len) BTM_TRACE_WARNING1 ("btm_read_ble_local_supported_features_complete status = %d", status); } + btsnd_hcic_ble_set_evt_mask((UINT8 *)HCI_BLE_EVENT_MASK_DEF); + #if BTM_INTERNAL_BB == TRUE { UINT8 buf[9] = BTM_INTERNAL_LOCAL_FEA; @@ -874,6 +925,8 @@ void btm_read_white_list_size_complete(UINT8 *p, UINT16 evt_len) STREAM_TO_UINT8(btm_cb.ble_ctr_cb.max_filter_entries, p); btm_cb.ble_ctr_cb.num_empty_filter = btm_cb.ble_ctr_cb.max_filter_entries; } + /* write LE host support and simultatunous LE supported */ + btsnd_hcic_ble_write_host_supported(BTM_BLE_HOST_SUPPORT, BTM_BLE_SIMULTANEOUS_HOST); btm_get_ble_buffer_size(); } diff --git a/stack/btm/btm_inq.c b/stack/btm/btm_inq.c index 24f91a86d..01cbd56fd 100644 --- a/stack/btm/btm_inq.c +++ b/stack/btm/btm_inq.c @@ -796,10 +796,10 @@ tBTM_STATUS BTM_CancelInquiry(void) #if BLE_INCLUDED == TRUE if (((p_inq->inqparms.mode & BTM_BLE_INQUIRY_MASK) != 0) #if (defined(BTA_HOST_INTERLEAVE_SEARCH) && BTA_HOST_INTERLEAVE_SEARCH == TRUE) - &&(active_mode & BTM_LE_INQ_ACTIVE_MASK) + &&(active_mode & BTM_BLE_INQ_ACTIVE_MASK) #endif ) - btm_ble_stop_scan(); + btm_ble_stop_inquiry(); #endif } @@ -869,7 +869,6 @@ tBTM_STATUS BTM_StartInquiry (tBTM_INQ_PARMS *p_inqparms, tBTM_INQ_RESULTS_CB *p p_inq->scan_type = INQ_GENERAL; p_inq->inq_active = BTM_INQUIRY_INACTIVE; btm_cb.ble_ctr_cb.inq_var.scan_type = BTM_BLE_SCAN_MODE_NONE; - btm_cb.ble_ctr_cb.inq_var.proc_mode = BTM_BLE_INQUIRY_NONE; btsnd_hcic_ble_set_scan_enable (BTM_BLE_SCAN_DISABLE, BTM_BLE_DUPLICATE_ENABLE); } else @@ -1080,7 +1079,8 @@ tBTM_STATUS BTM_StartInquiry (tBTM_INQ_PARMS *p_inqparms, tBTM_INQ_RESULTS_CB *p ** BTM_WRONG_MODE if the device is not up. ** *******************************************************************************/ -tBTM_STATUS BTM_ReadRemoteDeviceName (BD_ADDR remote_bda, tBTM_CMPL_CB *p_cb) +tBTM_STATUS BTM_ReadRemoteDeviceName (BD_ADDR remote_bda, tBTM_CMPL_CB *p_cb + ,tBT_TRANSPORT transport) { tBTM_INQ_INFO *p_cur = NULL; tINQ_DB_ENT *p_i; @@ -1101,7 +1101,7 @@ tBTM_STATUS BTM_ReadRemoteDeviceName (BD_ADDR remote_bda, tBTM_CMPL_CB *p_cb) BTM_TRACE_API0 ("no device found in inquiry db"); #if (BLE_INCLUDED == TRUE) - if (BTM_UseLeLink(remote_bda)) + if (transport == BT_TRANSPORT_LE) { return btm_ble_read_remote_name(remote_bda, p_cur, p_cb); } @@ -2266,7 +2266,7 @@ void btm_process_inq_results (UINT8 *p, UINT8 inq_res_mode) #if BLE_INCLUDED == TRUE if ((p_inq->inqparms.mode & BTM_BLE_INQUIRY_MASK) != 0) - btm_ble_stop_scan(); + btm_ble_stop_inquiry(); #endif @@ -2493,14 +2493,13 @@ void btm_process_inq_complete (UINT8 status, UINT8 mode) (p_inq_cb)((tBTM_INQUIRY_CMPL *) &p_inq->inq_cmpl_info); } #if (defined(BTA_HOST_INTERLEAVE_SEARCH) && BTA_HOST_INTERLEAVE_SEARCH == TRUE) - if(p_inq->inqparms.mode != 0 && !(p_inq->inq_active & BTM_PERIODIC_INQUIRY_ACTIVE)) - { - /* make inquiry inactive for next iteration */ - p_inq->inq_active = BTM_INQUIRY_INACTIVE; - /* call the inquiry again */ - BTM_StartInquiry(&p_inq->inqparms,p_inq->p_inq_results_cb,p_inq->p_inq_cmpl_cb); - return; - } + if(p_inq->inqparms.mode != 0 && !(p_inq->inq_active & BTM_PERIODIC_INQUIRY_ACTIVE)) + { + /* make inquiry inactive for next iteration */ + p_inq->inq_active = BTM_INQUIRY_INACTIVE; + /* call the inquiry again */ + BTM_StartInquiry(&p_inq->inqparms,p_inq->p_inq_results_cb,p_inq->p_inq_cmpl_cb); + } #endif } if(p_inq->inqparms.mode == 0 && p_inq->scan_type == INQ_GENERAL)//this inquiry is complete @@ -3422,9 +3421,6 @@ void btm_set_eir_uuid( UINT8 *p_eir, tBTM_INQ_RESULTS *p_results ) BTM_AddEirService( p_results->eir_uuid, uuid16 ); } } - - BTM_TRACE_DEBUG2("btm_set_eir_uuid eir_uuid=0x%08X %08X", - p_results->eir_uuid[1], p_results->eir_uuid[0] ); } #endif diff --git a/stack/btm/btm_int.h b/stack/btm/btm_int.h index 7865b3eb3..913e253aa 100644 --- a/stack/btm/btm_int.h +++ b/stack/btm/btm_int.h @@ -46,7 +46,7 @@ typedef char tBTM_LOC_BD_NAME[BTM_MAX_LOC_BD_NAME_LEN + 1]; #endif -#define BTM_ACL_IS_CONNECTED(bda) (btm_bda_to_acl (bda) != NULL) +#define BTM_ACL_IS_CONNECTED(bda) (btm_bda_to_acl (bda, BT_TRANSPORT_BR_EDR) != NULL) /* Definitions for Server Channel Number (SCN) management */ @@ -119,8 +119,9 @@ typedef struct #if BTM_PWR_MGR_INCLUDED == FALSE UINT8 mode; #endif /* BTM_PWR_MGR_INCLUDED */ + #if BLE_INCLUDED == TRUE - UINT8 is_le_link; + tBT_TRANSPORT transport; BD_ADDR conn_addr; /* local device address used for this connection */ UINT8 conn_addr_type; /* local device address type for this connection */ BD_ADDR active_remote_addr; /* remote address used on this connection */ @@ -189,24 +190,29 @@ typedef struct BD_FEATURES local_lmp_features[HCI_EXT_FEATURES_PAGE_MAX + 1]; #if BLE_INCLUDED == TRUE + + tBTM_CMPL_CB *p_le_test_cmd_cmpl_cb; /* Callback function to be called when + LE test mode command has been sent successfully */ + BD_ADDR read_tx_pwr_addr; /* read TX power target address */ BD_FEATURES local_le_features; /* Local LE Supported features mask for the device */ tBTM_BLE_LOCAL_ID_KEYS id_keys; /* local BLE ID keys */ BT_OCTET16 er; /* BLE encryption key */ +#define BTM_LE_SUPPORT_STATE_SIZE 8 +UINT8 le_supported_states[BTM_LE_SUPPORT_STATE_SIZE]; + + + #if BTM_BLE_CONFORMANCE_TESTING == TRUE BOOLEAN no_disc_if_pair_fail; - BOOLEAN enable_test_mac_val; + BOOLEAN enable_test_mac_val; BT_OCTET8 test_mac; - BOOLEAN enable_test_local_sign_cntr; - UINT32 test_local_sign_cntr; + BOOLEAN enable_test_local_sign_cntr; + UINT32 test_local_sign_cntr; #endif -#if BLE_INCLUDED == TRUE - tBTM_CMPL_CB *p_le_test_cmd_cmpl_cb; /* Callback function to be called when - LE test mode command has been sent successfully */ -#endif #endif /* BLE_INCLUDED */ @@ -218,6 +224,7 @@ typedef struct tBTM_IO_CAP loc_io_caps; /* IO capability of the local device */ BOOLEAN loc_auth_req; /* the auth_req flag */ BD_FEATURES brcm_features; /* Broadcom specific features bit mask */ +#define BTM_RELOAD_LE_HOST_FEATURE 0x10 #define BTM_RE_READ_1ST_PAGE 0x01 /* Set it if you set at least one of "..._HOST_MAY_SUPP_..." bits */ #define BTM_HOST_MAY_SUPP_SSP 0x02 @@ -504,12 +511,13 @@ typedef struct tBLE_ADDR_TYPE ble_addr_type; /* LE device type: public or random address */ tBLE_ADDR_TYPE static_addr_type; /* static address type */ BD_ADDR static_addr; /* static address */ -#if BTM_BLE_PRIVACY_SPT == TRUE +#if BLE_PRIVACY_SPT == TRUE BD_ADDR cur_rand_addr; /* current random address */ #define BTM_BLE_ADDR_PSEUDO 0 /* address index device record */ #define BTM_BLE_ADDR_RRA 1 /* cur_rand_addr */ #define BTM_BLE_ADDR_STATIC 2 /* static_addr */ + UINT8 active_addr_type; #endif @@ -519,6 +527,7 @@ typedef struct #endif } tBTM_SEC_BLE; + #endif /* BLE_INCLUDED */ /* @@ -546,8 +555,14 @@ typedef struct #define BTM_SEC_LINK_KEY_AUTHED 0x20 #define BTM_SEC_ROLE_SWITCHED 0x40 #define BTM_SEC_IN_USE 0x80 + /* LE link security flag */ +#define BTM_SEC_LE_AUTHENTICATED 0x0200 /* 0x0200 */ +#define BTM_SEC_LE_ENCRYPTED 0x0400 /* 0x04 */ +#define BTM_SEC_LE_NAME_KNOWN 0x0800 +#define BTM_SEC_LE_LINK_KEY_KNOWN 0x1000 /* 0x10 */ +#define BTM_SEC_LE_LINK_KEY_AUTHED 0x2000 - UINT8 sec_flags; /* Current device security state */ + UINT16 sec_flags; /* Current device security state */ tBTM_BD_NAME sec_bd_name; /* User friendly name of the device. (may be truncated to save space in dev_rec table) */ BD_FEATURES features[HCI_EXT_FEATURES_PAGE_MAX + 1]; /* Features supported by the device */ @@ -589,6 +604,7 @@ typedef struct BOOLEAN rmt_auth_req; /* the auth_req flag as in the IO caps rsp evt */ #if (BLE_INCLUDED == TRUE) + UINT16 ble_hci_handle; /* use in DUMO connection */ UINT8 enc_key_size; /* current link encryption key size */ tBTM_SEC_BLE ble; tBT_DEVICE_TYPE device_type; @@ -612,6 +628,7 @@ typedef struct #define BTM_SEC_IS_SM4_LEGACY(sm) ((BOOLEAN)(BTM_SM4_KNOWN == ((sm)&BTM_SM4_TRUE))) #define BTM_SEC_IS_SM4_UNKNOWN(sm) ((BOOLEAN)(BTM_SM4_UNKNOWN == ((sm)&BTM_SM4_TRUE))) +#define BTM_SEC_LE_MASK (BTM_SEC_LE_AUTHENTICATED|BTM_SEC_LE_ENCRYPTED|BTM_SEC_LE_LINK_KEY_KNOWN|BTM_SEC_LE_LINK_KEY_AUTHED) /* ** Define device configuration structure @@ -726,11 +743,13 @@ typedef UINT8 tBTM_PAIRING_STATE; #define BTM_PAIR_FLAGS_WE_STARTED_DD 0x01 /* We want to do dedicated bonding */ #define BTM_PAIR_FLAGS_PEER_STARTED_DD 0x02 /* Peer initiated dedicated bonding */ -#define BTM_PAIR_FLAGS_DISC_WHEN_DONE 0x04 +#define BTM_PAIR_FLAGS_DISC_WHEN_DONE 0x04 /* Disconnect when done */ #define BTM_PAIR_FLAGS_PIN_REQD 0x08 /* set this bit when pin_callback is called */ #define BTM_PAIR_FLAGS_PRE_FETCH_PIN 0x10 /* set this bit when pre-fetch pin */ #define BTM_PAIR_FLAGS_REJECTED_CONNECT 0x20 /* set this bit when rejected incoming connection */ #define BTM_PAIR_FLAGS_WE_CANCEL_DD 0x40 /* set this bit when cancelling a bonding procedure */ +#define BTM_PAIR_FLAGS_LE_ACTIVE 0x80 /* use this bit when SMP pairing is active */ + typedef struct { @@ -975,8 +994,8 @@ extern BOOLEAN btm_lookup_eir(BD_ADDR_PTR p_rem_addr); extern void btm_acl_init (void); extern void btm_acl_timeout (TIMER_LIST_ENT *p_tle); extern void btm_acl_created (BD_ADDR bda, DEV_CLASS dc, BD_NAME bdn, - UINT16 hci_handle, UINT8 link_role, UINT8 is_le_link); -extern void btm_acl_removed (BD_ADDR bda); + UINT16 hci_handle, UINT8 link_role, tBT_TRANSPORT transport); +extern void btm_acl_removed (BD_ADDR bda, tBT_TRANSPORT transport); extern void btm_acl_device_down (void); extern void btm_acl_update_busy_level (tBTM_BLI_EVENT event); extern void btm_acl_link_key_change (UINT16 handle, UINT8 status); @@ -995,7 +1014,7 @@ extern void btm_process_clk_off_comp_evt (UINT16 hci_handle, UINT16 cloc extern void btm_acl_role_changed (UINT8 hci_status, BD_ADDR bd_addr, UINT8 new_role); extern void btm_acl_encrypt_change (UINT16 handle, UINT8 status, UINT8 encr_enable); BTM_API extern UINT16 btm_get_acl_disc_reason_code (void); -BTM_API extern tBTM_STATUS btm_remove_acl (BD_ADDR bd_addr); +BTM_API extern tBTM_STATUS btm_remove_acl (BD_ADDR bd_addr, tBT_TRANSPORT transport); extern void btm_read_remote_features_complete (UINT8 *p); extern void btm_read_remote_ext_features_complete (UINT8 *p); extern void btm_read_remote_ext_features_failed (UINT8 status, UINT16 handle); @@ -1005,7 +1024,7 @@ extern void btm_acl_chk_peer_pkt_type_support (tACL_CONN *p, UINT16 *p_p // btla-specific -- /* Read maximum data packet that can be sent over current connection */ extern UINT16 btm_get_max_packet_size (BD_ADDR addr); -extern tACL_CONN *btm_bda_to_acl (BD_ADDR bda); +extern tACL_CONN *btm_bda_to_acl (BD_ADDR bda, tBT_TRANSPORT transport); extern BOOLEAN btm_acl_notif_conn_collision (BD_ADDR bda); #if BTM_PWR_MGR_INCLUDED == FALSE @@ -1139,7 +1158,7 @@ extern void btm_sec_link_key_notification (UINT8 *p_bda, UINT8 *p_link_key, UIN extern void btm_sec_link_key_request (UINT8 *p_bda); extern void btm_sec_pin_code_request (UINT8 *p_bda); extern void btm_sec_update_clock_offset (UINT16 handle, UINT16 clock_offset); -extern void btm_sec_dev_rec_cback_event (tBTM_SEC_DEV_REC *p_dev_rec, UINT8 res); +extern void btm_sec_dev_rec_cback_event (tBTM_SEC_DEV_REC *p_dev_rec, UINT8 res, BOOLEAN is_le_trasnport); #if BLE_INCLUDED == TRUE extern void btm_sec_clear_ble_keys (tBTM_SEC_DEV_REC *p_dev_rec); diff --git a/stack/btm/btm_pm.c b/stack/btm/btm_pm.c index 02e3a6a92..711a69b76 100644 --- a/stack/btm/btm_pm.c +++ b/stack/btm/btm_pm.c @@ -420,7 +420,11 @@ static int btm_pm_find_acl_ind(BD_ADDR remote_bda) for (xx = 0; xx < MAX_L2CAP_LINKS; xx++, p++) { - if ((p->in_use) && (!memcmp (p->remote_addr, remote_bda, BD_ADDR_LEN))) + if ((p->in_use) && (!memcmp (p->remote_addr, remote_bda, BD_ADDR_LEN)) +#if (BLE_INCLUDED == TRUE) + && p->transport == BT_TRANSPORT_BR_EDR +#endif + ) { #if BTM_PM_DEBUG == TRUE BTM_TRACE_DEBUG2( "btm_pm_find_acl_ind ind:%d, st:%d", xx, btm_cb.pm_mode_db[xx].state); @@ -848,15 +852,17 @@ void btm_pm_proc_mode_change (UINT8 hci_status, UINT16 hci_handle, UINT8 mode, U BTM_TRACE_DEBUG2( "btm_pm_proc_mode_change new state:0x%x (old:0x%x)", p_cb->state, old_state); #endif - if ((p_cb->state == HCI_MODE_ACTIVE) && - ((p_lcb = l2cu_find_lcb_by_bd_addr (p->remote_addr)) != NULL)) + if ((p_lcb = l2cu_find_lcb_by_bd_addr(p->remote_addr, BT_TRANSPORT_BR_EDR)) != NULL) { - /* There might be any pending packets due to SNIFF or PENDING state */ - /* Trigger L2C to start transmission of the pending packets. */ - BTM_TRACE_DEBUG0 ("btm mode change to active; check l2c_link for outgoing packets"); - l2c_link_check_send_pkts (p_lcb, NULL, NULL); + if ((p_cb->state == BTM_PM_ST_ACTIVE) || (p_cb->state == BTM_PM_ST_SNIFF)) + { + /* There might be any pending packets due to SNIFF or PENDING state */ + /* Trigger L2C to start transmission of the pending packets. */ + BTM_TRACE_DEBUG0("btm mode change to active; check l2c_link for outgoing packets"); + l2c_link_check_send_pkts(p_lcb, NULL, NULL); //btu_stop_timer (&p_lcb->timer_entry); + } } /* notify registered parties */ @@ -955,7 +961,9 @@ void btm_pm_proc_ssr_evt (UINT8 *p, UINT16 evt_len) } } } + #endif + #else /* BTM_PWR_MGR_INCLUDED == TRUE */ /******************************************************************************* @@ -984,6 +992,7 @@ tBTM_STATUS BTM_ReadPowerMode (BD_ADDR remote_bda, tBTM_PM_MODE *p_mode) #endif + /******************************************************************************* ** ** Function BTM_IsPowerManagerOn @@ -998,3 +1007,5 @@ BOOLEAN BTM_IsPowerManagerOn (void) { return BTM_PWR_MGR_INCLUDED; } + + diff --git a/stack/btm/btm_sco.c b/stack/btm/btm_sco.c index 2200b7119..1ef38271a 100644 --- a/stack/btm/btm_sco.c +++ b/stack/btm/btm_sco.c @@ -582,7 +582,7 @@ tBTM_STATUS BTM_CreateSco (BD_ADDR remote_bda, BOOLEAN is_orig, UINT16 pkt_types /* If originating, ensure that there is an ACL connection to the BD Address */ if (is_orig) { - if ((!remote_bda) || ((acl_handle = BTM_GetHCIConnHandle (remote_bda)) == 0xFFFF)) + if ((!remote_bda) || ((acl_handle = BTM_GetHCIConnHandle (remote_bda, BT_TRANSPORT_BR_EDR)) == 0xFFFF)) return (BTM_UNKNOWN_ADDR); } @@ -682,7 +682,7 @@ tBTM_STATUS BTM_CreateSco (BD_ADDR remote_bda, BOOLEAN is_orig, UINT16 pkt_types { /* If role change is in progress, do not proceed with SCO setup * Wait till role change is complete */ - p_acl = btm_bda_to_acl(remote_bda); + p_acl = btm_bda_to_acl(remote_bda, BT_TRANSPORT_BR_EDR); if (p_acl && p_acl->switch_role_state != BTM_ACL_SWKEY_STATE_IDLE) { BTM_TRACE_API1("Role Change is in progress for ACL handle 0x%04x",acl_handle); @@ -740,7 +740,7 @@ void btm_sco_chk_pend_unpark (UINT8 hci_status, UINT16 hci_handle) for (xx = 0; xx < BTM_MAX_SCO_LINKS; xx++, p++) { if ((p->state == SCO_ST_PEND_UNPARK) && - ((acl_handle = BTM_GetHCIConnHandle (p->esco.data.bd_addr)) == hci_handle)) + ((acl_handle = BTM_GetHCIConnHandle (p->esco.data.bd_addr, BT_TRANSPORT_BR_EDR)) == hci_handle)) { BTM_TRACE_API3("btm_sco_chk_pend_unpark -> (e)SCO Link for ACL handle 0x%04x, Desired Type %d, hci_status 0x%02x", @@ -774,7 +774,7 @@ void btm_sco_chk_pend_rolechange (UINT16 hci_handle) for (xx = 0; xx < BTM_MAX_SCO_LINKS; xx++, p++) { if ((p->state == SCO_ST_PEND_ROLECHANGE) && - ((acl_handle = BTM_GetHCIConnHandle (p->esco.data.bd_addr)) == hci_handle)) + ((acl_handle = BTM_GetHCIConnHandle (p->esco.data.bd_addr, BT_TRANSPORT_BR_EDR)) == hci_handle)) { BTM_TRACE_API1("btm_sco_chk_pend_rolechange -> (e)SCO Link for ACL handle 0x%04x", acl_handle); diff --git a/stack/btm/btm_sec.c b/stack/btm/btm_sec.c index 09f41b799..625297cc4 100644 --- a/stack/btm/btm_sec.c +++ b/stack/btm/btm_sec.c @@ -80,13 +80,19 @@ static BOOLEAN btm_sec_check_prefetch_pin (tBTM_SEC_DEV_REC *p_dev_rec); static UINT8 btm_sec_start_authorization (tBTM_SEC_DEV_REC *p_dev_rec); BOOLEAN btm_sec_are_all_trusted(UINT32 p_mask[]); -static tBTM_STATUS btm_sec_send_hci_disconnect (tBTM_SEC_DEV_REC *p_dev_rec, UINT8 reason); +static tBTM_STATUS btm_sec_send_hci_disconnect (tBTM_SEC_DEV_REC *p_dev_rec, UINT8 reason, UINT16 conn_handle); +UINT8 btm_sec_start_role_switch (tBTM_SEC_DEV_REC *p_dev_rec); tBTM_SEC_DEV_REC *btm_sec_find_dev_by_sec_state (UINT8 state); static BOOLEAN btm_sec_set_security_level ( CONNECTION_TYPE conn_type, char *p_name, UINT8 service_id, UINT16 sec_level, UINT16 psm, UINT32 mx_proto_id, UINT32 mx_chan_id); +static BOOLEAN btm_dev_authenticated(tBTM_SEC_DEV_REC *p_dev_rec); +static BOOLEAN btm_dev_encrypted(tBTM_SEC_DEV_REC *p_dev_rec); +static BOOLEAN btm_dev_authorized(tBTM_SEC_DEV_REC *p_dev_rec); +static BOOLEAN btm_serv_trusted(tBTM_SEC_DEV_REC *p_dev_rec, tBTM_SEC_SERV_REC *p_serv_rec); + /* TRUE - authenticated link key is possible */ static const BOOLEAN btm_sec_io_map [BTM_IO_CAP_MAX][BTM_IO_CAP_MAX] = { @@ -103,6 +109,78 @@ static const BOOLEAN btm_sec_io_map [BTM_IO_CAP_MAX][BTM_IO_CAP_MAX] = /******************************************************************************* ** +** Function btm_dev_authenticated +** +** Description check device is authenticated +** +** Returns BOOLEAN TRUE or FALSE +** +*******************************************************************************/ +static BOOLEAN btm_dev_authenticated (tBTM_SEC_DEV_REC *p_dev_rec) +{ + if(p_dev_rec->sec_flags & BTM_SEC_AUTHENTICATED) + { + return(TRUE); + } + return(FALSE); +} + +/******************************************************************************* +** +** Function btm_dev_encrypted +** +** Description check device is encrypted +** +** Returns BOOLEAN TRUE or FALSE +** +*******************************************************************************/ +static BOOLEAN btm_dev_encrypted (tBTM_SEC_DEV_REC *p_dev_rec) +{ + if(p_dev_rec->sec_flags & BTM_SEC_ENCRYPTED) + { + return(TRUE); + } + return(FALSE); +} + +/******************************************************************************* +** +** Function btm_dev_authorized +** +** Description check device is authorized +** +** Returns BOOLEAN TRUE or FALSE +** +*******************************************************************************/ +static BOOLEAN btm_dev_authorized (tBTM_SEC_DEV_REC *p_dev_rec) +{ + if(p_dev_rec->sec_flags & BTM_SEC_AUTHORIZED) + { + return(TRUE); + } + return(FALSE); +} + +/******************************************************************************* +** +** Function btm_serv_trusted +** +** Description check service is trusted +** +** Returns BOOLEAN TRUE or FALSE +** +*******************************************************************************/ +static BOOLEAN btm_serv_trusted(tBTM_SEC_DEV_REC *p_dev_rec, tBTM_SEC_SERV_REC *p_serv_rec) +{ + if(BTM_SEC_IS_SERVICE_TRUSTED(p_dev_rec->trusted_mask, p_serv_rec->service_id)) + { + return(TRUE); + } + return(FALSE); +} + +/******************************************************************************* +** ** Function BTM_SecRegister ** ** Description Application manager calls this function to register for @@ -121,28 +199,29 @@ BOOLEAN BTM_SecRegister (tBTM_APPL_INFO *p_cb_info) BTM_TRACE_EVENT0 ("BTM_Sec: application registered"); #if BLE_INCLUDED == TRUE && SMP_INCLUDED == TRUE - BTM_TRACE_ERROR1 ("BTM_SecRegister:p_cb_info->p_le_callback == 0x%x ", p_cb_info->p_le_callback); - if (p_cb_info->p_le_callback) { -#if SMP_INCLUDED == TRUE - BTM_TRACE_EVENT0 ("BTM_Sec: SMP_Register( btm_proc_smp_cback )"); - SMP_Register(btm_proc_smp_cback); -#endif - /* if no IR is loaded, need to regenerate all the keys */ - if (memcmp(btm_cb.devcb.id_keys.ir, &temp_value, sizeof(BT_OCTET16)) == 0) + BTM_TRACE_ERROR1 ("BTM_SecRegister:p_cb_info->p_le_callback == 0x%x ", p_cb_info->p_le_callback); + + if (p_cb_info->p_le_callback) { - btm_ble_reset_id(); + #if SMP_INCLUDED == TRUE + BTM_TRACE_EVENT0 ("BTM_Sec: SMP_Register( btm_proc_smp_cback )"); + SMP_Register(btm_proc_smp_cback); + #endif + /* if no IR is loaded, need to regenerate all the keys */ + if (memcmp(btm_cb.devcb.id_keys.ir, &temp_value, sizeof(BT_OCTET16)) == 0) + { + btm_ble_reset_id(); + } + } + else + { + BTM_TRACE_ERROR0 ("BTM_SecRegister:p_cb_info->p_le_callback == NULL "); } - } - else - { - BTM_TRACE_ERROR0 ("BTM_SecRegister:p_cb_info->p_le_callback == NULL "); } #endif - - btm_cb.api = *p_cb_info; #if BLE_INCLUDED == TRUE && SMP_INCLUDED == TRUE BTM_TRACE_ERROR1 ("BTM_SecRegister: btm_cb.api.p_le_callback = 0x%x ", btm_cb.api.p_le_callback); @@ -270,7 +349,34 @@ BOOLEAN BTM_GetSecurityFlags (BD_ADDR bd_addr, UINT8 * p_sec_flags) if ((p_dev_rec = btm_find_dev (bd_addr)) != NULL) { - *p_sec_flags = p_dev_rec->sec_flags; + *p_sec_flags = (UINT8) p_dev_rec->sec_flags; + return(TRUE); + } + BTM_TRACE_ERROR0 ("BTM_GetSecurityFlags false"); + return(FALSE); +} + +/******************************************************************************* +** +** Function BTM_GetSecurityFlagsByTransport +** +** Description Get security flags for the device on a particular transport +** +** Returns BOOLEAN TRUE or FALSE is device found +** +*******************************************************************************/ +BOOLEAN BTM_GetSecurityFlagsByTransport (BD_ADDR bd_addr, UINT8 * p_sec_flags, + tBT_TRANSPORT transport) +{ + tBTM_SEC_DEV_REC *p_dev_rec; + + if ((p_dev_rec = btm_find_dev (bd_addr)) != NULL) + { + if (transport == BT_TRANSPORT_BR_EDR) + *p_sec_flags = (UINT8) p_dev_rec->sec_flags; + else + *p_sec_flags = (UINT8) (p_dev_rec->sec_flags >> 8); + return(TRUE); } BTM_TRACE_ERROR0 ("BTM_GetSecurityFlags false"); @@ -958,7 +1064,8 @@ void BTM_PINCodeReply (BD_ADDR bd_addr, UINT8 res, UINT8 pin_len, UINT8 *p_pin, btm_sec_change_pairing_state (BTM_PAIR_STATE_IDLE); p_dev_rec->sec_flags &= ~BTM_SEC_LINK_KEY_AUTHED; - (*btm_cb.api.p_auth_complete_callback) (p_dev_rec->bd_addr, p_dev_rec->dev_class, + if (btm_cb.api.p_auth_complete_callback) + (*btm_cb.api.p_auth_complete_callback) (p_dev_rec->bd_addr, p_dev_rec->dev_class, p_dev_rec->sec_bd_name, HCI_ERR_AUTH_FAILURE); } return; @@ -1028,25 +1135,21 @@ void BTM_DeviceAuthorized (BD_ADDR bd_addr, UINT8 res, UINT32 trusted_mask[]) if (res != BTM_SUCCESS) { - btm_sec_dev_rec_cback_event (p_dev_rec, res); + btm_sec_dev_rec_cback_event (p_dev_rec, res, FALSE); return; } if ((res = (UINT8)btm_sec_execute_procedure (p_dev_rec)) != BTM_CMD_STARTED) { - btm_sec_dev_rec_cback_event (p_dev_rec, res); + btm_sec_dev_rec_cback_event (p_dev_rec, res, FALSE); } } - - /******************************************************************************* ** -** Function BTM_SecBond +** Function btm_sec_bond_by_transport ** -** Description This function is called to perform bonding with peer device. -** If the connection is already up, but not secure, pairing -** is attempted. If already paired BTM_SUCCESS is returned. +** Description this is the bond function that will start either SSP or SMP. ** ** Parameters: bd_addr - Address of the device to bond ** pin_len - length in bytes of the PIN Code @@ -1055,16 +1158,20 @@ void BTM_DeviceAuthorized (BD_ADDR bd_addr, UINT8 res, UINT32 trusted_mask[]) ** ** Note: After 2.1 parameters are not used and preserved here not to change API *******************************************************************************/ -tBTM_STATUS BTM_SecBond (BD_ADDR bd_addr, UINT8 pin_len, UINT8 *p_pin, UINT32 trusted_mask[]) +tBTM_STATUS btm_sec_bond_by_transport (BD_ADDR bd_addr, tBT_TRANSPORT transport, + UINT8 pin_len, UINT8 *p_pin, UINT32 trusted_mask[]) { tBTM_SEC_DEV_REC *p_dev_rec; tBTM_STATUS status; UINT8 *p_features; UINT8 ii; - - BTM_TRACE_API6 ("BTM_SecBond BDA: %02x:%02x:%02x:%02x:%02x:%02x", + tACL_CONN *p= btm_bda_to_acl(bd_addr, transport); + BTM_TRACE_API6 ("btm_sec_bond_by_transport BDA: %02x:%02x:%02x:%02x:%02x:%02x", bd_addr[0], bd_addr[1], bd_addr[2], bd_addr[3], bd_addr[4], bd_addr[5]); + BTM_TRACE_DEBUG1("btm_sec_bond_by_transport: Transport used %d" , transport); + + /* Other security process is in progress */ if (btm_cb.pairing_state != BTM_PAIR_STATE_IDLE) { @@ -1075,13 +1182,19 @@ tBTM_STATUS BTM_SecBond (BD_ADDR bd_addr, UINT8 pin_len, UINT8 *p_pin, UINT32 tr if ((p_dev_rec = btm_find_or_alloc_dev (bd_addr)) == NULL) { return(BTM_NO_RESOURCES); - } + } BTM_TRACE_DEBUG1 ("before update sec_flags=0x%x", p_dev_rec->sec_flags); /* Finished if connection is active and already paired */ - if ( (p_dev_rec->hci_handle != BTM_SEC_INVALID_HANDLE) - && (p_dev_rec->sec_flags & BTM_SEC_AUTHENTICATED) ) + if ( ((p_dev_rec->hci_handle != BTM_SEC_INVALID_HANDLE) && transport == BT_TRANSPORT_BR_EDR + && (p_dev_rec->sec_flags & BTM_SEC_AUTHENTICATED)) +#if (BLE_INCLUDED == TRUE) + ||((p_dev_rec->ble_hci_handle != BTM_SEC_INVALID_HANDLE) && transport == BT_TRANSPORT_LE + && (p_dev_rec->sec_flags & BTM_SEC_LE_AUTHENTICATED)) +#endif + + ) { BTM_TRACE_WARNING0("BTM_SecBond -> Already Paired"); return(BTM_SUCCESS); @@ -1107,25 +1220,28 @@ tBTM_STATUS BTM_SecBond (BD_ADDR bd_addr, UINT8 pin_len, UINT8 *p_pin, UINT32 tr if (trusted_mask) BTM_SEC_COPY_TRUSTED_DEVICE(trusted_mask, p_dev_rec->trusted_mask); - p_dev_rec->sec_flags &= ~(BTM_SEC_LINK_KEY_KNOWN | BTM_SEC_AUTHENTICATED | BTM_SEC_ENCRYPTED - | BTM_SEC_ROLE_SWITCHED | BTM_SEC_LINK_KEY_AUTHED); - - #if BLE_INCLUDED == TRUE && SMP_INCLUDED == TRUE - /* LE device, do SMP pairing */ - if (BTM_UseLeLink(bd_addr)) + if (transport == BT_TRANSPORT_LE) { + p_dev_rec->sec_flags &= ~ BTM_SEC_LE_MASK; + if (SMP_Pair(bd_addr) == SMP_STARTED) { - btm_cb.pairing_state = BTM_PAIR_STATE_WAIT_AUTH_COMPLETE; + btm_cb.pairing_flags |= BTM_PAIR_FLAGS_LE_ACTIVE; p_dev_rec->sec_state = BTM_SEC_STATE_AUTHENTICATING; + btm_sec_change_pairing_state (BTM_PAIR_STATE_WAIT_AUTH_COMPLETE); return BTM_CMD_STARTED; } - else - return(BTM_NO_RESOURCES); + + btm_cb.pairing_flags = 0; + return(BTM_NO_RESOURCES); } #endif + p_dev_rec->sec_flags &= ~(BTM_SEC_LINK_KEY_KNOWN | BTM_SEC_AUTHENTICATED | BTM_SEC_ENCRYPTED + | BTM_SEC_ROLE_SWITCHED | BTM_SEC_LINK_KEY_AUTHED); + + BTM_TRACE_DEBUG1 ("after update sec_flags=0x%x", p_dev_rec->sec_flags); if (!HCI_SIMPLE_PAIRING_SUPPORTED(btm_cb.devcb.local_lmp_features[HCI_EXT_FEATURES_PAGE_0])) { @@ -1157,7 +1273,7 @@ tBTM_STATUS BTM_SecBond (BD_ADDR bd_addr, UINT8 pin_len, UINT8 *p_pin, UINT32 tr #endif /* If connection already exists... */ - if (p_dev_rec->hci_handle != BTM_SEC_INVALID_HANDLE) + if (p && p->hci_handle != BTM_SEC_INVALID_HANDLE) { if (!btm_sec_start_authentication (p_dev_rec)) return(BTM_NO_RESOURCES); @@ -1185,14 +1301,15 @@ tBTM_STATUS BTM_SecBond (BD_ADDR bd_addr, UINT8 pin_len, UINT8 *p_pin, UINT32 tr * -> RNR (to learn if peer is 2.1) * RNR when no ACL causes HCI_RMT_HOST_SUP_FEAT_NOTIFY_EVT */ btm_sec_change_pairing_state (BTM_PAIR_STATE_GET_REM_NAME); - BTM_ReadRemoteDeviceName(bd_addr, NULL); + BTM_ReadRemoteDeviceName(bd_addr, NULL, BT_TRANSPORT_BR_EDR); } else { /* We are accepting connection request from peer */ btm_sec_change_pairing_state (BTM_PAIR_STATE_WAIT_PIN_REQ); } - BTM_TRACE_DEBUG3 ("State:%s sm4: 0x%x sec_state:%d", btm_pair_state_descr (btm_cb.pairing_state), p_dev_rec->sm4, p_dev_rec->sec_state); + BTM_TRACE_DEBUG3 ("State:%s sm4: 0x%x sec_state:%d", + btm_pair_state_descr (btm_cb.pairing_state), p_dev_rec->sm4, p_dev_rec->sec_state); return BTM_CMD_STARTED; } @@ -1207,23 +1324,78 @@ tBTM_STATUS BTM_SecBond (BD_ADDR bd_addr, UINT8 pin_len, UINT8 *p_pin, UINT32 tr return status; } +/******************************************************************************* +** +** Function BTM_SecBondByTransport +** +** Description This function is called to perform bonding with peer device. +** If the connection is already up, but not secure, pairing +** is attempted. If already paired BTM_SUCCESS is returned. +** +** Parameters: bd_addr - Address of the device to bond +** transport - doing SSP over BR/EDR or SMP over LE +** pin_len - length in bytes of the PIN Code +** p_pin - pointer to array with the PIN Code +** trusted_mask - bitwise OR of trusted services (array of UINT32) +** +** Note: After 2.1 parameters are not used and preserved here not to change API +*******************************************************************************/ +tBTM_STATUS BTM_SecBondByTransport (BD_ADDR bd_addr, tBT_TRANSPORT transport, + UINT8 pin_len, UINT8 *p_pin, UINT32 trusted_mask[]) +{ +#if SMP_INCLUDED == TRUE + tBT_DEVICE_TYPE dev_type; + tBLE_ADDR_TYPE addr_type; + + BTM_ReadDevInfo(bd_addr, &dev_type, &addr_type); + /* LE device, do SMP pairing */ + if ((transport == BT_TRANSPORT_LE && (dev_type & BT_DEVICE_TYPE_BLE) == 0) || + (transport == BT_TRANSPORT_BR_EDR && (dev_type & BT_DEVICE_TYPE_BREDR) == 0)) + { + return BTM_ILLEGAL_ACTION; + } +#endif + return btm_sec_bond_by_transport(bd_addr, transport, pin_len, p_pin, trusted_mask); +} /******************************************************************************* ** +** Function BTM_SecBond +** +** Description This function is called to perform bonding with peer device. +** If the connection is already up, but not secure, pairing +** is attempted. If already paired BTM_SUCCESS is returned. +** +** Parameters: bd_addr - Address of the device to bond +** pin_len - length in bytes of the PIN Code +** p_pin - pointer to array with the PIN Code +** trusted_mask - bitwise OR of trusted services (array of UINT32) +** +** Note: After 2.1 parameters are not used and preserved here not to change API +*******************************************************************************/ +tBTM_STATUS BTM_SecBond (BD_ADDR bd_addr, UINT8 pin_len, UINT8 *p_pin, UINT32 trusted_mask[]) +{ + tBT_TRANSPORT transport = BT_TRANSPORT_BR_EDR; +#if BLE_INCLUDED == TRUE + if (BTM_UseLeLink(bd_addr)) + transport = BT_TRANSPORT_LE; +#endif + return btm_sec_bond_by_transport(bd_addr, transport, pin_len, p_pin, trusted_mask); +} +/******************************************************************************* +** ** Function BTM_SecBondCancel ** ** Description This function is called to cancel ongoing bonding process ** with peer device. ** ** Parameters: bd_addr - Address of the peer device +** transport - FALSE for BR/EDR link; TRUE for LE link ** *******************************************************************************/ tBTM_STATUS BTM_SecBondCancel (BD_ADDR bd_addr) { tBTM_SEC_DEV_REC *p_dev_rec; -#if SMP_INCLUDED == TRUE - tACL_CONN *p=NULL; -#endif BTM_TRACE_API2 ("BTM_SecBondCancel() State: %s flags:0x%x", btm_pair_state_descr (btm_cb.pairing_state), btm_cb.pairing_flags); @@ -1233,19 +1405,17 @@ tBTM_STATUS BTM_SecBondCancel (BD_ADDR bd_addr) return BTM_UNKNOWN_ADDR; #if SMP_INCLUDED == TRUE - p = btm_bda_to_acl(bd_addr); - if (p && p->is_le_link && - (p_dev_rec->sec_state == BTM_SEC_STATE_AUTHENTICATING)) + if (btm_cb.pairing_flags & BTM_PAIR_FLAGS_LE_ACTIVE) { - BTM_TRACE_DEBUG0 ("Cancel LE pairing"); - if (SMP_PairCancel(bd_addr)) + if (p_dev_rec->sec_state == BTM_SEC_STATE_AUTHENTICATING) { - return BTM_CMD_STARTED; - } - else - { - return BTM_WRONG_MODE; + BTM_TRACE_DEBUG0 ("Cancel LE pairing"); + if (SMP_PairCancel(bd_addr)) + { + return BTM_CMD_STARTED; + } } + return BTM_WRONG_MODE; } #endif @@ -1271,7 +1441,7 @@ tBTM_STATUS BTM_SecBondCancel (BD_ADDR bd_addr) /* If the HCI link was set up by Bonding process */ if (btm_cb.pairing_flags & BTM_PAIR_FLAGS_DISC_WHEN_DONE) - return btm_sec_send_hci_disconnect(p_dev_rec, HCI_ERR_PEER_USER); + return btm_sec_send_hci_disconnect(p_dev_rec, HCI_ERR_PEER_USER, p_dev_rec->hci_handle); else l2cu_update_lcb_4_bonding(bd_addr, FALSE); @@ -1375,6 +1545,8 @@ tBTM_STATUS BTM_SecGetDeviceLinkKey (BD_ADDR bd_addr, LINK_KEY link_key) ** p_ref_data - pointer to any data the caller wishes to receive ** in the callback function upon completion. * can be set to NULL if not used. +** transport - TRUE to encryption the link over LE trasnport +** or FALSE for BR/EDR trasnport ** ** Returns BTM_SUCCESS - already encrypted ** BTM_PENDING - command will be returned in the callback @@ -1383,41 +1555,45 @@ tBTM_STATUS BTM_SecGetDeviceLinkKey (BD_ADDR bd_addr, LINK_KEY link_key) ** BTM_MODE_UNSUPPORTED - if security manager not linked in. ** *******************************************************************************/ -tBTM_STATUS BTM_SetEncryption (BD_ADDR bd_addr, tBTM_SEC_CBACK *p_callback, +tBTM_STATUS BTM_SetEncryption (BD_ADDR bd_addr, tBT_TRANSPORT transport, tBTM_SEC_CBACK *p_callback, void *p_ref_data) { tBTM_SEC_DEV_REC *p_dev_rec; tBTM_STATUS rc; - #if BLE_INCLUDED == TRUE - tACL_CONN *p; - p = btm_bda_to_acl(bd_addr); + tACL_CONN *p = btm_bda_to_acl(bd_addr, transport); #endif p_dev_rec = btm_find_dev (bd_addr); - if (!p_dev_rec || (p_dev_rec->hci_handle == BTM_SEC_INVALID_HANDLE)) + + if (!p_dev_rec || + (transport == BT_TRANSPORT_BR_EDR && p_dev_rec->hci_handle == BTM_SEC_INVALID_HANDLE) +#if BLE_INCLUDED == TRUE + || (transport == BT_TRANSPORT_LE && p_dev_rec->ble_hci_handle == BTM_SEC_INVALID_HANDLE) +#endif + ) { /* Connection should be up and runnning */ BTM_TRACE_WARNING0 ("Security Manager: BTM_SetEncryption not connected"); if (p_callback) - (*p_callback) (bd_addr, p_ref_data, BTM_WRONG_MODE); + (*p_callback) (bd_addr, transport, p_ref_data, BTM_WRONG_MODE); return(BTM_WRONG_MODE); } - - if ( -#if BLE_INCLUDED == TRUE - !p->is_le_link && + if ((transport == BT_TRANSPORT_BR_EDR && + (p_dev_rec->sec_flags & BTM_SEC_ENCRYPTED)) +#if BLE_INCLUDED == TRUE && SMP_INCLUDED == TRUE + || (transport == BT_TRANSPORT_LE && + (p_dev_rec->sec_flags & BTM_SEC_LE_ENCRYPTED)) #endif - (p_dev_rec->sec_flags & (BTM_SEC_AUTHENTICATED | BTM_SEC_ENCRYPTED)) - == (BTM_SEC_AUTHENTICATED | BTM_SEC_ENCRYPTED)) + ) { BTM_TRACE_EVENT0 ("Security Manager: BTM_SetEncryption already encrypted"); if (p_callback) - (*p_callback) (bd_addr, p_ref_data, BTM_SUCCESS); + (*p_callback) (bd_addr, transport, p_ref_data, BTM_SUCCESS); return(BTM_SUCCESS); } @@ -1428,7 +1604,7 @@ tBTM_STATUS BTM_SetEncryption (BD_ADDR bd_addr, tBTM_SEC_CBACK *p_callback, BTM_TRACE_WARNING0 ("Security Manager: BTM_SetEncryption busy"); if (p_callback) - (*p_callback) (bd_addr, p_ref_data, BTM_BUSY); + (*p_callback) (bd_addr, transport, p_ref_data, BTM_BUSY); return(BTM_BUSY); } @@ -1441,8 +1617,9 @@ tBTM_STATUS BTM_SetEncryption (BD_ADDR bd_addr, tBTM_SEC_CBACK *p_callback, BTM_TRACE_API4 ("Security Manager: BTM_SetEncryption Handle:%d State:%d Flags:0x%x Required:0x%x", p_dev_rec->hci_handle, p_dev_rec->sec_state, p_dev_rec->sec_flags, p_dev_rec->security_required); + #if BLE_INCLUDED == TRUE && SMP_INCLUDED == TRUE - if (p->is_le_link) + if (transport == BT_TRANSPORT_LE) { rc = btm_ble_set_encryption(bd_addr, p_ref_data, p->link_role); } @@ -1451,12 +1628,12 @@ tBTM_STATUS BTM_SetEncryption (BD_ADDR bd_addr, tBTM_SEC_CBACK *p_callback, rc = btm_sec_execute_procedure (p_dev_rec); - if ( rc != BTM_CMD_STARTED) + if (rc != BTM_CMD_STARTED && rc != BTM_BUSY) { if (p_callback) { p_dev_rec->p_callback = NULL; - (*p_callback) (bd_addr, p_dev_rec->p_ref_data, rc); + (*p_callback) (bd_addr, transport, p_dev_rec->p_ref_data, rc); } } return(rc); @@ -1465,13 +1642,13 @@ tBTM_STATUS BTM_SetEncryption (BD_ADDR bd_addr, tBTM_SEC_CBACK *p_callback, /******************************************************************************* * disconnect the ACL link, if it's not done yet. *******************************************************************************/ -static tBTM_STATUS btm_sec_send_hci_disconnect (tBTM_SEC_DEV_REC *p_dev_rec, UINT8 reason) +static tBTM_STATUS btm_sec_send_hci_disconnect (tBTM_SEC_DEV_REC *p_dev_rec, UINT8 reason, UINT16 conn_handle) { UINT8 old_state = p_dev_rec->sec_state; tBTM_STATUS status = BTM_CMD_STARTED; BTM_TRACE_EVENT2 ("btm_sec_send_hci_disconnect: handle:0x%x, reason=0x%x", - p_dev_rec->hci_handle, reason); + conn_handle, reason); /* if some other thread disconnecting, we do not send second command */ if (BTM_SEC_STATE_DISCONNECTING != old_state) @@ -1480,16 +1657,18 @@ static tBTM_STATUS btm_sec_send_hci_disconnect (tBTM_SEC_DEV_REC *p_dev_rec, UIN #if BTM_DISC_DURING_RS == TRUE /* If a Role Switch is in progress, delay the HCI Disconnect to avoid controller problem (4329B1) */ - if (p_dev_rec->rs_disc_pending == BTM_SEC_RS_PENDING) + if (p_dev_rec->rs_disc_pending == BTM_SEC_RS_PENDING && + p_dev_rec->hci_handle == conn_handle) + { - BTM_TRACE_ERROR0("RS in progress - Set DISC Pending flag in btm_sec_send_hci_disconnect to delay disconnect"); + BTM_TRACE_DEBUG0("RS in progress - Set DISC Pending flag in btm_sec_send_hci_disconnect to delay disconnect"); p_dev_rec->rs_disc_pending = BTM_SEC_DISC_PENDING; status = BTM_SUCCESS; } else #endif /* Tear down the HCI link */ - if (!btsnd_hcic_disconnect (p_dev_rec->hci_handle, reason)) + if (!btsnd_hcic_disconnect (conn_handle, reason)) { /* could not send disconnect. restore old state */ p_dev_rec->sec_state = old_state; @@ -1579,7 +1758,7 @@ void BTM_PasskeyReqReply(tBTM_STATUS res, BD_ADDR bd_addr, UINT32 passkey) btm_cb.acl_disc_reason = HCI_ERR_HOST_REJECT_SECURITY; if (p_dev_rec->hci_handle != BTM_SEC_INVALID_HANDLE) - btm_sec_send_hci_disconnect (p_dev_rec, HCI_ERR_AUTH_FAILURE); + btm_sec_send_hci_disconnect (p_dev_rec, HCI_ERR_AUTH_FAILURE, p_dev_rec->hci_handle); else BTM_SecBondCancel(bd_addr); @@ -1951,9 +2130,17 @@ static BOOLEAN btm_sec_is_upgrade_possible(tBTM_SEC_DEV_REC *p_dev_rec, BOOLEAN if (p_dev_rec->sec_flags & BTM_SEC_LINK_KEY_KNOWN) { is_possible = FALSE; + if(p_dev_rec->p_cur_service) + { BTM_TRACE_DEBUG5 ("btm_sec_is_upgrade_possible id:%d, link_key_typet:%d, rmt_io_caps:%d, chk flags:x%x, flags:x%x", p_dev_rec->p_cur_service->service_id, p_dev_rec->link_key_type, p_dev_rec->rmt_io_caps, mtm_check, p_dev_rec->p_cur_service->security_flags); + } + else + { + BTM_TRACE_DEBUG3 ("btm_sec_is_upgrade_possible link_key_typet:%d, rmt_io_caps:%d, chk flags:x%x, ", + p_dev_rec->link_key_type, p_dev_rec->rmt_io_caps, mtm_check); + } /* Already have a link key to the connected peer. Is the link key secure enough? ** Is a link key upgrade even possible? */ @@ -2050,6 +2237,7 @@ tBTM_STATUS btm_sec_l2cap_access_req (BD_ADDR bd_addr, UINT16 psm, UINT16 handle tBTM_STATUS rc = BTM_SUCCESS; BOOLEAN chk_acp_auth_done = FALSE; BOOLEAN is_originator; + BOOLEAN transport = FALSE; /* should check PSM range in LE connection oriented L2CAP connection */ #if (L2CAP_UCD_INCLUDED == TRUE) if (conn_type & CONNECTION_TYPE_ORIG_MASK) @@ -2077,7 +2265,7 @@ tBTM_STATUS btm_sec_l2cap_access_req (BD_ADDR bd_addr, UINT16 psm, UINT16 handle { BTM_TRACE_WARNING1 ("btm_sec_l2cap_access_req() PSM:%d no application registerd", psm); - (*p_callback) (bd_addr, p_ref_data, BTM_MODE_UNSUPPORTED); + (*p_callback) (bd_addr, transport, p_ref_data, BTM_MODE_UNSUPPORTED); return(BTM_MODE_UNSUPPORTED); } @@ -2085,7 +2273,7 @@ tBTM_STATUS btm_sec_l2cap_access_req (BD_ADDR bd_addr, UINT16 psm, UINT16 handle /* SDP connection we will always let through */ if (BT_PSM_SDP == psm) { - (*p_callback) (bd_addr, p_ref_data, BTM_SUCCESS_NO_SECURITY); + (*p_callback) (bd_addr,transport, p_ref_data, BTM_SUCCESS_NO_SECURITY); return(BTM_SUCCESS); } @@ -2119,7 +2307,7 @@ tBTM_STATUS btm_sec_l2cap_access_req (BD_ADDR bd_addr, UINT16 psm, UINT16 handle if (rc == BTM_SUCCESS) { if (p_callback) - (*p_callback) (bd_addr, (void *)p_ref_data, BTM_SUCCESS); + (*p_callback) (bd_addr, transport, (void *)p_ref_data, BTM_SUCCESS); return(BTM_SUCCESS); } @@ -2148,9 +2336,9 @@ tBTM_STATUS btm_sec_l2cap_access_req (BD_ADDR bd_addr, UINT16 psm, UINT16 handle if (is_originator) { if (((security_required & BTM_SEC_OUT_FLAGS) == 0) || - ((((security_required & BTM_SEC_OUT_FLAGS) == BTM_SEC_OUT_AUTHENTICATE) && (p_dev_rec->sec_flags & BTM_SEC_AUTHENTICATED))) || - ((((security_required & BTM_SEC_OUT_FLAGS) == (BTM_SEC_OUT_AUTHENTICATE | BTM_SEC_OUT_ENCRYPT)) && (p_dev_rec->sec_flags & BTM_SEC_ENCRYPTED))) || - ((((security_required & BTM_SEC_OUT_FLAGS) == BTM_SEC_OUT_FLAGS) && (p_dev_rec->sec_flags & BTM_SEC_AUTHORIZED))) ) + ((((security_required & BTM_SEC_OUT_FLAGS) == BTM_SEC_OUT_AUTHENTICATE) && btm_dev_authenticated(p_dev_rec))) || + ((((security_required & BTM_SEC_OUT_FLAGS) == (BTM_SEC_OUT_AUTHENTICATE | BTM_SEC_OUT_ENCRYPT)) && btm_dev_encrypted(p_dev_rec))) || + ((((security_required & BTM_SEC_OUT_FLAGS) == BTM_SEC_OUT_FLAGS) && btm_dev_authorized(p_dev_rec) && btm_dev_encrypted(p_dev_rec))) ) { rc = BTM_SUCCESS; } @@ -2158,9 +2346,12 @@ tBTM_STATUS btm_sec_l2cap_access_req (BD_ADDR bd_addr, UINT16 psm, UINT16 handle else { if (((security_required & BTM_SEC_IN_FLAGS) == 0) || - ((((security_required & BTM_SEC_IN_FLAGS) == BTM_SEC_IN_AUTHENTICATE) && (p_dev_rec->sec_flags & BTM_SEC_AUTHENTICATED))) || - ((((security_required & BTM_SEC_IN_FLAGS) == (BTM_SEC_IN_AUTHENTICATE | BTM_SEC_IN_ENCRYPT)) && (p_dev_rec->sec_flags & BTM_SEC_ENCRYPTED))) || - ((((security_required & BTM_SEC_IN_FLAGS) == BTM_SEC_IN_FLAGS) && (p_dev_rec->sec_flags & BTM_SEC_AUTHORIZED))) ) + (((security_required & BTM_SEC_IN_FLAGS) == BTM_SEC_IN_AUTHENTICATE) && btm_dev_authenticated(p_dev_rec)) || + (((security_required & BTM_SEC_IN_FLAGS) == (BTM_SEC_IN_AUTHENTICATE | BTM_SEC_IN_ENCRYPT)) && btm_dev_encrypted(p_dev_rec)) || + (((security_required & BTM_SEC_IN_FLAGS) == BTM_SEC_IN_AUTHORIZE) && (btm_dev_authorized(p_dev_rec)||btm_serv_trusted(p_dev_rec, p_serv_rec))) || + (((security_required & BTM_SEC_IN_FLAGS) == (BTM_SEC_IN_AUTHENTICATE | BTM_SEC_IN_AUTHORIZE)) && ((btm_dev_authorized(p_dev_rec)||btm_serv_trusted(p_dev_rec, p_serv_rec)) && btm_dev_authenticated(p_dev_rec))) || + (((security_required & BTM_SEC_IN_FLAGS) == (BTM_SEC_IN_ENCRYPT | BTM_SEC_IN_AUTHORIZE)) && ((btm_dev_authorized(p_dev_rec)||btm_serv_trusted(p_dev_rec, p_serv_rec)) && btm_dev_encrypted(p_dev_rec))) || + (((security_required & BTM_SEC_IN_FLAGS) == BTM_SEC_IN_FLAGS) && btm_dev_encrypted(p_dev_rec) && (btm_dev_authorized(p_dev_rec)||btm_serv_trusted(p_dev_rec, p_serv_rec)))) { rc = BTM_SUCCESS; } @@ -2169,7 +2360,7 @@ tBTM_STATUS btm_sec_l2cap_access_req (BD_ADDR bd_addr, UINT16 psm, UINT16 handle if (rc == BTM_SUCCESS) { if (p_callback) - (*p_callback) (bd_addr, (void *)p_ref_data, BTM_SUCCESS); + (*p_callback) (bd_addr, transport, (void *)p_ref_data, BTM_SUCCESS); return(BTM_SUCCESS); } @@ -2262,7 +2453,7 @@ tBTM_STATUS btm_sec_l2cap_access_req (BD_ADDR bd_addr, UINT16 psm, UINT16 handle p_dev_rec->security_required = old_security_required; p_dev_rec->is_originator = old_is_originator; - (*p_callback) (bd_addr, p_ref_data, BTM_SUCCESS); + (*p_callback) (bd_addr, transport, p_ref_data, BTM_SUCCESS); return(BTM_SUCCESS); } @@ -2277,7 +2468,7 @@ tBTM_STATUS btm_sec_l2cap_access_req (BD_ADDR bd_addr, UINT16 psm, UINT16 handle p_dev_rec->security_required = old_security_required; p_dev_rec->is_originator = old_is_originator; - (*p_callback) (bd_addr, p_ref_data, BTM_SUCCESS); + (*p_callback) (bd_addr, transport, p_ref_data, BTM_SUCCESS); return(BTM_SUCCESS); } @@ -2299,7 +2490,7 @@ tBTM_STATUS btm_sec_l2cap_access_req (BD_ADDR bd_addr, UINT16 psm, UINT16 handle BTM_TRACE_ERROR0 ("peer should have initiated security process by now (SM4 to SM4)"); p_dev_rec->p_callback = p_callback; p_dev_rec->sec_state = BTM_SEC_STATE_DELAY_FOR_ENC; - (*p_callback) (bd_addr, p_ref_data, rc); + (*p_callback) (bd_addr, transport, p_ref_data, rc); return(BTM_SUCCESS); } @@ -2330,7 +2521,7 @@ tBTM_STATUS btm_sec_l2cap_access_req (BD_ADDR bd_addr, UINT16 psm, UINT16 handle if ((rc = btm_sec_execute_procedure (p_dev_rec)) != BTM_CMD_STARTED) { p_dev_rec->p_callback = NULL; - (*p_callback) (bd_addr, p_dev_rec->p_ref_data, (UINT8)rc); + (*p_callback) (bd_addr, transport, p_dev_rec->p_ref_data, (UINT8)rc); } return(rc); @@ -2368,6 +2559,7 @@ tBTM_STATUS btm_sec_mx_access_request (BD_ADDR bd_addr, UINT16 psm, BOOLEAN is_o tBTM_SEC_SERV_REC *p_serv_rec; tBTM_STATUS rc; UINT16 security_required; + BOOLEAN transport = FALSE;/* should check PSM range in LE connection oriented L2CAP connection */ BTM_TRACE_DEBUG1 ("btm_sec_mx_access_request is_originator:%d", is_originator); /* Find or get oldest record */ @@ -2380,7 +2572,7 @@ tBTM_STATUS btm_sec_mx_access_request (BD_ADDR bd_addr, UINT16 psm, BOOLEAN is_o if (!p_serv_rec) { if (p_callback) - (*p_callback) (bd_addr, p_ref_data, BTM_MODE_UNSUPPORTED); + (*p_callback) (bd_addr, transport, p_ref_data, BTM_MODE_UNSUPPORTED); BTM_TRACE_ERROR3 ("Security Manager: MX service not found PSM:%d Proto:%d SCN:%d", psm, mx_proto_id, mx_chan_id); @@ -2406,8 +2598,8 @@ tBTM_STATUS btm_sec_mx_access_request (BD_ADDR bd_addr, UINT16 psm, BOOLEAN is_o if (is_originator) { if (((security_required & BTM_SEC_OUT_FLAGS) == 0) || - ((((security_required & BTM_SEC_OUT_FLAGS) == BTM_SEC_OUT_AUTHENTICATE) && (p_dev_rec->sec_flags & BTM_SEC_AUTHENTICATED))) || - ((((security_required & BTM_SEC_OUT_FLAGS) == (BTM_SEC_OUT_AUTHENTICATE | BTM_SEC_OUT_ENCRYPT)) && (p_dev_rec->sec_flags & BTM_SEC_ENCRYPTED))) + ((((security_required & BTM_SEC_OUT_FLAGS) == BTM_SEC_OUT_AUTHENTICATE) && btm_dev_authenticated(p_dev_rec))) || + ((((security_required & BTM_SEC_OUT_FLAGS) == (BTM_SEC_OUT_AUTHENTICATE | BTM_SEC_OUT_ENCRYPT)) && btm_dev_encrypted(p_dev_rec))) ) { rc = BTM_SUCCESS; @@ -2416,8 +2608,11 @@ tBTM_STATUS btm_sec_mx_access_request (BD_ADDR bd_addr, UINT16 psm, BOOLEAN is_o else { if (((security_required & BTM_SEC_IN_FLAGS) == 0) || - ((((security_required & BTM_SEC_IN_FLAGS) == BTM_SEC_IN_AUTHENTICATE) && (p_dev_rec->sec_flags & BTM_SEC_AUTHENTICATED))) || - ((((security_required & BTM_SEC_IN_FLAGS) == (BTM_SEC_IN_AUTHENTICATE | BTM_SEC_IN_ENCRYPT)) && (p_dev_rec->sec_flags & BTM_SEC_ENCRYPTED))) + ((((security_required & BTM_SEC_IN_FLAGS) == BTM_SEC_IN_AUTHENTICATE) && btm_dev_authenticated(p_dev_rec))) || + (((security_required & BTM_SEC_IN_FLAGS) == BTM_SEC_IN_AUTHORIZE) && (btm_dev_authorized(p_dev_rec)||btm_serv_trusted(p_dev_rec, p_serv_rec))) || + (((security_required & BTM_SEC_IN_FLAGS) == (BTM_SEC_IN_AUTHORIZE | BTM_SEC_IN_AUTHENTICATE)) && ((btm_dev_authorized(p_dev_rec)||btm_serv_trusted(p_dev_rec, p_serv_rec)) && btm_dev_authenticated(p_dev_rec))) || + (((security_required & BTM_SEC_IN_FLAGS) == (BTM_SEC_IN_AUTHORIZE | BTM_SEC_IN_ENCRYPT)) && ((btm_dev_authorized(p_dev_rec)||btm_serv_trusted(p_dev_rec, p_serv_rec))&& btm_dev_encrypted(p_dev_rec))) || + ((((security_required & BTM_SEC_IN_FLAGS) == (BTM_SEC_IN_AUTHENTICATE | BTM_SEC_IN_ENCRYPT)) && btm_dev_encrypted(p_dev_rec))) ) { rc = BTM_SUCCESS; @@ -2462,7 +2657,7 @@ tBTM_STATUS btm_sec_mx_access_request (BD_ADDR bd_addr, UINT16 psm, BOOLEAN is_o { p_dev_rec->p_callback = NULL; - (*p_callback) (bd_addr, p_ref_data, (UINT8)rc); + (*p_callback) (bd_addr,transport, p_ref_data, (UINT8)rc); } } @@ -2666,7 +2861,7 @@ void btm_sec_check_pending_reqs (void) while ((p_e = (tBTM_SEC_QUEUE_ENTRY *)GKI_dequeue (&bq)) != NULL) { /* Check that the ACL is still up before starting security procedures */ - if (btm_bda_to_acl(p_e->bd_addr) != NULL) + if (btm_bda_to_acl(p_e->bd_addr, BT_TRANSPORT_BR_EDR) != NULL) { BTM_TRACE_EVENT4 ("btm_sec_check_pending_reqs() submitting PSM: 0x%04x Is_Orig: %u mx_proto_id: %u mx_chan_id: %u", p_e->psm, p_e->is_orig, p_e->mx_proto_id, p_e->mx_chan_id); @@ -2747,9 +2942,13 @@ void btm_sec_dev_reset (void) * right now. */ if (HCI_SIMPLE_PAIRING_SUPPORTED(btm_cb.devcb.local_lmp_features[HCI_EXT_FEATURES_PAGE_0])) { + btsnd_hcic_write_simple_pairing_mode(HCI_SP_MODE_ENABLED); #if BLE_INCLUDED == TRUE btsnd_hcic_set_event_mask(LOCAL_BR_EDR_CONTROLLER_ID, (UINT8 *)HCI_DUMO_EVENT_MASK_EXT); + + btsnd_hcic_ble_set_evt_mask((UINT8 *)HCI_BLE_EVENT_MASK_DEF); + #else btsnd_hcic_set_event_mask(LOCAL_BR_EDR_CONTROLLER_ID, (UINT8 *)HCI_LISBON_EVENT_MASK_EXT); @@ -2815,7 +3014,7 @@ static tBTM_STATUS btm_sec_dd_create_conn (tBTM_SEC_DEV_REC *p_dev_rec) tL2C_LCB *p_lcb; /* Make sure an L2cap link control block is available */ - if ((p_lcb = l2cu_allocate_lcb (p_dev_rec->bd_addr, TRUE)) == NULL) + if ((p_lcb = l2cu_allocate_lcb (p_dev_rec->bd_addr, TRUE, BT_TRANSPORT_BR_EDR)) == NULL) { BTM_TRACE_WARNING6 ("Security Manager: failed allocate LCB [%02x%02x%02x%02x%02x%02x]", p_dev_rec->bd_addr[0], p_dev_rec->bd_addr[1], p_dev_rec->bd_addr[2], @@ -2827,7 +3026,7 @@ static tBTM_STATUS btm_sec_dd_create_conn (tBTM_SEC_DEV_REC *p_dev_rec) /* set up the control block to indicated dedicated bonding */ btm_cb.pairing_flags |= BTM_PAIR_FLAGS_DISC_WHEN_DONE; - if (l2cu_create_conn(p_lcb) == FALSE) + if (l2cu_create_conn(p_lcb, BT_TRANSPORT_BR_EDR) == FALSE) { BTM_TRACE_WARNING6 ("Security Manager: failed create [%02x%02x%02x%02x%02x%02x]", p_dev_rec->bd_addr[0], p_dev_rec->bd_addr[1], p_dev_rec->bd_addr[2], @@ -2995,23 +3194,29 @@ void btm_sec_rmt_name_request_complete (UINT8 *p_bd_addr, UINT8 *p_bd_name, UINT { btm_sec_change_pairing_state (BTM_PAIR_STATE_IDLE); - (*btm_cb.api.p_auth_complete_callback) (p_dev_rec->bd_addr, p_dev_rec->dev_class, - p_dev_rec->sec_bd_name, status); + if (btm_cb.api.p_auth_complete_callback) + (*btm_cb.api.p_auth_complete_callback) (p_dev_rec->bd_addr, p_dev_rec->dev_class, + p_dev_rec->sec_bd_name, status); return; } /* if peer is very old legacy devices, HCI_RMT_HOST_SUP_FEAT_NOTIFY_EVT is not reported */ if (BTM_SEC_IS_SM4_UNKNOWN(p_dev_rec->sm4)) { - /* set the KNOWN flag only if BTM_PAIR_FLAGS_REJECTED_CONNECT is not set. - * If it is set, there may be a race condition */ - BTM_TRACE_EVENT1 ("btm_sec_rmt_name_request_complete IS_SM4_UNKNOWN Flags:0x%04x", btm_cb.pairing_flags); + /* set the KNOWN flag only if BTM_PAIR_FLAGS_REJECTED_CONNECT is not set.*/ + /* If it is set, there may be a race condition */ + BTM_TRACE_DEBUG1 ("btm_sec_rmt_name_request_complete IS_SM4_UNKNOWN Flags:0x%04x", + btm_cb.pairing_flags); if ((btm_cb.pairing_flags & BTM_PAIR_FLAGS_REJECTED_CONNECT) == 0) { p_dev_rec->sm4 |= BTM_SM4_KNOWN; } } + BTM_TRACE_DEBUG5("%s, SM4 Value: %x, Legacy:%d,IS SM4:%d, Unknown:%d",__FUNCTION__, + p_dev_rec->sm4, BTM_SEC_IS_SM4_LEGACY(p_dev_rec->sm4), + BTM_SEC_IS_SM4(p_dev_rec->sm4),BTM_SEC_IS_SM4_UNKNOWN(p_dev_rec->sm4)); + /* BT 2.1 or carkit, bring up the connection to force the peer to request PIN. ** Else prefetch (btm_sec_check_prefetch_pin will do the prefetching if needed) */ @@ -3030,6 +3235,7 @@ void btm_sec_rmt_name_request_complete (UINT8 *p_bd_addr, UINT8 *p_bd_name, UINT btm_sec_change_pairing_state (BTM_PAIR_STATE_IDLE); + if (btm_cb.api.p_auth_complete_callback) (*btm_cb.api.p_auth_complete_callback) (p_dev_rec->bd_addr, p_dev_rec->dev_class, p_dev_rec->sec_bd_name, HCI_ERR_MEMORY_FULL); } @@ -3040,7 +3246,7 @@ void btm_sec_rmt_name_request_complete (UINT8 *p_bd_addr, UINT8 *p_bd_name, UINT { BTM_TRACE_WARNING0 ("btm_sec_rmt_name_request_complete: wrong BDA, retry with pairing BDA"); - BTM_ReadRemoteDeviceName (btm_cb.pairing_bda, NULL); + BTM_ReadRemoteDeviceName (btm_cb.pairing_bda, NULL, BT_TRANSPORT_BR_EDR); return; } } @@ -3084,7 +3290,7 @@ void btm_sec_rmt_name_request_complete (UINT8 *p_bd_addr, UINT8 *p_bd_name, UINT /* If get name failed, notify the waiting layer */ if (status != HCI_SUCCESS) { - btm_sec_dev_rec_cback_event (p_dev_rec, BTM_ERR_PROCESSING); + btm_sec_dev_rec_cback_event (p_dev_rec, BTM_ERR_PROCESSING, FALSE); return; } @@ -3102,7 +3308,7 @@ void btm_sec_rmt_name_request_complete (UINT8 *p_bd_addr, UINT8 *p_bd_name, UINT return; /* There is no next procedure or start of procedure failed, notify the waiting layer */ - btm_sec_dev_rec_cback_event (p_dev_rec, status); + btm_sec_dev_rec_cback_event (p_dev_rec, status, FALSE); } /******************************************************************************* @@ -3592,7 +3798,7 @@ void btm_simple_pair_complete (UINT8 *p) if (disc) { /* simple pairing failed */ - btm_sec_send_hci_disconnect (p_dev_rec, HCI_ERR_AUTH_FAILURE); + btm_sec_send_hci_disconnect (p_dev_rec, HCI_ERR_AUTH_FAILURE, p_dev_rec->hci_handle); } } @@ -3831,7 +4037,7 @@ void btm_sec_auth_complete (UINT16 handle, UINT8 status) p_dev_rec->security_required &= ~BTM_SEC_OUT_AUTHENTICATE; if (status != HCI_SUCCESS) - btm_sec_send_hci_disconnect (p_dev_rec, HCI_ERR_PEER_USER); + btm_sec_send_hci_disconnect (p_dev_rec, HCI_ERR_PEER_USER, p_dev_rec->hci_handle); else l2cu_start_post_bond_timer (p_dev_rec->hci_handle); @@ -3871,11 +4077,11 @@ void btm_sec_auth_complete (UINT16 handle, UINT8 status) } } - btm_sec_dev_rec_cback_event (p_dev_rec, BTM_ERR_PROCESSING); + btm_sec_dev_rec_cback_event (p_dev_rec, BTM_ERR_PROCESSING, FALSE); if (btm_cb.pairing_flags & BTM_PAIR_FLAGS_DISC_WHEN_DONE) { - btm_sec_send_hci_disconnect (p_dev_rec, HCI_ERR_AUTH_FAILURE); + btm_sec_send_hci_disconnect (p_dev_rec, HCI_ERR_AUTH_FAILURE, p_dev_rec->hci_handle); } return; } @@ -3887,7 +4093,7 @@ void btm_sec_auth_complete (UINT16 handle, UINT8 status) /* If there is no next procedure, or procedure failed to start, notify the caller */ if (status != BTM_CMD_STARTED) - btm_sec_dev_rec_cback_event (p_dev_rec, status); + btm_sec_dev_rec_cback_event (p_dev_rec, status, FALSE); } /******************************************************************************* @@ -3933,7 +4139,8 @@ void btm_sec_encrypt_change (UINT16 handle, UINT8 status, UINT8 encr_enable) { tBTM_SEC_DEV_REC *p_dev_rec = btm_find_dev_by_handle (handle); #if BLE_INCLUDED == TRUE && SMP_INCLUDED == TRUE - tACL_CONN *p_acl; + tACL_CONN *p_acl = NULL; + UINT8 acl_idx = btm_handle_to_acl_index(handle); #endif BTM_TRACE_EVENT3 ("Security Manager: encrypt_change status:%d State:%d, encr_enable = %d", status, (p_dev_rec) ? p_dev_rec->sec_state : 0, encr_enable); @@ -3952,19 +4159,30 @@ void btm_sec_encrypt_change (UINT16 handle, UINT8 status, UINT8 encr_enable) return; if ((status == HCI_SUCCESS) && encr_enable) - p_dev_rec->sec_flags |= (BTM_SEC_AUTHENTICATED | BTM_SEC_ENCRYPTED); + { + if (p_dev_rec->hci_handle == handle) + p_dev_rec->sec_flags |= (BTM_SEC_AUTHENTICATED | BTM_SEC_ENCRYPTED); + else + p_dev_rec->sec_flags |= (BTM_SEC_LE_AUTHENTICATED | BTM_SEC_LE_ENCRYPTED); + } /* It is possible that we decrypted the link to perform role switch */ /* mark link not to be encrypted, so that when we execute security next time it will kick in again */ if ((status == HCI_SUCCESS) && !encr_enable) - p_dev_rec->sec_flags &= ~BTM_SEC_ENCRYPTED; + { + if (p_dev_rec->hci_handle == handle) + p_dev_rec->sec_flags &= ~BTM_SEC_ENCRYPTED; + else + p_dev_rec->sec_flags &= ~BTM_SEC_LE_ENCRYPTED; + } BTM_TRACE_DEBUG1 ("after update p_dev_rec->sec_flags=0x%x", p_dev_rec->sec_flags ); #if BLE_INCLUDED == TRUE && SMP_INCLUDED == TRUE - p_acl = btm_bda_to_acl(p_dev_rec->bd_addr); + if (acl_idx != MAX_L2CAP_LINKS ) + p_acl = &btm_cb.acl_db[acl_idx]; - if (p_acl && p_acl->is_le_link) + if (p_acl && p_acl->transport == BT_TRANSPORT_LE) { btm_ble_link_encrypted(p_dev_rec->bd_addr, encr_enable); return; @@ -3991,7 +4209,7 @@ void btm_sec_encrypt_change (UINT16 handle, UINT8 status, UINT8 encr_enable) /* If encryption setup failed, notify the waiting layer */ if (status != HCI_SUCCESS) { - btm_sec_dev_rec_cback_event (p_dev_rec, BTM_ERR_PROCESSING); + btm_sec_dev_rec_cback_event (p_dev_rec, BTM_ERR_PROCESSING, FALSE); return; } @@ -4000,7 +4218,7 @@ void btm_sec_encrypt_change (UINT16 handle, UINT8 status, UINT8 encr_enable) /* If there is no next procedure, or procedure failed to start, notify the caller */ if (status != BTM_CMD_STARTED) - btm_sec_dev_rec_cback_event (p_dev_rec, status); + btm_sec_dev_rec_cback_event (p_dev_rec, status, FALSE); } /******************************************************************************* @@ -4060,6 +4278,7 @@ static void btm_sec_connect_after_reject_timeout (TIMER_LIST_ENT *p_tle) btm_sec_change_pairing_state (BTM_PAIR_STATE_IDLE); + if (btm_cb.api.p_auth_complete_callback) (*btm_cb.api.p_auth_complete_callback) (p_dev_rec->bd_addr, p_dev_rec->dev_class, p_dev_rec->sec_bd_name, HCI_ERR_MEMORY_FULL); } @@ -4081,6 +4300,7 @@ void btm_sec_connected (UINT8 *bda, UINT16 handle, UINT8 status, UINT8 enc_mode) UINT8 res; BOOLEAN is_pairing_device = FALSE; tACL_CONN *p_acl_cb; + UINT8 bit_shift = 0; btm_acl_resubmit_page(); @@ -4108,9 +4328,6 @@ void btm_sec_connected (UINT8 *bda, UINT16 handle, UINT8 status, UINT8 enc_mode) if (status == HCI_SUCCESS) { p_dev_rec = btm_sec_alloc_dev (bda); -#if BLE_INCLUDED == TRUE - p_dev_rec->device_type |= BT_DEVICE_TYPE_BREDR; -#endif } else { @@ -4121,6 +4338,10 @@ void btm_sec_connected (UINT8 *bda, UINT16 handle, UINT8 status, UINT8 enc_mode) } else /* Update the timestamp for this device */ { + +#if BLE_INCLUDED == TRUE + bit_shift = (handle == p_dev_rec->ble_hci_handle) ? 8 :0; +#endif p_dev_rec->timestamp = btm_cb.dev_rec_count++; if (p_dev_rec->sm4 & BTM_SM4_CONN_PEND) { @@ -4147,7 +4368,7 @@ void btm_sec_connected (UINT8 *bda, UINT16 handle, UINT8 status, UINT8 enc_mode) else { btm_sec_change_pairing_state (BTM_PAIR_STATE_GET_REM_NAME); - BTM_ReadRemoteDeviceName(p_dev_rec->bd_addr, NULL); + BTM_ReadRemoteDeviceName(p_dev_rec->bd_addr, NULL, BT_TRANSPORT_BR_EDR); } #if BTM_DISC_DURING_RS == TRUE p_dev_rec->rs_disc_pending = BTM_SEC_RS_NOT_PENDING; /* reset flag */ @@ -4164,6 +4385,10 @@ void btm_sec_connected (UINT8 *bda, UINT16 handle, UINT8 status, UINT8 enc_mode) } } +#if BLE_INCLUDED == TRUE + p_dev_rec->device_type |= BT_DEVICE_TYPE_BREDR; +#endif + #if BTM_DISC_DURING_RS == TRUE p_dev_rec->rs_disc_pending = BTM_SEC_RS_NOT_PENDING; /* reset flag */ #endif @@ -4185,7 +4410,7 @@ void btm_sec_connected (UINT8 *bda, UINT16 handle, UINT8 status, UINT8 enc_mode) { /* Try again: RNR when no ACL causes HCI_RMT_HOST_SUP_FEAT_NOTIFY_EVT */ btm_sec_change_pairing_state (BTM_PAIR_STATE_GET_REM_NAME); - BTM_ReadRemoteDeviceName(bda, NULL); + BTM_ReadRemoteDeviceName(bda, NULL, BT_TRANSPORT_BR_EDR); return; } @@ -4221,7 +4446,7 @@ void btm_sec_connected (UINT8 *bda, UINT16 handle, UINT8 status, UINT8 enc_mode) if (is_pairing_device) { p_dev_rec->security_required &= ~BTM_SEC_OUT_AUTHENTICATE; - p_dev_rec->sec_flags &= ~(BTM_SEC_LINK_KEY_KNOWN | BTM_SEC_LINK_KEY_AUTHED); + p_dev_rec->sec_flags &= ~((BTM_SEC_LINK_KEY_KNOWN | BTM_SEC_LINK_KEY_AUTHED) << bit_shift); BTM_TRACE_DEBUG1 ("security_required:%x ", p_dev_rec->security_required ); btm_sec_change_pairing_state (BTM_PAIR_STATE_IDLE); @@ -4234,17 +4459,33 @@ void btm_sec_connected (UINT8 *bda, UINT16 handle, UINT8 status, UINT8 enc_mode) p_dev_rec->sec_bd_name, status); } } - else if ((status == HCI_ERR_AUTH_FAILURE) || + /* + Do not send authentication failure, if following conditions hold good + 1. BTM Sec Pairing state is idle + 2. Link key for the remote device is present. + 3. Remote is SSP capable. + */ + else if ((p_dev_rec->link_key_type <= BTM_LKEY_TYPE_REMOTE_UNIT) && + (((status == HCI_ERR_AUTH_FAILURE) || (status == HCI_ERR_KEY_MISSING) || (status == HCI_ERR_HOST_REJECT_SECURITY) || (status == HCI_ERR_PAIRING_NOT_ALLOWED) || (status == HCI_ERR_UNIT_KEY_USED) || (status == HCI_ERR_PAIRING_WITH_UNIT_KEY_NOT_SUPPORTED) || (status == HCI_ERR_ENCRY_MODE_NOT_ACCEPTABLE) || - (status == HCI_ERR_REPEATED_ATTEMPTS)) + (status == HCI_ERR_REPEATED_ATTEMPTS)))) { p_dev_rec->security_required &= ~BTM_SEC_OUT_AUTHENTICATE; - p_dev_rec->sec_flags &= ~BTM_SEC_LINK_KEY_KNOWN; + p_dev_rec->sec_flags &= ~ (BTM_SEC_LE_LINK_KEY_KNOWN << bit_shift); + + +#ifdef BRCM_NOT_4_BTE + /* If we rejected pairing, pass this special result code */ + if (btm_cb.acl_disc_reason == HCI_ERR_HOST_REJECT_SECURITY) + { + status = HCI_ERR_HOST_REJECT_SECURITY; + } +#endif /* We need to notify host that the key is not known any more */ if (btm_cb.api.p_auth_complete_callback) @@ -4257,9 +4498,9 @@ void btm_sec_connected (UINT8 *bda, UINT16 handle, UINT8 status, UINT8 enc_mode) if (status == HCI_ERR_CONNECTION_TOUT || status == HCI_ERR_LMP_RESPONSE_TIMEOUT || status == HCI_ERR_UNSPECIFIED || status == HCI_ERR_PAGE_TIMEOUT) - btm_sec_dev_rec_cback_event (p_dev_rec, BTM_DEVICE_TIMEOUT); + btm_sec_dev_rec_cback_event (p_dev_rec, BTM_DEVICE_TIMEOUT, FALSE); else - btm_sec_dev_rec_cback_event (p_dev_rec, BTM_ERR_PROCESSING); + btm_sec_dev_rec_cback_event (p_dev_rec, BTM_ERR_PROCESSING, FALSE); return; } @@ -4304,7 +4545,7 @@ void btm_sec_connected (UINT8 *bda, UINT16 handle, UINT8 status, UINT8 enc_mode) /* role may not be correct here, it will be updated by l2cap, but we need to */ /* notify btm_acl that link is up, so starting of rmt name request will not */ /* set paging flag up */ - p_acl_cb = btm_bda_to_acl(bda); + p_acl_cb = btm_bda_to_acl(bda, BT_TRANSPORT_BR_EDR); if (p_acl_cb) { /* whatever is in btm_establish_continue() without reporting the BTM_BL_CONN_EVT event */ @@ -4318,19 +4559,19 @@ void btm_sec_connected (UINT8 *bda, UINT16 handle, UINT8 status, UINT8 enc_mode) BTM_SetLinkPolicy (p_acl_cb->remote_addr, &btm_cb.btm_def_link_policy); #endif } - btm_acl_created (bda, p_dev_rec->dev_class, p_dev_rec->sec_bd_name, handle, HCI_ROLE_SLAVE, FALSE); + btm_acl_created (bda, p_dev_rec->dev_class, p_dev_rec->sec_bd_name, handle, HCI_ROLE_SLAVE, BT_TRANSPORT_BR_EDR); /* Initialize security flags. We need to do that because some */ /* authorization complete could have come after the connection is dropped */ /* and that would set wrong flag that link has been authorized already */ - p_dev_rec->sec_flags &= ~(BTM_SEC_AUTHORIZED | BTM_SEC_AUTHENTICATED | - BTM_SEC_ENCRYPTED | BTM_SEC_ROLE_SWITCHED); + p_dev_rec->sec_flags &= ~((BTM_SEC_AUTHORIZED | BTM_SEC_AUTHENTICATED | + BTM_SEC_ENCRYPTED | BTM_SEC_ROLE_SWITCHED) << bit_shift); if (enc_mode != HCI_ENCRYPT_MODE_DISABLED) - p_dev_rec->sec_flags |= (BTM_SEC_AUTHENTICATED | BTM_SEC_ENCRYPTED); + p_dev_rec->sec_flags |= ((BTM_SEC_AUTHENTICATED | BTM_SEC_ENCRYPTED) << bit_shift); if (btm_cb.security_mode == BTM_SEC_MODE_LINK) - p_dev_rec->sec_flags |= BTM_SEC_AUTHENTICATED; + p_dev_rec->sec_flags |= (BTM_SEC_AUTHENTICATED << bit_shift); p_dev_rec->link_key_changed = FALSE; @@ -4341,7 +4582,7 @@ void btm_sec_connected (UINT8 *bda, UINT16 handle, UINT8 status, UINT8 enc_mode) if (!(p_dev_rec->sec_flags & BTM_SEC_NAME_KNOWN) || p_dev_rec->is_originator) { if ((res = btm_sec_execute_procedure (p_dev_rec)) != BTM_CMD_STARTED) - btm_sec_dev_rec_cback_event (p_dev_rec, res); + btm_sec_dev_rec_cback_event (p_dev_rec, res, FALSE); } return; } @@ -4371,7 +4612,7 @@ void btm_sec_role_changed (void *p_ref_data) if (((p_dev_rec->security_required & BTM_SEC_FORCE_MASTER) && !p_dev_rec->role_master) || ((p_dev_rec->security_required & BTM_SEC_FORCE_SLAVE) && p_dev_rec->role_master)) { - btm_sec_dev_rec_cback_event (p_dev_rec, BTM_ERR_PROCESSING); + btm_sec_dev_rec_cback_event (p_dev_rec, BTM_ERR_PROCESSING, FALSE); return; } @@ -4384,7 +4625,7 @@ void btm_sec_role_changed (void *p_ref_data) if ((res = (UINT8)btm_sec_execute_procedure (p_dev_rec)) != BTM_CMD_STARTED) { - btm_sec_dev_rec_cback_event (p_dev_rec, res); + btm_sec_dev_rec_cback_event (p_dev_rec, res, FALSE); } } @@ -4418,7 +4659,7 @@ tBTM_STATUS btm_sec_disconnect (UINT16 handle, UINT8 reason) return(BTM_BUSY); } - return(btm_sec_send_hci_disconnect(p_dev_rec, reason)); + return(btm_sec_send_hci_disconnect(p_dev_rec, reason, handle)); } /******************************************************************************* @@ -4437,6 +4678,7 @@ void btm_sec_disconnected (UINT16 handle, UINT8 reason) UINT8 old_pairing_flags = btm_cb.pairing_flags; int result = HCI_ERR_AUTH_FAILURE; tBTM_SEC_CALLBACK *p_callback = NULL; + tBT_TRANSPORT transport = BT_TRANSPORT_BR_EDR; /* If page was delayed for disc complete, can do it now */ btm_cb.discing = FALSE; @@ -4446,6 +4688,8 @@ void btm_sec_disconnected (UINT16 handle, UINT8 reason) if (!p_dev_rec) return; + transport = (handle == p_dev_rec->hci_handle) ? BT_TRANSPORT_BR_EDR: BT_TRANSPORT_LE; + p_dev_rec->rs_disc_pending = BTM_SEC_RS_NOT_PENDING; /* reset flag */ #if BTM_DISC_DURING_RS == TRUE @@ -4487,16 +4731,24 @@ void btm_sec_disconnected (UINT16 handle, UINT8 reason) } } - p_dev_rec->hci_handle = BTM_SEC_INVALID_HANDLE; - p_dev_rec->sec_state = BTM_SEC_STATE_IDLE; - #if BLE_INCLUDED == TRUE && SMP_INCLUDED == TRUE p_dev_rec->enc_key_size = 0; btm_ble_update_mode_operation(HCI_ROLE_UNKNOWN, p_dev_rec->bd_addr, FALSE); /* see sec_flags processing in btm_acl_removed */ + + if (transport == BT_TRANSPORT_LE) + { + p_dev_rec->ble_hci_handle = BTM_SEC_INVALID_HANDLE; + p_dev_rec->sec_flags &= ~(BTM_SEC_LE_AUTHENTICATED|BTM_SEC_LE_ENCRYPTED); + } + else #endif - p_dev_rec->sec_flags &= ~(BTM_SEC_AUTHORIZED | BTM_SEC_AUTHENTICATED | BTM_SEC_ENCRYPTED | BTM_SEC_ROLE_SWITCHED); + { + p_dev_rec->hci_handle = BTM_SEC_INVALID_HANDLE; + p_dev_rec->sec_flags &= ~(BTM_SEC_AUTHORIZED | BTM_SEC_AUTHENTICATED | BTM_SEC_ENCRYPTED | BTM_SEC_ROLE_SWITCHED); + } + p_dev_rec->sec_state = BTM_SEC_STATE_IDLE; p_dev_rec->security_required = BTM_SEC_NONE; p_callback = p_dev_rec->p_callback; @@ -4506,7 +4758,7 @@ void btm_sec_disconnected (UINT16 handle, UINT8 reason) { p_dev_rec->p_callback = NULL; /* when the peer device time out the authentication before we do, this call back must be reset here */ - (*p_callback) (p_dev_rec->bd_addr, p_dev_rec->p_ref_data, BTM_ERR_PROCESSING); + (*p_callback) (p_dev_rec->bd_addr, transport, p_dev_rec->p_ref_data, BTM_ERR_PROCESSING); } BTM_TRACE_EVENT1("after Update sec_flags=0x%x", p_dev_rec->sec_flags); @@ -4741,7 +4993,7 @@ static void btm_sec_pairing_timeout (TIMER_LIST_ENT *p_tle) (p_cb->pairing_bda[4] << 8) + p_cb->pairing_bda[5]); break; } - btm_sec_send_hci_disconnect (p_dev_rec, HCI_ERR_AUTH_FAILURE); + btm_sec_send_hci_disconnect (p_dev_rec, HCI_ERR_AUTH_FAILURE, p_dev_rec->hci_handle); btm_sec_change_pairing_state (BTM_PAIR_STATE_IDLE); break; @@ -5379,7 +5631,7 @@ static void btm_sec_collision_timeout (TIMER_LIST_ENT *p_tle) if (status != BTM_CMD_STARTED) { /* There is no next procedure or start of procedure failed, notify the waiting layer */ - btm_sec_dev_rec_cback_event (btm_cb.p_collided_dev_rec, status); + btm_sec_dev_rec_cback_event (btm_cb.p_collided_dev_rec, status, FALSE); } } @@ -5604,7 +5856,7 @@ static char *btm_pair_state_descr (tBTM_PAIRING_STATE state) ** Parameters: void ** *******************************************************************************/ -void btm_sec_dev_rec_cback_event (tBTM_SEC_DEV_REC *p_dev_rec, UINT8 res) +void btm_sec_dev_rec_cback_event (tBTM_SEC_DEV_REC *p_dev_rec, UINT8 res, BOOLEAN transport) { tBTM_SEC_CALLBACK *p_callback = p_dev_rec->p_callback; @@ -5612,7 +5864,7 @@ void btm_sec_dev_rec_cback_event (tBTM_SEC_DEV_REC *p_dev_rec, UINT8 res) { p_dev_rec->p_callback = NULL; - (*p_callback) (p_dev_rec->bd_addr, p_dev_rec->p_ref_data, res); + (*p_callback) (p_dev_rec->bd_addr, transport, p_dev_rec->p_ref_data, res); } btm_sec_check_pending_reqs(); @@ -5690,7 +5942,7 @@ static BOOLEAN btm_sec_check_prefetch_pin (tBTM_SEC_DEV_REC *p_dev_rec) if (btm_cb.api.p_pin_callback && ((btm_cb.pairing_flags & BTM_PAIR_FLAGS_PIN_REQD) == 0)) { BTM_TRACE_DEBUG0("btm_sec_check_prefetch_pin: PIN code callback called"); - if (btm_bda_to_acl(p_dev_rec->bd_addr) == NULL) + if (btm_bda_to_acl(p_dev_rec->bd_addr, BT_TRANSPORT_BR_EDR) == NULL) btm_cb.pairing_flags |= BTM_PAIR_FLAGS_PIN_REQD; (btm_cb.api.p_pin_callback) (p_dev_rec->bd_addr, p_dev_rec->dev_class, p_dev_rec->sec_bd_name); } @@ -5741,12 +5993,14 @@ BOOLEAN btm_sec_is_a_bonded_dev (BD_ADDR bda) tBTM_SEC_DEV_REC *p_dev_rec= btm_find_dev (bda); BOOLEAN is_bonded= FALSE; + if (p_dev_rec && #if (SMP_INCLUDED== TRUE) - if (p_dev_rec && (p_dev_rec->ble.key_type || (p_dev_rec->sec_flags & BTM_SEC_LINK_KEY_KNOWN))) + ((p_dev_rec->ble.key_type && (p_dev_rec->sec_flags & BTM_SEC_LE_LINK_KEY_KNOWN))|| +#endif + (p_dev_rec->sec_flags & BTM_SEC_LINK_KEY_KNOWN))) { is_bonded = TRUE; } -#endif BTM_TRACE_DEBUG1 ("btm_sec_is_a_bonded_dev is_bonded=%d", is_bonded); return(is_bonded); } diff --git a/stack/btu/btu_hcif.c b/stack/btu/btu_hcif.c index 0081850c7..fa1951593 100644 --- a/stack/btu/btu_hcif.c +++ b/stack/btu/btu_hcif.c @@ -37,6 +37,7 @@ #include "btm_api.h" #include "btm_int.h" + // btla-specific ++ #define LOG_TAG "BTLD" #if (defined(ANDROID_APP_INCLUDED) && (ANDROID_APP_INCLUDED == TRUE) && (!defined(LINUX_NATIVE)) ) @@ -136,6 +137,9 @@ static void btu_ble_read_remote_feat_evt (UINT8 *p); static void btu_ble_ll_conn_param_upd_evt (UINT8 *p); static void btu_ble_proc_ltk_req (UINT8 *p); static void btu_hcif_encryption_key_refresh_cmpl_evt (UINT8 *p); +#if (BLE_LLT_INCLUDED == TRUE) +static void btu_ble_rc_param_req_evt(UINT8 *p); +#endif #endif /******************************************************************************* ** @@ -421,6 +425,12 @@ void btu_hcif_process_event (UINT8 controller_id, BT_HDR *p_msg) case HCI_BLE_LTK_REQ_EVT: /* received only at slave device */ btu_ble_proc_ltk_req(p); break; +#if (BLE_LLT_INCLUDED == TRUE) + case HCI_BLE_RC_PARAM_REQ_EVT: + btu_ble_rc_param_req_evt(p); + break; +#endif + } break; #endif /* BLE_INCLUDED */ @@ -1138,6 +1148,10 @@ static void btu_hcif_hdl_command_complete (UINT16 opcode, UINT8 *p, UINT16 evt_l btm_ble_write_adv_enable_complete(p); break; + case HCI_BLE_READ_SUPPORTED_STATES: + btm_read_ble_local_supported_states_complete(p, evt_len); + break; + case HCI_BLE_TRANSMITTER_TEST: case HCI_BLE_RECEIVER_TEST: case HCI_BLE_TEST_END: @@ -2266,16 +2280,7 @@ static void btu_ble_ll_conn_complete_evt ( UINT8 *p, UINT16 evt_len) static void btu_ble_ll_conn_param_upd_evt (UINT8 *p) { - /* LE connection update has completed successfully as a master. */ - /* We can enable the update request if the result is a success. */ - /* extract the HCI handle first */ - UINT8 status; - UINT16 handle; - BT_TRACE_0(TRACE_LAYER_HCI, TRACE_TYPE_EVENT, "btu_ble_ll_conn_param_upd_evt"); - - STREAM_TO_UINT8 (status, p); - STREAM_TO_UINT16 (handle, p); - L2CA_HandleConnUpdateEvent(handle, status); + /* This is empty until an upper layer cares about returning event */ } static void btu_ble_read_remote_feat_evt (UINT8 *p) @@ -2299,5 +2304,21 @@ static void btu_ble_proc_ltk_req (UINT8 *p) /********************************************** ** End of BLE Events Handler ***********************************************/ +#if (defined BLE_LLT_INCLUDED) && (BLE_LLT_INCLUDED == TRUE) +static void btu_ble_rc_param_req_evt(UINT8 *p) +{ + UINT16 handle; + UINT16 int_min, int_max, latency, timeout; + + STREAM_TO_UINT16(handle, p); + STREAM_TO_UINT16(int_min, p); + STREAM_TO_UINT16(int_max, p); + STREAM_TO_UINT16(latency, p); + STREAM_TO_UINT16(timeout, p); + + l2cble_process_rc_param_request_evt(handle, int_min, int_max, latency, timeout); +} +#endif /* BLE_LLT_INCLUDED */ + #endif /* BLE_INCLUDED */ diff --git a/stack/btu/btu_task.c b/stack/btu/btu_task.c index 9c0921413..5b5108afd 100644 --- a/stack/btu/btu_task.c +++ b/stack/btu/btu_task.c @@ -400,6 +400,9 @@ BTU_API UINT32 btu_task (UINT32 param) case BTU_TTYPE_L2CAP_HOLD: case BTU_TTYPE_L2CAP_INFO: case BTU_TTYPE_L2CAP_FCR_ACK: +#if (BLE_INCLUDED == TRUE) + case BTU_TTYPE_L2CAP_END_CONN_UPD: +#endif l2c_process_timeout (p_tle); break; @@ -473,6 +476,8 @@ BTU_API UINT32 btu_task (UINT32 param) case BTU_TTYPE_BLE_INQUIRY: case BTU_TTYPE_BLE_GAP_LIM_DISC: case BTU_TTYPE_BLE_RANDOM_ADDR: + case BTU_TTYPE_BLE_GAP_FAST_ADV: + case BTU_TTYPE_BLE_OBSERVE: btm_ble_timeout(p_tle); break; diff --git a/stack/gap/gap_api.c b/stack/gap/gap_api.c index fb90d038c..e04fc8e05 100644 --- a/stack/gap/gap_api.c +++ b/stack/gap/gap_api.c @@ -734,7 +734,7 @@ UINT16 GAP_GetRemoteDeviceName (BD_ADDR addr, tGAP_CALLBACK *callback) p_cb->gap_cback = callback; p_cb->event = GAP_EVT_REM_NAME_COMPLETE; /* Return event expected */ - btm_status = BTM_ReadRemoteDeviceName (addr, gap_cb.btm_cback[p_cb->index]); + btm_status = BTM_ReadRemoteDeviceName (addr, gap_cb.btm_cback[p_cb->index], BT_TRANSPORT_BR_EDR); /* If the name was not returned immediately, or if an error occurred, release the control block */ if ((retval = gap_convert_btm_status (btm_status)) != GAP_CMD_INITIATED) diff --git a/stack/gap/gap_ble.c b/stack/gap/gap_ble.c index d44577dc0..d67bf5a8a 100644 --- a/stack/gap/gap_ble.c +++ b/stack/gap/gap_ble.c @@ -57,7 +57,8 @@ static void gap_ble_s_attr_request_cback (UINT16 conn_id, UINT32 trans_id, tGATTS_REQ_TYPE op_code, tGATTS_DATA *p_data); /* client connection callback */ -static void gap_ble_c_connect_cback (tGATT_IF gatt_if, BD_ADDR bda, UINT16 conn_id, BOOLEAN connected, tGATT_DISCONN_REASON reason); +static void gap_ble_c_connect_cback (tGATT_IF gatt_if, BD_ADDR bda, UINT16 conn_id, BOOLEAN connected, + tGATT_DISCONN_REASON reason, tGATT_TRANSPORT transport); static void gap_ble_c_cmpl_cback (UINT16 conn_id, tGATTC_OPTYPE op, tGATT_STATUS status, tGATT_CL_COMPLETE *p_data); static tGATT_CBACK gap_cback = @@ -213,65 +214,6 @@ UINT16 gap_get_conn_id_if_connected (BD_ADDR bd_addr) return(GATT_INVALID_CONN_ID); } -/******************************************************************************* -** -** Function gap_ble_enqueue_op -** -** Description enqueue a GAP operation when GAP client is busy -** -** Returns void -** -*******************************************************************************/ -void gap_ble_enqueue_op( tGAP_CLCB * p_clcb, UINT8 op, BD_ADDR reconn_addr, UINT8 privacy_flag, void *p_cback) -{ - tGAP_BLE_PENDING_OP *p_op = (tGAP_BLE_PENDING_OP *)GKI_getbuf(sizeof(tGAP_BLE_PENDING_OP)); - - if (p_op != NULL) - { - p_op->op = op; - p_op->p_pending_cback = p_cback; - - if (op == GATT_SET_GAP_PRIVACY_FLAG) - p_op->pending_data.privacy_flag = privacy_flag; - else if (op == GATT_UPDATE_RECONN_ADDR) - memcpy(p_op->pending_data.reconn_addr, reconn_addr, BD_ADDR_LEN); - - GKI_enqueue(&p_clcb->pending_op_q, p_op); - } -} - -/******************************************************************************* -** -** Function gap_ble_process_pending_op -** -** Description get next pending operation and process it -** -** Returns void -** -*******************************************************************************/ -static BOOLEAN gap_ble_process_pending_op(tGAP_CLCB *p_clcb) -{ - tGAP_BLE_PENDING_OP *p_pending_op = (tGAP_BLE_PENDING_OP *)GKI_dequeue(&p_clcb->pending_op_q); - BOOLEAN started = FALSE; - - if (p_pending_op != NULL) - { - if (p_pending_op->op == GATT_UPDATE_RECONN_ADDR) - { - GAP_BleUpdateReconnectAddr( p_clcb->bda, - p_pending_op->pending_data.reconn_addr, - (tGAP_BLE_RECONN_ADDR_CBACK *)p_pending_op->p_pending_cback); - started = TRUE; - } - GKI_freebuf(p_pending_op); - } - else - { - GAP_TRACE_EVENT0("No pending operation"); - } - - return started; -} /******************************************************************************* ** GAP Attributes Database Request callback @@ -316,16 +258,6 @@ tGATT_STATUS gap_read_attr_value (UINT16 handle, tGATT_VALUE *p_value, BOOLEAN i p_value->len = 2; break; - case GATT_UUID_GAP_PRIVACY_FLAG: - UINT8_TO_STREAM(p, p_db_attr->attr_value.privacy); - p_value->len = 1; - break; - - case GATT_UUID_GAP_RECONN_ADDR: - p_value->len = BD_ADDR_LEN; - BDADDR_TO_STREAM(p, p_db_attr->attr_value.reconn_bda); - break; - case GATT_UUID_GAP_PREF_CONN_PARAM: UINT16_TO_STREAM(p, p_db_attr->attr_value.conn_param.int_min); /* int_min */ UINT16_TO_STREAM(p, p_db_attr->attr_value.conn_param.int_max); /* int_max */ @@ -357,18 +289,6 @@ tGATT_STATUS gap_proc_read (tGATTS_REQ_TYPE type, tGATT_READ_REQ *p_data, tGATTS return status; } -BOOLEAN gap_read_local_reconn_addr(BD_ADDR_PTR reconn_bda) -{ - BD_ADDR dummy_bda = {0}; - - if (memcmp(gap_cb.reconn_bda, dummy_bda, BD_ADDR_LEN) != 0) - { - memcpy(reconn_bda, gap_cb.reconn_bda, BD_ADDR_LEN); - return TRUE; - } - else - return FALSE; -} /****************************************************************************** ** @@ -389,26 +309,7 @@ UINT8 gap_proc_write_req( tGATTS_REQ_TYPE type, tGATT_WRITE_REQ *p_data) { if (p_data-> handle == p_db_attr->handle) { - if (p_data->offset != 0) return GATT_NOT_LONG; - if (p_data->is_prep) return GATT_REQ_NOT_SUPPORTED; - -/* DO NOT SUPPORT RECONNECTION ADDRESS FOR NOW - - if (p_db_attr->uuid == GATT_UUID_GAP_RECONN_ADDR) - { - if (!btm_cb.ble_ctr_cb.privacy) - return GATT_WRITE_NOT_PERMIT; - if (p_data->len != BD_ADDR_LEN) return GATT_INVALID_ATTR_LEN; - - STREAM_TO_BDADDR(p_db_attr->attr_value.reconn_bda, p); - // write direct connection address - memcpy(&gap_cb.reconn_bda, p_db_attr->attr_value.reconn_bda, BD_ADDR_LEN); - - return GATT_SUCCESS; - } - else -*/ - return GATT_WRITE_NOT_PERMIT; + return GATT_WRITE_NOT_PERMIT; } } return GATT_NOT_FOUND; @@ -513,6 +414,21 @@ void gap_attr_db_init(void) GATT_CHAR_PROP_BIT_READ); p_db_attr ++; +#if BTM_PERIPHERAL_ENABLED == TRUE /* Only needed for peripheral testing */ + /* add preferred connection parameter characteristic + */ + uuid.uu.uuid16 = p_db_attr->uuid = GATT_UUID_GAP_PREF_CONN_PARAM; + p_db_attr->attr_value.conn_param.int_max = GAP_PREFER_CONN_INT_MAX; /* 6 */ + p_db_attr->attr_value.conn_param.int_min = GAP_PREFER_CONN_INT_MIN; /* 0 */ + p_db_attr->attr_value.conn_param.latency = GAP_PREFER_CONN_LATENCY; /* 0 */ + p_db_attr->attr_value.conn_param.sp_tout = GAP_PREFER_CONN_SP_TOUT; /* 2000 */ + p_db_attr->handle = GATTS_AddCharacteristic(service_handle, + &uuid, + GATT_PERM_READ, + GATT_CHAR_PROP_BIT_READ); + p_db_attr ++; +#endif + /* start service now */ memset (&app_uuid.uu.uuid128, 0x81, LEN_UUID_128); @@ -596,8 +512,6 @@ void gap_ble_cl_op_cmpl(tGAP_CLCB *p_clcb, BOOLEAN status, UINT16 len, UINT8 *p_ (* p_dev_name_cback)(status, p_clcb->bda, len, (char *)p_name); } - if (!gap_ble_process_pending_op(p_clcb) && - p_clcb->cl_op_uuid == 0) GATT_Disconnect(p_clcb->conn_id); } @@ -612,11 +526,14 @@ void gap_ble_cl_op_cmpl(tGAP_CLCB *p_clcb, BOOLEAN status, UINT16 len, UINT8 *p_ ** *******************************************************************************/ static void gap_ble_c_connect_cback (tGATT_IF gatt_if, BD_ADDR bda, UINT16 conn_id, - BOOLEAN connected, tGATT_DISCONN_REASON reason) + BOOLEAN connected, tGATT_DISCONN_REASON reason, + tGATT_TRANSPORT transport) { tGAP_CLCB *p_clcb = gap_find_clcb_by_bd_addr (bda); UINT16 cl_op_uuid; + UNUSED(gatt_if); + UNUSED(transport); GAP_TRACE_EVENT5 ("gap_ble_c_connect_cback: from %08x%04x connected:%d conn_id=%d reason = 0x%04x", (bda[0]<<24)+(bda[1]<<16)+(bda[2]<<8)+bda[3], @@ -636,9 +553,6 @@ static void gap_ble_c_connect_cback (tGATT_IF gatt_if, BD_ADDR bda, UINT16 conn_ p_clcb->conn_id = conn_id; p_clcb->connected = TRUE; - /* Do not use reconnection address for now --> - check privacy enabled? set reconnect address - btm_ble_update_reconnect_address(bda);*/ } else { @@ -659,6 +573,10 @@ static void gap_ble_c_connect_cback (tGATT_IF gatt_if, BD_ADDR bda, UINT16 conn_ { GAP_BleReadPeerDevName (bda, (tGAP_BLE_DEV_NAME_CBACK *)p_clcb->p_cback); } + else if (cl_op_uuid == GATT_UUID_GAP_PREF_CONN_PARAM) + { + GAP_BleReadPeerPrefConnParams(bda); + } } /* current link disconnect */ else @@ -695,7 +613,7 @@ static void gap_ble_c_cmpl_cback (UINT16 conn_id, tGATTC_OPTYPE op, tGATT_STATUS GAP_TRACE_EVENT3 ("gap_ble_c_cmpl_cback() - op_code: 0x%02x status: 0x%02x read_type: 0x%04x", op, status, op_type); /* Currently we only issue read commands */ - if (op != GATTC_OPTYPE_READ && op != GATTC_OPTYPE_WRITE) + if (op != GATTC_OPTYPE_READ) return; if (status != GATT_SUCCESS) @@ -731,7 +649,6 @@ static void gap_ble_c_cmpl_cback (UINT16 conn_id, tGATTC_OPTYPE op, tGATT_STATUS break; case GATT_UUID_GAP_ICON: break; - } } @@ -806,18 +723,20 @@ BOOLEAN GAP_BleReadPeerPrefConnParams (BD_ADDR peer_bda) return(FALSE); /* hold the link here */ - GATT_Connect(gap_cb.gatt_if, p_clcb->bda, TRUE); - - if (p_clcb->connected) + if (GATT_Connect(gap_cb.gatt_if, p_clcb->bda, TRUE, BT_TRANSPORT_LE)) { - return gap_ble_cl_read_request(p_clcb, GATT_UUID_GAP_PREF_CONN_PARAM, NULL); - } - /* Mark currently active operation */ - p_clcb->cl_op_uuid = GATT_UUID_GAP_PREF_CONN_PARAM; - - return(TRUE); + if (p_clcb->connected) + { + return gap_ble_cl_read_request(p_clcb, GATT_UUID_GAP_PREF_CONN_PARAM, NULL); + } + /* Mark currently active operation */ + p_clcb->cl_op_uuid = GATT_UUID_GAP_PREF_CONN_PARAM; + return(TRUE); + } + else + return FALSE; } /******************************************************************************* @@ -839,10 +758,10 @@ BOOLEAN GAP_BleReadPeerDevName (BD_ADDR peer_bda, tGAP_BLE_DEV_NAME_CBACK *p_cba if ((p_clcb = gap_find_clcb_by_bd_addr (peer_bda)) == NULL) { if ((p_clcb = gap_clcb_alloc(0, peer_bda)) == NULL) - { - GAP_TRACE_ERROR0("GAP_BleReadPeerDevName max connection reached"); + { + GAP_TRACE_ERROR0("GAP_BleReadPeerDevName max connection reached"); return FALSE; - } + } p_clcb->connected = FALSE; } @@ -855,21 +774,26 @@ BOOLEAN GAP_BleReadPeerDevName (BD_ADDR peer_bda, tGAP_BLE_DEV_NAME_CBACK *p_cba return(FALSE); /* hold the link here */ - GATT_Connect(gap_cb.gatt_if, p_clcb->bda, TRUE); - if (p_clcb->connected) + if (GATT_Connect(gap_cb.gatt_if, p_clcb->bda, TRUE, BT_TRANSPORT_LE)) { - return gap_ble_cl_read_request(p_clcb, GATT_UUID_GAP_DEVICE_NAME, (void *)p_cback); - } + if (p_clcb->connected) + { + return gap_ble_cl_read_request(p_clcb, GATT_UUID_GAP_DEVICE_NAME, (void *)p_cback); + } - p_clcb->p_cback = (void *)p_cback; - /* Mark currently active operation */ - p_clcb->cl_op_uuid = GATT_UUID_GAP_DEVICE_NAME; + p_clcb->p_cback = (void *)p_cback; + /* Mark currently active operation */ + p_clcb->cl_op_uuid = GATT_UUID_GAP_DEVICE_NAME; - return(TRUE); + return(TRUE); + } + else + return FALSE; } + /******************************************************************************* ** ** Function GAP_BleCancelReadPeerDevName @@ -907,73 +831,6 @@ BOOLEAN GAP_BleCancelReadPeerDevName (BD_ADDR peer_bda) return(TRUE); } -/******************************************************************************* -** -** Function GAP_BleUpdateReconnectAddr -** -** Description Start a process to udpate the reconnect address if remote devive -** has privacy enabled. -** -** Returns TRUE if read started, else FALSE if GAP is busy -** -*******************************************************************************/ -BOOLEAN GAP_BleUpdateReconnectAddr (BD_ADDR peer_bda, BD_ADDR reconn_addr, - tGAP_BLE_RECONN_ADDR_CBACK *p_cback) -{ - tGAP_CLCB *p_clcb; - tGATT_DISC_PARAM param; - - if (p_cback == NULL) - return(FALSE); - - /* This function should only be called if there is a connection to */ - /* the peer. Get a client handle for that connection. */ - if ((p_clcb = gap_find_clcb_by_bd_addr (peer_bda)) == NULL || - !p_clcb->connected) - { - GAP_TRACE_ERROR0("No connection, can not update reconnect address"); - return(FALSE); - } - - GAP_TRACE_API3 ("GAP_BleUpdateReconnectAddr() - BDA: %08x%04x cl_op_uuid: 0x%04x", - (peer_bda[0]<<24)+(peer_bda[1]<<16)+(peer_bda[2]<<8)+peer_bda[3], - (peer_bda[4]<<8)+peer_bda[5], p_clcb->cl_op_uuid); - - /* For now we only handle one at a time */ - if (p_clcb->cl_op_uuid != 0) - { - gap_ble_enqueue_op(p_clcb, GATT_UPDATE_RECONN_ADDR, reconn_addr, 0, (void *)p_cback); - return(FALSE); - } - - /* hold the link here */ - GATT_Connect(gap_cb.gatt_if, p_clcb->bda, TRUE); - - memset(¶m, 0, sizeof(tGATT_DISC_PARAM)); - - param.service.len = LEN_UUID_16; - param.service.uu.uuid16 = GATT_UUID_GAP_RECONN_ADDR; - param.s_handle = 1; - param.e_handle = 0xFFFF; - - if (GATTC_Discover(p_clcb->conn_id, GATT_DISC_CHAR, ¶m) != GATT_SUCCESS) - { - GAP_TRACE_ERROR0 ("GAP_BleReadPeerPrefConnParams: GATT_Read Failed"); - /* release the link here */ - GATT_Disconnect(p_clcb->conn_id); - return(FALSE); - } - else - { - p_clcb->p_cback = (void *)p_cback; - memcpy(p_clcb->reconn_addr, reconn_addr, BD_ADDR_LEN); - p_clcb->cl_op_uuid = GATT_UUID_GAP_RECONN_ADDR; - } - - return TRUE; - -} - #endif /* BLE_INCLUDED */ diff --git a/stack/gap/gap_conn.c b/stack/gap/gap_conn.c index 44bb5ece8..5e26ce279 100644 --- a/stack/gap/gap_conn.c +++ b/stack/gap/gap_conn.c @@ -799,10 +799,11 @@ static void gap_checks_con_flags (tGAP_CCB *p_ccb) ** Returns void ** *******************************************************************************/ -static void gap_sec_check_complete (BD_ADDR bd_addr, void *p_ref_data, UINT8 res) +static void gap_sec_check_complete (BD_ADDR bd_addr, tBT_TRANSPORT transport, void *p_ref_data, UINT8 res) { tGAP_CCB *p_ccb = (tGAP_CCB *)p_ref_data; UNUSED(bd_addr); + UNUSED (transport); GAP_TRACE_EVENT3 ("gap_sec_check_complete conn_state:%d, conn_flags:0x%x, status:%d", p_ccb->con_state, p_ccb->con_flags, res); diff --git a/stack/gap/gap_utils.c b/stack/gap/gap_utils.c index 866ad7ab6..e852d20d2 100644 --- a/stack/gap/gap_utils.c +++ b/stack/gap/gap_utils.c @@ -183,7 +183,7 @@ void gap_find_addr_name_cb (tBTM_REMOTE_DEV_NAME *p) if ((p_cb->p_cur_inq = BTM_InqDbNext(p_cb->p_cur_inq)) != NULL) { if ((BTM_ReadRemoteDeviceName (p_cb->p_cur_inq->results.remote_bd_addr, - (tBTM_CMPL_CB *) gap_find_addr_name_cb)) == BTM_CMD_STARTED) + (tBTM_CMPL_CB *) gap_find_addr_name_cb, BT_TRANSPORT_BR_EDR)) == BTM_CMD_STARTED) return; /* This routine will get called again with the next results */ else p_result->status = gap_convert_btm_status ((tBTM_STATUS) p->status); @@ -246,7 +246,7 @@ void gap_find_addr_inq_cb (tBTM_INQUIRY_CMPL *p) if ((p_cb->p_cur_inq = BTM_InqDbFirst()) != NULL) { if ((BTM_ReadRemoteDeviceName (p_cb->p_cur_inq->results.remote_bd_addr, - (tBTM_CMPL_CB *) gap_find_addr_name_cb)) == BTM_CMD_STARTED) + (tBTM_CMPL_CB *) gap_find_addr_name_cb, BT_TRANSPORT_BR_EDR)) == BTM_CMD_STARTED) return; /* Wait for the response in gap_find_addr_name_cb() */ else p_result->status = gap_convert_btm_status (p->status); diff --git a/stack/gatt/att_protocol.c b/stack/gatt/att_protocol.c index 33485997c..51ea28490 100644 --- a/stack/gatt/att_protocol.c +++ b/stack/gatt/att_protocol.c @@ -162,7 +162,7 @@ BT_HDR *attp_build_browse_cmd(UINT8 op_code, UINT16 s_hdl, UINT16 e_hdl, tBT_UUI ** Returns pointer to the command buffer. ** *******************************************************************************/ -BT_HDR *attp_build_read_handles_cmd (UINT16 payload_size, tGATT_FIND_TYPE_VALUE *p_value_type) +BT_HDR *attp_build_read_by_type_value_cmd (UINT16 payload_size, tGATT_FIND_TYPE_VALUE *p_value_type) { BT_HDR *p_buf = NULL; UINT8 *p; @@ -606,7 +606,7 @@ tGATT_STATUS attp_send_cl_msg (tGATT_TCB *p_tcb, UINT16 clcb_idx, UINT8 op_code, break; case GATT_REQ_FIND_TYPE_VALUE: - p_cmd = attp_build_read_handles_cmd(p_tcb->payload_size, &p_msg->find_type_value); + p_cmd = attp_build_read_by_type_value_cmd(p_tcb->payload_size, &p_msg->find_type_value); break; case GATT_REQ_READ_MULTI: diff --git a/stack/gatt/gatt_api.c b/stack/gatt/gatt_api.c index 54ea0f085..0321fe841 100644 --- a/stack/gatt/gatt_api.c +++ b/stack/gatt/gatt_api.c @@ -238,7 +238,7 @@ UINT16 GATTS_CreateService (tGATT_IF gatt_if, tBT_UUID *p_svc_uuid, } } - if (!gatts_init_service_db(&p_list->svc_db, *p_svc_uuid, is_pri, s_hdl , num_handles)) + if (!gatts_init_service_db(&p_list->svc_db, p_svc_uuid, is_pri, s_hdl , num_handles)) { GATT_TRACE_ERROR0 ("GATTS_ReserveHandles: service DB initialization failed"); if (p_list) @@ -366,7 +366,8 @@ UINT16 GATTS_AddCharDescriptor (UINT16 service_handle, return 0; } if (p_descr_uuid == NULL || - (p_descr_uuid->len != LEN_UUID_128 && p_descr_uuid->len != LEN_UUID_16)) + (p_descr_uuid->len != LEN_UUID_128 && p_descr_uuid->len != LEN_UUID_16 + && p_descr_uuid->len != LEN_UUID_32)) { GATT_TRACE_DEBUG0("Illegal parameter"); return 0; @@ -689,8 +690,13 @@ tGATT_STATUS GATTS_HandleValueNotification (UINT16 conn_id, UINT16 attr_handle, memcpy (notif.value, p_val, val_len); notif.auth_req = GATT_AUTH_REQ_NONE;; - p_buf = attp_build_sr_msg (p_tcb, GATT_HANDLE_VALUE_NOTIF, (tGATT_SR_MSG *)¬if); - cmd_sent = attp_send_sr_msg (p_tcb, p_buf); + if ((p_buf = attp_build_sr_msg (p_tcb, GATT_HANDLE_VALUE_NOTIF, (tGATT_SR_MSG *)¬if)) + != NULL) + { + cmd_sent = attp_send_sr_msg (p_tcb, p_buf); + } + else + cmd_sent = GATT_NO_RESOURCES; } return cmd_sent; } @@ -1147,12 +1153,12 @@ tGATT_STATUS GATTC_SendHandleValueConfirm (UINT16 conn_id, UINT16 handle) ** Returns void ** *******************************************************************************/ -void GATT_SetIdleTimeout (BD_ADDR bd_addr, UINT16 idle_tout) +void GATT_SetIdleTimeout (BD_ADDR bd_addr, UINT16 idle_tout, tBT_TRANSPORT transport) { tGATT_TCB *p_tcb; BOOLEAN status = FALSE; - if ((p_tcb = gatt_find_tcb_by_addr (bd_addr)) != NULL) + if ((p_tcb = gatt_find_tcb_by_addr (bd_addr, transport)) != NULL) { if (p_tcb->att_lcid == L2CAP_ATT_CID) { @@ -1275,7 +1281,7 @@ void GATT_Deregister (tGATT_IF gatt_if) if (!gatt_num_apps_hold_link(p_tcb)) { /* this will disconnect the link or cancel the pending connect request at lower layer*/ - gatt_disconnect(p_tcb->peer_bda); + gatt_disconnect(p_tcb); } } @@ -1323,19 +1329,20 @@ void GATT_StartIf (tGATT_IF gatt_if) BD_ADDR bda; UINT8 start_idx, found_idx; UINT16 conn_id; + tGATT_TRANSPORT transport ; GATT_TRACE_API1 ("GATT_StartIf gatt_if=%d", gatt_if); if ((p_reg = gatt_get_regcb(gatt_if)) != NULL) { p_reg = &gatt_cb.cl_rcb[gatt_if - 1]; start_idx = 0; - while (gatt_find_the_connected_bda(start_idx, bda, &found_idx)) + while (gatt_find_the_connected_bda(start_idx, bda, &found_idx, &transport)) { - p_tcb = gatt_find_tcb_by_addr(bda); + p_tcb = gatt_find_tcb_by_addr(bda, transport); if (p_reg->app_cb.p_conn_cb && p_tcb) { conn_id = GATT_CREATE_CONN_ID(p_tcb->tcb_idx, gatt_if); - (*p_reg->app_cb.p_conn_cb)(gatt_if, bda, conn_id, TRUE, 0); + (*p_reg->app_cb.p_conn_cb)(gatt_if, bda, conn_id, TRUE, 0, transport); } start_idx = ++found_idx; } @@ -1357,9 +1364,10 @@ void GATT_StartIf (tGATT_IF gatt_if) ** Returns TRUE if connection started; FALSE if connection start failure. ** *******************************************************************************/ -BOOLEAN GATT_Connect (tGATT_IF gatt_if, BD_ADDR bd_addr, BOOLEAN is_direct){ +BOOLEAN GATT_Connect (tGATT_IF gatt_if, BD_ADDR bd_addr, BOOLEAN is_direct, tBT_TRANSPORT transport) +{ tGATT_REG *p_reg; - BOOLEAN status; + BOOLEAN status = FALSE; GATT_TRACE_API1 ("GATT_Connect gatt_if=%d", gatt_if); @@ -1371,9 +1379,16 @@ BOOLEAN GATT_Connect (tGATT_IF gatt_if, BD_ADDR bd_addr, BOOLEAN is_direct){ } if (is_direct) - status = gatt_act_connect (p_reg, bd_addr); + status = gatt_act_connect (p_reg, bd_addr, transport); else + { + if (transport == BT_TRANSPORT_LE) status = gatt_update_auto_connect_dev(gatt_if,TRUE, bd_addr, TRUE); + else + { + GATT_TRACE_ERROR0("Unsupported transport for background connection"); + } + } return status; @@ -1414,7 +1429,8 @@ BOOLEAN GATT_CancelConnect (tGATT_IF gatt_if, BD_ADDR bd_addr, BOOLEAN is_direct { GATT_TRACE_DEBUG0("GATT_CancelConnect - unconditional"); start_idx = 0; - p_tcb = gatt_find_tcb_by_addr(bd_addr); + /* only LE connection can be cancelled */ + p_tcb = gatt_find_tcb_by_addr(bd_addr, BT_TRANSPORT_LE); if (p_tcb && gatt_num_apps_hold_link(p_tcb)) { while (status && gatt_find_app_hold_link(p_tcb, start_idx, &found_idx, &temp_gatt_if)) @@ -1486,7 +1502,7 @@ tGATT_STATUS GATT_Disconnect (UINT16 conn_id) gatt_update_app_use_link_flag(gatt_if, p_tcb, FALSE, FALSE); if (!gatt_num_apps_hold_link(p_tcb)) { - gatt_disconnect(p_tcb->peer_bda); + gatt_disconnect(p_tcb); } ret = GATT_SUCCESS; } @@ -1508,7 +1524,8 @@ tGATT_STATUS GATT_Disconnect (UINT16 conn_id) ** Returns TRUE the ligical link information is found for conn_id ** *******************************************************************************/ -BOOLEAN GATT_GetConnectionInfor(UINT16 conn_id, tGATT_IF *p_gatt_if, BD_ADDR bd_addr) +BOOLEAN GATT_GetConnectionInfor(UINT16 conn_id, tGATT_IF *p_gatt_if, BD_ADDR bd_addr, + tBT_TRANSPORT *p_transport) { tGATT_IF gatt_if = GATT_GET_GATT_IF(conn_id); @@ -1523,6 +1540,7 @@ BOOLEAN GATT_GetConnectionInfor(UINT16 conn_id, tGATT_IF *p_gatt_if, BD_ADDR bd_ { memcpy(bd_addr, p_tcb->peer_bda, BD_ADDR_LEN); *p_gatt_if = gatt_if; + *p_transport = p_tcb->transport; status = TRUE; } return status; @@ -1539,14 +1557,16 @@ BOOLEAN GATT_GetConnectionInfor(UINT16 conn_id, tGATT_IF *p_gatt_if, BD_ADDR bd_ ** Parameters gatt_if: applicaiton interface (input) ** bd_addr: peer device address. (input) ** p_conn_id: connection id (output) +** transport: transport option ** ** Returns TRUE the logical link is connected ** *******************************************************************************/ -BOOLEAN GATT_GetConnIdIfConnected(tGATT_IF gatt_if, BD_ADDR bd_addr, UINT16 *p_conn_id) +BOOLEAN GATT_GetConnIdIfConnected(tGATT_IF gatt_if, BD_ADDR bd_addr, UINT16 *p_conn_id, + tBT_TRANSPORT transport) { tGATT_REG *p_reg = gatt_get_regcb(gatt_if); - tGATT_TCB *p_tcb= gatt_find_tcb_by_addr(bd_addr); + tGATT_TCB *p_tcb= gatt_find_tcb_by_addr(bd_addr, transport); BOOLEAN status=FALSE; if (p_reg && p_tcb && (gatt_get_ch_state(p_tcb) == GATT_CH_OPEN) ) @@ -1598,10 +1618,7 @@ BOOLEAN GATT_Listen (tGATT_IF gatt_if, BOOLEAN start, BD_ADDR_PTR bd_addr) p_reg->listening = start ? GATT_LISTEN_TO_ALL : GATT_LISTEN_TO_NONE; } - gatt_update_listen_mode(); - - return status; - + return gatt_update_listen_mode(); } #endif diff --git a/stack/gatt/gatt_attr.c b/stack/gatt/gatt_attr.c index 1ee4ae3a6..60beaa7a7 100644 --- a/stack/gatt/gatt_attr.c +++ b/stack/gatt/gatt_attr.c @@ -41,7 +41,8 @@ #endif static void gatt_profile_request_cback (UINT16 conn_id, UINT32 trans_id, UINT8 op_code, tGATTS_DATA *p_data); -static void gatt_profile_connect_cback (tGATT_IF gatt_if, BD_ADDR bda, UINT16 conn_id, BOOLEAN connected, tGATT_DISCONN_REASON reason); +static void gatt_profile_connect_cback (tGATT_IF gatt_if, BD_ADDR bda, UINT16 conn_id, + BOOLEAN connected, tGATT_DISCONN_REASON reason, tBT_TRANSPORT transport); static tGATT_CBACK gatt_profile_cback = { @@ -87,14 +88,15 @@ UINT16 gatt_profile_find_conn_id_by_bd_addr(BD_ADDR bda) ** Returns Pointer to the found link conenction control block. ** *******************************************************************************/ -tGATT_PROFILE_CLCB *gatt_profile_find_clcb_by_bd_addr(BD_ADDR bda) +static tGATT_PROFILE_CLCB *gatt_profile_find_clcb_by_bd_addr(BD_ADDR bda, tBT_TRANSPORT transport) { UINT8 i_clcb; tGATT_PROFILE_CLCB *p_clcb = NULL; for (i_clcb = 0, p_clcb= gatt_cb.profile_clcb; i_clcb < GATT_MAX_APPS; i_clcb++, p_clcb++) { - if (p_clcb->in_use && p_clcb->connected && !memcmp(p_clcb->bda, bda, BD_ADDR_LEN)) + if (p_clcb->in_use && p_clcb->transport == transport && + p_clcb->connected && !memcmp(p_clcb->bda, bda, BD_ADDR_LEN)) { return p_clcb; } @@ -112,7 +114,7 @@ tGATT_PROFILE_CLCB *gatt_profile_find_clcb_by_bd_addr(BD_ADDR bda) ** Returns NULL if not found. Otherwise pointer to the connection link block. ** *******************************************************************************/ -tGATT_PROFILE_CLCB *gatt_profile_clcb_alloc (UINT16 conn_id, BD_ADDR bda) +tGATT_PROFILE_CLCB *gatt_profile_clcb_alloc (UINT16 conn_id, BD_ADDR bda, tBT_TRANSPORT tranport) { UINT8 i_clcb = 0; tGATT_PROFILE_CLCB *p_clcb = NULL; @@ -124,6 +126,7 @@ tGATT_PROFILE_CLCB *gatt_profile_clcb_alloc (UINT16 conn_id, BD_ADDR bda) p_clcb->in_use = TRUE; p_clcb->conn_id = conn_id; p_clcb->connected = TRUE; + p_clcb->transport = tranport; memcpy (p_clcb->bda, bda, BD_ADDR_LEN); break; } @@ -215,7 +218,8 @@ static void gatt_profile_request_cback (UINT16 conn_id, UINT32 trans_id, tGATTS_ ** *******************************************************************************/ static void gatt_profile_connect_cback (tGATT_IF gatt_if, BD_ADDR bda, UINT16 conn_id, - BOOLEAN connected, tGATT_DISCONN_REASON reason) + BOOLEAN connected, tGATT_DISCONN_REASON reason, + tBT_TRANSPORT transport) { UNUSED(gatt_if); @@ -225,7 +229,7 @@ static void gatt_profile_connect_cback (tGATT_IF gatt_if, BD_ADDR bda, UINT16 co if (connected) { - if (gatt_profile_clcb_alloc(conn_id, bda) == NULL) + if (gatt_profile_clcb_alloc(conn_id, bda, transport) == NULL) { GATT_TRACE_ERROR0 ("gatt_profile_connect_cback: no_resource"); return; diff --git a/stack/gatt/gatt_auth.c b/stack/gatt/gatt_auth.c index 7dc99e195..b09372532 100644 --- a/stack/gatt/gatt_auth.c +++ b/stack/gatt/gatt_auth.c @@ -114,9 +114,8 @@ void gatt_verify_signature(tGATT_TCB *p_tcb, BT_HDR *p_buf) } else { - /* if this is a bad signature, assume from attacker, ignore it */ - GATT_TRACE_ERROR0("Signature Verification Failed"); - gatt_disconnect(p_tcb->peer_bda); + /* if this is a bad signature, assume from attacker, ignore it */ + GATT_TRACE_ERROR0("Signature Verification Failed, data ignored"); } return; @@ -157,7 +156,7 @@ void gatt_sec_check_complete(BOOLEAN sec_check_ok, tGATT_CLCB *p_clcb, UINT8 s ** Returns ** *******************************************************************************/ -void gatt_enc_cmpl_cback(BD_ADDR bd_addr, void *p_ref_data, tBTM_STATUS result) +void gatt_enc_cmpl_cback(BD_ADDR bd_addr, tBT_TRANSPORT transport, void *p_ref_data, tBTM_STATUS result) { tGATT_TCB *p_tcb; UINT8 sec_flag; @@ -167,7 +166,7 @@ void gatt_enc_cmpl_cback(BD_ADDR bd_addr, void *p_ref_data, tBTM_STATUS result) UNUSED(p_ref_data); GATT_TRACE_DEBUG0("gatt_enc_cmpl_cback"); - if ((p_tcb = gatt_find_tcb_by_addr(bd_addr)) != NULL) + if ((p_tcb = gatt_find_tcb_by_addr(bd_addr, transport)) != NULL) { if (gatt_get_sec_act(p_tcb) == GATT_SEC_ENC_PENDING) return; @@ -178,8 +177,9 @@ void gatt_enc_cmpl_cback(BD_ADDR bd_addr, void *p_ref_data, tBTM_STATUS result) { if (gatt_get_sec_act(p_tcb) == GATT_SEC_ENCRYPT_MITM ) { - BTM_GetSecurityFlags(bd_addr, &sec_flag); - if (sec_flag & sec_flag & BTM_SEC_FLAG_LKEY_AUTHED) + BTM_GetSecurityFlagsByTransport(bd_addr, &sec_flag, transport); + + if (sec_flag & BTM_SEC_FLAG_LKEY_AUTHED) { status = TRUE; } @@ -232,7 +232,7 @@ void gatt_notify_enc_cmpl(BD_ADDR bd_addr) UINT16 count; UINT8 i = 0; - if ((p_tcb = gatt_find_tcb_by_addr(bd_addr)) != NULL) + if ((p_tcb = gatt_find_tcb_by_addr(bd_addr, BT_TRANSPORT_LE)) != NULL) { for (i = 0; i < GATT_MAX_APPS; i++) { @@ -316,9 +316,7 @@ tGATT_SEC_ACTION gatt_determine_sec_act(tGATT_CLCB *p_clcb ) UINT8 sec_flag; tGATT_TCB *p_tcb = p_clcb->p_tcb; tGATT_AUTH_REQ auth_req = p_clcb->auth_req; - BOOLEAN is_link_encrypted= FALSE; - BOOLEAN is_le_link=FALSE; BOOLEAN is_link_key_known=FALSE; BOOLEAN is_key_mitm=FALSE; UINT8 key_type; @@ -327,8 +325,8 @@ tGATT_SEC_ACTION gatt_determine_sec_act(tGATT_CLCB *p_clcb ) if (auth_req == GATT_AUTH_REQ_NONE ) return act; - is_le_link = BTM_UseLeLink(p_tcb->peer_bda); - BTM_GetSecurityFlags(p_tcb->peer_bda, &sec_flag); + BTM_GetSecurityFlagsByTransport(p_tcb->peer_bda, &sec_flag, p_clcb->p_tcb->transport); + btm_ble_link_sec_check(p_tcb->peer_bda, auth_req, &sec_act); /* if a encryption is pending, need to wait */ @@ -336,24 +334,15 @@ tGATT_SEC_ACTION gatt_determine_sec_act(tGATT_CLCB *p_clcb ) auth_req != GATT_AUTH_REQ_NONE) return GATT_SEC_ENC_PENDING; - if (sec_flag & BTM_SEC_FLAG_ENCRYPTED) + if (sec_flag & (BTM_SEC_FLAG_ENCRYPTED| BTM_SEC_FLAG_LKEY_KNOWN)) { - is_link_encrypted = TRUE; - is_link_key_known = TRUE; - - if (sec_flag & BTM_SEC_FLAG_LKEY_AUTHED) - { - is_key_mitm = TRUE; - } + if (sec_flag & BTM_SEC_FLAG_ENCRYPTED) + is_link_encrypted = TRUE; - } - else if (sec_flag & BTM_SEC_FLAG_LKEY_KNOWN) - { is_link_key_known = TRUE; + if (sec_flag & BTM_SEC_FLAG_LKEY_AUTHED) - { is_key_mitm = TRUE; - } } /* first check link key upgrade required or not */ @@ -377,7 +366,7 @@ tGATT_SEC_ACTION gatt_determine_sec_act(tGATT_CLCB *p_clcb ) /* now check link needs to be encrypted or not if the link key upgrade is not required */ if (act == GATT_SEC_OK) { - if (is_le_link && + if (p_tcb->transport == BT_TRANSPORT_LE && (p_clcb->operation == GATTC_OPTYPE_WRITE) && (p_clcb->op_subtype == GATT_WRITE_NO_RSP)) { @@ -430,7 +419,7 @@ tGATT_STATUS gatt_get_link_encrypt_status(tGATT_TCB *p_tcb) tGATT_STATUS encrypt_status = GATT_NOT_ENCRYPTED; UINT8 sec_flag=0; - BTM_GetSecurityFlags(p_tcb->peer_bda, &sec_flag); + BTM_GetSecurityFlagsByTransport(p_tcb->peer_bda, &sec_flag, p_tcb->transport); if ((sec_flag & BTM_SEC_FLAG_ENCRYPTED) && (sec_flag & BTM_SEC_FLAG_LKEY_KNOWN)) { @@ -510,7 +499,7 @@ BOOLEAN gatt_security_check_start(tGATT_CLCB *p_clcb) { GATT_TRACE_DEBUG0("gatt_security_check_start: Encrypt now or key upgreade first"); gatt_convert_sec_action(gatt_sec_act, &btm_ble_sec_act); - btm_status = BTM_SetEncryption(p_tcb->peer_bda, gatt_enc_cmpl_cback, &btm_ble_sec_act); + btm_status = BTM_SetEncryption(p_tcb->peer_bda, p_tcb->transport , gatt_enc_cmpl_cback, &btm_ble_sec_act); if ( (btm_status != BTM_SUCCESS) && (btm_status != BTM_CMD_STARTED)) { GATT_TRACE_ERROR1("gatt_security_check_start BTM_SetEncryption failed btm_status=%d", btm_status); diff --git a/stack/gatt/gatt_cl.c b/stack/gatt/gatt_cl.c index e8c41fcba..930cd35ee 100644 --- a/stack/gatt/gatt_cl.c +++ b/stack/gatt/gatt_cl.c @@ -27,6 +27,7 @@ #if BLE_INCLUDED == TRUE #include +#include "bt_utils.h" #include "gki.h" #include "gatt_int.h" @@ -102,6 +103,13 @@ void gatt_act_discovery(tGATT_CLCB *p_clcb) cl_req.find_type_value.s_handle = p_clcb->s_handle; cl_req.find_type_value.e_handle = p_clcb->e_handle; cl_req.find_type_value.value_len = p_clcb->uuid.len; + /* if service type is 32 bits UUID, convert it now */ + if (p_clcb->uuid.len == LEN_UUID_32) + { + cl_req.find_type_value.value_len = LEN_UUID_128; + gatt_convert_uuid32_to_uuid128(cl_req.find_type_value.value, p_clcb->uuid.uu.uuid32); + } + else memcpy (cl_req.find_type_value.value, &p_clcb->uuid.uu, p_clcb->uuid.len); } @@ -402,11 +410,13 @@ void gatt_send_prepare_write(tGATT_TCB *p_tcb, tGATT_CLCB *p_clcb) ** Returns void ** *******************************************************************************/ -static void gatt_process_find_type_value_rsp (tGATT_CLCB *p_clcb, UINT16 len, UINT8 *p_data) +void gatt_process_find_type_value_rsp (tGATT_TCB *p_tcb, tGATT_CLCB *p_clcb, UINT16 len, UINT8 *p_data) { tGATT_DISC_RES result; UINT8 *p = p_data; + UNUSED(p_tcb); + GATT_TRACE_DEBUG0("gatt_process_find_type_value_rsp "); /* unexpected response */ if (p_clcb->operation != GATTC_OPTYPE_DISCOVERY || p_clcb->op_subtype != GATT_DISC_SRVC_BY_UUID) @@ -445,11 +455,15 @@ static void gatt_process_find_type_value_rsp (tGATT_CLCB *p_clcb, UINT16 len, UI ** Returns void ** *******************************************************************************/ -static void gatt_process_read_info_rsp(tGATT_CLCB *p_clcb, UINT16 len, UINT8 *p_data) +void gatt_process_read_info_rsp(tGATT_TCB *p_tcb, tGATT_CLCB *p_clcb, UINT8 op_code, + UINT16 len, UINT8 *p_data) { tGATT_DISC_RES result; UINT8 *p = p_data, uuid_len = 0, type; + UNUSED(p_tcb); + UNUSED(op_code); + if (len < GATT_INFO_RSP_MIN_LEN) { GATT_TRACE_ERROR0("invalid Info Response PDU received, discard."); @@ -500,10 +514,14 @@ static void gatt_process_read_info_rsp(tGATT_CLCB *p_clcb, UINT16 len, UINT8 *p_ ** Returns void. ** *******************************************************************************/ -static void gatt_proc_disc_error_rsp(tGATT_CLCB *p_clcb, UINT8 opcode, UINT8 reason) +void gatt_proc_disc_error_rsp(tGATT_TCB *p_tcb, tGATT_CLCB *p_clcb, UINT8 opcode, + UINT16 handle, UINT8 reason) { tGATT_STATUS status = (tGATT_STATUS) reason; + UNUSED(p_tcb); + UNUSED(handle); + GATT_TRACE_DEBUG2("gatt_proc_disc_error_rsp reason: %02x cmd_code %04x", reason, opcode); switch (opcode) @@ -536,12 +554,16 @@ static void gatt_proc_disc_error_rsp(tGATT_CLCB *p_clcb, UINT8 opcode, UINT8 rea ** Returns void ** *******************************************************************************/ -static void gatt_process_error_rsp(tGATT_TCB *p_tcb, tGATT_CLCB *p_clcb, UINT8 *p_data) +void gatt_process_error_rsp(tGATT_TCB *p_tcb, tGATT_CLCB *p_clcb, UINT8 op_code, + UINT16 len, UINT8 *p_data) { UINT8 opcode, reason, * p= p_data; UINT16 handle; tGATT_VALUE *p_attr = (tGATT_VALUE *)p_clcb->p_attr_buf; + UNUSED(op_code); + UNUSED(len); + GATT_TRACE_DEBUG0("gatt_process_error_rsp "); STREAM_TO_UINT8(opcode, p); STREAM_TO_UINT16(handle, p); @@ -549,7 +571,7 @@ static void gatt_process_error_rsp(tGATT_TCB *p_tcb, tGATT_CLCB *p_clcb, UINT8 * if (p_clcb->operation == GATTC_OPTYPE_DISCOVERY) { - gatt_proc_disc_error_rsp(p_clcb, opcode, reason); + gatt_proc_disc_error_rsp(p_tcb, p_clcb, opcode, handle, reason); } else { @@ -921,12 +943,14 @@ void gatt_process_read_by_type_rsp (tGATT_TCB *p_tcb, tGATT_CLCB *p_clcb, UINT8 ** Returns void ** *******************************************************************************/ -static void gatt_process_read_rsp(tGATT_TCB *p_tcb, tGATT_CLCB *p_clcb, - UINT16 len, UINT8 *p_data) +void gatt_process_read_rsp(tGATT_TCB *p_tcb, tGATT_CLCB *p_clcb, UINT8 op_code, + UINT16 len, UINT8 *p_data) { UINT16 offset = p_clcb->counter; UINT8 * p= p_data; + UNUSED(op_code); + if (p_clcb->operation == GATTC_OPTYPE_READ) { if (p_clcb->op_subtype != GATT_READ_BY_HANDLE) @@ -1169,7 +1193,7 @@ void gatt_client_handle_server_rsp (tGATT_TCB *p_tcb, UINT8 op_code, switch (op_code) { case GATT_RSP_ERROR: - gatt_process_error_rsp(p_tcb, p_clcb, p_data); + gatt_process_error_rsp(p_tcb, p_clcb, op_code, len, p_data); break; case GATT_RSP_MTU: /* 2 bytes mtu */ @@ -1177,7 +1201,7 @@ void gatt_client_handle_server_rsp (tGATT_TCB *p_tcb, UINT8 op_code, break; case GATT_RSP_FIND_INFO: - gatt_process_read_info_rsp(p_clcb, len, p_data); + gatt_process_read_info_rsp(p_tcb, p_clcb, op_code, len, p_data); break; case GATT_RSP_READ_BY_TYPE: @@ -1188,11 +1212,11 @@ void gatt_client_handle_server_rsp (tGATT_TCB *p_tcb, UINT8 op_code, case GATT_RSP_READ: case GATT_RSP_READ_BLOB: case GATT_RSP_READ_MULTI: - gatt_process_read_rsp(p_tcb, p_clcb, len, p_data); + gatt_process_read_rsp(p_tcb, p_clcb, op_code, len, p_data); break; case GATT_RSP_FIND_TYPE_VALUE: /* disc service with UUID */ - gatt_process_find_type_value_rsp(p_clcb, len, p_data); + gatt_process_find_type_value_rsp(p_tcb, p_clcb, len, p_data); break; case GATT_RSP_WRITE: diff --git a/stack/gatt/gatt_db.c b/stack/gatt/gatt_db.c index 268bc7d78..a1b0a8aa7 100644 --- a/stack/gatt/gatt_db.c +++ b/stack/gatt/gatt_db.c @@ -27,6 +27,7 @@ #if BLE_INCLUDED == TRUE #include "bt_trace.h" +#include "bt_utils.h" #include #include @@ -38,11 +39,11 @@ ** L O C A L F U N C T I O N P R O T O T Y P E S * *********************************************************************************/ static BOOLEAN allocate_svc_db_buf(tGATT_SVC_DB *p_db); -static void *allocate_attr_in_db(tGATT_SVC_DB *p_db, UINT16 uuid16, UINT8 *p_uuid128, tGATT_PERM perm); +static void *allocate_attr_in_db(tGATT_SVC_DB *p_db, tBT_UUID *p_uuid, tGATT_PERM perm); static BOOLEAN deallocate_attr_in_db(tGATT_SVC_DB *p_db, void *p_attr); static BOOLEAN copy_extra_byte_in_db(tGATT_SVC_DB *p_db, void **p_dst, UINT16 len); -static void gatts_db_add_service_declaration(tGATT_SVC_DB *p_db, tBT_UUID service, BOOLEAN is_pri); +static BOOLEAN gatts_db_add_service_declaration(tGATT_SVC_DB *p_db, tBT_UUID *p_service, BOOLEAN is_pri); static tGATT_STATUS gatts_send_app_read_request(tGATT_TCB *p_tcb, UINT8 op_code, UINT16 handle, UINT16 offset, UINT32 trans_id); @@ -58,7 +59,7 @@ static tGATT_STATUS gatts_send_app_read_request(tGATT_TCB *p_tcb, UINT8 op_code, ** Returns Status of te operation. ** *******************************************************************************/ -BOOLEAN gatts_init_service_db (tGATT_SVC_DB *p_db, tBT_UUID service, BOOLEAN is_pri, +BOOLEAN gatts_init_service_db (tGATT_SVC_DB *p_db, tBT_UUID *p_service, BOOLEAN is_pri, UINT16 s_hdl, UINT16 num_handle) { if (!allocate_svc_db_buf(p_db)) @@ -74,9 +75,7 @@ BOOLEAN gatts_init_service_db (tGATT_SVC_DB *p_db, tBT_UUID service, BOOLEAN is p_db->next_handle = s_hdl; p_db->end_handle = s_hdl + num_handle; - gatts_db_add_service_declaration(p_db, service, is_pri); - - return TRUE; + return gatts_db_add_service_declaration(p_db, p_service, is_pri); } /******************************************************************************* @@ -115,6 +114,7 @@ tBT_UUID * gatts_get_service_uuid (tGATT_SVC_DB *p_db) ** *******************************************************************************/ static tGATT_STATUS gatts_check_attr_readability(tGATT_ATTR16 *p_attr, + UINT16 offset, BOOLEAN read_long, tGATT_SEC_FLAG sec_flag, UINT8 key_size) @@ -122,6 +122,7 @@ static tGATT_STATUS gatts_check_attr_readability(tGATT_ATTR16 *p_attr, UINT16 min_key_size; tGATT_PERM perm = p_attr->permission; + UNUSED(offset); min_key_size = (((perm & GATT_ENCRYPT_KEY_SIZE_MASK) >> 12)); if (min_key_size != 0 ) { @@ -223,14 +224,14 @@ static tGATT_STATUS read_attr_value (void *p_attr, offset, read_long); - status = gatts_check_attr_readability((tGATT_ATTR16 *)p_attr, read_long, sec_flag, key_size); - - if (p_attr16->uuid_type == GATT_ATTR_UUID_TYPE_16) - uuid16 = p_attr16->uuid; + status = gatts_check_attr_readability((tGATT_ATTR16 *)p_attr, offset, read_long, sec_flag, key_size); if (status != GATT_SUCCESS) return status; + if (p_attr16->uuid_type == GATT_ATTR_UUID_TYPE_16) + uuid16 = p_attr16->uuid; + status = GATT_NO_RESOURCES; if (read_long && @@ -261,6 +262,12 @@ static tGATT_STATUS read_attr_value (void *p_attr, { UINT16_TO_STREAM(p, ((tGATT_ATTR16 *)(p_attr16->p_next))->uuid); } + /* convert a 32bits UUID to 128 bits */ + else if (((tGATT_ATTR32 *)(p_attr16->p_next))->uuid_type == GATT_ATTR_UUID_TYPE_32) + { + gatt_convert_uuid32_to_uuid128 (p, ((tGATT_ATTR32 *)(p_attr16->p_next))->uuid); + p += LEN_UUID_128; + } else { ARRAY_TO_STREAM (p, ((tGATT_ATTR128 *)(p_attr16->p_next))->uuid, LEN_UUID_128); @@ -271,13 +278,17 @@ static tGATT_STATUS read_attr_value (void *p_attr, } else if (uuid16 == GATT_UUID_INCLUDE_SERVICE) { - len = (p_attr16->p_value->incl_handle.service_type.len == 2) ? 6 : 4; + if (p_attr16->p_value->incl_handle.service_type.len == LEN_UUID_16) + len = 6; + else + len = 4; + if (mtu >= len) { UINT16_TO_STREAM(p, p_attr16->p_value->incl_handle.s_handle); UINT16_TO_STREAM(p, p_attr16->p_value->incl_handle.e_handle); - if (p_attr16->p_value->incl_handle.service_type.len == 2) + if (p_attr16->p_value->incl_handle.service_type.len == LEN_UUID_16) { UINT16_TO_STREAM(p, p_attr16->p_value->incl_handle.service_type.uu.uuid16); } @@ -345,6 +356,11 @@ tGATT_STATUS gatts_db_read_attr_value_by_type (tGATT_TCB *p_tcb, attr_uuid.len = LEN_UUID_16; attr_uuid.uu.uuid16 = p_attr->uuid; } + else if (p_attr->uuid_type == GATT_ATTR_UUID_TYPE_32) + { + attr_uuid.len = LEN_UUID_32; + attr_uuid.uu.uuid32 = ((tGATT_ATTR32 *)p_attr)->uuid; + } else { attr_uuid.len = LEN_UUID_128; @@ -436,6 +452,7 @@ UINT16 gatts_add_included_service (tGATT_SVC_DB *p_db, UINT16 s_handle, UINT16 e tBT_UUID service) { tGATT_ATTR16 *p_attr; + tBT_UUID uuid = {LEN_UUID_16, {GATT_UUID_INCLUDE_SERVICE}}; GATT_TRACE_DEBUG3("gatts_add_included_service: s_hdl = 0x%04x e_hdl = 0x%04x uuid = 0x%04x", s_handle, e_handle, service.uu.uuid16); @@ -446,7 +463,7 @@ UINT16 gatts_add_included_service (tGATT_SVC_DB *p_db, UINT16 s_handle, UINT16 e return 0; } - if ((p_attr = (tGATT_ATTR16 *) allocate_attr_in_db(p_db, GATT_UUID_INCLUDE_SERVICE, NULL, GATT_PERM_READ)) != NULL) + if ((p_attr = (tGATT_ATTR16 *) allocate_attr_in_db(p_db, &uuid, GATT_PERM_READ)) != NULL) { if (copy_extra_byte_in_db(p_db, (void **)&p_attr->p_value, sizeof(tGATT_INCL_SRVC))) { @@ -485,11 +502,11 @@ UINT16 gatts_add_characteristic (tGATT_SVC_DB *p_db, tGATT_PERM perm, tBT_UUID * p_char_uuid) { tGATT_ATTR16 *p_char_decl, *p_char_val; - UINT16 uuid16 = (p_char_uuid->len == LEN_UUID_16) ? p_char_uuid->uu.uuid16 : 0; + tBT_UUID uuid = {LEN_UUID_16, {GATT_UUID_CHAR_DECLARE}}; GATT_TRACE_DEBUG2("gatts_add_characteristic perm=0x%0x property=0x%0x", perm, property); - if ((p_char_decl = (tGATT_ATTR16 *)allocate_attr_in_db(p_db, GATT_UUID_CHAR_DECLARE, NULL, GATT_PERM_READ)) != NULL) + if ((p_char_decl = (tGATT_ATTR16 *)allocate_attr_in_db(p_db, &uuid, GATT_PERM_READ)) != NULL) { if (!copy_extra_byte_in_db(p_db, (void **)&p_char_decl->p_value, sizeof(tGATT_CHAR_DECL))) { @@ -497,7 +514,7 @@ UINT16 gatts_add_characteristic (tGATT_SVC_DB *p_db, tGATT_PERM perm, return 0; } - p_char_val = (tGATT_ATTR16 *)allocate_attr_in_db(p_db, uuid16, p_char_uuid->uu.uuid128, perm); + p_char_val = (tGATT_ATTR16 *)allocate_attr_in_db(p_db, p_char_uuid, perm); if (p_char_val == NULL) { @@ -578,14 +595,12 @@ UINT16 gatts_add_char_descr (tGATT_SVC_DB *p_db, tGATT_PERM perm, tBT_UUID * p_descr_uuid) { tGATT_ATTR16 *p_char_dscptr; - UINT16 uuid16 = (p_descr_uuid->len == LEN_UUID_16)? p_descr_uuid->uu.uuid16 : 0; GATT_TRACE_DEBUG1("gatts_add_char_descr uuid=0x%04x", p_descr_uuid->uu.uuid16); /* Add characteristic descriptors */ if ((p_char_dscptr = (tGATT_ATTR16 *)allocate_attr_in_db(p_db, - uuid16, - p_descr_uuid->uu.uuid128, + p_descr_uuid, perm)) == NULL) { @@ -695,7 +710,7 @@ tGATT_STATUS gatts_read_attr_perm_check(tGATT_SVC_DB *p_db, { if (p_attr->handle == handle) { - status = gatts_check_attr_readability (p_attr, + status = gatts_check_attr_readability (p_attr, 0, is_long, sec_flag, key_size); break; @@ -812,7 +827,8 @@ tGATT_STATUS gatts_write_attr_perm_check (tGATT_SVC_DB *p_db, UINT8 op_code, GATT_TRACE_ERROR0( "gatts_write_attr_perm_check - GATT_INSUF_KEY_SIZE"); } /* LE security mode 2 attribute */ - else if (perm & GATT_WRITE_SIGNED_PERM && op_code != GATT_SIGN_CMD_WRITE && !(sec_flag & GATT_SEC_FLAG_ENCRYPTED)) + else if (perm & GATT_WRITE_SIGNED_PERM && op_code != GATT_SIGN_CMD_WRITE && !(sec_flag & GATT_SEC_FLAG_ENCRYPTED) + && (perm & GATT_WRITE_ALLOWED) == 0) { status = GATT_INSUF_AUTHENTICATION; GATT_TRACE_ERROR0( "gatts_write_attr_perm_check - GATT_INSUF_AUTHENTICATION: LE security mode 2 required"); @@ -842,7 +858,8 @@ tGATT_STATUS gatts_write_attr_perm_check (tGATT_SVC_DB *p_db, UINT8 op_code, break; } } - else if (p_attr->uuid_type == GATT_ATTR_UUID_TYPE_128) + else if (p_attr->uuid_type == GATT_ATTR_UUID_TYPE_128 || + p_attr->uuid_type == GATT_ATTR_UUID_TYPE_32) { status = GATT_SUCCESS; } @@ -897,25 +914,32 @@ tGATT_STATUS gatts_write_attr_perm_check (tGATT_SVC_DB *p_db, UINT8 op_code, ** ** ** Parameter p_db : database pointer. +** p_uuid: pointer to attribute UUID ** service : type of attribute to be added. ** ** Returns pointer to the newly allocated attribute. ** *******************************************************************************/ -static void *allocate_attr_in_db(tGATT_SVC_DB *p_db, UINT16 uuid16, UINT8 *uuid128, tGATT_PERM perm) +static void *allocate_attr_in_db(tGATT_SVC_DB *p_db, tBT_UUID *p_uuid, tGATT_PERM perm) { tGATT_ATTR16 *p_attr16 = NULL, *p_last; + tGATT_ATTR32 *p_attr32 = NULL; tGATT_ATTR128 *p_attr128 = NULL; - UINT16 len = (uuid16 == 0) ? sizeof(tGATT_ATTR128): sizeof(tGATT_ATTR16); + UINT16 len = sizeof(tGATT_ATTR128); - GATT_TRACE_DEBUG1("allocate attr %d bytes ",len); - - if (uuid16 == GATT_ILLEGAL_UUID && uuid128 == NULL) + if (p_uuid == NULL) { GATT_TRACE_ERROR0("illegal UUID"); return NULL; } + if (p_uuid->len == LEN_UUID_16) + len = sizeof(tGATT_ATTR16); + else if (p_uuid->len == LEN_UUID_32) + len = sizeof(tGATT_ATTR32); + + GATT_TRACE_DEBUG1("allocate attr %d bytes ",len); + if (p_db->end_handle <= p_db->next_handle) { GATT_TRACE_DEBUG2("handle space full. handle_max = %d next_handle = %d", @@ -931,21 +955,25 @@ static void *allocate_attr_in_db(tGATT_SVC_DB *p_db, UINT16 uuid16, UINT8 *uuid1 return NULL; } } - + memset(p_db->p_free_mem, 0, len); p_attr16 = (tGATT_ATTR16 *) p_db->p_free_mem; - p_attr128 = (tGATT_ATTR128 *) p_db->p_free_mem; - - memset(p_attr16, 0, len); - if (uuid16 != GATT_ILLEGAL_UUID) + if (p_uuid->len == LEN_UUID_16 && p_uuid->uu.uuid16 != GATT_ILLEGAL_UUID) { p_attr16->uuid_type = GATT_ATTR_UUID_TYPE_16; - p_attr16->uuid = uuid16; + p_attr16->uuid = p_uuid->uu.uuid16; } - else + else if (p_uuid->len == LEN_UUID_32) { + p_attr32 = (tGATT_ATTR32 *) p_db->p_free_mem; + p_attr32->uuid_type = GATT_ATTR_UUID_TYPE_32; + p_attr32->uuid = p_uuid->uu.uuid32; + } + else if (p_uuid->len == LEN_UUID_128) + { + p_attr128 = (tGATT_ATTR128 *) p_db->p_free_mem; p_attr128->uuid_type = GATT_ATTR_UUID_TYPE_128; - memcpy(p_attr128->uuid, uuid128, LEN_UUID_128); + memcpy(p_attr128->uuid, p_uuid->uu.uuid128, LEN_UUID_128); } p_db->p_free_mem += len; @@ -970,9 +998,14 @@ static void *allocate_attr_in_db(tGATT_SVC_DB *p_db, UINT16 uuid16, UINT8 *uuid1 if (p_attr16->uuid_type == GATT_ATTR_UUID_TYPE_16) { - GATT_TRACE_DEBUG3("=====> handle = [0x%04x] uuid = [0x%04x] perm=0x%02x ", + GATT_TRACE_DEBUG3("=====> handle = [0x%04x] uuid16 = [0x%04x] perm=0x%02x ", p_attr16->handle, p_attr16->uuid, p_attr16->permission); } + else if (p_attr16->uuid_type == GATT_ATTR_UUID_TYPE_32) + { + GATT_TRACE_DEBUG3("=====> handle = [0x%04x] uuid32 = [0x%08x] perm=0x%02x ", + p_attr32->handle, p_attr32->uuid, p_attr32->permission); + } else { GATT_TRACE_DEBUG4("=====> handle = [0x%04x] uuid128 = [0x%02x:0x%02x] perm=0x%02x ", @@ -1151,21 +1184,44 @@ static tGATT_STATUS gatts_send_app_read_request(tGATT_TCB *p_tcb, UINT8 op_code, ** Returns void ** *******************************************************************************/ -static void gatts_db_add_service_declaration(tGATT_SVC_DB *p_db, tBT_UUID service, BOOLEAN is_pri) +static BOOLEAN gatts_db_add_service_declaration(tGATT_SVC_DB *p_db, tBT_UUID *p_service, BOOLEAN is_pri) { tGATT_ATTR16 *p_attr; - UINT16 service_type = is_pri ? GATT_UUID_PRI_SERVICE: GATT_UUID_SEC_SERVICE; + tBT_UUID uuid = {LEN_UUID_16, {0}}; + BOOLEAN rt = FALSE; GATT_TRACE_DEBUG0( "add_service_declaration"); + if (is_pri) + uuid.uu.uuid16 = GATT_UUID_PRI_SERVICE; + else + uuid.uu.uuid16 = GATT_UUID_SEC_SERVICE; + /* add service declration record */ - if ((p_attr = (tGATT_ATTR16 *)(allocate_attr_in_db(p_db, service_type, NULL, GATT_PERM_READ))) != NULL) + if ((p_attr = (tGATT_ATTR16 *)(allocate_attr_in_db(p_db, &uuid, GATT_PERM_READ))) != NULL) { if (copy_extra_byte_in_db (p_db, (void **)&p_attr->p_value, sizeof(tBT_UUID))) { - memcpy (&p_attr->p_value->uuid, &service, sizeof(tBT_UUID)); + if (p_service->len == LEN_UUID_16) + { + p_attr->p_value->uuid.len = LEN_UUID_16; + p_attr->p_value->uuid.uu.uuid16 = p_service->uu.uuid16; + } + else if (p_service->len == LEN_UUID_32) + { + p_attr->p_value->uuid.len = LEN_UUID_128; + gatt_convert_uuid32_to_uuid128(p_attr->p_value->uuid.uu.uuid128, p_service->uu.uuid32); + } + else + { + p_attr->p_value->uuid.len = LEN_UUID_128; + memcpy(p_attr->p_value->uuid.uu.uuid128, p_service->uu.uuid128, LEN_UUID_128); + } + rt = TRUE; } + } + return rt; } #endif /* BLE_INCLUDED */ diff --git a/stack/gatt/gatt_int.h b/stack/gatt/gatt_int.h index 1f81d6357..b6bb95c7c 100644 --- a/stack/gatt/gatt_int.h +++ b/stack/gatt/gatt_int.h @@ -21,8 +21,6 @@ #include "bt_target.h" -#if BLE_INCLUDED == TRUE - #include "bt_trace.h" #include "gatt_api.h" @@ -169,6 +167,7 @@ typedef union */ #define GATT_ATTR_UUID_TYPE_16 0 #define GATT_ATTR_UUID_TYPE_128 1 +#define GATT_ATTR_UUID_TYPE_32 2 typedef UINT8 tGATT_ATTR_UUID_TYPE; /* 16 bits UUID Attribute in server database @@ -184,6 +183,20 @@ typedef struct UINT16 uuid; } tGATT_ATTR16; +/* 32 bits UUID Attribute in server database +*/ +typedef struct +{ + void *p_next; /* pointer to the next attribute, + either tGATT_ATTR16, tGATT_ATTR32 or tGATT_ATTR128 */ + tGATT_ATTR_VALUE *p_value; + tGATT_ATTR_UUID_TYPE uuid_type; + tGATT_PERM permission; + UINT16 handle; + UINT32 uuid; +} tGATT_ATTR32; + + /* 128 bits UUID Attribute in server database */ typedef struct @@ -340,6 +353,7 @@ typedef struct BUFFER_Q pending_enc_clcb; /* pending encryption channel q */ tGATT_SEC_ACTION sec_act; BD_ADDR peer_bda; + tBT_TRANSPORT transport; UINT32 trans_id; UINT16 att_lcid; /* L2CAP channel ID for ATT */ @@ -400,6 +414,7 @@ typedef struct BOOLEAN in_use; TIMER_LIST_ENT rsp_timer_ent; /* peer response timer */ UINT8 retry_count; + } tGATT_CLCB; typedef struct @@ -454,6 +469,7 @@ typedef struct BOOLEAN in_use; BOOLEAN connected; BD_ADDR bda; + tBT_TRANSPORT transport; }tGATT_PROFILE_CLCB; typedef struct @@ -524,9 +540,9 @@ GATT_API extern void gatt_set_err_rsp(BOOLEAN enable, UINT8 req_op_code, UINT8 e extern void gatt_init (void); /* from gatt_main.c */ -extern BOOLEAN gatt_disconnect (BD_ADDR rem_bda); -extern BOOLEAN gatt_act_connect (tGATT_REG *p_reg, BD_ADDR bd_addr); -extern BOOLEAN gatt_connect (BD_ADDR rem_bda, tGATT_TCB *p_tcb); +extern BOOLEAN gatt_disconnect (tGATT_TCB *p_tcb); +extern BOOLEAN gatt_act_connect (tGATT_REG *p_reg, BD_ADDR bd_addr, tBT_TRANSPORT transport); +extern BOOLEAN gatt_connect (BD_ADDR rem_bda, tGATT_TCB *p_tcb, tBT_TRANSPORT transport); extern void gatt_data_process (tGATT_TCB *p_tcb, BT_HDR *p_buf); extern void gatt_update_app_use_link_flag ( tGATT_IF gatt_if, tGATT_TCB *p_tcb, BOOLEAN is_add, BOOLEAN check_acl_link); @@ -541,9 +557,8 @@ extern void gatt_add_a_bonded_dev_for_srv_chg (BD_ADDR bda); /* from gatt_attr.c */ extern UINT16 gatt_profile_find_conn_id_by_bd_addr(BD_ADDR bda); -extern tGATT_PROFILE_CLCB *gatt_profile_find_clcb_by_bd_addr(BD_ADDR bda); extern BOOLEAN gatt_profile_clcb_dealloc (UINT16 conn_id); -extern tGATT_PROFILE_CLCB *gatt_profile_clcb_alloc (UINT16 conn_id, BD_ADDR bda); +extern tGATT_PROFILE_CLCB *gatt_profile_clcb_alloc (UINT16 conn_id, BD_ADDR bda, tBT_TRANSPORT transport); /* Functions provided by att_protocol.c */ @@ -558,7 +573,8 @@ extern UINT32 gatt_add_sdp_record (tBT_UUID *p_uuid, UINT16 start_hdl, UINT16 en extern BOOLEAN gatt_parse_uuid_from_cmd(tBT_UUID *p_uuid, UINT16 len, UINT8 **p_data); extern UINT8 gatt_build_uuid_to_stream(UINT8 **p_dst, tBT_UUID uuid); extern BOOLEAN gatt_uuid_compare(tBT_UUID src, tBT_UUID tar); -extern void gatt_sr_get_sec_info(BD_ADDR rem_bda, BOOLEAN le_conn, UINT8 *p_sec_flag, UINT8 *p_key_size); +extern void gatt_convert_uuid32_to_uuid128(UINT8 uuid_128[LEN_UUID_128], UINT32 uuid_32); +extern void gatt_sr_get_sec_info(BD_ADDR rem_bda, tBT_TRANSPORT transport, UINT8 *p_sec_flag, UINT8 *p_key_size); extern void gatt_start_rsp_timer(UINT16 clcb_idx); extern void gatt_start_conf_timer(tGATT_TCB *p_tcb); extern void gatt_rsp_timeout(TIMER_LIST_ENT *p_tle); @@ -573,13 +589,13 @@ extern tGATTS_PENDING_NEW_SRV_START *gatt_sr_is_new_srv_chg(tBT_UUID *p_app_uuid extern BOOLEAN gatt_is_srv_chg_ind_pending (tGATT_TCB *p_tcb); extern tGATTS_SRV_CHG *gatt_is_bda_in_the_srv_chg_clt_list (BD_ADDR bda); -extern BOOLEAN gatt_find_the_connected_bda(UINT8 start_idx, BD_ADDR bda, UINT8 *p_found_idx); +extern BOOLEAN gatt_find_the_connected_bda(UINT8 start_idx, BD_ADDR bda, UINT8 *p_found_idx, tBT_TRANSPORT *p_transport); extern void gatt_set_srv_chg(void); extern void gatt_delete_dev_from_srv_chg_clt_list(BD_ADDR bd_addr); extern tGATT_VALUE *gatt_add_pending_ind(tGATT_TCB *p_tcb, tGATT_VALUE *p_ind); extern tGATTS_PENDING_NEW_SRV_START *gatt_add_pending_new_srv_start( tGATTS_HNDL_RANGE *p_new_srv_start); extern void gatt_free_srvc_db_buffer_app_id(tBT_UUID *p_app_id); -extern void gatt_update_listen_mode(void); +extern BOOLEAN gatt_update_listen_mode(void); /* reserved handle list */ extern tGATT_HDL_LIST_ELEM *gatt_find_hdl_buffer_by_app_id (tBT_UUID *p_app_uuid128, tBT_UUID *p_svc_uuid, UINT16 svc_inst); @@ -635,16 +651,16 @@ extern BOOLEAN gatt_find_app_hold_link(tGATT_TCB *p_tcb, UINT8 start_idx, UINT8 extern UINT8 gatt_num_apps_hold_link(tGATT_TCB *p_tcb); extern UINT8 gatt_num_clcb_by_bd_addr(BD_ADDR bda); extern tGATT_TCB * gatt_find_tcb_by_cid(UINT16 lcid); -extern tGATT_TCB * gatt_allocate_tcb_by_bdaddr(BD_ADDR bda); +extern tGATT_TCB * gatt_allocate_tcb_by_bdaddr(BD_ADDR bda, tBT_TRANSPORT transport); extern tGATT_TCB * gatt_get_tcb_by_idx(UINT8 tcb_idx); -extern tGATT_TCB * gatt_find_tcb_by_addr(BD_ADDR bda); - +extern tGATT_TCB * gatt_find_tcb_by_addr(BD_ADDR bda, tBT_TRANSPORT transport); +extern BOOLEAN gatt_send_ble_burst_data (BD_ADDR remote_bda, BT_HDR *p_buf); /* GATT client functions */ extern void gatt_dequeue_sr_cmd (tGATT_TCB *p_tcb); extern UINT8 gatt_send_write_msg(tGATT_TCB *p_tcb, UINT16 clcb_idx, UINT8 op_code, UINT16 handle, UINT16 len, UINT16 offset, UINT8 *p_data); -extern void gatt_cleanup_upon_disc(BD_ADDR bda, UINT16 reason); +extern void gatt_cleanup_upon_disc(BD_ADDR bda, UINT16 reason, tBT_TRANSPORT transport); extern void gatt_end_operation(tGATT_CLCB *p_clcb, tGATT_STATUS status, void *p_data); extern void gatt_act_discovery(tGATT_CLCB *p_clcb); @@ -667,7 +683,7 @@ extern tGATT_SEC_ACTION gatt_get_sec_act(tGATT_TCB *p_tcb); extern void gatt_set_sec_act(tGATT_TCB *p_tcb, tGATT_SEC_ACTION sec_act); /* gatt_db.c */ -extern BOOLEAN gatts_init_service_db (tGATT_SVC_DB *p_db, tBT_UUID service, BOOLEAN is_pri, UINT16 s_hdl, UINT16 num_handle); +extern BOOLEAN gatts_init_service_db (tGATT_SVC_DB *p_db, tBT_UUID *p_service, BOOLEAN is_pri, UINT16 s_hdl, UINT16 num_handle); extern UINT16 gatts_add_included_service (tGATT_SVC_DB *p_db, UINT16 s_handle, UINT16 e_handle, tBT_UUID service); extern UINT16 gatts_add_characteristic (tGATT_SVC_DB *p_db, tGATT_PERM perm, tGATT_CHAR_PROP property, tBT_UUID *p_char_uuid); extern UINT16 gatts_add_char_descr (tGATT_SVC_DB *p_db, tGATT_PERM perm, tBT_UUID *p_dscp_uuid); @@ -684,4 +700,4 @@ extern tBT_UUID * gatts_get_service_uuid (tGATT_SVC_DB *p_db); extern void gatt_reset_bgdev_list(void); #endif -#endif /* BLE_INCLUDED */ + diff --git a/stack/gatt/gatt_main.c b/stack/gatt/gatt_main.c index d5e017b55..59c6759d9 100644 --- a/stack/gatt/gatt_main.c +++ b/stack/gatt/gatt_main.c @@ -44,7 +44,7 @@ /********************************************************************************/ /* L O C A L F U N C T I O N P R O T O T Y P E S */ /********************************************************************************/ -static void gatt_le_connect_cback (BD_ADDR bd_addr, BOOLEAN connected, UINT16 reason); +static void gatt_le_connect_cback (BD_ADDR bd_addr, BOOLEAN connected, UINT16 reason, tBT_TRANSPORT transport); static void gatt_le_data_ind (BD_ADDR bd_addr, BT_HDR *p_buf); static void gatt_l2cif_connect_ind_cback (BD_ADDR bd_addr, UINT16 l2cap_cid, UINT16 psm, UINT8 l2cap_id); @@ -143,15 +143,14 @@ void gatt_init (void) ** Returns TRUE if connection is started, otherwise return FALSE. ** *******************************************************************************/ -BOOLEAN gatt_connect (BD_ADDR rem_bda, tGATT_TCB *p_tcb) +BOOLEAN gatt_connect (BD_ADDR rem_bda, tGATT_TCB *p_tcb, tBT_TRANSPORT transport) { BOOLEAN gatt_ret = FALSE; if (gatt_get_ch_state(p_tcb) != GATT_CH_OPEN) gatt_set_ch_state(p_tcb, GATT_CH_CONN); - /* select the physical link for GATT connection */ - if (BTM_UseLeLink(rem_bda)) + if (transport == BT_TRANSPORT_LE) { p_tcb->att_lcid = L2CAP_ATT_CID; gatt_ret = L2CA_ConnectFixedChnl (L2CAP_ATT_CID, rem_bda); @@ -171,15 +170,14 @@ BOOLEAN gatt_connect (BD_ADDR rem_bda, tGATT_TCB *p_tcb) ** ** Description This function is called to disconnect to an ATT device. ** -** Parameter rem_bda: remote device address to disconnect from. +** Parameter p_tcb: pointer to the TCB to disconnect. ** ** Returns TRUE: if connection found and to be disconnected; otherwise ** return FALSE. ** *******************************************************************************/ -BOOLEAN gatt_disconnect (BD_ADDR rem_bda) +BOOLEAN gatt_disconnect (tGATT_TCB *p_tcb) { - tGATT_TCB *p_tcb = gatt_find_tcb_by_addr(rem_bda); BOOLEAN ret = FALSE; tGATT_CH_STATE ch_state; GATT_TRACE_DEBUG0 ("gatt_disconnect "); @@ -194,12 +192,12 @@ BOOLEAN gatt_disconnect (BD_ADDR rem_bda) if (ch_state == GATT_CH_OPEN) { /* only LCB exist between remote device and local */ - ret = L2CA_RemoveFixedChnl (L2CAP_ATT_CID, rem_bda); + ret = L2CA_RemoveFixedChnl (L2CAP_ATT_CID, p_tcb->peer_bda); } else { gatt_set_ch_state(p_tcb, GATT_CH_CLOSING); - ret = L2CA_CancelBleConnectReq (rem_bda); + ret = L2CA_CancelBleConnectReq (p_tcb->peer_bda); } } else @@ -286,13 +284,14 @@ void gatt_update_app_use_link_flag (tGATT_IF gatt_if, tGATT_TCB *p_tcb, BOOLEAN if (check_acl_link && p_tcb && - (BTM_GetHCIConnHandle(p_tcb->peer_bda) != GATT_INVALID_ACL_HANDLE)) + p_tcb->att_lcid == L2CAP_ATT_CID && /* only update link idle timer for fixed channel */ + (BTM_GetHCIConnHandle(p_tcb->peer_bda, p_tcb->transport) != GATT_INVALID_ACL_HANDLE)) { if (is_add) { GATT_TRACE_DEBUG0("GATT disables link idle timer"); /* acl link is connected disable the idle timeout */ - GATT_SetIdleTimeout(p_tcb->peer_bda, GATT_LINK_NO_IDLE_TIMEOUT); + GATT_SetIdleTimeout(p_tcb->peer_bda, GATT_LINK_NO_IDLE_TIMEOUT, p_tcb->transport); } else { @@ -301,7 +300,7 @@ void gatt_update_app_use_link_flag (tGATT_IF gatt_if, tGATT_TCB *p_tcb, BOOLEAN /* acl link is connected but no application needs to use the link so set the timeout value to GATT_LINK_IDLE_TIMEOUT_WHEN_NO_APP seconds */ GATT_TRACE_DEBUG1("GATT starts link idle timer =%d sec", GATT_LINK_IDLE_TIMEOUT_WHEN_NO_APP); - GATT_SetIdleTimeout(p_tcb->peer_bda, GATT_LINK_IDLE_TIMEOUT_WHEN_NO_APP); + GATT_SetIdleTimeout(p_tcb->peer_bda, GATT_LINK_IDLE_TIMEOUT_WHEN_NO_APP, p_tcb->transport); } } @@ -317,25 +316,22 @@ void gatt_update_app_use_link_flag (tGATT_IF gatt_if, tGATT_TCB *p_tcb, BOOLEAN ** Returns void. ** *******************************************************************************/ -BOOLEAN gatt_act_connect (tGATT_REG *p_reg, BD_ADDR bd_addr) +BOOLEAN gatt_act_connect (tGATT_REG *p_reg, BD_ADDR bd_addr, tBT_TRANSPORT transport) { BOOLEAN ret = FALSE; tGATT_TCB *p_tcb; UINT8 st; - GATT_TRACE_DEBUG0("gatt_act_connect"); - - if ((p_tcb = gatt_find_tcb_by_addr(bd_addr)) != NULL) + if ((p_tcb = gatt_find_tcb_by_addr(bd_addr, transport)) != NULL) { ret = TRUE; st = gatt_get_ch_state(p_tcb); /* before link down, another app try to open a GATT connection */ if(st == GATT_CH_OPEN && gatt_num_apps_hold_link(p_tcb) == 0 && - /* only connection on fix channel when the l2cap channel is already open */ - p_tcb->att_lcid == L2CAP_ATT_CID ) + transport == BT_TRANSPORT_LE ) { - if (!gatt_connect(bd_addr, p_tcb)) + if (!gatt_connect(bd_addr, p_tcb, transport)) ret = FALSE; } else if(st == GATT_CH_CLOSING) @@ -346,9 +342,9 @@ BOOLEAN gatt_act_connect (tGATT_REG *p_reg, BD_ADDR bd_addr) } else { - if ((p_tcb = gatt_allocate_tcb_by_bdaddr(bd_addr)) != NULL) + if ((p_tcb = gatt_allocate_tcb_by_bdaddr(bd_addr, transport)) != NULL) { - if (!gatt_connect(bd_addr, p_tcb)) + if (!gatt_connect(bd_addr, p_tcb, transport)) { GATT_TRACE_ERROR0("gatt_connect failed"); memset(p_tcb, 0, sizeof(tGATT_TCB)); @@ -380,19 +376,22 @@ BOOLEAN gatt_act_connect (tGATT_REG *p_reg, BD_ADDR bd_addr) ** connected (conn = TRUE)/disconnected (conn = FALSE). ** *******************************************************************************/ -static void gatt_le_connect_cback (BD_ADDR bd_addr, BOOLEAN connected, UINT16 reason) +static void gatt_le_connect_cback (BD_ADDR bd_addr, BOOLEAN connected, + UINT16 reason, tBT_TRANSPORT transport) { - tGATT_TCB *p_tcb = gatt_find_tcb_by_addr(bd_addr); - + tGATT_TCB *p_tcb = gatt_find_tcb_by_addr(bd_addr, transport); BOOLEAN check_srv_chg = FALSE; tGATTS_SRV_CHG *p_srv_chg_clt=NULL; + /* ignore all fixed channel connect/disconnect on BR/EDR link for GATT */ + if (transport == BT_TRANSPORT_BR_EDR) + return; + GATT_TRACE_DEBUG3 ("GATT ATT protocol channel with BDA: %08x%04x is %s", (bd_addr[0]<<24)+(bd_addr[1]<<16)+(bd_addr[2]<<8)+bd_addr[3], (bd_addr[4]<<8)+bd_addr[5], (connected) ? "connected" : "disconnected"); - if ((p_srv_chg_clt = gatt_is_bda_in_the_srv_chg_clt_list(bd_addr)) != NULL) { check_srv_chg = TRUE; @@ -405,11 +404,6 @@ static void gatt_le_connect_cback (BD_ADDR bd_addr, BOOLEAN connected, UINT16 re if (connected) { - GATT_TRACE_DEBUG1("connected is TRUE reason=%d",reason ); - /* BR/EDR lik, ignore this callback */ - if (reason == 0) - return; - /* do we have a channel initiating a connection? */ if (p_tcb) { @@ -426,9 +420,10 @@ static void gatt_le_connect_cback (BD_ADDR bd_addr, BOOLEAN connected, UINT16 re } } /* this is incoming connection or background connection callback */ + else { - if ((p_tcb = gatt_allocate_tcb_by_bdaddr(bd_addr)) != NULL) + if ((p_tcb = gatt_allocate_tcb_by_bdaddr(bd_addr, BT_TRANSPORT_LE)) != NULL) { p_tcb->att_lcid = L2CAP_ATT_CID; @@ -450,7 +445,7 @@ static void gatt_le_connect_cback (BD_ADDR bd_addr, BOOLEAN connected, UINT16 re } else { - gatt_cleanup_upon_disc(bd_addr, reason); + gatt_cleanup_upon_disc(bd_addr, reason, transport); GATT_TRACE_DEBUG0 ("ATT disconnected"); } } @@ -475,7 +470,7 @@ static void gatt_le_data_ind (BD_ADDR bd_addr, BT_HDR *p_buf) tGATT_TCB *p_tcb; /* Find CCB based on bd addr */ - if ((p_tcb = gatt_find_tcb_by_addr (bd_addr)) != NULL && + if ((p_tcb = gatt_find_tcb_by_addr (bd_addr, BT_TRANSPORT_LE)) != NULL && gatt_get_ch_state(p_tcb) >= GATT_CH_OPEN) { gatt_data_process(p_tcb, p_buf); @@ -508,7 +503,7 @@ static void gatt_l2cif_connect_ind_cback (BD_ADDR bd_addr, UINT16 lcid, UINT16 /* do we already have a control channel for this peer? */ UINT8 result = L2CAP_CONN_OK; tL2CAP_CFG_INFO cfg; - tGATT_TCB *p_tcb = gatt_find_tcb_by_addr(bd_addr); + tGATT_TCB *p_tcb = gatt_find_tcb_by_addr(bd_addr, BT_TRANSPORT_BR_EDR); UNUSED(psm); GATT_TRACE_ERROR1("Connection indication cid = %d", lcid); @@ -516,7 +511,7 @@ static void gatt_l2cif_connect_ind_cback (BD_ADDR bd_addr, UINT16 lcid, UINT16 if (p_tcb == NULL) { /* allocate tcb */ - if ((p_tcb = gatt_allocate_tcb_by_bdaddr(bd_addr)) == NULL) + if ((p_tcb = gatt_allocate_tcb_by_bdaddr(bd_addr, BT_TRANSPORT_BR_EDR)) == NULL) { /* no tcb available, reject L2CAP connection */ result = L2CAP_CONN_NO_RESOURCES; @@ -586,7 +581,7 @@ void gatt_l2cif_connect_cfm_cback(UINT16 lcid, UINT16 result) /* else initiating connection failure */ else { - gatt_cleanup_upon_disc(p_tcb->peer_bda, GATT_CONN_L2C_FAILURE); + gatt_cleanup_upon_disc(p_tcb->peer_bda, result, GATT_TRANSPORT_BR_EDR); } } else /* wrong state, disconnect it */ @@ -701,11 +696,8 @@ void gatt_l2cif_config_ind_cback(UINT16 lcid, tL2CAP_CFG_INFO *p_cfg) } else { - if (btm_sec_is_a_bonded_dev(p_tcb->peer_bda) && - btm_sec_is_le_capable_dev(p_tcb->peer_bda)) - { + if (btm_sec_is_a_bonded_dev(p_tcb->peer_bda)) gatt_add_a_bonded_dev_for_srv_chg(p_tcb->peer_bda); - } } /* send callback */ @@ -738,20 +730,17 @@ void gatt_l2cif_disconnect_ind_cback(UINT16 lcid, BOOLEAN ack_needed) /* send L2CAP disconnect response */ L2CA_DisconnectRsp(lcid); } - if (gatt_is_bda_in_the_srv_chg_clt_list(p_tcb->peer_bda) == NULL) { - if (btm_sec_is_a_bonded_dev(p_tcb->peer_bda) && - btm_sec_is_le_capable_dev(p_tcb->peer_bda)) + if (btm_sec_is_a_bonded_dev(p_tcb->peer_bda)) gatt_add_a_bonded_dev_for_srv_chg(p_tcb->peer_bda); } - /* if ACL link is still up, no reason is logged, l2cap is disconnect from peer */ - if ((reason = L2CA_GetDisconnectReason(p_tcb->peer_bda)) == 0) + if ((reason = L2CA_GetDisconnectReason(p_tcb->peer_bda, p_tcb->transport)) == 0) reason = GATT_CONN_TERMINATE_PEER_USER; /* send disconnect callback */ - gatt_cleanup_upon_disc(p_tcb->peer_bda, reason); + gatt_cleanup_upon_disc(p_tcb->peer_bda, reason, GATT_TRANSPORT_BR_EDR); } } @@ -777,17 +766,16 @@ void gatt_l2cif_disconnect_cfm_cback(UINT16 lcid, UINT16 result) /* If the device is not in the service changed client list, add it... */ if (gatt_is_bda_in_the_srv_chg_clt_list(p_tcb->peer_bda) == NULL) { - if (btm_sec_is_a_bonded_dev(p_tcb->peer_bda) && - btm_sec_is_le_capable_dev(p_tcb->peer_bda)) + if (btm_sec_is_a_bonded_dev(p_tcb->peer_bda)) gatt_add_a_bonded_dev_for_srv_chg(p_tcb->peer_bda); } /* send disconnect callback */ /* if ACL link is still up, no reason is logged, l2cap is disconnect from peer */ - if ((reason = L2CA_GetDisconnectReason(p_tcb->peer_bda)) == 0) + if ((reason = L2CA_GetDisconnectReason(p_tcb->peer_bda, p_tcb->transport)) == 0) reason = GATT_CONN_TERMINATE_LOCAL_HOST; - gatt_cleanup_upon_disc(p_tcb->peer_bda, reason); + gatt_cleanup_upon_disc(p_tcb->peer_bda, reason, GATT_TRANSPORT_BR_EDR); } } @@ -846,16 +834,17 @@ static void gatt_send_conn_cback(tGATT_TCB *p_tcb) if (p_reg->app_cb.p_conn_cb) { conn_id = GATT_CREATE_CONN_ID(p_tcb->tcb_idx, p_reg->gatt_if); - (*p_reg->app_cb.p_conn_cb)(p_reg->gatt_if, p_tcb->peer_bda, conn_id, TRUE, 0); + (*p_reg->app_cb.p_conn_cb)(p_reg->gatt_if, p_tcb->peer_bda, conn_id, + TRUE, 0, p_tcb->transport); } } } - if (gatt_num_apps_hold_link(p_tcb)) + if (gatt_num_apps_hold_link(p_tcb) && p_tcb->att_lcid == L2CAP_ATT_CID ) { /* disable idle timeout if one or more clients are holding the link disable the idle timer */ - GATT_SetIdleTimeout(p_tcb->peer_bda, GATT_LINK_NO_IDLE_TIMEOUT); + GATT_SetIdleTimeout(p_tcb->peer_bda, GATT_LINK_NO_IDLE_TIMEOUT, p_tcb->transport); } } @@ -894,7 +883,6 @@ void gatt_data_process (tGATT_TCB *p_tcb, BT_HDR *p_buf) if (op_code == GATT_SIGN_CMD_WRITE) { gatt_verify_signature(p_tcb, p_buf); - return; } else { @@ -1068,6 +1056,7 @@ void gatt_proc_srv_chg (void) BD_ADDR bda; BOOLEAN srv_chg_ind_pending=FALSE; tGATT_TCB *p_tcb; + tBT_TRANSPORT transport; GATT_TRACE_DEBUG0 ("gatt_proc_srv_chg"); @@ -1075,7 +1064,7 @@ void gatt_proc_srv_chg (void) { gatt_set_srv_chg(); start_idx =0; - while (gatt_find_the_connected_bda(start_idx, bda, &found_idx)) + while (gatt_find_the_connected_bda(start_idx, bda, &found_idx, &transport)) { p_tcb = &gatt_cb.tcb[found_idx];; srv_chg_ind_pending = gatt_is_srv_chg_ind_pending(p_tcb); diff --git a/stack/gatt/gatt_sr.c b/stack/gatt/gatt_sr.c index c006dd263..226aad0dc 100644 --- a/stack/gatt/gatt_sr.c +++ b/stack/gatt/gatt_sr.c @@ -328,7 +328,7 @@ tGATT_STATUS gatt_sr_process_app_rsp (tGATT_TCB *p_tcb, tGATT_IF gatt_if, ** Returns void ** *******************************************************************************/ -static void gatt_process_exec_write_req (tGATT_TCB *p_tcb, UINT8 op_code, UINT8 *p_data) +void gatt_process_exec_write_req (tGATT_TCB *p_tcb, UINT8 op_code, UINT16 len, UINT8 *p_data) { UINT8 *p = p_data, flag, i = 0; UINT32 trans_id = 0; @@ -336,11 +336,13 @@ static void gatt_process_exec_write_req (tGATT_TCB *p_tcb, UINT8 op_code, UINT8 tGATT_IF gatt_if; UINT16 conn_id; + UNUSED(len); + #if GATT_CONFORMANCE_TESTING == TRUE if (gatt_cb.enable_err_rsp && gatt_cb.req_op_code == op_code) { - GATT_TRACE_DEBUG2("conf test forced err rsp for %s error status=%d", - __FUNCTION__,gatt_cb.err_status); + GATT_TRACE_DEBUG1("Conformance tst: forced err rspv for Execute Write: error status=%d", + gatt_cb.err_status); gatt_send_error_rsp (p_tcb, gatt_cb.err_status, gatt_cb.req_op_code, gatt_cb.handle, FALSE); @@ -409,7 +411,7 @@ void gatt_process_read_multi_req (tGATT_TCB *p_tcb, UINT8 op_code, UINT16 len, U p_tcb->sr_cmd.multi_req.num_handles = 0; gatt_sr_get_sec_info(p_tcb->peer_bda, - (BOOLEAN)(p_tcb->att_lcid == L2CAP_ATT_CID), + p_tcb->transport, &sec_flag, &key_size); @@ -527,7 +529,7 @@ void gatt_process_read_multi_req (tGATT_TCB *p_tcb, UINT8 op_code, UINT16 len, U *******************************************************************************/ static tGATT_STATUS gatt_build_primary_service_rsp (BT_HDR *p_msg, tGATT_TCB *p_tcb, UINT8 op_code, UINT16 s_hdl, - UINT16 e_hdl, tBT_UUID value) + UINT16 e_hdl, UINT8 *p_data, tBT_UUID value) { tGATT_STATUS status = GATT_NOT_FOUND; UINT8 handle_len =4, *p ; @@ -536,6 +538,8 @@ static tGATT_STATUS gatt_build_primary_service_rsp (BT_HDR *p_msg, tGATT_TCB *p_ tGATT_SRV_LIST_ELEM *p_srv=NULL; tBT_UUID *p_uuid; + UNUSED(p_data); + p = (UINT8 *)(p_msg + 1) + L2CAP_MIN_OFFSET; p_srv = p_list->p_first; @@ -643,7 +647,7 @@ static tGATT_STATUS gatt_build_find_info_rsp(tGATT_SR_REG *p_rcb, BT_HDR *p_msg, if (p_attr->handle >= s_hdl) { if (p_msg->offset == 0) - p_msg->offset = (p_attr->uuid_type == GATT_ATTR_UUID_TYPE_128) ? GATT_INFO_TYPE_PAIR_128 : GATT_INFO_TYPE_PAIR_16; + p_msg->offset = (p_attr->uuid_type == GATT_ATTR_UUID_TYPE_16) ? GATT_INFO_TYPE_PAIR_16 : GATT_INFO_TYPE_PAIR_128; if (len >= info_pair_len[p_msg->offset - 1]) { @@ -652,12 +656,17 @@ static tGATT_STATUS gatt_build_find_info_rsp(tGATT_SR_REG *p_rcb, BT_HDR *p_msg, UINT16_TO_STREAM(p, p_attr->handle); UINT16_TO_STREAM(p, p_attr->uuid); } - else if (p_msg->offset == GATT_INFO_TYPE_PAIR_128 && - p_attr->uuid_type == GATT_ATTR_UUID_TYPE_128 ) + else if (p_msg->offset == GATT_INFO_TYPE_PAIR_128 && p_attr->uuid_type == GATT_ATTR_UUID_TYPE_128 ) { UINT16_TO_STREAM(p, p_attr->handle); ARRAY_TO_STREAM (p, ((tGATT_ATTR128 *) p_attr)->uuid, LEN_UUID_128); } + else if (p_msg->offset == GATT_INFO_TYPE_PAIR_128 && p_attr->uuid_type == GATT_ATTR_UUID_TYPE_32) + { + UINT16_TO_STREAM(p, p_attr->handle); + gatt_convert_uuid32_to_uuid128(p, ((tGATT_ATTR32 *) p_attr)->uuid); + p += LEN_UUID_128; + } else { GATT_TRACE_ERROR0("format mismatch"); @@ -764,6 +773,7 @@ void gatts_process_primary_service_req(tGATT_TCB *p_tcb, UINT8 op_code, UINT16 l BT_HDR *p_msg = NULL; UINT16 msg_len = (UINT16)(sizeof(BT_HDR) + p_tcb->payload_size + L2CAP_MIN_OFFSET); + memset (&value, 0, sizeof(tBT_UUID)); reason = gatts_validate_packet_format(op_code, &len, &p_data, &uuid, &s_hdl, &e_hdl); if (reason == GATT_SUCCESS) @@ -786,7 +796,7 @@ void gatts_process_primary_service_req(tGATT_TCB *p_tcb, UINT8 op_code, UINT16 l else { memset(p_msg, 0, msg_len); - reason = gatt_build_primary_service_rsp (p_msg, p_tcb, op_code, s_hdl, e_hdl, value); + reason = gatt_build_primary_service_rsp (p_msg, p_tcb, op_code, s_hdl, e_hdl, p_data, value); } } } @@ -1025,7 +1035,7 @@ void gatts_process_read_by_type_req(tGATT_TCB *p_tcb, UINT8 op_code, UINT16 len, p_rcb->e_hdl < s_hdl)) { gatt_sr_get_sec_info(p_tcb->peer_bda, - (BOOLEAN)(p_tcb->att_lcid == L2CAP_ATT_CID), + p_tcb->transport, &sec_flag, &key_size); @@ -1120,7 +1130,7 @@ void gatts_process_write_req (tGATT_TCB *p_tcb, UINT8 i_rcb, UINT16 handle, } gatt_sr_get_sec_info(p_tcb->peer_bda, - (BOOLEAN)(p_tcb->att_lcid == L2CAP_ATT_CID), + p_tcb->transport, &sec_flag, &key_size); @@ -1173,7 +1183,7 @@ void gatts_process_write_req (tGATT_TCB *p_tcb, UINT8 i_rcb, UINT16 handle, ** *******************************************************************************/ static void gatts_process_read_req(tGATT_TCB *p_tcb, tGATT_SR_REG *p_rcb, UINT8 op_code, - UINT16 handle, UINT8 *p_data) + UINT16 handle, UINT16 len, UINT8 *p_data) { UINT16 buf_len = (UINT16)(sizeof(BT_HDR) + p_tcb->payload_size + L2CAP_MIN_OFFSET); tGATT_STATUS reason; @@ -1181,6 +1191,7 @@ static void gatts_process_read_req(tGATT_TCB *p_tcb, tGATT_SR_REG *p_rcb, UINT8 UINT8 sec_flag, key_size, *p; UINT16 offset = 0, value_len = 0; + UNUSED (len); if ((p_msg = (BT_HDR *)GKI_getbuf(buf_len)) == NULL) { GATT_TRACE_ERROR0("gatts_process_find_info failed. no resources."); @@ -1199,7 +1210,7 @@ static void gatts_process_read_req(tGATT_TCB *p_tcb, tGATT_SR_REG *p_rcb, UINT8 buf_len = p_tcb->payload_size - 1; gatt_sr_get_sec_info(p_tcb->peer_bda, - (BOOLEAN)(p_tcb->att_lcid == L2CAP_ATT_CID), + p_tcb->transport, &sec_flag, &key_size); @@ -1289,7 +1300,7 @@ void gatts_process_attribute_req (tGATT_TCB *p_tcb, UINT8 op_code, { case GATT_REQ_READ: /* read char/char descriptor value */ case GATT_REQ_READ_BLOB: - gatts_process_read_req(p_tcb, p_rcb, op_code, handle, p); + gatts_process_read_req(p_tcb, p_rcb, op_code, handle, len, p); break; case GATT_REQ_WRITE: /* write char/char descriptor value */ @@ -1506,7 +1517,7 @@ void gatt_server_handle_client_req (tGATT_TCB *p_tcb, UINT8 op_code, break; case GATT_REQ_EXEC_WRITE: - gatt_process_exec_write_req (p_tcb, op_code, p_data); + gatt_process_exec_write_req (p_tcb, op_code, len, p_data); break; case GATT_REQ_READ_MULTI: diff --git a/stack/gatt/gatt_utils.c b/stack/gatt/gatt_utils.c index 978c88ce5..d3d4c924d 100644 --- a/stack/gatt/gatt_utils.c +++ b/stack/gatt/gatt_utils.c @@ -705,7 +705,8 @@ BOOLEAN gatt_remove_an_item_from_list(tGATT_HDL_LIST_INFO *p_list, tGATT_HDL_LIS ** Returns TRUE if found ** *******************************************************************************/ -BOOLEAN gatt_find_the_connected_bda(UINT8 start_idx, BD_ADDR bda, UINT8 *p_found_idx) +BOOLEAN gatt_find_the_connected_bda(UINT8 start_idx, BD_ADDR bda, UINT8 *p_found_idx, + tBT_TRANSPORT *p_transport) { UINT8 i; BOOLEAN found = FALSE; @@ -717,6 +718,7 @@ BOOLEAN gatt_find_the_connected_bda(UINT8 start_idx, BD_ADDR bda, UINT8 *p_found { memcpy( bda, gatt_cb.tcb[i].peer_bda, BD_ADDR_LEN); *p_found_idx = i; + *p_transport = gatt_cb.tcb[i].transport; found = TRUE; GATT_TRACE_DEBUG6("gatt_find_the_connected_bda bda :%02x-%02x-%02x-%02x-%02x-%02x", bda[0], bda[1], bda[2], bda[3], bda[4], bda[5]); @@ -833,19 +835,19 @@ BOOLEAN gatt_is_bda_connected(BD_ADDR bda) ** Returns GATT_INDEX_INVALID if not found. Otherwise index to the tcb. ** *******************************************************************************/ -UINT8 gatt_find_i_tcb_by_addr(BD_ADDR bda) +UINT8 gatt_find_i_tcb_by_addr(BD_ADDR bda, tBT_TRANSPORT transport) { - UINT8 i = 0, j = GATT_INDEX_INVALID; + UINT8 i = 0; for ( ; i < GATT_MAX_PHY_CHANNEL; i ++) { - if (!memcmp(gatt_cb.tcb[i].peer_bda, bda, BD_ADDR_LEN)) + if (!memcmp(gatt_cb.tcb[i].peer_bda, bda, BD_ADDR_LEN) && + gatt_cb.tcb[i].transport == transport) { - j = i; - break; + return i; } } - return j; + return GATT_INDEX_INVALID; } @@ -877,12 +879,12 @@ tGATT_TCB * gatt_get_tcb_by_idx(UINT8 tcb_idx) ** Returns NULL if not found. Otherwise index to the tcb. ** *******************************************************************************/ -tGATT_TCB * gatt_find_tcb_by_addr(BD_ADDR bda) +tGATT_TCB * gatt_find_tcb_by_addr(BD_ADDR bda, tBT_TRANSPORT transport) { tGATT_TCB *p_tcb = NULL; UINT8 i = 0; - if ((i = gatt_find_i_tcb_by_addr(bda)) != GATT_INDEX_INVALID) + if ((i = gatt_find_i_tcb_by_addr(bda, transport)) != GATT_INDEX_INVALID) p_tcb = &gatt_cb.tcb[i]; return p_tcb; @@ -919,14 +921,14 @@ UINT8 gatt_find_i_tcb_free(void) ** Returns GATT_INDEX_INVALID if not found. Otherwise index to the tcb. ** *******************************************************************************/ -tGATT_TCB * gatt_allocate_tcb_by_bdaddr(BD_ADDR bda) +tGATT_TCB * gatt_allocate_tcb_by_bdaddr(BD_ADDR bda, tBT_TRANSPORT transport) { UINT8 i = 0; BOOLEAN allocated = FALSE; tGATT_TCB *p_tcb = NULL; /* search for existing tcb with matching bda */ - i = gatt_find_i_tcb_by_addr(bda); + i = gatt_find_i_tcb_by_addr(bda, transport); /* find free tcb */ if (i == GATT_INDEX_INVALID) { @@ -944,6 +946,7 @@ tGATT_TCB * gatt_allocate_tcb_by_bdaddr(BD_ADDR bda) GKI_init_q (&p_tcb->pending_ind_q); p_tcb->in_use = TRUE; p_tcb->tcb_idx = i; + p_tcb->transport = transport; } memcpy(p_tcb->peer_bda, bda, BD_ADDR_LEN); } @@ -970,6 +973,23 @@ void gatt_convert_uuid16_to_uuid128(UINT8 uuid_128[LEN_UUID_128], UINT16 uuid_16 /******************************************************************************* ** +** Function gatt_convert_uuid32_to_uuid128 +** +** Description Convert a 32 bits UUID to be an standard 128 bits one. +** +** Returns TRUE if two uuid match; FALSE otherwise. +** +*******************************************************************************/ +void gatt_convert_uuid32_to_uuid128(UINT8 uuid_128[LEN_UUID_128], UINT32 uuid_32) +{ + UINT8 *p = &uuid_128[LEN_UUID_128 - 4]; + + memcpy (uuid_128, base_uuid, LEN_UUID_128); + + UINT32_TO_STREAM(p, uuid_32); +} +/******************************************************************************* +** ** Function gatt_uuid_compare ** ** Description Compare two UUID to see if they are the same. @@ -989,11 +1009,17 @@ BOOLEAN gatt_uuid_compare (tBT_UUID src, tBT_UUID tar) } /* If both are 16-bit, we can do a simple compare */ - if (src.len == 2 && tar.len == 2) + if (src.len == LEN_UUID_16 && tar.len == LEN_UUID_16) { return src.uu.uuid16 == tar.uu.uuid16; } + /* If both are 32-bit, we can do a simple compare */ + if (src.len == LEN_UUID_32 && tar.len == LEN_UUID_32) + { + return src.uu.uuid32 == tar.uu.uuid32; + } + /* One or both of the UUIDs is 128-bit */ if (src.len == LEN_UUID_16) { @@ -1001,6 +1027,11 @@ BOOLEAN gatt_uuid_compare (tBT_UUID src, tBT_UUID tar) gatt_convert_uuid16_to_uuid128(su, src.uu.uuid16); ps = su; } + else if (src.len == LEN_UUID_32) + { + gatt_convert_uuid32_to_uuid128(su, src.uu.uuid32); + ps = su; + } else ps = src.uu.uuid128; @@ -1010,6 +1041,12 @@ BOOLEAN gatt_uuid_compare (tBT_UUID src, tBT_UUID tar) gatt_convert_uuid16_to_uuid128(tu, tar.uu.uuid16); pt = tu; } + else if (tar.len == LEN_UUID_32) + { + /* convert a 32 bits UUID to 128 bits value */ + gatt_convert_uuid32_to_uuid128(tu, tar.uu.uuid32); + pt = tu; + } else pt = tar.uu.uuid128; @@ -1035,6 +1072,12 @@ UINT8 gatt_build_uuid_to_stream(UINT8 **p_dst, tBT_UUID uuid) UINT16_TO_STREAM (p, uuid.uu.uuid16); len = LEN_UUID_16; } + else if (uuid.len == LEN_UUID_32) /* always convert 32 bits into 128 bits as alwats */ + { + gatt_convert_uuid32_to_uuid128(p, uuid.uu.uuid32); + p += LEN_UUID_128; + len = LEN_UUID_128; + } else if (uuid.len == LEN_UUID_128) { ARRAY_TO_STREAM (p, uuid.uu.uuid128, LEN_UUID_128); @@ -1090,7 +1133,11 @@ BOOLEAN gatt_parse_uuid_from_cmd(tBT_UUID *p_uuid_rec, UINT16 uuid_size, UINT8 * STREAM_TO_UINT16(p_uuid_rec->uu.uuid16, p_uuid); } else - is_base_uuid = FALSE; + { + p_uuid += (LEN_UUID_128 - LEN_UUID_32); + p_uuid_rec->len = LEN_UUID_32; + STREAM_TO_UINT32(p_uuid_rec->uu.uuid32, p_uuid); + } } if (!is_base_uuid) { @@ -1100,6 +1147,9 @@ BOOLEAN gatt_parse_uuid_from_cmd(tBT_UUID *p_uuid_rec, UINT16 uuid_size, UINT8 * *p_data += LEN_UUID_128; break; + /* do not allow 32 bits UUID in ATT PDU now */ + case LEN_UUID_32: + GATT_TRACE_ERROR0("DO NOT ALLOW 32 BITS UUID IN ATT PDU"); case 0: default: if (uuid_size != 0) ret = FALSE; @@ -1200,7 +1250,7 @@ void gatt_rsp_timeout(TIMER_LIST_ENT *p_tle) } GATT_TRACE_WARNING0("gatt_rsp_timeout disconnecting..."); - gatt_disconnect (p_clcb->p_tcb->peer_bda); + gatt_disconnect (p_clcb->p_tcb); } /******************************************************************************* @@ -1330,12 +1380,11 @@ UINT8 gatt_sr_alloc_rcb(tGATT_HDL_LIST_ELEM *p_list ) ** Returns void ** *******************************************************************************/ -void gatt_sr_get_sec_info(BD_ADDR rem_bda, BOOLEAN le_conn, UINT8 *p_sec_flag, UINT8 *p_key_size) +void gatt_sr_get_sec_info(BD_ADDR rem_bda, tBT_TRANSPORT transport, UINT8 *p_sec_flag, UINT8 *p_key_size) { UINT8 sec_flag = 0; - UNUSED(le_conn); - BTM_GetSecurityFlags(rem_bda, &sec_flag); + BTM_GetSecurityFlagsByTransport(rem_bda, &sec_flag, transport); sec_flag &= (GATT_SEC_FLAG_LKEY_UNAUTHED | GATT_SEC_FLAG_LKEY_AUTHED | GATT_SEC_FLAG_ENCRYPTED); @@ -1438,6 +1487,14 @@ UINT32 gatt_add_sdp_record (tBT_UUID *p_uuid, UINT16 start_hdl, UINT16 end_hdl) case LEN_UUID_16: SDP_AddServiceClassIdList(sdp_handle, 1, &p_uuid->uu.uuid16); break; + + case LEN_UUID_32: + UINT8_TO_BE_STREAM (p, (UUID_DESC_TYPE << 3) | SIZE_FOUR_BYTES); + UINT32_TO_BE_STREAM (p, p_uuid->uu.uuid32); + SDP_AddAttribute (sdp_handle, ATTR_ID_SERVICE_CLASS_ID_LIST, DATA_ELE_SEQ_DESC_TYPE, + (UINT32) (p - buff), buff); + break; + case LEN_UUID_128: UINT8_TO_BE_STREAM (p, (UUID_DESC_TYPE << 3) | SIZE_SIXTEEN_BYTES); ARRAY_TO_BE_STREAM (p, p_uuid->uu.uuid128, LEN_UUID_128); @@ -1889,7 +1946,8 @@ BOOLEAN gatt_cancel_open(tGATT_IF gatt_if, BD_ADDR bda) tGATT_TCB *p_tcb=NULL; BOOLEAN status= TRUE; - p_tcb = gatt_find_tcb_by_addr(bda); + p_tcb = gatt_find_tcb_by_addr(bda, BT_TRANSPORT_LE); + if (p_tcb) { if (gatt_get_ch_state(p_tcb) == GATT_CH_OPEN) @@ -1902,7 +1960,7 @@ BOOLEAN gatt_cancel_open(tGATT_IF gatt_if, BD_ADDR bda) gatt_update_app_use_link_flag(gatt_if, p_tcb, FALSE, FALSE); if (!gatt_num_apps_hold_link(p_tcb)) { - gatt_disconnect(p_tcb->peer_bda); + gatt_disconnect(p_tcb); } } } @@ -2131,7 +2189,7 @@ void gatt_end_operation(tGATT_CLCB *p_clcb, tGATT_STATUS status, void *p_data) ** Returns 16 bits uuid. ** *******************************************************************************/ -void gatt_cleanup_upon_disc(BD_ADDR bda, UINT16 reason) +void gatt_cleanup_upon_disc(BD_ADDR bda, UINT16 reason, tBT_TRANSPORT transport) { tGATT_TCB *p_tcb = NULL; tGATT_CLCB *p_clcb; @@ -2142,9 +2200,10 @@ void gatt_cleanup_upon_disc(BD_ADDR bda, UINT16 reason) GATT_TRACE_DEBUG0 ("gatt_cleanup_upon_disc "); - if ((p_tcb = gatt_find_tcb_by_addr(bda)) != NULL) + if ((p_tcb = gatt_find_tcb_by_addr(bda, transport)) != NULL) { GATT_TRACE_DEBUG0 ("found p_tcb "); + gatt_set_ch_state(p_tcb, GATT_CH_CLOSE); for (i = 0; i < GATT_CL_MAX_LCB; i ++) { p_clcb = &gatt_cb.clcb[i]; @@ -2172,7 +2231,7 @@ void gatt_cleanup_upon_disc(BD_ADDR bda, UINT16 reason) { conn_id = GATT_CREATE_CONN_ID(p_tcb->tcb_idx, p_reg->gatt_if); GATT_TRACE_DEBUG3 ("found p_reg tcb_idx=%d gatt_if=%d conn_id=0x%x", p_tcb->tcb_idx, p_reg->gatt_if, conn_id); - (*p_reg->app_cb.p_conn_cb)(p_reg->gatt_if, bda, conn_id, FALSE, reason); + (*p_reg->app_cb.p_conn_cb)(p_reg->gatt_if, bda, conn_id, FALSE, reason, transport); } } memset(p_tcb, 0, sizeof(tGATT_TCB)); @@ -2228,6 +2287,10 @@ void gatt_dbg_display_uuid(tBT_UUID bt_uuid) { sprintf(str_buf, "0x%04x", bt_uuid.uu.uuid16); } + else if (bt_uuid.len == LEN_UUID_32) + { + sprintf(str_buf, "0x%08x", (unsigned int)bt_uuid.uu.uuid32); + } else if (bt_uuid.len == LEN_UUID_128) { x += sprintf(&str_buf[x], "0x%02x%02x%02x%02x%02x%02x%02x%02x", @@ -2406,7 +2469,7 @@ BOOLEAN gatt_add_bg_dev_list(tGATT_REG *p_reg, BD_ADDR bd_addr, BOOLEAN is_init *******************************************************************************/ BOOLEAN gatt_remove_bg_dev_for_app(tGATT_IF gatt_if, BD_ADDR bd_addr) { - tGATT_TCB *p_tcb = gatt_find_tcb_by_addr(bd_addr); + tGATT_TCB *p_tcb = gatt_find_tcb_by_addr(bd_addr, BT_TRANSPORT_LE); BOOLEAN status; if (p_tcb) @@ -2628,7 +2691,7 @@ BOOLEAN gatt_update_auto_connect_dev (tGATT_IF gatt_if, BOOLEAN add, BD_ADDR bd_ { BOOLEAN ret = FALSE; tGATT_REG *p_reg; - tGATT_TCB *p_tcb = gatt_find_tcb_by_addr(bd_addr); + tGATT_TCB *p_tcb = gatt_find_tcb_by_addr(bd_addr, BT_TRANSPORT_LE); GATT_TRACE_API0 ("gatt_update_auto_connect_dev "); /* Make sure app is registered */ @@ -2659,54 +2722,6 @@ BOOLEAN gatt_update_auto_connect_dev (tGATT_IF gatt_if, BOOLEAN add, BD_ADDR bd_ /******************************************************************************* ** -** Function gatt_get_conn_id -** -** Description This function returns a connecttion handle to a ATT server -** if the server is already connected -** -** Parameters gatt_if: client interface. -** bd_addr: peer device address. -** -** Returns Connection handle or invalid handle value -** -*******************************************************************************/ -UINT16 gatt_get_conn_id (tGATT_IF gatt_if, BD_ADDR bd_addr) -{ - tGATT_REG *p_reg; - tGATT_CLCB *p_clcb; - tGATT_TCB *p_tcb; - UINT8 i; - - GATT_TRACE_API1 ("GATTC_GetConnIfConnected gatt_if=%d", gatt_if); - /* Do we have a transport to the peer ? If not, we are not connected */ - if ((p_tcb = gatt_find_tcb_by_addr(bd_addr)) == NULL) - { - GATT_TRACE_EVENT0 ("GATTC_GetConnIfConnected - no TCB found"); - return(GATT_INVALID_CONN_ID); - } - - /* Make sure app is registered */ - if ((p_reg = gatt_get_regcb(gatt_if)) == NULL) - { - GATT_TRACE_ERROR1("GATTC_GetConnIfConnected - gatt_if is not registered", gatt_if); - return(GATT_INVALID_CONN_ID); - } - - /* Now see if the app already has a client control block to that peer */ - for (i = 0, p_clcb = gatt_cb.clcb; i < GATT_CL_MAX_LCB; i++, p_clcb++) - { - if ( p_clcb->in_use && (p_clcb->p_reg == p_reg) && (p_clcb->p_tcb == p_tcb) ) - { - return(p_clcb->conn_id); - } - } - - /* If here, failed to allocate a client control block */ - GATT_TRACE_ERROR1 ("gatt_get_conn_id: not connected- gatt_if: %u", gatt_if); - return(GATT_INVALID_CONN_ID); -} -/******************************************************************************* -** ** Function gatt_add_pending_new_srv_start ** ** Description Add a pending new srv start to the new service start queue @@ -2736,12 +2751,13 @@ tGATT_PENDING_ENC_CLCB* gatt_add_pending_enc_channel_clcb(tGATT_TCB *p_tcb, tGAT ** Returns Pointer to the new service start buffer, NULL no buffer available ** *******************************************************************************/ -void gatt_update_listen_mode(void) +BOOLEAN gatt_update_listen_mode(void) { UINT8 ii = 0; tGATT_REG *p_reg = &gatt_cb.cl_rcb[0]; UINT8 listening = 0; UINT16 connectability, window, interval; + BOOLEAN rt = TRUE; for (; ii < GATT_MAX_APPS; ii ++, p_reg ++) { @@ -2757,16 +2773,24 @@ void gatt_update_listen_mode(void) else BTM_BleUpdateAdvFilterPolicy (AP_SCAN_CONN_WL); - connectability = BTM_ReadConnectability (&window, &interval); - - if (listening != GATT_LISTEN_TO_NONE) + if (rt) { - connectability |= BTM_BLE_CONNECTABLE; + connectability = BTM_ReadConnectability (&window, &interval); + + if (listening != GATT_LISTEN_TO_NONE) + { + connectability |= BTM_BLE_CONNECTABLE; + } + else + { + if ((connectability & BTM_BLE_CONNECTABLE) == 0) + connectability &= ~BTM_BLE_CONNECTABLE; + } + /* turning on the adv now */ + btm_ble_set_connectability(connectability); } - else - connectability &= ~BTM_BLE_CONNECTABLE; - /* turning on the adv now */ - BTM_SetConnectability(connectability, window, interval); + + return rt; } #endif diff --git a/stack/hcic/hciblecmds.c b/stack/hcic/hciblecmds.c index aa2e74714..860fb7a10 100644 --- a/stack/hcic/hciblecmds.c +++ b/stack/hcic/hciblecmds.c @@ -35,27 +35,6 @@ #if (defined BLE_INCLUDED) && (BLE_INCLUDED == TRUE) -BOOLEAN btsnd_hcic_ble_reset(void) -{ - BT_HDR *p; - UINT8 *pp; - - if ((p = HCI_GET_CMD_BUF(HCIC_PARAM_SIZE_READ_CMD)) == NULL) - return (FALSE); - - pp = (UINT8 *)(p + 1); - - p->len = HCIC_PREAMBLE_SIZE + HCIC_PARAM_SIZE_READ_CMD; - p->offset = 0; - - UINT16_TO_STREAM (pp, HCI_BLE_RESET); - UINT8_TO_STREAM (pp, 0); - - btu_hcif_send_cmd (LOCAL_BR_EDR_CONTROLLER_ID, p); - return (TRUE); - -} - BOOLEAN btsnd_hcic_ble_set_evt_mask (BT_EVENT_MASK event_mask) { BT_HDR *p; @@ -856,4 +835,62 @@ BOOLEAN btsnd_hcic_ble_write_host_supported (UINT8 le_host_spt, UINT8 simul_le_h return (TRUE); } +#if (defined BLE_LLT_INCLUDED) && (BLE_LLT_INCLUDED == TRUE) + +BOOLEAN btsnd_hcic_ble_rc_param_req_reply( UINT16 handle, + UINT16 conn_int_min, UINT16 conn_int_max, + UINT16 conn_latency, UINT16 conn_timeout, + UINT16 min_ce_len, UINT16 max_ce_len ) +{ + BT_HDR *p; + UINT8 *pp; + + if ((p = HCI_GET_CMD_BUF(HCIC_PARAM_SIZE_BLE_RC_PARAM_REQ_REPLY)) == NULL) + return (FALSE); + + pp = (UINT8 *)(p + 1); + + p->len = HCIC_PREAMBLE_SIZE + HCIC_PARAM_SIZE_BLE_RC_PARAM_REQ_REPLY; + p->offset = 0; + + UINT16_TO_STREAM (pp, HCI_BLE_RC_PARAM_REQ_REPLY); + UINT8_TO_STREAM (pp, HCIC_PARAM_SIZE_BLE_RC_PARAM_REQ_REPLY); + + UINT16_TO_STREAM (pp, handle); + UINT16_TO_STREAM (pp, conn_int_min); + UINT16_TO_STREAM (pp, conn_int_max); + UINT16_TO_STREAM (pp, conn_latency); + UINT16_TO_STREAM (pp, conn_timeout); + UINT16_TO_STREAM (pp, min_ce_len); + UINT16_TO_STREAM (pp, max_ce_len); + + btu_hcif_send_cmd (LOCAL_BR_EDR_CONTROLLER_ID, p); + return (TRUE); +} + +BOOLEAN btsnd_hcic_ble_rc_param_req_neg_reply(UINT16 handle, UINT8 reason) +{ + BT_HDR *p; + UINT8 *pp; + + if ((p = HCI_GET_CMD_BUF(HCIC_PARAM_SIZE_BLE_RC_PARAM_REQ_NEG_REPLY)) == NULL) + return (FALSE); + + pp = (UINT8 *)(p + 1); + + p->len = HCIC_PREAMBLE_SIZE + HCIC_PARAM_SIZE_BLE_RC_PARAM_REQ_NEG_REPLY; + p->offset = 0; + + UINT16_TO_STREAM (pp, HCI_BLE_RC_PARAM_REQ_NEG_REPLY); + UINT8_TO_STREAM (pp, HCIC_PARAM_SIZE_BLE_RC_PARAM_REQ_NEG_REPLY); + + UINT16_TO_STREAM (pp, handle); + UINT8_TO_STREAM (pp, reason); + + btu_hcif_send_cmd (LOCAL_BR_EDR_CONTROLLER_ID, p); + return (TRUE); +} #endif + +#endif + diff --git a/stack/hid/hidh_conn.c b/stack/hid/hidh_conn.c index 00c9d05b6..6fbf84932 100644 --- a/stack/hid/hidh_conn.c +++ b/stack/hid/hidh_conn.c @@ -163,10 +163,11 @@ tHID_STATUS hidh_conn_disconnect (UINT8 dhandle) ** send security block L2C connection response. ** *******************************************************************************/ -void hidh_sec_check_complete_term (BD_ADDR bd_addr, void *p_ref_data, UINT8 res) +void hidh_sec_check_complete_term (BD_ADDR bd_addr, tBT_TRANSPORT transport, void *p_ref_data, UINT8 res) { tHID_HOST_DEV_CTB *p_dev= (tHID_HOST_DEV_CTB *) p_ref_data; UNUSED(bd_addr); + UNUSED (transport); if( res == BTM_SUCCESS && p_dev->conn.conn_state == HID_CONN_STATE_SECURITY ) { @@ -316,7 +317,7 @@ void hidh_proc_repage_timeout (TIMER_LIST_ENT *p_tle) ** Returns void ** *******************************************************************************/ -void hidh_sec_check_complete_orig (BD_ADDR bd_addr, void *p_ref_data, UINT8 res) +void hidh_sec_check_complete_orig (BD_ADDR bd_addr, tBT_TRANSPORT transport, void *p_ref_data, UINT8 res) { tHID_HOST_DEV_CTB *p_dev = (tHID_HOST_DEV_CTB *) p_ref_data; UINT8 dhandle; @@ -325,6 +326,7 @@ void hidh_sec_check_complete_orig (BD_ADDR bd_addr, void *p_ref_data, UINT8 res) #endif UINT32 reason; UNUSED(bd_addr); + UNUSED (transport); dhandle = ((UINT32)p_dev - (UINT32)&(hh_cb.devices[0]))/ sizeof(tHID_HOST_DEV_CTB); if( res == BTM_SUCCESS && p_dev->conn.conn_state == HID_CONN_STATE_SECURITY ) @@ -880,6 +882,13 @@ tHID_STATUS hidh_conn_snd_data (UINT8 dhandle, UINT8 trans_type, UINT8 param, UINT8 use_data = 0 ; BOOLEAN blank_datc = FALSE; + if (!BTM_IsAclConnectionUp(hh_cb.devices[dhandle].addr, BT_TRANSPORT_BR_EDR)) + { + if (buf) + GKI_freebuf ((void *)buf); + return( HID_ERR_NO_CONNECTION ); + } + if (p_hcon->conn_flags & HID_CONN_FLAGS_CONGESTED) { if (buf) diff --git a/stack/include/bt_types.h b/stack/include/bt_types.h index 33fb88435..e7a79372a 100644 --- a/stack/include/bt_types.h +++ b/stack/include/bt_types.h @@ -497,6 +497,10 @@ typedef struct #define BLE_ADDR_TYPE_MASK (BLE_ADDR_RANDOM | BLE_ADDR_PUBLIC) typedef UINT8 tBLE_ADDR_TYPE; +#define BT_TRANSPORT_BR_EDR 1 +#define BT_TRANSPORT_LE 2 +typedef UINT8 tBT_TRANSPORT; + #define BLE_ADDR_IS_STATIC(x) ((x[0] & 0xC0) == 0xC0) typedef struct diff --git a/stack/include/btm_api.h b/stack/include/btm_api.h index f4b17d467..368e70db8 100644 --- a/stack/include/btm_api.h +++ b/stack/include/btm_api.h @@ -200,20 +200,20 @@ typedef UINT8 (tBTM_FILTER_CB) (BD_ADDR bd_addr, DEV_CLASS dc); /* BTM_IsInquiryActive return values (Bit Mask) * Note: These bit masks are associated with the inquiry modes (BTM_*_INQUIRY) */ #define BTM_INQUIRY_INACTIVE 0x0 /* no inquiry in progress */ -#define BTM_GENERAL_INQUIRY_ACTIVE 0x1 /* a general inquiry is in progress */ -#define BTM_LIMITED_INQUIRY_ACTIVE 0x2 /* a limited inquiry is in progress */ +#define BTM_GENERAL_INQUIRY_ACTIVE BTM_GENERAL_INQUIRY /* a general inquiry is in progress */ +#define BTM_LIMITED_INQUIRY_ACTIVE BTM_LIMITED_INQUIRY /* a limited inquiry is in progress */ #define BTM_PERIODIC_INQUIRY_ACTIVE 0x8 /* a periodic inquiry is active */ #define BTM_SSP_INQUIRY_ACTIVE 0x4 /* SSP is active, so inquiry is disallowed (work around for FW bug) */ -#define BTM_LE_GENERAL_INQUIRY_ACTIVE 0x10 /* a general inquiry is in progress */ -#define BTM_LE_LIMITED_INQUIRY_ACTIVE 0x20 /* a limited inquiry is in progress */ -#define BTM_LE_SELECT_CONN_ACTIVE 0x40 /* selection connection is in progress */ -#define BTM_LE_OBSERVE_ACTIVE 0x80 /* selection connection is in progress */ +#define BTM_LE_GENERAL_INQUIRY_ACTIVE BTM_BLE_GENERAL_INQUIRY /* a general inquiry is in progress */ +#define BTM_LE_LIMITED_INQUIRY_ACTIVE BTM_BLE_LIMITED_INQUIRY /* a limited inquiry is in progress */ +#define BTM_LE_SELECT_CONN_ACTIVE 0x40 /* selection connection is in progress */ +#define BTM_LE_OBSERVE_ACTIVE 0x80 /* selection connection is in progress */ /* inquiry activity mask */ -#define BTM_BR_INQ_ACTIVE_MASK (BTM_GENERAL_INQUIRY_ACTIVE|BTM_LIMITED_INQUIRY_ACTIVE|BTM_PERIODIC_INQUIRY_ACTIVE) /* BR/EDR inquiry activity mask */ -#define BTM_LE_SCAN_ACTIVE_MASK 0xF0 /* LE scan activity mask */ -#define BTM_LE_INQ_ACTIVE_MASK (BTM_LE_GENERAL_INQUIRY_ACTIVE|BTM_LE_LIMITED_INQUIRY_ACTIVE) /* LE inquiry activity mask*/ -#define BTM_INQUIRY_ACTIVE_MASK (BTM_BR_INQ_ACTIVE_MASK | BTM_LE_INQ_ACTIVE_MASK) /* inquiry activity mask */ +#define BTM_BR_INQ_ACTIVE_MASK (BTM_GENERAL_INQUIRY_ACTIVE|BTM_LIMITED_INQUIRY_ACTIVE|BTM_PERIODIC_INQUIRY_ACTIVE) /* BR/EDR inquiry activity mask */ +#define BTM_BLE_SCAN_ACTIVE_MASK 0xF0 /* LE scan activity mask */ +#define BTM_BLE_INQ_ACTIVE_MASK (BTM_LE_GENERAL_INQUIRY_ACTIVE|BTM_LE_LIMITED_INQUIRY_ACTIVE) /* LE inquiry activity mask*/ +#define BTM_INQUIRY_ACTIVE_MASK (BTM_BR_INQ_ACTIVE_MASK | BTM_BLE_INQ_ACTIVE_MASK) /* inquiry activity mask */ /* Define scan types */ #define BTM_SCAN_TYPE_STANDARD 0 @@ -659,6 +659,7 @@ typedef struct typedef struct { UINT16 status; + BD_ADDR bd_addr; UINT16 length; BD_NAME remote_bd_name; } tBTM_REMOTE_DEV_NAME; @@ -837,6 +838,10 @@ typedef struct DEV_CLASS_PTR p_dc; /* The device class */ BD_NAME_PTR p_bdn; /* The device name */ UINT8 *p_features; /* pointer to the remote device's features page[0] (supported features page) */ +#if BLE_INCLUDED == TRUE + UINT16 handle; /* connection handle */ + tBT_TRANSPORT transport; /* link is LE or not */ +#endif } tBTM_BL_CONN_DATA; /* the data type associated with BTM_BL_DISCN_EVT */ @@ -844,6 +849,10 @@ typedef struct { tBTM_BL_EVENT event; /* The event reported. */ BD_ADDR_PTR p_bda; /* The address of the disconnected device */ +#if BLE_INCLUDED == TRUE + UINT16 handle; /* disconnected connection handle */ + tBT_TRANSPORT transport; /* link is LE link or not */ +#endif } tBTM_BL_DISCN_DATA; /* Busy-Level shall have the inquiry_paging mask set when @@ -893,10 +902,16 @@ typedef void (tBTM_BL_CHANGE_CB) (tBTM_BL_EVENT_DATA *p_data); ** changes. First param is BD address, second is if added or removed. ** Registered through BTM_AclRegisterForChanges call. */ +#if BLE_INCLUDED == TRUE +typedef void (tBTM_ACL_DB_CHANGE_CB) (BD_ADDR p_bda, DEV_CLASS p_dc, + BD_NAME p_bdn, UINT8 *features, + BOOLEAN is_new, UINT16 handle, + tBT_TRANSPORT transport); +#else typedef void (tBTM_ACL_DB_CHANGE_CB) (BD_ADDR p_bda, DEV_CLASS p_dc, BD_NAME p_bdn, UINT8 *features, BOOLEAN is_new); - +#endif /***************************************************************************** ** SCO CHANNEL MANAGEMENT *****************************************************************************/ @@ -1565,7 +1580,8 @@ typedef void (tBTM_MKEY_CALLBACK) (BD_ADDR bd_addr, UINT8 status, UINT8 key_flag ** optional data passed in by BTM_SetEncryption ** tBTM_STATUS - result of the operation */ -typedef void (tBTM_SEC_CBACK) (BD_ADDR bd_addr, void *p_ref_data, tBTM_STATUS result); +typedef void (tBTM_SEC_CBACK) (BD_ADDR bd_addr, tBT_TRANSPORT trasnport, + void *p_ref_data, tBTM_STATUS result); /* Bond Cancel complete. Parameters are ** Result of the cancel operation @@ -1897,73 +1913,6 @@ typedef struct #define BTM_VSC_NFC_SUPPORTED(x) ((x)[BTM_FEATURE_NFC_OFF] & BTM_FEATURE_NFC_MASK) -/************************ -** Dual-Stack support -*************************/ -/* BTM_SYNC_FAIL_EVT reason codes */ -#define BTM_SYNC_SUCCESS 0 -#define BTM_SYNC_FAIL_BTE_SWITCH_REJECTED 1 -#define BTM_SYNC_FAIL_TRANS_PAUSE 2 -#define BTM_SYNC_FAIL_CORE_SYNC 3 -#define BTM_SYNC_FAIL_BTA_SYNC 4 -#define BTM_SYNC_FAIL_TRANS_RESUME 5 -#define BTM_SYNC_FAIL_RESYNC 6 -#define BTM_SYNC_FAIL_ERROR 7 -#define BTM_SYNC_FAIL_UIPC_OPEN 8 -typedef UINT8 tBTM_SYNC_STATUS; - -/* Direction of sync (used by BTM_SyncStack) */ -#define BTM_SW_BB_TO_MM 0 -#define BTM_SW_TO_BB 1 /* Switch back to baseband stack (from either MM or BTC host) */ -#define BTM_SW_RESYNC 2 -#define BTM_SW_BB_TO_BTC 3 /* Switch from baseband stack to Bluetooth Controller Host stack */ -#define BTM_SW_MM_TO_BB 4 -#define BTM_SW_BTC_TO_BB 5 -typedef UINT8 tBTM_SW_DIR; - -/* Stack synchronization events (returned by tBTM_SYNC_STACK_CBACK callback) */ -#define BTM_SYNC_CPLT_EVT 0 -#define BTM_SYNC_BTA_EVT 1 -#define BTM_RESYNC_CPLT_EVT 2 -#define BTM_UIPC_OPENED_EVT 3 -#define BTM_UIPC_CLOSED_EVT 4 -typedef UINT8 tBTM_SYNC_STACK_EVT; - -/* Synchronization info from BTA/application that will be sent when calling BTE sync request functions */ -typedef struct -{ - tBTM_SW_DIR dir; - UINT16 lcid[BTM_SYNC_INFO_NUM_STR]; - UINT8 avdt_handle[BTM_SYNC_INFO_NUM_STR]; -} tBTM_SYNC_INFO; - -/* Stack synchonization callback function -** Parameters are -** event: stack synchronization event -** status: BTM_SUCCESS if event was successful -*/ -typedef void (*tBTM_SYNC_STACK_CBACK)(tBTM_SYNC_STACK_EVT event, tBTM_SYNC_STATUS status); - - -/* Sync complete callback function. Called by bte layers after synchronization is complete -** so that BTM_SYNC can procede with the next step for switching stack to MM -** -** Parameters are -** status: BTM_SUCCESS if synchronization was successful -*/ -typedef void (*tBTM_SYNC_CPLT_CBACK)(tBTM_STATUS status); - - - -/* IPC event callback function. Called by BTM when an IPC event is received. -** These events are currently sent to DM through the callback function. -** -** Parameters are -** status: BTM_SUCCESS if synchronization was successful -** p_data: Actual message in the IPC -*/ -typedef void (tBTM_IPC_EVT_CBACK)(tBTM_STATUS status, BT_HDR *p_data); - /* MIP evnets, callbacks */ enum { @@ -2659,7 +2608,8 @@ BTM_API extern BOOLEAN BTM_TryAllocateSCN(UINT8 scn); ** *******************************************************************************/ BTM_API extern tBTM_STATUS BTM_ReadRemoteDeviceName (BD_ADDR remote_bda, - tBTM_CMPL_CB *p_cb); + tBTM_CMPL_CB *p_cb, + tBT_TRANSPORT transport); /******************************************************************************* @@ -3187,7 +3137,7 @@ BTM_API extern BOOLEAN BTM_TryAllocateSCN(UINT8 scn); ** Returns TRUE if connection is up, else FALSE. ** *******************************************************************************/ - BTM_API extern BOOLEAN BTM_IsAclConnectionUp (BD_ADDR remote_bda); + BTM_API extern BOOLEAN BTM_IsAclConnectionUp (BD_ADDR remote_bda, tBT_TRANSPORT transport); /******************************************************************************* @@ -3273,7 +3223,8 @@ BTM_API extern BOOLEAN BTM_TryAllocateSCN(UINT8 scn); ** BTM_BUSY if command is already in progress ** *******************************************************************************/ - BTM_API extern tBTM_STATUS BTM_ReadTxPower (BD_ADDR remote_bda, tBTM_CMPL_CB *p_cb); + BTM_API extern tBTM_STATUS BTM_ReadTxPower (BD_ADDR remote_bda, + tBT_TRANSPORT transport, tBTM_CMPL_CB *p_cb); /******************************************************************************* ** @@ -3640,7 +3591,8 @@ BTM_API extern tBTM_STATUS BTM_SetWBSCodec (tBTM_SCO_CODEC_TYPE codec_type); ** Returns TRUE if registered OK, else FALSE ** *******************************************************************************/ - BTM_API extern BOOLEAN BTM_SecRegisterLinkKeyNotificationCallback (tBTM_LINK_KEY_CALLBACK *p_callback); + BTM_API extern BOOLEAN BTM_SecRegisterLinkKeyNotificationCallback ( + tBTM_LINK_KEY_CALLBACK *p_callback); /******************************************************************************* @@ -3653,7 +3605,8 @@ BTM_API extern tBTM_STATUS BTM_SetWBSCodec (tBTM_SCO_CODEC_TYPE codec_type); ** Returns TRUE if registered OK, else FALSE ** *******************************************************************************/ - BTM_API extern BOOLEAN BTM_SecAddRmtNameNotifyCallback (tBTM_RMT_NAME_CALLBACK *p_callback); + BTM_API extern BOOLEAN BTM_SecAddRmtNameNotifyCallback ( + tBTM_RMT_NAME_CALLBACK *p_callback); /******************************************************************************* @@ -3666,7 +3619,8 @@ BTM_API extern tBTM_STATUS BTM_SetWBSCodec (tBTM_SCO_CODEC_TYPE codec_type); ** Returns TRUE if OK, else FALSE ** *******************************************************************************/ - BTM_API extern BOOLEAN BTM_SecDeleteRmtNameNotifyCallback (tBTM_RMT_NAME_CALLBACK *p_callback); + BTM_API extern BOOLEAN BTM_SecDeleteRmtNameNotifyCallback ( + tBTM_RMT_NAME_CALLBACK *p_callback); /******************************************************************************* @@ -3709,6 +3663,22 @@ BTM_API extern tBTM_STATUS BTM_SetWBSCodec (tBTM_SCO_CODEC_TYPE codec_type); /******************************************************************************* ** +** Function BTM_GetSecurityFlagsByTransport +** +** Description Get security flags for the device on a particular transport +** +** Parameters bd_addr: BD address of remote device +** p_sec_flags : Out parameter to be filled with security flags for the connection +** transport : Physical transport of the connection (BR/EDR or LE) +** +** Returns BOOLEAN TRUE or FALSE is device found +** +*******************************************************************************/ + BTM_API extern BOOLEAN BTM_GetSecurityFlagsByTransport (BD_ADDR bd_addr, + UINT8 * p_sec_flags, tBT_TRANSPORT transport); + +/******************************************************************************* +** ** Function BTM_ReadTrustedMask ** ** Description Get trusted mask for the device @@ -3789,9 +3759,10 @@ BTM_API extern tBTM_STATUS BTM_SetWBSCodec (tBTM_SCO_CODEC_TYPE codec_type); ** Returns TRUE if registered OK, else FALSE ** *******************************************************************************/ - BTM_API extern BOOLEAN BTM_SetUCDSecurityLevel (BOOLEAN is_originator, char *p_name, UINT8 service_id, - UINT16 sec_level, UINT16 psm, UINT32 mx_proto_id, - UINT32 mx_chan_id); + BTM_API extern BOOLEAN BTM_SetUCDSecurityLevel (BOOLEAN is_originator, char *p_name, + UINT8 service_id, UINT16 sec_level, + UINT16 psm, UINT32 mx_proto_id, + UINT32 mx_chan_id); /******************************************************************************* ** @@ -3951,10 +3922,37 @@ BTM_API extern tBTM_STATUS BTM_SetWBSCodec (tBTM_SCO_CODEC_TYPE codec_type); ** ** Description This function is called to perform bonding with peer device. ** +** Parameters: bd_addr - Address of the device to bond +** pin_len - length in bytes of the PIN Code +** p_pin - pointer to array with the PIN Code +** trusted_mask - bitwise OR of trusted services (array of UINT32) + ** Returns BTM_CMD_STARTED if successfully initiated, otherwise error ** *******************************************************************************/ - BTM_API extern tBTM_STATUS BTM_SecBond (BD_ADDR bd_addr, UINT8 pin_len, UINT8 *p_pin, UINT32 trusted_mask[]); + BTM_API extern tBTM_STATUS BTM_SecBond (BD_ADDR bd_addr, + UINT8 pin_len, UINT8 *p_pin, + UINT32 trusted_mask[]); + +/******************************************************************************* +** +** Function BTM_SecBondByTransport +** +** Description This function is called to perform bonding by designated transport +** +** Parameters: bd_addr - Address of the device to bond +** pin_len - length in bytes of the PIN Code +** p_pin - pointer to array with the PIN Code +** trusted_mask - bitwise OR of trusted services (array of UINT32) +** transport : Physical transport to use for bonding (BR/EDR or LE) +** +** Returns BTM_CMD_STARTED if successfully initiated, otherwise error +** +*******************************************************************************/ + BTM_API extern tBTM_STATUS BTM_SecBondByTransport (BD_ADDR bd_addr, + tBT_TRANSPORT transport, + UINT8 pin_len, UINT8 *p_pin, + UINT32 trusted_mask[]); /******************************************************************************* ** @@ -3993,8 +3991,8 @@ BTM_API extern tBTM_STATUS BTM_SetWBSCodec (tBTM_SCO_CODEC_TYPE codec_type); ** BTM_MODE_UNSUPPORTED - if security manager not linked in. ** *******************************************************************************/ - BTM_API extern tBTM_STATUS BTM_SetEncryption (BD_ADDR bd_addr, tBTM_SEC_CBACK *p_callback, - void *p_ref_data); + BTM_API extern tBTM_STATUS BTM_SetEncryption (BD_ADDR bd_addr, tBT_TRANSPORT transport, + tBTM_SEC_CBACK *p_callback, void *p_ref_data); /******************************************************************************* ** @@ -4079,7 +4077,8 @@ BTM_API extern tBTM_STATUS BTM_SetWBSCodec (tBTM_SCO_CODEC_TYPE codec_type); ** r - simple pairing Randomizer C. ** *******************************************************************************/ - BTM_API extern void BTM_RemoteOobDataReply(tBTM_STATUS res, BD_ADDR bd_addr, BT_OCTET16 c, BT_OCTET16 r); + BTM_API extern void BTM_RemoteOobDataReply(tBTM_STATUS res, BD_ADDR bd_addr, + BT_OCTET16 c, BT_OCTET16 r); /******************************************************************************* ** @@ -4232,7 +4231,7 @@ BTM_API extern tBTM_STATUS BTM_SetWBSCodec (tBTM_SCO_CODEC_TYPE codec_type); ** Returns the handle of the connection, or 0xFFFF if none. ** *******************************************************************************/ - BTM_API extern UINT16 BTM_GetHCIConnHandle (BD_ADDR remote_bda); + BTM_API extern UINT16 BTM_GetHCIConnHandle (BD_ADDR remote_bda, tBT_TRANSPORT transport); /******************************************************************************* @@ -4419,171 +4418,6 @@ BTM_API extern tBTM_STATUS BTM_SetWBSCodec (tBTM_SCO_CODEC_TYPE codec_type); BTM_API extern UINT8 BTM_GetEirUuidList( UINT8 *p_eir, UINT8 uuid_size, UINT8 *p_num_uuid, UINT8 *p_uuid_list, UINT8 max_num_uuid); -/******************************************************************************* -** -** Function BTM_SyncStack -** -** Description For Dual-Stack support. Called to initiate switching to/from -** main stack (running on phone baseband) to mm stack (light -** stack running on multi-media chip) -** -** Parameters sync_dir: BTM_SW_BB_TO_MM: switch from BB to MM stack -** BTM_SW_MM_TO_BB: switch from MM to BB stack -** BTM_SW_RESYNC: resync MM and BB stacks -** -** p_sync_cback: callback function for event notification -** Returns -** -*******************************************************************************/ - BTM_API extern tBTM_STATUS BTM_SyncStack(tBTM_SW_DIR sync_dir, tBTM_SYNC_STACK_CBACK p_sync_cback); - -/******************************************************************************* -** -** Function BTM_SyncBtaRsp -** -** Description For Dual-Stack support. Called to indicate that upper layers -** (e.g. BTA or application) have completed synchronizing bta/app -** specific layers for switching. -** -** Called in response to 'BTM_SYNC_BTA_EVT' -** -** Parameters status: BTM_SUCESS: bta/app successfully synchronized -** otherwise: sync was unsuccessfule. Abort switch. -** -** p_btm_sync_info: information from bta/app that will be needed -** by BTE (avdt and l2cap) for switching. -** -** Returns void -** -*******************************************************************************/ - BTM_API extern void BTM_SyncBtaRsp(tBTM_STATUS status, tBTM_SYNC_INFO *p_btm_sync_info); - -/******************************************************************************* -** -** Function BTM_OpenUIPC -** -** Description For Dual-Stack support. Called to open UIPC between -** main stack (running on phone baseband) to embedded light stack -** (running on Multimedia or Bluetooth Controller chip) -** -** Parameters sync_dir: BTM_SW_BB_TO_MM: switch from BB to MM stack -** BTM_SW_BB_TO_BTC:switch from BB to BTC stack -** -** p_sync_callback: callback function for event notification -** Returns -** -*******************************************************************************/ - BTM_API extern tBTM_STATUS BTM_OpenUIPC(tBTM_SW_DIR sync_dir, tBTM_SYNC_STACK_CBACK p_sync_callback); - -/******************************************************************************* -** -** Function BTM_CloseUIPC -** -** Description For Dual-Stack support. Called to close UIPC between -** main stack (running on phone baseband) to embedded light stack -** (running on Multimedia or Bluetooth Controller chip) -** -** Parameters -** p_sync_callback: callback function for event notification -** Returns -** -*******************************************************************************/ - BTM_API extern tBTM_STATUS BTM_CloseUIPC(tBTM_SYNC_STACK_CBACK p_sync_callback); - -/******************************************************************************* -** -** Function BTM_IpcSend -** -** Description For Dual-Stack support. Called to send ipc messages from -** full stack to lite stack and vice-versa. This API is -** typically called by bta layers e.g. bta_av. -** -** -** Parameters len: Length of the buffer in the ipc message -** -** buffer: Pointer to the buffer to be passed in the IPC message -** -** Returns void -** -*******************************************************************************/ - BTM_API extern void BTM_IpcSend(UINT16 len, UINT8* buffer); - -/******************************************************************************* -** -** Function BTM_IpcSendBuf -** -** Description For Dual-Stack support. Called to send ipc messages from -** full stack to lite stack and vice-versa. This API is -** typically called by bta layers e.g. bta_av_sync. -** -** -** Parameters p_buf: Pointer to the buffer to be passed in the IPC message -** -** Returns void -** -*******************************************************************************/ - BTM_API extern void BTM_IpcSendBuf(BT_HDR* p_buf); - -/******************************************************************************* -** -** Function BTM_RegIpcEvtHandler -** -** Description registers the DM provided handler for IPC events -** -** -** Returns void -** -*******************************************************************************/ - BTM_API extern void BTM_RegIpcEvtHandler(tBTM_IPC_EVT_CBACK *p_cback); - -/******************************************************************************* -** -** Function BTM_RegRTIpcEvtHandler -** -** Description registers the RT(Audio Routing) provided handler for IPC events -** -** -** Returns void -** -*******************************************************************************/ - BTM_API extern void BTM_RegRTIpcEvtHandler(tBTM_IPC_EVT_CBACK *p_cback); - -/***************************************************************************** -** N2BT -*****************************************************************************/ - -/* Data callback for N2BT */ - typedef void (tBTM_N2BT_DATA_CB) (BD_ADDR bd_addr, UINT16 handle, UINT8 *p_data, UINT16 datalen); - -/******************************************************************************* -** -** Function BTM_N2BtAcquire -** -** Description Put controller into acquisition mode -** -** Returns void -** -*******************************************************************************/ - BTM_API extern void BTM_N2BtAcquire(BD_ADDR bd_addr, UINT16 timeout, - UINT8 freq, UINT8 src_addrlen, UINT8 sensor_flags, - UINT8 sensor_type, UINT8 sensor_clk_accuracy, - UINT16 add_rx_window, UINT16 init_crc, - UINT32 ac_low, UINT32 ac_high, UINT16 pkt_hdr, - UINT16 list_dur, UINT16 list_int, - UINT8 oor_missed_pkts, tBTM_VSC_CMPL_CB *p_cb, - tBTM_N2BT_DATA_CB *p_data_cback); - -/******************************************************************************* -** -** Function BTM_N2BtDisconnect -** -** Description Disconnects all N2BT devices -** -** Returns void -** -*******************************************************************************/ - BTM_API extern void BTM_N2BtDisconnect(void); - /***************************************************************************** ** SCO OVER HCI *****************************************************************************/ diff --git a/stack/include/btm_ble_api.h b/stack/include/btm_ble_api.h index 584ce9a0a..0bfaea96a 100644 --- a/stack/include/btm_ble_api.h +++ b/stack/include/btm_ble_api.h @@ -30,12 +30,17 @@ #define CHNL_MAP_LEN 5 typedef UINT8 tBTM_BLE_CHNL_MAP[CHNL_MAP_LEN]; -#define BTM_BLE_CONNECT_EVT 0x00 -#define BTM_BLE_CONNECT_DIR_EVT 0x01 -#define BTM_BLE_DISCOVER_EVT 0x02 -#define BTM_BLE_NON_CONNECT_EVT 0x03 +/* 0x00-0x04 only used for set advertising parameter command */ +#define BTM_BLE_CONNECT_EVT 0x00 /* 0x00-0x04 only used for set advertising + parameter command */ +#define BTM_BLE_CONNECT_DIR_EVT 0x01 /* Connectable directed advertising */ +#define BTM_BLE_DISCOVER_EVT 0x02 /* Scannable undirected advertising */ +#define BTM_BLE_NON_CONNECT_EVT 0x03 /* Non connectable undirected advertising */ +#define BTM_BLE_CONNECT_LO_DUTY_DIR_EVT 0x04 /* Connectable low duty + cycle directed advertising */ + /* 0x00 - 0x05 can be received on adv event type */ #define BTM_BLE_SCAN_RSP_EVT 0x04 -#define BTM_BLE_SCAN_REQ_EVT 0x06 +#define BTM_BLE_SCAN_REQ_EVT 0x05 #define BTM_BLE_UNKNOWN_EVT 0xff #define BTM_BLE_UNKNOWN_EVT 0xff @@ -191,27 +196,33 @@ typedef struct #define BTM_BLE_LIMIT_DISC_FLAG (0x01 << 0) #define BTM_BLE_GEN_DISC_FLAG (0x01 << 1) #define BTM_BLE_BREDR_NOT_SPT (0x01 << 2) +/* 4.1 spec adv flag for simultaneous BR/EDR+LE connection support */ +#define BTM_BLE_DMT_CONTROLLER_SPT (0x01 << 3) +#define BTM_BLE_DMT_HOST_SPT (0x01 << 4) + #define BTM_BLE_NON_LIMIT_DISC_FLAG (0x00 ) /* lowest bit unset */ #define BTM_BLE_ADV_FLAG_MASK (BTM_BLE_LIMIT_DISC_FLAG | BTM_BLE_BREDR_NOT_SPT | BTM_BLE_GEN_DISC_FLAG) #define BTM_BLE_LIMIT_DISC_MASK (BTM_BLE_LIMIT_DISC_FLAG ) -#define BTM_BLE_AD_BIT_DEV_NAME (0x0001 << 0) -#define BTM_BLE_AD_BIT_FLAGS (0x0001 << 1) -#define BTM_BLE_AD_BIT_MANU (0x0001 << 2) -#define BTM_BLE_AD_BIT_TX_PWR (0x0001 << 3) -#define BTM_BLE_AD_BIT_INT_RANGE (0x0001 << 5) -#define BTM_BLE_AD_BIT_SERVICE (0x0001 << 6) -#define BTM_BLE_AD_BIT_SERVICE_SOL (0x0001 << 7) -#define BTM_BLE_AD_BIT_SERVICE_DATA (0x0001 << 8) -#define BTM_BLE_AD_BIT_SIGN_DATA (0x0001 << 9) -#define BTM_BLE_AD_BIT_SERVICE_128SOL (0x0001 << 10) -#define BTM_BLE_AD_BIT_APPEARANCE (0x0001 << 11) -#define BTM_BLE_AD_BIT_PUBLIC_ADDR (0x0001 << 12) -#define BTM_BLE_AD_BIT_RANDOM_ADDR (0x0001 << 13) - -#define BTM_BLE_AD_BIT_PROPRIETARY (0x0001 << 15) - -typedef UINT16 tBTM_BLE_AD_MASK; +#define BTM_BLE_AD_BIT_DEV_NAME (0x00000001 << 0) +#define BTM_BLE_AD_BIT_FLAGS (0x00000001 << 1) +#define BTM_BLE_AD_BIT_MANU (0x00000001 << 2) +#define BTM_BLE_AD_BIT_TX_PWR (0x00000001 << 3) +#define BTM_BLE_AD_BIT_INT_RANGE (0x00000001 << 5) +#define BTM_BLE_AD_BIT_SERVICE (0x00000001 << 6) +#define BTM_BLE_AD_BIT_SERVICE_SOL (0x00000001 << 7) +#define BTM_BLE_AD_BIT_SERVICE_DATA (0x00000001 << 8) +#define BTM_BLE_AD_BIT_SIGN_DATA (0x00000001 << 9) +#define BTM_BLE_AD_BIT_SERVICE_128SOL (0x00000001 << 10) +#define BTM_BLE_AD_BIT_APPEARANCE (0x00000001 << 11) +#define BTM_BLE_AD_BIT_PUBLIC_ADDR (0x00000001 << 12) +#define BTM_BLE_AD_BIT_RANDOM_ADDR (0x00000001 << 13) +#define BTM_BLE_AD_BIT_SERVICE_32 (0x00000001 << 4) +#define BTM_BLE_AD_BIT_SERVICE_32SOL (0x00000001 << 14) + +#define BTM_BLE_AD_BIT_PROPRIETARY (0x00000001 << 15) + +typedef UINT32 tBTM_BLE_AD_MASK; #define BTM_BLE_AD_TYPE_FLAG HCI_EIR_FLAGS_TYPE /* 0x01 */ #define BTM_BLE_AD_TYPE_16SRV_PART HCI_EIR_MORE_16BITS_UUID_TYPE /* 0x02 */ @@ -233,6 +244,11 @@ typedef UINT16 tBTM_BLE_AD_MASK; #define BTM_BLE_AD_TYPE_PUBLIC_TARGET 0x17 #define BTM_BLE_AD_TYPE_RANDOM_TARGET 0x18 #define BTM_BLE_AD_TYPE_APPEARANCE 0x19 +#define BTM_BLE_AD_TYPE_ADV_INT 0x1a +#define BTM_BLE_AD_TYPE_32SOL_SRV_UUID 0x1b +#define BTM_BLE_AD_TYPE_32SERVICE_DATA 0x1c +#define BTM_BLE_AD_TYPE_128SERVICE_DATA 0x1d + #define BTM_BLE_AD_TYPE_MANU HCI_EIR_MANUFACTURER_SPECIFIC_TYPE /* 0xff */ typedef UINT8 tBTM_BLE_AD_TYPE; @@ -252,12 +268,30 @@ typedef struct UINT16 *p_uuid; }tBTM_BLE_SERVICE; +/* Service tag supported in the device */ +typedef struct +{ + UINT8 num_service; + BOOLEAN list_cmpl; + UINT32 *p_uuid; +}tBTM_BLE_32SERVICE; + + typedef struct { UINT8 len; UINT8 *p_val; }tBTM_BLE_MANU; + +typedef struct +{ + tBT_UUID service_uuid; + UINT8 len; + UINT8 *p_val; +}tBTM_BLE_SERVICE_DATA; + + typedef struct { UINT8 adv_type; @@ -273,9 +307,12 @@ typedef struct typedef struct { - tBTM_BLE_MANU manu; /* manufactuer data */ + tBTM_BLE_SERVICE_DATA *p_service_data; + tBTM_BLE_MANU manu; /* manufactuer data */ tBTM_BLE_INT_RANGE int_range; /* slave prefered conn interval range */ tBTM_BLE_SERVICE services; /* services */ + tBTM_BLE_32SERVICE service_32b; /* 32 bits Service UUID */ + tBTM_BLE_32SERVICE sol_service_32b; /* List of 32 bit Service Solicitation UUIDs */ UINT16 appearance; UINT8 flag; tBTM_BLE_PROPRIETARY *p_proprietary; @@ -434,19 +471,6 @@ BTM_API extern tBTM_STATUS BTM_BleWriteScanRsp(tBTM_BLE_AD_MASK data_mask, /******************************************************************************* ** -** Function BTM_BleReset -** -** Description This function is called to reset ULP controller. -** -** Parameters None. -** -** Returns void -** -*******************************************************************************/ -BTM_API extern void BTM_BleReset(void); - -/******************************************************************************* -** ** Function BTM_BleObserve ** ** Description This procedure keep the device listening for advertising @@ -866,25 +890,28 @@ void BTM_BleTestEnd(tBTM_CMPL_CB *p_cmd_cmpl_cback); /******************************************************************************* ** -** Function BTM_IsBleLink +** Function BTM_UseLeLink ** -** Description This function is to check the link type is BLE or BR/EDR. +** Description This function is to select the underneath physical link to use. ** -** Returns TRUE if BLE link; FALSE if BR/EDR. +** Returns TRUE to use LE, FALSE use BR/EDR. ** *******************************************************************************/ -BTM_API extern BOOLEAN BTM_IsBleLink (BD_ADDR bd_addr); +BTM_API extern BOOLEAN BTM_UseLeLink (BD_ADDR bd_addr); /******************************************************************************* ** -** Function BTM_UseLeLink +** Function BTM_BleStackEnable ** -** Description This function is to select the underneath physical link to use. +** Description Enable/Disable BLE functionality on stack regarless controller +** capability. ** -** Returns TRUE to use LE, FALSE use BR/EDR. +** Parameters: enable: TRUE to enable, FALSE to disable. +** +** Returns TRUE if added OK, else FALSE ** *******************************************************************************/ -BTM_API extern BOOLEAN BTM_UseLeLink (BD_ADDR bd_addr); +BTM_API extern tBTM_STATUS BTM_BleStackEnable (BOOLEAN enable); #ifdef __cplusplus } diff --git a/stack/include/btu.h b/stack/include/btu.h index 4f0e1622c..805fea79f 100644 --- a/stack/include/btu.h +++ b/stack/include/btu.h @@ -153,10 +153,15 @@ typedef void (*tBTU_EVENT_CALLBACK)(BT_HDR *p_hdr); #define BTU_TTYPE_ATT_WAIT_FOR_APP_RSP 104 #define BTU_TTYPE_ATT_WAIT_FOR_IND_ACK 105 -#define BTU_TTYPE_UCD_TO 106 +#define BTU_TTYPE_L2CAP_END_CONN_UPD 106 + +#define BTU_TTYPE_BLE_GAP_FAST_ADV 107 +#define BTU_TTYPE_BLE_OBSERVE 108 + + +#define BTU_TTYPE_UCD_TO 109 + -/* BTU timer event for TBFC */ -#define BTU_TTYPE_TBFC_RESUME 107 /* Define the BTU_TASK APPL events */ diff --git a/stack/include/gap_api.h b/stack/include/gap_api.h index a17510fc7..645323d2c 100644 --- a/stack/include/gap_api.h +++ b/stack/include/gap_api.h @@ -225,6 +225,9 @@ typedef union typedef void (tGAP_BLE_DEV_NAME_CBACK)(BOOLEAN status, BD_ADDR addr, UINT16 length, char *p_name); typedef void (tGAP_BLE_RECONN_ADDR_CBACK)(BOOLEAN status, BD_ADDR addr, BD_ADDR reconn_bda); +#if BLE_PRIVACY_SPT == TRUE +typedef void (tGAP_BLE_PRIVACY_CBACK)(BOOLEAN status, BD_ADDR addr, BOOLEAN privacy_enabled); +#endif /***************************************************************************** ** External Function Declarations @@ -440,10 +443,16 @@ GAP_API extern UINT16 GAP_SetPairableMode (UINT16 mode, BOOLEAN connect_only_pai ** ** Description This function is called to initiate bonding with peer device ** +** Parameters: bd_addr - Address of the device to bond +** pin_len - length in bytes of the PIN Code +** p_pin - pointer to array with the PIN Code +** trusted_mask - bitwise OR of trusted services (array of UINT32) +** ** Returns tBTM_STATUS - BTM_CMD_STARTED of successfully initiated ** *******************************************************************************/ -GAP_API extern UINT8 GAP_Bond (BD_ADDR bd_addr, UINT8 pin_len, UINT8 *p_pin, UINT32 trusted_mask[]); +GAP_API extern UINT8 GAP_Bond (BD_ADDR bd_addr, UINT8 pin_len, + UINT8 *p_pin, UINT32 trusted_mask[]); /******************************************************************************* ** diff --git a/stack/include/gatt_api.h b/stack/include/gatt_api.h index f3df8b7ea..9da7d9c04 100644 --- a/stack/include/gatt_api.h +++ b/stack/include/gatt_api.h @@ -25,44 +25,47 @@ ** Constants *****************************************************************************/ /* Success code and error codes */ -#define GATT_SUCCESS 0x0000 -#define GATT_INVALID_HANDLE 0x0001 -#define GATT_READ_NOT_PERMIT 0x0002 -#define GATT_WRITE_NOT_PERMIT 0x0003 -#define GATT_INVALID_PDU 0x0004 -#define GATT_INSUF_AUTHENTICATION 0x0005 -#define GATT_REQ_NOT_SUPPORTED 0x0006 -#define GATT_INVALID_OFFSET 0x0007 -#define GATT_INSUF_AUTHORIZATION 0x0008 -#define GATT_PREPARE_Q_FULL 0x0009 -#define GATT_NOT_FOUND 0x000a -#define GATT_NOT_LONG 0x000b -#define GATT_INSUF_KEY_SIZE 0x000c -#define GATT_INVALID_ATTR_LEN 0x000d -#define GATT_ERR_UNLIKELY 0x000e -#define GATT_INSUF_ENCRYPTION 0x000f -#define GATT_UNSUPPORT_GRP_TYPE 0x0010 -#define GATT_INSUF_RESOURCE 0x0011 - - -#define GATT_ILLEGAL_PARAMETER 0x0087 -#define GATT_NO_RESOURCES 0x0080 -#define GATT_INTERNAL_ERROR 0x0081 -#define GATT_WRONG_STATE 0x0082 -#define GATT_DB_FULL 0x0083 -#define GATT_BUSY 0x0084 -#define GATT_ERROR 0x0085 -#define GATT_CMD_STARTED 0x0086 -#define GATT_PENDING 0x0088 -#define GATT_AUTH_FAIL 0x0089 -#define GATT_MORE 0x008a -#define GATT_INVALID_CFG 0x008b -#define GATT_SERVICE_STARTED 0x008c +#define GATT_SUCCESS 0x00 +#define GATT_INVALID_HANDLE 0x01 +#define GATT_READ_NOT_PERMIT 0x02 +#define GATT_WRITE_NOT_PERMIT 0x03 +#define GATT_INVALID_PDU 0x04 +#define GATT_INSUF_AUTHENTICATION 0x05 +#define GATT_REQ_NOT_SUPPORTED 0x06 +#define GATT_INVALID_OFFSET 0x07 +#define GATT_INSUF_AUTHORIZATION 0x08 +#define GATT_PREPARE_Q_FULL 0x09 +#define GATT_NOT_FOUND 0x0a +#define GATT_NOT_LONG 0x0b +#define GATT_INSUF_KEY_SIZE 0x0c +#define GATT_INVALID_ATTR_LEN 0x0d +#define GATT_ERR_UNLIKELY 0x0e +#define GATT_INSUF_ENCRYPTION 0x0f +#define GATT_UNSUPPORT_GRP_TYPE 0x10 +#define GATT_INSUF_RESOURCE 0x11 + + +#define GATT_ILLEGAL_PARAMETER 0x87 +#define GATT_NO_RESOURCES 0x80 +#define GATT_INTERNAL_ERROR 0x81 +#define GATT_WRONG_STATE 0x82 +#define GATT_DB_FULL 0x83 +#define GATT_BUSY 0x84 +#define GATT_ERROR 0x85 +#define GATT_CMD_STARTED 0x86 +#define GATT_PENDING 0x88 +#define GATT_AUTH_FAIL 0x89 +#define GATT_MORE 0x8a +#define GATT_INVALID_CFG 0x8b +#define GATT_SERVICE_STARTED 0x8c #define GATT_ENCRYPED_MITM GATT_SUCCESS -#define GATT_ENCRYPED_NO_MITM 0x008d -#define GATT_NOT_ENCRYPTED 0x008e - +#define GATT_ENCRYPED_NO_MITM 0x8d +#define GATT_NOT_ENCRYPTED 0x8e + /* 0xE0 ~ 0xFC reserved for future use */ +#define GATT_CCC_CFG_ERR 0xFD /* Client Characteristic Configuration Descriptor Improperly Configured */ +#define GATT_PRC_IN_PROGRESS 0xFE /* Procedure Already in progress */ +#define GATT_OUT_OF_RANGE 0xFF /* Attribute value out of range */ typedef UINT8 tGATT_STATUS; @@ -325,12 +328,9 @@ typedef union } tGATTS_RSP; /* Transports for the primary service */ -enum -{ - GATT_TRANSPORT_LE, - GATT_TRANSPORT_BR_EDR, - GATT_TRANSPORT_LE_BR_EDR -}; +#define GATT_TRANSPORT_LE BT_TRANSPORT_LE +#define GATT_TRANSPORT_BR_EDR BT_TRANSPORT_BR_EDR +#define GATT_TRANSPORT_LE_BR_EDR (BT_TRANSPORT_LE|BT_TRANSPORT_BR_EDR) typedef UINT8 tGATT_TRANSPORT; #define GATT_PREP_WRITE_CANCEL 0x00 @@ -548,26 +548,30 @@ typedef struct typedef UINT8 tGATT_IF; -#define GATT_LINK_IDLE_TIMEOUT_WHEN_NO_APP 0 /* start a idle timer for this duration when no application - need to use the link */ +#define GATT_LINK_IDLE_TIMEOUT_WHEN_NO_APP 0 /* start a idle timer for this duration + when no application need to use the link */ #define GATT_LINK_NO_IDLE_TIMEOUT 0xFFFF #define GATT_INVALID_ACL_HANDLE 0xFFFF /* discover result callback function */ -typedef void (tGATT_DISC_RES_CB) (UINT16 conn_id, tGATT_DISC_TYPE disc_type, tGATT_DISC_RES *p_data); +typedef void (tGATT_DISC_RES_CB) (UINT16 conn_id, tGATT_DISC_TYPE disc_type, + tGATT_DISC_RES *p_data); /* discover complete callback function */ typedef void (tGATT_DISC_CMPL_CB) (UINT16 conn_id, tGATT_DISC_TYPE disc_type, tGATT_STATUS status); /* Define a callback function for when read/write/disc/config operation is completed. */ -typedef void (tGATT_CMPL_CBACK) (UINT16 conn_id, tGATTC_OPTYPE op, tGATT_STATUS status, tGATT_CL_COMPLETE *p_data); +typedef void (tGATT_CMPL_CBACK) (UINT16 conn_id, tGATTC_OPTYPE op, tGATT_STATUS status, + tGATT_CL_COMPLETE *p_data); /* Define a callback function when an initialized connection is established. */ -typedef void (tGATT_CONN_CBACK) (tGATT_IF gatt_if, BD_ADDR bda, UINT16 conn_id, BOOLEAN connected, tGATT_DISCONN_REASON reason); +typedef void (tGATT_CONN_CBACK) (tGATT_IF gatt_if, BD_ADDR bda, UINT16 conn_id, BOOLEAN connected, + tGATT_DISCONN_REASON reason, tBT_TRANSPORT transport); /* attribute request callback for ATT server */ -typedef void (tGATT_REQ_CBACK )(UINT16 conn_id, UINT32 trans_id, tGATTS_REQ_TYPE type, tGATTS_DATA *p_data); +typedef void (tGATT_REQ_CBACK )(UINT16 conn_id, UINT32 trans_id, tGATTS_REQ_TYPE type, + tGATTS_DATA *p_data); /* Define a callback function when encryption is established. */ typedef void (tGATT_ENC_CMPL_CB)(tGATT_IF gatt_if, BD_ADDR bda); @@ -639,7 +643,8 @@ typedef struct /* Attibute server handle ranges NV storage callback functions */ typedef void (tGATTS_NV_SAVE_CBACK)(BOOLEAN is_saved, tGATTS_HNDL_RANGE *p_hndl_range); -typedef BOOLEAN (tGATTS_NV_SRV_CHG_CBACK)(tGATTS_SRV_CHG_CMD cmd, tGATTS_SRV_CHG_REQ *p_req, tGATTS_SRV_CHG_RSP *p_rsp); +typedef BOOLEAN (tGATTS_NV_SRV_CHG_CBACK)(tGATTS_SRV_CHG_CMD cmd, tGATTS_SRV_CHG_REQ *p_req, + tGATTS_SRV_CHG_RSP *p_rsp); typedef struct { @@ -801,7 +806,8 @@ extern "C" ** Returns TRUE if operation succeed, FALSE if handle block was not found. ** *******************************************************************************/ - GATT_API extern BOOLEAN GATTS_DeleteService (tGATT_IF gatt_if, tBT_UUID *p_svc_uuid, UINT16 svc_inst); + GATT_API extern BOOLEAN GATTS_DeleteService (tGATT_IF gatt_if, tBT_UUID *p_svc_uuid, + UINT16 svc_inst); /******************************************************************************* ** @@ -998,11 +1004,13 @@ extern "C" ** ** Parameter bd_addr: target device bd address. ** idle_tout: timeout value in seconds. +** transport: trasnport option. ** ** Returns void ** *******************************************************************************/ - GATT_API extern void GATT_SetIdleTimeout (BD_ADDR bd_addr, UINT16 idle_tout); + GATT_API extern void GATT_SetIdleTimeout (BD_ADDR bd_addr, UINT16 idle_tout, + tGATT_TRANSPORT transport); /******************************************************************************* @@ -1058,11 +1066,13 @@ extern "C" ** Parameters gatt_if: applicaiton interface ** bd_addr: peer device address. ** is_direct: is a direct conenection or a background auto connection +** transport : Physical transport for GATT connection (BR/EDR or LE) ** ** Returns TRUE if connection started; FALSE if connection start failure. ** *******************************************************************************/ - GATT_API extern BOOLEAN GATT_Connect (tGATT_IF gatt_if, BD_ADDR bd_addr, BOOLEAN is_direct); + GATT_API extern BOOLEAN GATT_Connect (tGATT_IF gatt_if, BD_ADDR bd_addr, + BOOLEAN is_direct, tBT_TRANSPORT transport); /******************************************************************************* @@ -1080,7 +1090,8 @@ extern "C" ** Returns TRUE if connection started; FALSE if connection start failure. ** *******************************************************************************/ - GATT_API extern BOOLEAN GATT_CancelConnect (tGATT_IF gatt_if, BD_ADDR bd_addr, BOOLEAN is_direct); + GATT_API extern BOOLEAN GATT_CancelConnect (tGATT_IF gatt_if, BD_ADDR bd_addr, + BOOLEAN is_direct); /******************************************************************************* ** @@ -1108,11 +1119,13 @@ extern "C" ** Parameters conn_id: connection id (input) ** p_gatt_if: applicaiton interface (output) ** bd_addr: peer device address. (output) +** transport : physical transport of the GATT connection (BR/EDR or LE) ** ** Returns TRUE the ligical link information is found for conn_id ** *******************************************************************************/ - GATT_API extern BOOLEAN GATT_GetConnectionInfor(UINT16 conn_id, tGATT_IF *p_gatt_if, BD_ADDR bd_addr); + GATT_API extern BOOLEAN GATT_GetConnectionInfor(UINT16 conn_id, tGATT_IF *p_gatt_if, + BD_ADDR bd_addr, tBT_TRANSPORT *p_transport); /******************************************************************************* @@ -1125,11 +1138,13 @@ extern "C" ** Parameters gatt_if: applicaiton interface (input) ** bd_addr: peer device address. (input) ** p_conn_id: connection id (output) +** transport : physical transport of the GATT connection (BR/EDR or LE) ** ** Returns TRUE the ligical link is connected ** *******************************************************************************/ - GATT_API extern BOOLEAN GATT_GetConnIdIfConnected(tGATT_IF gatt_if, BD_ADDR bd_addr, UINT16 *p_conn_id); + GATT_API extern BOOLEAN GATT_GetConnIdIfConnected(tGATT_IF gatt_if, BD_ADDR bd_addr, + UINT16 *p_conn_id, tBT_TRANSPORT transport); /******************************************************************************* diff --git a/stack/include/hcidefs.h b/stack/include/hcidefs.h index ad31d52bb..14ae89351 100644 --- a/stack/include/hcidefs.h +++ b/stack/include/hcidefs.h @@ -231,11 +231,11 @@ #define HCI_SET_MWS_PATTERN_CONFIGURATION (0x0073 | HCI_GRP_HOST_CONT_BASEBAND_CMDS) /* ConnectionLess Broadcast */ -#define HCI_SET_RESERVED_LT_ADDR (0x0077 | HCI_GRP_HOST_CONT_BASEBAND_CMDS) -#define HCI_DELETE_RESERVED_LT_ADDR (0x0078 | HCI_GRP_HOST_CONT_BASEBAND_CMDS) -#define HCI_WRITE_CLB_DATA (0x0079 | HCI_GRP_HOST_CONT_BASEBAND_CMDS) -#define HCI_WRITE_SYNC_TRAIN_PARAM (0x007A | HCI_GRP_HOST_CONT_BASEBAND_CMDS) -#define HCI_READ_SYNC_TRAIN_PARAM (0x007B | HCI_GRP_HOST_CONT_BASEBAND_CMDS) +#define HCI_SET_RESERVED_LT_ADDR (0x0074 | HCI_GRP_HOST_CONT_BASEBAND_CMDS) +#define HCI_DELETE_RESERVED_LT_ADDR (0x0075 | HCI_GRP_HOST_CONT_BASEBAND_CMDS) +#define HCI_WRITE_CLB_DATA (0x0076 | HCI_GRP_HOST_CONT_BASEBAND_CMDS) +#define HCI_READ_SYNC_TRAIN_PARAM (0x0077 | HCI_GRP_HOST_CONT_BASEBAND_CMDS) +#define HCI_WRITE_SYNC_TRAIN_PARAM (0x0078 | HCI_GRP_HOST_CONT_BASEBAND_CMDS) #define HCI_CONT_BASEBAND_CMDS_FIRST HCI_SET_EVENT_MASK #define HCI_CONT_BASEBAND_CMDS_LAST HCI_READ_SYNC_TRAIN_PARAM @@ -323,13 +323,17 @@ #define HCI_BLE_LTK_REQ_REPLY (0x001A | HCI_GRP_BLE_CMDS) #define HCI_BLE_LTK_REQ_NEG_REPLY (0x001B | HCI_GRP_BLE_CMDS) #define HCI_BLE_READ_SUPPORTED_STATES (0x001C | HCI_GRP_BLE_CMDS) + /*0x001D, 0x001E and 0x001F are reserved*/ + +#define HCI_BLE_RC_PARAM_REQ_REPLY (0x0020 | HCI_GRP_BLE_CMDS) +#define HCI_BLE_RC_PARAM_REQ_NEG_REPLY (0x0021 | HCI_GRP_BLE_CMDS) + + /* BLE TEST COMMANDS */ #define HCI_BLE_RECEIVER_TEST (0x001D | HCI_GRP_BLE_CMDS) #define HCI_BLE_TRANSMITTER_TEST (0x001E | HCI_GRP_BLE_CMDS) #define HCI_BLE_TEST_END (0x001F | HCI_GRP_BLE_CMDS) -#define HCI_BLE_RESET (0x0020 | HCI_GRP_BLE_CMDS) - /* LE supported states definition */ #define HCI_LE_ADV_STATE 0x00000001 #define HCI_LE_SCAN_STATE 0x00000002 @@ -344,6 +348,214 @@ #define HCI_LE_SCAN_SL_STATE 0x00000400 #define HCI_LE_INIT_MA_STATE 0x00000800 +/* LE Supported States */ +/* Non Connectable Adv state is supported. 0x0000000000000001 */ +#define HCI_SUPP_LE_STATES_NON_CONN_ADV_MASK 0x01 +#define HCI_SUPP_LE_STATES_NON_CONN_ADV_OFF 0 +#define HCI_LE_STATES_NON_CONN_ADV_SUPPORTED(x) ((x)[HCI_SUPP_LE_STATES_NON_CONN_ADV_OFF] & HCI_SUPP_LE_STATES_NON_CONN_ADV_MASK) + +/*Scanneable Connectable Adv state is supported. 0x0000000000000002 */ +#define HCI_SUPP_LE_STATES_SCAN_ADV_MASK 0x02 +#define HCI_SUPP_LE_STATESSCAN_ADV_OFF 0 +#define HCI_LE_STATES_SCAN_ADV_SUPPORTED(x) ((x)[HCI_SUPP_LE_STATESSCAN_ADV_OFF] & HCI_SUPP_LE_STATES_SCAN_ADV_MASK) + +/* Connectable Adv state is supported. 0x0000000000000004 */ +#define HCI_SUPP_LE_STATES_CONN_ADV_MASK 0x04 +#define HCI_SUPP_LE_STATES_CONN_ADV_OFF 0 +#define HCI_LE_STATES_CONN_ADV_SUPPORTED(x) ((x)[HCI_SUPP_LE_STATES_CONN_ADV_OFF] & HCI_SUPP_LE_STATES_CONN_ADV_MASK) + +/* Hi duty Cycle Directed Adv state is supported. 0x0000000000000008 */ +#define HCI_SUPP_LE_STATES_HI_DUTY_DIR_ADV_MASK 0x08 +#define HCI_SUPP_LE_STATES_HI_DUTY_DIR_ADV_OFF 0 +#define HCI_LE_STATES_HI_DUTY_DIR_ADV_SUPPORTED(x) ((x)[HCI_SUPP_LE_STATES_HI_DUTY_DIR_ADV_OFF] & HCI_SUPP_LE_STATES_HI_DUTY_DIR_ADV_MASK) + +/* Passive Scan state is supported. 0x0000000000000010 */ +#define HCI_SUPP_LE_STATES_PASS_SCAN_MASK 0x10 +#define HCI_SUPP_LE_STATES_PASS_SCAN_OFF 0 +#define HCI_LE_STATES_PASS_SCAN_SUPPORTED(x) ((x)[HCI_SUPP_LE_STATES_PASS_SCAN_OFF] & HCI_SUPP_LE_STATES_PASS_SCAN_MASK) + +/* Active Scan state is supported. 0x0000000000000020 */ +#define HCI_SUPP_LE_STATES_ACTIVE_SCAN_MASK 0x20 +#define HCI_SUPP_LE_STATES_ACTIVE_SCAN_OFF 0 +#define HCI_LE_STATES_ACTIVE_SCAN_SUPPORTED(x) ((x)[HCI_SUPP_LE_STATES_ACTIVE_SCAN_OFF] & HCI_SUPP_LE_STATES_ACTIVE_SCAN_MASK) + +/* Initiating state is supported. 0x0000000000000040 (or connection state in master role is also supported) */ +#define HCI_SUPP_LE_STATES_INIT_MASK 0x40 +#define HCI_SUPP_LE_STATES_INIT_OFF 0 +#define HCI_LE_STATES_INIT_SUPPORTED(x) ((x)[HCI_SUPP_LE_STATES_INIT_OFF] & HCI_SUPP_LE_STATES_INIT_MASK) + +/*connection state in slave role is also supported. 0x0000000000000080 */ +#define HCI_SUPP_LE_STATES_SLAVE_MASK 0x80 +#define HCI_SUPP_LE_STATES_SLAVE_OFF 0 +#define HCI_LE_STATES_SLAVE_SUPPORTED(x) ((x)[HCI_SUPP_LE_STATES_SLAVE_OFF] & HCI_SUPP_LE_STATES_SLAVE_MASK) + +/* Non Connectable Adv state and Passive Scanning State combination is supported. 0x0000000000000100 */ +#define HCI_SUPP_LE_STATES_NON_CONN_ADV_PASS_SCAN_MASK 0x01 +#define HCI_SUPP_LE_STATES_NON_CONN_ADV_PASS_SCAN_OFF 1 +#define HCI_LE_STATES_NON_CONN_ADV_PASS_SCAN_SUPPORTED(x) ((x)[HCI_SUPP_LE_STATES_NON_CONN_ADV_PASS_SCAN_OFF] & HCI_SUPP_LE_STATES_NON_CONN_ADV_PASS_SCAN_MASK) + +/*Scannable Adv state and Passive Scanning State combination is supported. 0x0000000000000200 */ +#define HCI_SUPP_LE_STATES_SCAN_ADV_PASS_SCAN_MASK 0x02 +#define HCI_SUPP_LE_STATES_SCAN_ADV_PASS_SCAN_OFF 1 +#define HCI_LE_STATES_SCAN_ADV_PASS_SCAN_SUPPORTED(x) ((x)[HCI_SUPP_LE_STATES_SCAN_ADV_PASS_SCAN_OFF] & HCI_SUPP_LE_STATES_SCAN_ADV_PASS_SCAN_MASK) + +/*Connectable Adv state and Passive Scanning State combination is supported. 0x0000000000000400 */ +#define HCI_SUPP_LE_STATES_CONN_ADV_PASS_SCAN_MASK 0x04 +#define HCI_SUPP_LE_STATES_CONN_ADV_PASS_SCAN_OFF 1 +#define HCI_LE_STATES_CONN_ADV_PASS_SCAN_SUPPORTED(x) ((x)[HCI_SUPP_LE_STATES_CONN_ADV_PASS_SCAN_OFF] & HCI_SUPP_LE_STATES_CONN_ADV_PASS_SCAN_MASK) + +/*High Duty Cycl Directed ADv and Passive Scanning State combination is supported. 0x0000000000000800 */ +#define HCI_SUPP_LE_STATES_HI_DUTY_DIR_ADV_PASS_SCAN_MASK 0x08 +#define HCI_SUPP_LE_STATES_HI_DUTY_DIR_ADV_PASS_SCAN_OFF 1 +#define HCI_LE_STATES_HI_DUTY_DIR_ADV_PASS_SCAN_SUPPORTED(x) ((x)[HCI_SUPP_LE_STATES_HI_DUTY_DIR_ADV_PASS_SCAN_MASK] & HCI_SUPP_LE_STATES_HI_DUTY_DIR_ADV_PASS_SCAN_OFF) + +/*Non Connectable Adv state and Passive Scanning State combination is supported. 0x0000000000001000 */ +#define HCI_SUPP_LE_STATES_NON_CONN_ADV_ACTIVE_SCAN_MASK 0x10 +#define HCI_SUPP_LE_STATES_NON_CONN_ADV_ACTIVE_SCAN_OFF 1 +#define HCI_LE_STATES_NON_CONN_ADV_ACTIVE_SCAN_SUPPORTED(x) ((x)[HCI_SUPP_LE_STATES_NON_CONN_ADV_ACTIVE_SCAN_OFF] & HCI_SUPP_LE_STATES_NON_CONN_ADV_ACTIVE_SCAN_MASK) + +/*Scannable Adv state and Active Scanning State combination is supported. 0x0000000000002000 */ +#define HCI_SUPP_LE_STATES_SCAN_ADV_ACTIVE_SCAN_MASK 0x20 +#define HCI_SUPP_LE_STATES_SCAN_ADV_ACTIVE_SCAN_OFF 1 +#define HCI_LE_STATES_SCAN_ADV_ACTIVE_SCAN_SUPPORTED(x) ((x)[HCI_SUPP_LE_STATES_SCAN_ADV_ACTIVE_SCAN_OFF] & HCI_SUPP_LE_STATES_SCAN_ADV_ACTIVE_SCAN_MASK) + +/*Connectable Adv state and Active Scanning State combination is supported. 0x0000000000004000 */ +#define HCI_SUPP_LE_STATES_CONN_ADV_ACTIVE_SCAN_MASK 0x40 +#define HCI_SUPP_LE_STATES_CONN_ADV_ACTIVE_SCAN_OFF 1 +#define HCI_LE_STATES_CONN_ADV_ACTIVE_SCAN_SUPPORTED(x) ((x)[HCI_SUPP_LE_STATES_CONN_ADV_ACTIVE_SCAN_OFF] & HCI_SUPP_LE_STATES_CONN_ADV_ACTIVE_SCAN_MASK) + +/*High Duty Cycl Directed ADv and ACtive Scanning State combination is supported. 0x0000000000008000 */ +#define HCI_SUPP_LE_STATES_HI_DUTY_DIR_ADV_ACTIVE_SCAN_MASK 0x80 +#define HCI_SUPP_LE_STATES_HI_DUTY_DIR_ADV_ACTIVE_SCAN_OFF 1 +#define HCI_LE_STATES_HI_DUTY_DIR_ADV_ACTIVE_SCAN_SUPPORTED(x) ((x)[HCI_SUPP_LE_STATES_HI_DUTY_DIR_ADV_ACTIVE_SCAN_MASK] & HCI_SUPP_LE_STATES_HI_DUTY_DIR_ADV_ACTIVE_SCAN_OFF) + +/*Non-Connectable Adv state and Initiating State combination is supported. 0x0000000000010000 */ +#define HCI_SUPP_LE_STATES_NON_CONN_INIT_MASK 0x01 +#define HCI_SUPP_LE_STATES_NON_CONN_INIT_OFF 2 +#define HCI_LE_STATES_NON_CONN_INIT_SUPPORTED(x) ((x)[HCI_SUPP_LE_STATES_NON_CONN_INIT_OFF] & HCI_SUPP_LE_STATES_NON_CONN_INIT_MASK) + +/* Scannable Adv state and Initiating State combination is supported. 0x0000000000020000 */ +#define HCI_SUPP_LE_STATES_SCAN_ADV_INIT_MASK 0x02 +#define HCI_SUPP_LE_STATES_SCAN_ADV_INIT_OFF 2 +#define HCI_LE_STATES_SCAN_ADV_INIT_SUPPORTED(x) ((x)[HCI_SUPP_LE_STATES_SCAN_ADV_INIT_OFF] & HCI_SUPP_LE_STATES_SCAN_ADV_INIT_MASK) + +/* Non-Connectable Adv state and Master Role combination is supported. 0x0000000000040000 */ +#define HCI_SUPP_LE_STATES_NON_CONN_ADV_MASTER_MASK 0x04 +#define HCI_SUPP_LE_STATES_NON_CONN_ADV_MASTER_OFF 2 +#define HCI_LE_STATES_NON_CONN_ADV_MASTER_SUPPORTED(x) ((x)[HCI_SUPP_LE_STATES_NON_CONN_ADV_MASTER_OFF] & HCI_SUPP_LE_STATES_NON_CONN_ADV_MASTER_MASK) + +/*Scannable Adv state and Master Role combination is supported. 0x0000000000040000 */ +#define HCI_SUPP_LE_STATES_SCAN_ADV_MASTER_MASK 0x08 +#define HCI_SUPP_LE_STATES_SCAN_ADV_MASTER_OFF 2 +#define HCI_LE_STATES_SCAN_ADV_MASTER_SUPPORTED(x) ((x)[HCI_SUPP_LE_STATES_SCAN_ADV_MASTER_OFF] & HCI_SUPP_LE_STATES_SCAN_ADV_MASTER_MASK) + +/* Non-Connectable Adv and Slave Role combination is supported. 0x000000000100000 */ +#define HCI_SUPP_LE_STATES_NON_CONN_ADV_SLAVE_MASK 0x10 +#define HCI_SUPP_LE_STATES_NON_CONN_ADV_SLAVE_OFF 2 +#define HCI_LE_STATES_NON_CONN_ADV_SLAVE_SUPPORTED(x) ((x)[HCI_SUPP_LE_STATES_NON_CONN_ADV_SLAVE_OFF] & HCI_SUPP_LE_STATES_NON_CONN_ADV_SLAVE_MASK) + +/*Scannable Adv and Slave Role combination is supported. 0x000000000200000 */ +#define HCI_SUPP_LE_STATES_SCAN_ADV_SLAVE_MASK 0x20 +#define HCI_SUPP_LE_STATES_SCAN_ADV_SLAVE_OFF 2 +#define HCI_LE_STATES_SCAN_ADV_SLAVE_SUPPORTED(x) ((x)[HCI_SUPP_LE_STATES_SCAN_ADV_SLAVE_OFF] & HCI_SUPP_LE_STATES_SCAN_ADV_SLAVE_MASK) + +/*Passive Scan and Initiating State combination is supported. 0x000000000400000 */ +#define HCI_SUPP_LE_STATES_PASS_SCAN_INIT_MASK 0x40 +#define HCI_SUPP_LE_STATES_PASS_SCAN_INIT_OFF 2 +#define HCI_LE_STATES_PASS_SCAN_INIT_SUPPORTED(x) ((x)[HCI_SUPP_LE_STATES_PASS_SCAN_INIT_OFF] & HCI_SUPP_LE_STATES_PASS_SCAN_INIT_MASK) + +/*Active Scan and Initiating State combination is supported. 0x000000000800000 */ +#define HCI_SUPP_LE_STATES_ACTIVE_SCAN_INIT_MASK 0x80 +#define HCI_SUPP_LE_STATES_ACTIVE_SCAN_INIT_OFF 2 +#define HCI_LE_STATES_ACTIVE_SCAN_INIT_SUPPORTED(x) ((x)[HCI_SUPP_LE_STATES_ACTIVE_SCAN_INIT_OFF] & HCI_SUPP_LE_STATES_ACTIVE_SCAN_INIT_MASK) + +/*Passive Scan and Master Role combination is supported. 0x000000001000000 */ +#define HCI_SUPP_LE_STATES_PASS_SCAN_MASTER_MASK 0x01 +#define HCI_SUPP_LE_STATES_PASS_SCAN_MASTER_OFF 3 +#define HCI_LE_STATES_PASS_SCAN_MASTER_SUPPORTED(x) ((x)[HCI_SUPP_LE_STATES_PASS_SCAN_MASTER_OFF] & HCI_SUPP_LE_STATES_PASS_SCAN_MASTER_MASK) + +/*Active Scan and Master Role combination is supported. 0x000000002000000 */ +#define HCI_SUPP_LE_STATES_ACTIVE_SCAN_MASTER_MASK 0x02 +#define HCI_SUPP_LE_STATES_ACTIVE_SCAN_MASTER_OFF 3 +#define HCI_LE_STATES_ACTIVE_SCAN_MASTER_SUPPORTED(x) ((x)[HCI_SUPP_LE_STATES_ACTIVE_SCAN_MASTER_OFF] & HCI_SUPP_LE_STATES_ACTIVE_SCAN_MASTER_MASK) + +/*Passive Scan and Slave Role combination is supported. 0x000000004000000 */ +#define HCI_SUPP_LE_STATES_PASS_SCAN_SLAVE_MASK 0x04 +#define HCI_SUPP_LE_STATES_PASS_SCAN_SLAVE_OFF 3 +#define HCI_LE_STATES_PASS_SCAN_SLAVE_SUPPORTED(x) ((x)[HCI_SUPP_LE_STATES_PASS_SCAN_SLAVE_OFF] & HCI_SUPP_LE_STATES_PASS_SCAN_SLAVE_MASK) + +/*Active Scan and Slave Role combination is supported. 0x000000008000000 */ +#define HCI_SUPP_LE_STATES_ACTIVE_SCAN_SLAVE_MASK 0x08 +#define HCI_SUPP_LE_STATES_ACTIVE_SCAN_SLAVE_OFF 3 +#define HCI_LE_STATES_ACTIVE_SCAN_SLAVE_SUPPORTED(x) ((x)[HCI_SUPP_LE_STATES_ACTIVE_SCAN_SLAVE_OFF] & HCI_SUPP_LE_STATES_ACTIVE_SCAN_SLAVE_MASK) + +/*Link Layer Topology Added States Combo */ +/*Initiating State and Master Role combination supported. + Master Role and Master Role combination is also supported. 0x0000000010000000 */ +#define HCI_SUPP_LE_STATES_INIT_MASTER_MASK 0x10 +#define HCI_SUPP_LE_STATES_INIT_MASTER_OFF 3 +#define HCI_LE_STATES_INIT_MASTER_SUPPORTED(x) ((x)[HCI_SUPP_LE_STATES_INIT_MASTER_OFF] & HCI_SUPP_LE_STATES_INIT_MASTER_MASK) + +/* Connectable Advertising State and Initiating State combination supported. 0x0000000100000000 */ +#define HCI_SUPP_LE_STATES_CONN_ADV_INIT_MASK 0x01 +#define HCI_SUPP_LE_STATES_CONN_ADV_INIT_OFF 4 +#define HCI_LE_STATES_CONN_ADV_INIT_SUPPORTED(x) ((x)[HCI_SUPP_LE_STATES_CONN_ADV_INIT_OFF] & HCI_SUPP_LE_STATES_CONN_ADV_INIT_MASK) + +/* High Duty Cycle Directed Advertising State and Initiating State combination supported. */ +#define HCI_SUPP_LE_STATES_HI_DUTY_DIR_ADV_INIT_MASK 0x02 +#define HCI_SUPP_LE_STATES_HI_DUTY_DIR_ADV_INIT_OFF 4 +#define HCI_LE_STATES_HI_DUTY_DIR_ADV_INIT_SUPPORTED(x) ((x)[HCI_SUPP_LE_STATES_HI_DUTY_DIR_ADV_INIT_OFF] & HCI_SUPP_LE_STATES_HI_DUTY_DIR_ADV_INIT_MASK) + +/* Low Duty Cycle Directed Advertising State and Initiating State combination supported.*/ +#define HCI_SUPP_LE_STATES_LO_DUTY_DIR_ADV_INIT_MASK 0x04 +#define HCI_SUPP_LE_STATES_LO_DUTY_DIR_ADV_INIT_OFF 4 +#define HCI_LE_STATES_LO_DUTY_DIR_ADV_INIT_SUPPORTED(x) ((x)[HCI_SUPP_LE_STATES_LO_DUTY_DIR_ADV_INIT_OFF] & HCI_SUPP_LE_STATES_LO_DUTY_DIR_ADV_INIT_MASK) + +/* Connectable Advertising State and Master Role combination supported.*/ +#define HCI_SUPP_LE_STATES_CONN_ADV_MASTER_MASK 0x08 +#define HCI_SUPP_LE_STATES_CONN_ADV_MASTER_OFF 4 +#define HCI_LE_STATES_CONN_ADV_MASTER_SUPPORTED(x) ((x)[HCI_SUPP_LE_STATES_CONN_ADV_MASTER_OFF] & HCI_SUPP_LE_STATES_CONN_ADV_MASTER_MASK) + +/* High Duty Cycle Directed Advertising State and Master Role combination supported.*/ +#define HCI_SUPP_LE_STATES_HI_DUTY_DIR_ADV_MASTER_MASK 0x10 +#define HCI_SUPP_LE_STATES_HI_DUTY_DIR_ADV_MASTER_OFF 4 +#define HCI_LE_STATES_HI_DUTY_DIR_ADV_MASTER_SUPPORTED(x) ((x)[HCI_SUPP_LE_STATES_HI_DUTY_DIR_ADV_MASTER_OFF] & HCI_SUPP_LE_STATES_HI_DUTY_DIR_ADV_MASTER_MASK) + +/* Low Duty Cycle Directed Advertising State and Master Role combination supported.*/ +#define HCI_SUPP_LE_STATES_LO_DUTY_DIR_ADV_MASTER_MASK 0x20 +#define HCI_SUPP_LE_STATES_LO_DUTY_DIR_ADV_MASTER_OFF 4 +#define HCI_LE_STATES_LO_DUTY_DIR_ADV_MASTER_SUPPORTED(x) ((x)[HCI_SUPP_LE_STATES_LO_DUTY_DIR_ADV_MASTER_OFF] & HCI_SUPP_LE_STATES_LO_DUTY_DIR_ADV_MASTER_MASK) + +/* Connectable Advertising State and Slave Role combination supported. */ +#define HCI_SUPP_LE_STATES_CONN_ADV_SLAVE_MASK 0x40 +#define HCI_SUPP_LE_STATES_CONN_ADV_SLAVE_OFF 4 +#define HCI_LE_STATES_CONN_ADV_SLAVE_SUPPORTED(x) ((x)[HCI_SUPP_LE_STATES_CONN_ADV_SLAVE_OFF] & HCI_SUPP_LE_STATES_CONN_ADV_SLAVE_MASK) + +/* High Duty Cycle Directed Advertising State and slave Role combination supported.*/ +#define HCI_SUPP_LE_STATES_HI_DUTY_DIR_ADV_SLAVE_MASK 0x80 +#define HCI_SUPP_LE_STATES_HI_DUTY_DIR_ADV_SLAVE_OFF 4 +#define HCI_LE_STATES_HI_DUTY_DIR_ADV_SLAVE_SUPPORTED(x) ((x)[HCI_SUPP_LE_STATES_HI_DUTY_DIR_ADV_SLAVE_OFF] & HCI_SUPP_LE_STATES_HI_DUTY_DIR_ADV_SLAVE_MASK) + +/* Low Duty Cycle Directed Advertising State and slave Role combination supported.*/ +#define HCI_SUPP_LE_STATES_LO_DUTY_DIR_ADV_SLAVE_MASK 0x01 +#define HCI_SUPP_LE_STATES_LO_DUTY_DIR_ADV_SLAVE_OFF 5 +#define HCI_LE_STATES_LO_DUTY_DIR_ADV_SLAVE_SUPPORTED(x) ((x)[HCI_SUPP_LE_STATES_LO_DUTY_DIR_ADV_SLAVE_OFF] & HCI_SUPP_LE_STATES_LO_DUTY_DIR_ADV_SLAVE_MASK) + +/* Initiating State and Slave Role combination supported. + Master Role and Slave Role combination also supported. + */ +#define HCI_SUPP_LE_STATES_INIT_MASTER_SLAVE_MASK 0x02 +#define HCI_SUPP_LE_STATES_INIT_MASTER_SLAVE_OFF 5 +#define HCI_LE_STATES_INIT_MASTER_SLAVE_SUPPORTED(x) ((x)[HCI_SUPP_LE_STATES_INIT_MASTER_SLAVE_OFF] & HCI_SUPP_LE_STATES_INIT_MASTER_SLAVE_MASK) + +#define HCI_BRCM_ENABLE_WBS_MODIFIED (0x0102 | HCI_GRP_VENDOR_SPECIFIC) + +/* ConnectionLess Broadcast Stream VSC */ +#define HCI_BRCM_SET_CLB_STREAM (0x0111 | HCI_GRP_VENDOR_SPECIFIC) +#define HCI_BRCM_RECEIVE_CLB_STREAM (0x0112 | HCI_GRP_VENDOR_SPECIFIC) +#define HCI_BRCM_WRITE_CLB_STREAM_DATA (0x0113 | HCI_GRP_VENDOR_SPECIFIC) +#define HCI_BRCM_CLB_STREAM_FLUSH (0x0114 | HCI_GRP_VENDOR_SPECIFIC) + /* ** Definitions for HCI Events */ @@ -411,6 +623,7 @@ #define HCI_NUM_COMPL_DATA_BLOCKS_EVT 0x48 #define HCI_SHORT_RANGE_MODE_COMPLETE_EVT 0x4C #define HCI_AMP_STATUS_CHANGE_EVT 0x4D +#define HCI_SET_TRIGGERED_CLOCK_CAPTURE_EVT 0x4E /* ULP HCI Event */ #define HCI_BLE_EVENT 0x03E @@ -420,16 +633,11 @@ #define HCI_BLE_LL_CONN_PARAM_UPD_EVT 0x03 #define HCI_BLE_READ_REMOTE_FEAT_CMPL_EVT 0x04 #define HCI_BLE_LTK_REQ_EVT 0x05 +#define HCI_BLE_RC_PARAM_REQ_EVT 0x06 + +/* Definitions for LE Channel Map */ +#define HCI_BLE_CHNL_MAP_SIZE 5 -/* ConnectionLess Broadcast events */ -#define HCI_SYNC_TRAIN_COMP_EVT 0x4F -#define HCI_SYNC_TRAIN_RECEIVED_EVT 0x50 -#define HCI_CLB_RX_DATA_EVT 0x51 -#define HCI_CLB_RX_TIMEOUT_EVT 0x52 -#define HCI_TRUNCATED_PAGE_COMP_EVT 0x53 -#define HCI_SLAVE_PAGE_RESP_TIMEOUT_EVT 0x54 -#define HCI_CLB_CHANNEL_CHANGE_EVT 0x55 -#define HCI_INQUIRY_RESPONSE_NOTIF 0x56 #define HCI_EVENT_RSP_FIRST HCI_INQUIRY_COMP_EVT #define HCI_EVENT_RSP_LAST HCI_CLB_CHANNEL_CHANGE_EVT @@ -439,6 +647,9 @@ because conflict w/ TCI_EVT and per specification compliant */ +/* the event mask for BLE event mask */ +#define HCI_BLE_EVENT_MASK_DEF "\x00\x00\x00\x00\x00\x00\x00\x3f" + /* @@ -1583,6 +1794,10 @@ typedef struct #define HCI_EXT_FEATURE_SIMUL_DUMO_HOST_OFF 0 #define HCI_SIMUL_DUMO_HOST_SUPPORTED(x) ((x)[HCI_EXT_FEATURE_SIMUL_DUMO_HOST_OFF] & HCI_EXT_FEATURE_SIMUL_DUMO_HOST_MASK) +#define HCI_EXT_FEATURE_SC_HOST_MASK 0x08 +#define HCI_EXT_FEATURE_SC_HOST_OFF 0 +#define HCI_SC_HOST_SUPPORTED(x) ((x)[HCI_EXT_FEATURE_SC_HOST_OFF] & HCI_EXT_FEATURE_SC_HOST_MASK) + /* ** LMP features encoding - page 2 */ @@ -1606,19 +1821,43 @@ typedef struct #define HCI_EXT_FEATURE_INQ_RESP_NOTIF_OFF 0 #define HCI_INQ_RESP_NOTIF_SUPPORTED(x) ((x)[HCI_EXT_FEATURE_INQ_RESP_NOTIF_OFF] & HCI_EXT_FEATURE_INQ_RESP_NOTIF_MASK) +#define HCI_EXT_FEATURE_SC_CTRLR_MASK 0x01 +#define HCI_EXT_FEATURE_SC_CTRLR_OFF 1 +#define HCI_SC_CTRLR_SUPPORTED(x) ((x)[HCI_EXT_FEATURE_SC_CTRLR_OFF] & HCI_EXT_FEATURE_SC_CTRLR_MASK) + +#define HCI_EXT_FEATURE_PING_MASK 0x02 +#define HCI_EXT_FEATURE_PING_OFF 1 +#define HCI_PING_SUPPORTED(x) ((x)[HCI_EXT_FEATURE_PING_OFF] & HCI_EXT_FEATURE_PING_MASK) + /* ** LE features encoding - page 0 (the only page for now) */ +/* LE Encryption */ #define HCI_LE_FEATURE_LE_ENCRYPTION_MASK 0x01 #define HCI_LE_FEATURE_LE_ENCRYPTION_OFF 0 #define HCI_LE_ENCRYPTION_SUPPORTED(x) ((x)[HCI_LE_FEATURE_LE_ENCRYPTION_OFF] & HCI_LE_FEATURE_LE_ENCRYPTION_MASK) +/* Connection Parameters Request Procedure */ +#define HCI_LE_FEATURE_CONN_PARAM_REQ_MASK 0x02 +#define HCI_LE_FEATURE_CONN_PARAM_REQ_OFF 0 +#define HCI_LE_CONN_PARAM_REQ_SUPPORTED(x) ((x)[HCI_LE_FEATURE_CONN_PARAM_REQ_OFF] & HCI_LE_FEATURE_CONN_PARAM_REQ_MASK) + +/* Extended Reject Indication */ +#define HCI_LE_FEATURE_EXT_REJ_IND_MASK 0x04 +#define HCI_LE_FEATURE_EXT_REJ_IND_OFF 0 +#define HCI_LE_EXT_REJ_IND_SUPPORTED(x) ((x)[HCI_LE_FEATURE_EXT_REJ_IND_OFF] & HCI_LE_FEATURE_EXT_REJ_IND_MASK) + +/* Slave-initiated Features Exchange */ +#define HCI_LE_FEATURE_SLAVE_INIT_FEAT_EXC_MASK 0x08 +#define HCI_LE_FEATURE_SLAVE_INIT_FEAT_EXC_OFF 0 +#define HCI_LE_SLAVE_INIT_FEAT_EXC_SUPPORTED(x) ((x)[HCI_LE_FEATURE_SLAVE_INIT_FEAT_EXC_OFF] & HCI_LE_FEATURE_SLAVE_INIT_FEAT_EXC_MASK) /* ** Local Supported Commands encoding */ #define HCI_NUM_SUPP_COMMANDS_BYTES 64 +/* Supported Commands Byte 0 */ #define HCI_SUPP_COMMANDS_INQUIRY_MASK 0x01 #define HCI_SUPP_COMMANDS_INQUIRY_OFF 0 #define HCI_INQUIRY_SUPPORTED(x) ((x)[HCI_SUPP_COMMANDS_INQUIRY_OFF] & HCI_SUPP_COMMANDS_INQUIRY_MASK) @@ -2398,8 +2637,42 @@ typedef struct #define HCI_SUPP_COMMANDS_WRITE_SYNC_TRAIN_PARAM_OFF 32 #define HCI_WRITE_SYNC_TRAIN_PARAM_SUPPORTED(x) ((x)[HCI_SUPP_COMMANDS_WRITE_SYNC_TRAIN_PARAM_OFF] & HCI_SUPP_COMMANDS_WRITE_SYNC_TRAIN_PARAM) +#define HCI_SUPP_COMMANDS_REMOTE_OOB_EXTENDED_DATA_REQUEST_REPLY_MASK 0x02 +#define HCI_SUPP_COMMANDS_REMOTE_OOB_EXTENDED_DATA_REQUEST_REPLY_OFF 32 +#define HCI_REMOTE_OOB_EXTENDED_DATA_REQUEST_REPLY_SUPPORTED(x) ((x)[HCI_SUPP_COMMANDS_REMOTE_OOB_EXTENDED_DATA_REQUEST_REPLY_OFF] & HCI_SUPP_COMMANDS_REMOTE_OOB_EXTENDED_DATA_REQUEST_REPLY_MASK) + +#define HCI_SUPP_COMMANDS_READ_SECURE_CONNS_SUPPORT_MASK 0x04 +#define HCI_SUPP_COMMANDS_READ_SECURE_CONNS_SUPPORT_OFF 32 +#define HCI_READ_SECURE_CONNS_SUPPORT_SUPPORTED(x) ((x)[HCI_SUPP_COMMANDS_READ_SECURE_CONNS_SUPPORT_OFF] & HCI_SUPP_COMMANDS_READ_SECURE_CONNS_SUPPORT_MASK) + +#define HCI_SUPP_COMMANDS_WRITE_SECURE_CONNS_SUPPORT_MASK 0x08 +#define HCI_SUPP_COMMANDS_WRITE_SECURE_CONNS_SUPPORT_OFF 32 +#define HCI_WRITE_SECURE_CONNS_SUPPORT_SUPPORTED(x) ((x)[HCI_SUPP_COMMANDS_WRITE_SECURE_CONNS_SUPPORT_OFF] & HCI_SUPP_COMMANDS_WRITE_SECURE_CONNS_SUPPORT_MASK) + +#define HCI_SUPP_COMMANDS_READ_AUTHENT_PAYLOAD_TOUT_MASK 0x10 +#define HCI_SUPP_COMMANDS_READ_AUTHENT_PAYLOAD_TOUT_OFF 32 +#define HCI_READ_AUTHENT_PAYLOAD_TOUT_SUPPORTED(x) ((x)[HCI_SUPP_COMMANDS_READ_AUTHENT_PAYLOAD_TOUT_OFF] & HCI_SUPP_COMMANDS_READ_AUTHENT_PAYLOAD_TOUT_MASK) + +#define HCI_SUPP_COMMANDS_WRITE_AUTHENT_PAYLOAD_TOUT_MASK 0x20 +#define HCI_SUPP_COMMANDS_WRITE_AUTHENT_PAYLOAD_TOUT_OFF 32 +#define HCI_WRITE_AUTHENT_PAYLOAD_TOUT_SUPPORTED(x) ((x)[HCI_SUPP_COMMANDS_WRITE_AUTHENT_PAYLOAD_TOUT_OFF] & HCI_SUPP_COMMANDS_WRITE_AUTHENT_PAYLOAD_TOUT_MASK) + +#define HCI_SUPP_COMMANDS_READ_LOCAL_OOB_EXTENDED_DATA_MASK 0x40 +#define HCI_SUPP_COMMANDS_READ_LOCAL_OOB_EXTENDED_DATA_OFF 32 +#define HCI_READ_LOCAL_OOB_EXTENDED_DATA_SUPPORTED(x) ((x)[HCI_SUPP_COMMANDS_READ_LOCAL_OOB_EXTENDED_DATA_OFF] & HCI_SUPP_COMMANDS_READ_LOCAL_OOB_EXTENDED_DATA_MASK) + +#define HCI_SUPP_COMMANDS_WRITE_SECURE_CONNECTIONS_TEST_MODE_MASK 0x80 +#define HCI_SUPP_COMMANDS_WRITE_SECURE_CONNECTIONS_TEST_MODE_OFF 32 +#define HCI_WRITE_SECURE_CONNECTIONS_TEST_MODE_SUPPORTED(x) ((x)[HCI_SUPP_COMMANDS_WRITE_SECURE_CONNECTIONS_TEST_MODE_OFF] & HCI_SUPP_COMMANDS_WRITE_SECURE_CONNECTIONS_TEST_MODE_MASK) +/* supported LE remote control connection parameter request reply */ +#define HCI_SUPP_COMMANDS_LE_RC_CONN_PARAM_UPD_RPY_MASK 0x10 +#define HCI_SUPP_COMMANDS_LE_RC_CONN_PARAM_UPD_RPY_OFF 33 +#define HCI_LE_RC_CONN_PARAM_UPD_RPY_SUPPORTED(x) ((x)[HCI_SUPP_COMMANDS_LE_RC_CONN_PARAM_UPD_RPY_OFF] & HCI_SUPP_COMMANDS_LE_RC_CONN_PARAM_UPD_RPY_MASK) +#define HCI_SUPP_COMMANDS_RLE_RC_CONN_PARAM_UPD_NEG_RPY_MASK 0x20 +#define HCI_SUPP_COMMANDS_LE_RC_CONN_PARAM_UPD_NEG_RPY_OFF 33 +#define HCI_LE_RC_CONN_PARAM_UPD_NEG_RPY_SUPPORTED(x) ((x)[HCI_SUPP_COMMANDS_LE_RC_CONN_PARAM_UPD_NEG_RPY_OFF] & HCI_SUPP_COMMANDS_RLE_RC_CONN_PARAM_UPD_NEG_RPY_MASK) /* Commands of HCI_GRP_VENDOR_SPECIFIC group for WIDCOMM SW LM Simulator diff --git a/stack/include/hcimsgs.h b/stack/include/hcimsgs.h index 318e74819..3201f75d5 100644 --- a/stack/include/hcimsgs.h +++ b/stack/include/hcimsgs.h @@ -1252,8 +1252,6 @@ HCI_API extern void btsnd_hcie_ext_inquiry_result(void *buffer, UINT8 num_resp, #define HCIC_PARAM_SIZE_BLE_WRITE_ADV_DATA 31 /* ULP HCI command */ -HCI_API extern BOOLEAN btsnd_hcic_ble_reset(void); - HCI_API extern BOOLEAN btsnd_hcic_ble_set_evt_mask (BT_EVENT_MASK event_mask); HCI_API extern BOOLEAN btsnd_hcic_ble_read_buffer_size (void); @@ -1331,6 +1329,20 @@ HCI_API extern BOOLEAN btsnd_hcic_ble_transmitter_test(UINT8 tx_freq, UINT8 test UINT8 payload); HCI_API extern BOOLEAN btsnd_hcic_ble_test_end(void); +#if (defined BLE_LLT_INCLUDED) && (BLE_LLT_INCLUDED == TRUE) + +#define HCIC_PARAM_SIZE_BLE_RC_PARAM_REQ_REPLY 14 +HCI_API extern BOOLEAN btsnd_hcic_ble_rc_param_req_reply(UINT16 handle, + UINT16 conn_int_min, UINT16 conn_int_max, + UINT16 conn_latency, UINT16 conn_timeout, + UINT16 min_ce_len, UINT16 max_ce_len); + +#define HCIC_PARAM_SIZE_BLE_RC_PARAM_REQ_NEG_REPLY 3 +HCI_API extern BOOLEAN btsnd_hcic_ble_rc_param_req_neg_reply(UINT16 handle, UINT8 reason); + +#endif /* BLE_LLT_INCLUDED */ + + #endif /* BLE_INCLUDED */ #ifdef __cplusplus diff --git a/stack/include/l2c_api.h b/stack/include/l2c_api.h index 0da7f7969..54c7ddbcb 100644 --- a/stack/include/l2c_api.h +++ b/stack/include/l2c_api.h @@ -919,8 +919,9 @@ L2C_API extern BOOLEAN L2CA_UCDSetTxPriority ( BD_ADDR rem_bda, tL2CAP_CHNL_PRIO ** BD Address of remote ** TRUE if channel is connected, FALSE if disconnected ** Reason for connection failure +** transport : physical transport, BR/EDR or LE */ -typedef void (tL2CA_FIXED_CHNL_CB) (BD_ADDR, BOOLEAN, UINT16); +typedef void (tL2CA_FIXED_CHNL_CB) (BD_ADDR, BOOLEAN, UINT16, tBT_TRANSPORT); /* Signalling data received. Parameters are ** BD Address of remote @@ -1128,7 +1129,8 @@ L2C_API extern BOOLEAN L2CA_CancelBleConnectReq (BD_ADDR rem_bda); ** Return value: TRUE if update started ** *******************************************************************************/ -L2C_API extern BOOLEAN L2CA_UpdateBleConnParams (BD_ADDR rem_bdRa, UINT16 min_int, UINT16 max_int, UINT16 latency, UINT16 timeout); +L2C_API extern BOOLEAN L2CA_UpdateBleConnParams (BD_ADDR rem_bdRa, UINT16 min_int, + UINT16 max_int, UINT16 latency, UINT16 timeout); /******************************************************************************* ** @@ -1146,18 +1148,6 @@ L2C_API extern BOOLEAN L2CA_EnableUpdateBleConnParams (BD_ADDR rem_bda, BOOLEAN /******************************************************************************* ** -** Function L2CA_HandleConnUpdateEvent -** -** Description This function enables the connection update request from remote -** after a successful connection update response is received. -** -** Returns void -** -*******************************************************************************/ -L2C_API void L2CA_HandleConnUpdateEvent (UINT16 handle, UINT8 status); - -/******************************************************************************* -** ** Function L2CA_GetBleConnRole ** ** Description This function returns the connection role. @@ -1173,10 +1163,13 @@ L2C_API extern UINT8 L2CA_GetBleConnRole (BD_ADDR bd_addr); ** ** Description This function returns the disconnect reason code. ** +** Parameters: BD Address of remote +** Physical transport for the L2CAP connection (BR/EDR or LE) +** ** Returns disconnect reason ** *******************************************************************************/ -L2C_API extern UINT16 L2CA_GetDisconnectReason (BD_ADDR remote_bda); +L2C_API extern UINT16 L2CA_GetDisconnectReason (BD_ADDR remote_bda, tBT_TRANSPORT transport); #endif /* (BLE_INCLUDED == TRUE) */ diff --git a/stack/include/smp_api.h b/stack/include/smp_api.h index 68c9ebff5..e47cce321 100644 --- a/stack/include/smp_api.h +++ b/stack/include/smp_api.h @@ -134,9 +134,9 @@ typedef struct typedef struct { - UINT8 reason; - UINT8 sec_level; - BOOLEAN is_pair_cancel; + tSMP_STATUS reason; + tSMP_SEC_LEVEL sec_level; + BOOLEAN is_pair_cancel; } tSMP_CMPL; typedef union diff --git a/stack/include/uipc_msg.h b/stack/include/uipc_msg.h index 6a9a4ae4e..53cdccfc8 100644 --- a/stack/include/uipc_msg.h +++ b/stack/include/uipc_msg.h @@ -105,231 +105,6 @@ typedef struct t_uipc_log_msg } tUIPC_LOG_MSG; #define UIPC_LOG_MSGLEN (IPC_LOG_MSG_LEN + 4) -/******************************** - - H5 Sync Message - -********************************/ - -/* op_code */ -#define SLIP_SYNC_TO_LITE_REQ 0 -#define SLIP_SYNC_TO_LITE_RESP 1 -#define SLIP_SYNC_TO_FULL_REQ 2 -#define SLIP_SYNC_TO_FULL_RESP 3 -#define SLIP_SYNC_NOTIFY 4 - -/* status */ -#define SLIP_SYNC_SUCCESS 0 -#define SLIP_SYNC_FAILURE 1 - -typedef struct -{ - UINT8 op_code; - UINT8 status; - UINT16 acl_pkt_size; - UINT8 state; - UINT8 lp_state; /* Low Power state */ - UINT8 next_seqno; /* next send seq */ - UINT8 ack; /* next ack seq, expected seq from peer */ - UINT8 sent_ack; /* last sent ack */ - UINT8 sliding_window_size;/* window size */ - BOOLEAN oof_flow_control; /* Out of Frame SW Flow Control */ - BOOLEAN data_integrity_type;/* Level of Data Integrity Check */ - UINT8 rx_state; /* rx state for incoming packet processing */ -} tSLIP_SYNC_INFO; - -/******************************** - - L2CAP Sync Message - -********************************/ - -/* op_code */ -#define L2C_SYNC_TO_LITE_REQ 0 -#define L2C_SYNC_TO_LITE_RESP 1 -#define L2C_REMOVE_TO_LITE_REQ 2 -#define L2C_REMOVE_TO_LITE_RESP 3 -#define L2C_FLUSH_TO_FULL_IND 4 - -/* status */ -#define L2C_SYNC_SUCCESS 0 -#define L2C_SYNC_FAILURE 1 - -typedef struct t_l2c_stream_info -{ - UINT16 local_cid; /* Local CID */ - UINT16 remote_cid; /* Remote CID */ - UINT16 out_mtu; /* Max MTU we will send */ - UINT16 handle; /* The handle used with LM */ - UINT16 link_xmit_quota; /* Num outstanding pkts allowed */ - BOOLEAN is_flushable; /* TRUE if flushable channel */ -} tL2C_STREAM_INFO; - -typedef struct t_l2c_sync_to_lite_req -{ - UINT8 op_code; /* L2C_SYNC_TO_LITE_REQ */ - UINT16 light_xmit_quota; /* Total quota for light stack */ - UINT16 acl_data_size; /* Max ACL data size across HCI transport */ - UINT16 non_flushable_pbf; /* L2CAP_PKT_START_NON_FLUSHABLE if controller supports */ - /* Otherwise, L2CAP_PKT_START */ - UINT8 multi_av_data_cong_start; /* Multi-AV queue size to start congestion */ - UINT8 multi_av_data_cong_end; /* Multi-AV queue size to end congestion */ - UINT8 multi_av_data_cong_discard; /* Multi-AV queue size to discard */ - UINT8 num_stream; - tL2C_STREAM_INFO stream[BTM_SYNC_INFO_NUM_STR]; -} tL2C_SYNC_TO_LITE_REQ; - -typedef struct t_l2c_sync_to_lite_resp_stream -{ - UINT16 lcid; - UINT8 status; -} tL2C_SYNC_TO_LITE_RESP_STREAM; - -typedef struct t_l2c_sync_to_lite_resp -{ - UINT8 op_code; /* L2C_SYNC_TO_LITE_RESP */ - UINT16 light_xmit_unacked; /* unacked packet more than quota in light stack */ - UINT8 num_stream; - tL2C_SYNC_TO_LITE_RESP_STREAM stream[BTM_SYNC_INFO_NUM_STR]; -} tL2C_SYNC_TO_LITE_RESP; - -typedef struct t_l2c_remove_to_lite_req -{ - UINT8 op_code; /* L2C_REMOVE_TO_LITE_REQ */ - UINT16 light_xmit_quota; /* Total quota for light stack */ - UINT8 num_stream; - UINT16 lcid[BTM_SYNC_INFO_NUM_STR]; -} tL2C_REMOVE_TO_LITE_REQ; - -typedef tL2C_SYNC_TO_LITE_RESP tL2C_REMOVE_TO_LITE_RESP; -typedef tL2C_REMOVE_TO_LITE_REQ tL2C_FLUSH_TO_FULL_IND; - -typedef union t_l2c_sync_msg -{ - UINT8 op_code; - tL2C_SYNC_TO_LITE_REQ sync_req; - tL2C_SYNC_TO_LITE_RESP sync_resp; - tL2C_REMOVE_TO_LITE_REQ remove_req; - tL2C_REMOVE_TO_LITE_RESP remove_resp; - tL2C_FLUSH_TO_FULL_IND flush_ind; -} tL2C_SYNC_MSG; - -/******************************** - - AVDTP Sync Message - -********************************/ - -/* op_code */ -#define AVDT_SYNC_TO_LITE_REQ 0 -#define AVDT_SYNC_TO_LITE_RESP 1 -#define AVDT_RESYNC_TO_LITE_REQ 2 -#define AVDT_RESYNC_TO_LITE_RESP 3 -#define AVDT_SYNC_TO_FULL_REQ 4 -#define AVDT_SYNC_TO_FULL_RESP 5 -#define AVDT_REMOVE_TO_LITE_REQ 6 -#define AVDT_REMOVE_TO_LITE_RESP 7 -#define AVDT_SYNC_TO_BTC_LITE_REQ 8 -#define AVDT_SYNC_TO_BTC_LITE_RESP 9 - -/* status */ -#define AVDT_SYNC_SUCCESS 0 -#define AVDT_SYNC_FAILURE 1 - -typedef struct -{ - UINT16 lcid; - UINT32 ssrc; -} tAVDT_SYNC_TO_BTC_LITE_REQ_STREAM; - -typedef struct -{ - UINT8 opcode; /* AVDT_SYNC_TO_BTC_LITE_REQ */ - UINT8 num_stream; - tAVDT_SYNC_TO_BTC_LITE_REQ_STREAM stream[BTM_SYNC_INFO_NUM_STR]; -} tAVDT_SYNC_TO_BTC_LITE_REQ; - -typedef struct -{ - UINT8 opcode; /* AVDT_SYNC_TO_BTC_LITE_RESP */ - UINT8 status; -} tAVDT_SYNC_TO_BTC_LITE_RESP; - -typedef struct t_avdt_scb_sync_info -{ - UINT8 handle; /* SCB handle */ - BD_ADDR peer_addr; /* BD address of peer */ - UINT16 local_cid; /* Local CID */ - UINT16 peer_mtu; /* L2CAP mtu of the peer device */ - UINT8 mux_tsid_media; /* TSID for media transport session */ - UINT16 media_seq; /* media packet sequence number */ -} tAVDT_SCB_SYNC_INFO; - -typedef struct t_avdt_sync_info -{ - UINT8 op_code; - UINT8 status; - - tAVDT_SCB_SYNC_INFO scb_info[BTM_SYNC_INFO_NUM_STR]; - -} tAVDT_SYNC_INFO; - -typedef union t_avdt_sync_msg -{ - UINT8 op_code; - tAVDT_SYNC_INFO sync_info; - tAVDT_SYNC_TO_BTC_LITE_REQ btc_sync_req; - tAVDT_SYNC_TO_BTC_LITE_RESP btc_sync_resp; -} tAVDT_SYNC_MSG; - -/******************************** - - BTA AV Sync Message - -********************************/ - -/* op_code for MM light stack */ -#define BTA_AV_SYNC_TO_LITE_REQ 0 -#define BTA_AV_SYNC_TO_LITE_RESP 1 -#define BTA_AV_STR_START_TO_LITE_REQ 2 -#define BTA_AV_STR_START_TO_LITE_RESP 3 -#define BTA_AV_STR_STOP_TO_LITE_REQ 4 -#define BTA_AV_STR_STOP_TO_LITE_RESP 5 -#define BTA_AV_STR_CLEANUP_TO_LITE_REQ 6 -#define BTA_AV_STR_CLEANUP_TO_LITE_RESP 7 -#define BTA_AV_STR_SUSPEND_TO_LITE_REQ 8 -#define BTA_AV_STR_SUSPEND_TO_LITE_RESP 9 -#define BTA_AV_SYNC_ERROR_RESP 10 - -/* op_code for BTC light stack */ -#define A2DP_START_REQ 11 -#define A2DP_START_RESP 12 -#define A2DP_STOP_REQ 13 -#define A2DP_STOP_RESP 14 -#define A2DP_CLEANUP_REQ 15 -#define A2DP_CLEANUP_RESP 16 -#define A2DP_SUSPEND_REQ 17 -#define A2DP_SUSPEND_RESP 18 - -#define A2DP_JITTER_DONE_IND 41 /* For BTSNK */ - -#define AUDIO_CODEC_CONFIG_REQ 19 -#define AUDIO_CODEC_CONFIG_RESP 20 -#define AUDIO_CODEC_SET_BITRATE_REQ 21 -#define AUDIO_CODEC_FLUSH_REQ 22 -#define AUDIO_ROUTE_CONFIG_REQ 23 -#define AUDIO_ROUTE_CONFIG_RESP 24 -#define AUDIO_MIX_CONFIG_REQ 25 -#define AUDIO_MIX_CONFIG_RESP 26 -#define AUDIO_BURST_FRAMES_IND 27 -#define AUDIO_BURST_END_IND 28 -#define AUDIO_EQ_MODE_CONFIG_REQ 29 -#define AUDIO_SCALE_CONFIG_REQ 30 - -/* For TIVO, only applicable for I2S -> DAC */ -#define AUDIO_SUB_ROUTE_REQ 51 -#define AUDIO_SUB_ROUTE_RESP 52 - typedef struct { UINT8 opcode; /* A2DP_START_REQ */ @@ -789,96 +564,5 @@ typedef struct tMIX_SCALE_CONFIG mix_scale; } tAUDIO_SCALE_CONFIG_REQ; -typedef UINT8 tBTA_AV_DUAL_STACK_EVT; - -typedef struct -{ - UINT8 avdt_handle; /* AVDTP handle */ - UINT8 chnl; /* the channel: audio/video */ - UINT8 codec_type; /* codec type */ - BOOLEAN cong; /* TRUE if AVDTP congested */ - UINT8 hdi; /* the index to SCB[] */ - UINT8 hndl; /* the handle: ((hdi + 1)|chnl) */ - UINT8 l2c_bufs; /* the number of buffers queued to L2CAP */ - UINT16 l2c_cid; /* L2CAP channel ID */ - BD_ADDR peer_addr; /* peer BD address */ -}tBTA_AV_SYNC_INFO; - -typedef struct -{ - tBTA_AV_DUAL_STACK_EVT event; - tBTA_AV_SYNC_INFO sync_info; - UINT16 curr_mtu; /* common mtu shared by all active streams */ - UINT8 multi_av_supported; /* Whether multi-av is supported */ -}tBTA_AV_SYNC_INFO_REQ; /* SYNC_TO_LITE_REQ */ - -/* Dual stack stream events */ -typedef struct -{ - tBTA_AV_DUAL_STACK_EVT event; - UINT8 scb_idx; -}tBTA_AV_SCB_EVT; - -/* data type for the Audio Codec Information*/ -typedef struct -{ - UINT16 bit_rate; /* SBC encoder bit rate in kbps */ - UINT16 bit_rate_busy; /* SBC encoder bit rate in kbps */ - UINT16 bit_rate_swampd; /* SBC encoder bit rate in kbps */ - UINT8 busy_level; /* Busy level indicating the bit-rate to be used */ - UINT8 codec_info[AVDT_CODEC_SIZE]; - UINT8 codec_type; /* Codec type */ -} tBTA_AV_AUDIO_CODEC_SYNC_INFO; - -/* Dual stack stream events */ -typedef struct -{ - tBTA_AV_DUAL_STACK_EVT event; - UINT8 scb_idx; - UINT8 audio_open_cnt; - tBTA_AV_AUDIO_CODEC_SYNC_INFO p_codec_cfg; - UINT8 start_stop_flag; -}tBTA_AV_SCB_REQ; - -typedef struct -{ - tBTA_AV_DUAL_STACK_EVT event; - UINT8 scb_idx; - UINT8 audio_open_cnt; - UINT16 curr_mtu; /* common mtu shared by all active streams */ -}tBTA_AV_SCB_CLEANUP_REQ; - -/* Add request/response structures if needed ... -typedef struct -{ - event; - data; -}tBTA_AV_SYNC_*_REQ/RESP; -*/ - -typedef union -{ - /* MM light stack */ - tBTA_AV_DUAL_STACK_EVT event; - tBTA_AV_SYNC_INFO_REQ sync_info_req; - tBTA_AV_SCB_EVT scb_evt; - tBTA_AV_SCB_REQ scb_req; - tBTA_AV_SCB_CLEANUP_REQ scb_cleanup_req; - - /* BTC light stack */ - UINT8 opcode; - tA2DP_START_REQ btc_start_req; - tA2DP_STOP_REQ btc_stop_req; - tA2DP_CLEANUP_REQ btc_cleanup_req; - tA2DP_SUSPEND_REQ btc_suspend_req; - - tAUDIO_CODEC_CONFIG_REQ codec_config_req; - tAUDIO_CODEC_SET_BITRATE_REQ codec_bitrate_req; - tAUDIO_CODEC_FLUSH_REQ codec_flush_req; - tAUDIO_ROUTE_CONFIG_REQ route_config_req; - tAUDIO_MIX_CONFIG_REQ mix_config_req; - tAUDIO_EQ_MODE_CONFIG_REQ eq_mode_req; - tAUDIO_SCALE_CONFIG_REQ scale_config_req; -}tBTA_DUAL_STACK_MSG; - #endif /* UIPC_MSG_H */ + diff --git a/stack/l2cap/l2c_api.c b/stack/l2cap/l2c_api.c index 30249a4d6..338a7cd1c 100644 --- a/stack/l2cap/l2c_api.c +++ b/stack/l2cap/l2c_api.c @@ -223,6 +223,10 @@ UINT16 L2CA_ConnectReq (UINT16 psm, BD_ADDR p_bd_addr) ** connection establishment gets started. The callback function ** will be invoked when connection establishes or fails. ** +** Parameters: PSM: L2CAP PSM for the connection +** BD address of the peer +** Enhaced retransmission mode configurations + ** Returns the CID of the connection, or 0 if it failed to start ** *******************************************************************************/ @@ -232,10 +236,12 @@ UINT16 L2CA_ErtmConnectReq (UINT16 psm, BD_ADDR p_bd_addr, tL2CAP_ERTM_INFO *p_e tL2C_CCB *p_ccb; tL2C_RCB *p_rcb; - L2CAP_TRACE_API6 ("L2CA_ErtmConnectReq() PSM: 0x%04x BDA: %08x%04x p_ertm_info: 0x%08x allowed:0x%x preferred:%d", psm, + L2CAP_TRACE_API6 ("L2CA_ErtmConnectReq() PSM: 0x%04x BDA: %08x%04x p_ertm_info" + ": 0x%08x allowed:0x%x preferred:%d", psm, (p_bd_addr[0]<<24)+(p_bd_addr[1]<<16)+(p_bd_addr[2]<<8)+p_bd_addr[3], (p_bd_addr[4]<<8)+p_bd_addr[5], p_ertm_info, - (p_ertm_info) ? p_ertm_info->allowed_modes : 0, (p_ertm_info) ? p_ertm_info->preferred_mode : 0); + (p_ertm_info) ? p_ertm_info->allowed_modes : 0, + (p_ertm_info) ? p_ertm_info->preferred_mode : 0); /* Fail if we have not established communications with the controller */ if (!BTM_IsDeviceUp()) @@ -251,13 +257,16 @@ UINT16 L2CA_ErtmConnectReq (UINT16 psm, BD_ADDR p_bd_addr, tL2CAP_ERTM_INFO *p_e } /* First, see if we already have a link to the remote */ - if ((p_lcb = l2cu_find_lcb_by_bd_addr (p_bd_addr)) == NULL) + /* assume all ERTM l2cap connection is going over BR/EDR for now */ + if ((p_lcb = l2cu_find_lcb_by_bd_addr (p_bd_addr, BT_TRANSPORT_BR_EDR)) == NULL) { /* No link. Get an LCB and start link establishment */ - if ( ((p_lcb = l2cu_allocate_lcb (p_bd_addr, FALSE)) == NULL) - || (l2cu_create_conn(p_lcb) == FALSE) ) + if ( ((p_lcb = l2cu_allocate_lcb (p_bd_addr, FALSE, BT_TRANSPORT_BR_EDR)) == NULL) + /* currently use BR/EDR for ERTM mode l2cap connection */ + || (l2cu_create_conn(p_lcb, BT_TRANSPORT_BR_EDR) == FALSE) ) { - L2CAP_TRACE_WARNING2 ("L2CAP - conn not started for PSM: 0x%04x p_lcb: 0x%08x", psm, p_lcb); + L2CAP_TRACE_WARNING2 ("L2CAP - conn not started for PSM: 0x%04x p_lcb: 0x%08x", + psm, p_lcb); return (0); } } @@ -289,7 +298,8 @@ UINT16 L2CA_ErtmConnectReq (UINT16 psm, BD_ADDR p_bd_addr, tL2CAP_ERTM_INFO *p_e if (p_ccb->ertm_info.user_tx_pool_id == L2CAP_DEFAULT_ERM_POOL_ID) p_ccb->ertm_info.user_tx_pool_id = HCI_ACL_POOL_ID; - p_ccb->max_rx_mtu = GKI_get_pool_bufsize (p_ertm_info->user_rx_pool_id) - (L2CAP_MIN_OFFSET + L2CAP_SDU_LEN_OFFSET + L2CAP_FCS_LEN); + p_ccb->max_rx_mtu = GKI_get_pool_bufsize (p_ertm_info->user_rx_pool_id) - + (L2CAP_MIN_OFFSET + L2CAP_SDU_LEN_OFFSET + L2CAP_FCS_LEN); } /* If link is up, start the L2CAP connection */ @@ -312,7 +322,8 @@ UINT16 L2CA_ErtmConnectReq (UINT16 psm, BD_ADDR p_bd_addr, tL2CAP_ERTM_INFO *p_e p_lcb->p_pending_ccb = p_ccb; } - L2CAP_TRACE_API2 ("L2CAP - L2CA_conn_req(psm: 0x%04x) returned CID: 0x%04x", psm, p_ccb->local_cid); + L2CAP_TRACE_API2 ("L2CAP - L2CA_conn_req(psm: 0x%04x) returned CID: 0x%04x", + psm, p_ccb->local_cid); /* Return the local CID as our handle */ return (p_ccb->local_cid); @@ -330,7 +341,8 @@ UINT16 L2CA_ErtmConnectReq (UINT16 psm, BD_ADDR p_bd_addr, tL2CAP_ERTM_INFO *p_e ** Returns TRUE for success, FALSE for failure ** *******************************************************************************/ -BOOLEAN L2CA_ConnectRsp (BD_ADDR p_bd_addr, UINT8 id, UINT16 lcid, UINT16 result, UINT16 status) +BOOLEAN L2CA_ConnectRsp (BD_ADDR p_bd_addr, UINT8 id, UINT16 lcid, + UINT16 result, UINT16 status) { return L2CA_ErtmConnectRsp (p_bd_addr, id, lcid, result, status, NULL); } @@ -353,13 +365,14 @@ BOOLEAN L2CA_ErtmConnectRsp (BD_ADDR p_bd_addr, UINT8 id, UINT16 lcid, UINT16 re tL2C_LCB *p_lcb; tL2C_CCB *p_ccb; - L2CAP_TRACE_API6 ("L2CA_ErtmConnectRsp() CID: 0x%04x Result: %d Status: %d BDA: %08x%04x p_ertm_info:0x%08x", + L2CAP_TRACE_API6 ("L2CA_ErtmConnectRsp() CID: 0x%04x Result: %d Status: %d BDA: %08x%04x" + " p_ertm_info:0x%08x", lcid, result, status, (p_bd_addr[0]<<24)+(p_bd_addr[1]<<16)+(p_bd_addr[2]<<8)+p_bd_addr[3], (p_bd_addr[4]<<8)+p_bd_addr[5], p_ertm_info); /* First, find the link control block */ - if ((p_lcb = l2cu_find_lcb_by_bd_addr (p_bd_addr)) == NULL) + if ((p_lcb = l2cu_find_lcb_by_bd_addr (p_bd_addr, BT_TRANSPORT_BR_EDR)) == NULL) { /* No link. Get an LCB and start link establishment */ L2CAP_TRACE_WARNING0 ("L2CAP - no LCB for L2CA_conn_rsp"); @@ -594,15 +607,15 @@ BOOLEAN L2CA_Ping (BD_ADDR p_bd_addr, tL2CA_ECHO_RSP_CB *p_callback) return (FALSE); /* First, see if we already have a link to the remote */ - if ((p_lcb = l2cu_find_lcb_by_bd_addr (p_bd_addr)) == NULL) + if ((p_lcb = l2cu_find_lcb_by_bd_addr (p_bd_addr, BT_TRANSPORT_BR_EDR)) == NULL) { /* No link. Get an LCB and start link establishment */ - if ((p_lcb = l2cu_allocate_lcb (p_bd_addr, FALSE)) == NULL) + if ((p_lcb = l2cu_allocate_lcb (p_bd_addr, FALSE, BT_TRANSPORT_BR_EDR)) == NULL) { L2CAP_TRACE_WARNING0 ("L2CAP - no LCB for L2CA_ping"); return (FALSE); } - if (l2cu_create_conn(p_lcb) == FALSE) + if (l2cu_create_conn(p_lcb, BT_TRANSPORT_BR_EDR) == FALSE) { return (FALSE); } @@ -670,7 +683,7 @@ BOOLEAN L2CA_Echo (BD_ADDR p_bd_addr, BT_HDR *p_data, tL2CA_ECHO_DATA_CB *p_cal } /* We assume the upper layer will call this function only when the link is established. */ - if ((p_lcb = l2cu_find_lcb_by_bd_addr (p_bd_addr)) == NULL) + if ((p_lcb = l2cu_find_lcb_by_bd_addr (p_bd_addr, BT_TRANSPORT_BR_EDR)) == NULL) { L2CAP_TRACE_ERROR0 ("L2CA_Echo ERROR : link not established"); return FALSE; @@ -767,7 +780,7 @@ BOOLEAN L2CA_SetIdleTimeoutByBdAddr(BD_ADDR bd_addr, UINT16 timeout) if (memcmp (BT_BD_ANY, bd_addr, BD_ADDR_LEN)) { - p_lcb = l2cu_find_lcb_by_bd_addr( bd_addr ); + p_lcb = l2cu_find_lcb_by_bd_addr( bd_addr, BT_TRANSPORT_BR_EDR); if ((p_lcb) && (p_lcb->in_use) && (p_lcb->link_state == LST_CONNECTED)) p_lcb->idle_timeout = timeout; else @@ -880,7 +893,7 @@ UINT16 L2CA_LocalLoopbackReq (UINT16 psm, UINT16 handle, BD_ADDR p_bd_addr) return (0); } - if ((p_lcb = l2cu_allocate_lcb (p_bd_addr, FALSE)) == NULL) + if ((p_lcb = l2cu_allocate_lcb (p_bd_addr, FALSE, BT_TRANSPORT_BR_EDR)) == NULL) { L2CAP_TRACE_WARNING0 ("L2CAP - no LCB for L2CA_conn_req"); return (0); @@ -1129,7 +1142,7 @@ BOOLEAN L2CA_SetFlushTimeout (BD_ADDR bd_addr, UINT16 flush_tout) if (memcmp (BT_BD_ANY, bd_addr, BD_ADDR_LEN)) { - p_lcb = l2cu_find_lcb_by_bd_addr (bd_addr); + p_lcb = l2cu_find_lcb_by_bd_addr (bd_addr, BT_TRANSPORT_BR_EDR); if ((p_lcb) && (p_lcb->in_use) && (p_lcb->link_state == LST_CONNECTED)) { @@ -1195,7 +1208,7 @@ BOOLEAN L2CA_GetPeerFeatures (BD_ADDR bd_addr, UINT32 *p_ext_feat, UINT8 *p_chnl tL2C_LCB *p_lcb; /* We must already have a link to the remote */ - if ((p_lcb = l2cu_find_lcb_by_bd_addr (bd_addr)) == NULL) + if ((p_lcb = l2cu_find_lcb_by_bd_addr (bd_addr, BT_TRANSPORT_BR_EDR)) == NULL) { L2CAP_TRACE_WARNING2 ("L2CA_GetPeerFeatures() No BDA: %08x%04x", (bd_addr[0]<<24)+(bd_addr[1]<<16)+(bd_addr[2]<<8)+bd_addr[3], @@ -1307,9 +1320,8 @@ BOOLEAN L2CA_RegisterFixedChannel (UINT16 fixed_cid, tL2CAP_FIXED_CHNL_REG *p_f BOOLEAN L2CA_ConnectFixedChnl (UINT16 fixed_cid, BD_ADDR rem_bda) { tL2C_LCB *p_lcb; -#if BLE_INCLUDED == TRUE + tBT_TRANSPORT transport = BT_TRANSPORT_BR_EDR; UINT16 reason; -#endif L2CAP_TRACE_API3 ("L2CA_ConnectFixedChnl() CID: 0x%04x BDA: %08x%04x", fixed_cid, (rem_bda[0]<<24)+(rem_bda[1]<<16)+(rem_bda[2]<<8)+rem_bda[3], (rem_bda[4]<<8)+rem_bda[5]); @@ -1329,39 +1341,58 @@ BOOLEAN L2CA_ConnectFixedChnl (UINT16 fixed_cid, BD_ADDR rem_bda) return (FALSE); } +#if BLE_INCLUDED == TRUE + if (fixed_cid >= L2CAP_ATT_CID && fixed_cid <= L2CAP_SMP_CID) + transport = BT_TRANSPORT_LE; +#endif + /* If we already have a link to the remote, check if it supports that CID */ - if ((p_lcb = l2cu_find_lcb_by_bd_addr (rem_bda)) != NULL) + if ((p_lcb = l2cu_find_lcb_by_bd_addr (rem_bda, transport)) != NULL) { if (!(p_lcb->peer_chnl_mask[0] & (1 << fixed_cid))) { - L2CAP_TRACE_EVENT3 ("L2CA_ConnectFixedChnl() CID: 0x%04x BDA: %08x%04x not supported", fixed_cid, - (rem_bda[0]<<24)+(rem_bda[1]<<16)+(rem_bda[2]<<8)+rem_bda[3], (rem_bda[4]<<8)+rem_bda[5]); + L2CAP_TRACE_EVENT3 ("L2CA_ConnectFixedChnl() CID:0x%04x BDA: %08x%04x not supported", + fixed_cid,(rem_bda[0]<<24)+(rem_bda[1]<<16)+(rem_bda[2]<<8)+rem_bda[3], + (rem_bda[4]<<8)+rem_bda[5]); return (FALSE); } /* Get a CCB and link the lcb to it */ - if (!l2cu_initialize_fixed_ccb (p_lcb, fixed_cid, &l2cb.fixed_reg[fixed_cid - L2CAP_FIRST_FIXED_CHNL].fixed_chnl_opts)) + if (!l2cu_initialize_fixed_ccb (p_lcb, fixed_cid, + &l2cb.fixed_reg[fixed_cid - L2CAP_FIRST_FIXED_CHNL].fixed_chnl_opts)) { L2CAP_TRACE_WARNING1 ("L2CA_ConnectFixedChnl(0x%04x) - LCB but no CCB", fixed_cid); return (FALSE); } + + /* racing with disconnecting, queue the connection request */ + if (p_lcb->link_state == LST_DISCONNECTING) + { + L2CAP_TRACE_DEBUG0 ("L2CAP API - link disconnecting: RETRY LATER"); + /* Save ccb so it can be started after disconnect is finished */ + p_lcb->p_pending_ccb = p_lcb->p_fixed_ccbs[fixed_cid - L2CAP_FIRST_FIXED_CHNL]; + return (TRUE); + } + #if BLE_INCLUDED == TRUE - reason = (p_lcb->is_ble_link) ? 1: 0; - (*l2cb.fixed_reg[fixed_cid - L2CAP_FIRST_FIXED_CHNL].pL2CA_FixedConn_Cb)(p_lcb->remote_bd_addr, TRUE, reason); + (*l2cb.fixed_reg[fixed_cid - L2CAP_FIRST_FIXED_CHNL].pL2CA_FixedConn_Cb) + (p_lcb->remote_bd_addr, TRUE, 0, p_lcb->transport); #else - (*l2cb.fixed_reg[fixed_cid - L2CAP_FIRST_FIXED_CHNL].pL2CA_FixedConn_Cb)(p_lcb->remote_bd_addr, TRUE, 0); + (*l2cb.fixed_reg[fixed_cid - L2CAP_FIRST_FIXED_CHNL].pL2CA_FixedConn_Cb) + (p_lcb->remote_bd_addr, TRUE, 0, BT_TRANSPORT_BR_EDR); #endif return (TRUE); } /* No link. Get an LCB and start link establishment */ - if ((p_lcb = l2cu_allocate_lcb (rem_bda, FALSE)) == NULL) + if ((p_lcb = l2cu_allocate_lcb (rem_bda, FALSE, transport)) == NULL) { L2CAP_TRACE_WARNING1 ("L2CA_ConnectFixedChnl(0x%04x) - no LCB", fixed_cid); return (FALSE); } /* Get a CCB and link the lcb to it */ - if (!l2cu_initialize_fixed_ccb (p_lcb, fixed_cid, &l2cb.fixed_reg[fixed_cid - L2CAP_FIRST_FIXED_CHNL].fixed_chnl_opts)) + if (!l2cu_initialize_fixed_ccb (p_lcb, fixed_cid, + &l2cb.fixed_reg[fixed_cid - L2CAP_FIRST_FIXED_CHNL].fixed_chnl_opts)) { p_lcb->disc_reason = L2CAP_CONN_NO_RESOURCES; L2CAP_TRACE_WARNING1 ("L2CA_ConnectFixedChnl(0x%04x) - no CCB", fixed_cid); @@ -1369,7 +1400,7 @@ BOOLEAN L2CA_ConnectFixedChnl (UINT16 fixed_cid, BD_ADDR rem_bda) return (FALSE); } - return (l2cu_create_conn(p_lcb)); + return (l2cu_create_conn(p_lcb, transport)); } /******************************************************************************* @@ -1389,10 +1420,16 @@ BOOLEAN L2CA_ConnectFixedChnl (UINT16 fixed_cid, BD_ADDR rem_bda) UINT16 L2CA_SendFixedChnlData (UINT16 fixed_cid, BD_ADDR rem_bda, BT_HDR *p_buf) { tL2C_LCB *p_lcb; + tBT_TRANSPORT transport = BT_TRANSPORT_BR_EDR; L2CAP_TRACE_API3 ("L2CA_SendFixedChnlData() CID: 0x%04x BDA: %08x%04x", fixed_cid, (rem_bda[0]<<24)+(rem_bda[1]<<16)+(rem_bda[2]<<8)+rem_bda[3], (rem_bda[4]<<8)+rem_bda[5]); +#if BLE_INCLUDED == TRUE + if (fixed_cid >= L2CAP_ATT_CID && fixed_cid <= L2CAP_SMP_CID) + transport = BT_TRANSPORT_LE; +#endif + /* Check CID is valid and registered */ if ( (fixed_cid < L2CAP_FIRST_FIXED_CHNL) || (fixed_cid > L2CAP_LAST_FIXED_CHNL) || (l2cb.fixed_reg[fixed_cid - L2CAP_FIRST_FIXED_CHNL].pL2CA_FixedData_Cb == NULL) ) @@ -1409,7 +1446,9 @@ UINT16 L2CA_SendFixedChnlData (UINT16 fixed_cid, BD_ADDR rem_bda, BT_HDR *p_buf) } /* We need to have a link up */ - if ((p_lcb = l2cu_find_lcb_by_bd_addr (rem_bda)) == NULL) + if ((p_lcb = l2cu_find_lcb_by_bd_addr (rem_bda, transport)) == NULL || + /* if link is disconnecting, also report data sending failure */ + p_lcb->link_state == LST_DISCONNECTING) { L2CAP_TRACE_WARNING1 ("L2CA_SendFixedChnlData(0x%04x) - no LCB", fixed_cid); return (L2CAP_DW_FAILED); @@ -1463,6 +1502,7 @@ BOOLEAN L2CA_RemoveFixedChnl (UINT16 fixed_cid, BD_ADDR rem_bda) { tL2C_LCB *p_lcb; tL2C_CCB *p_ccb; + tBT_TRANSPORT transport = BT_TRANSPORT_BR_EDR; /* Check CID is valid and registered */ if ( (fixed_cid < L2CAP_FIRST_FIXED_CHNL) || (fixed_cid > L2CAP_LAST_FIXED_CHNL) @@ -1472,8 +1512,14 @@ BOOLEAN L2CA_RemoveFixedChnl (UINT16 fixed_cid, BD_ADDR rem_bda) return (FALSE); } +#if BLE_INCLUDED == TRUE + if (fixed_cid >= L2CAP_ATT_CID && fixed_cid <= L2CAP_SMP_CID) + transport = BT_TRANSPORT_LE; +#endif + /* Is a fixed channel connected to the remote BDA ?*/ - p_lcb = l2cu_find_lcb_by_bd_addr (rem_bda); + p_lcb = l2cu_find_lcb_by_bd_addr (rem_bda, transport); + if ( ((p_lcb) == NULL) || (!p_lcb->p_fixed_ccbs[fixed_cid - L2CAP_FIRST_FIXED_CHNL]) ) { L2CAP_TRACE_WARNING3 ("L2CA_RemoveFixedChnl() CID: 0x%04x BDA: %08x%04x not connected", fixed_cid, @@ -1491,7 +1537,14 @@ BOOLEAN L2CA_RemoveFixedChnl (UINT16 fixed_cid, BD_ADDR rem_bda) p_lcb->disc_reason = HCI_ERR_CONN_CAUSE_LOCAL_HOST; #if BLE_INCLUDED == TRUE - if (fixed_cid == L2CAP_ATT_CID && !p_lcb->ccb_queue.p_first_ccb) + /* retain the link for a few more seconds after SMP pairing is done, since Android + platformalways do service discovery after pairing complete. This way would avoid + the link down (pairing is complete) and an immediate reconnection for service + discovery. Some devices do not do auto advertising when link is dropped, thus fail + the second connection and service discovery. + BEFORE :if ((fixed_cid == L2CAP_ATT_CID || fixed_cid == L2CAP_SMP_CID) + && !p_lcb->ccb_queue.p_first_ccb)*/ + if ((fixed_cid == L2CAP_ATT_CID ) && !p_lcb->ccb_queue.p_first_ccb) p_lcb->idle_timeout = 0; #endif @@ -1520,9 +1573,15 @@ BOOLEAN L2CA_RemoveFixedChnl (UINT16 fixed_cid, BD_ADDR rem_bda) BOOLEAN L2CA_SetFixedChannelTout (BD_ADDR rem_bda, UINT16 fixed_cid, UINT16 idle_tout) { tL2C_LCB *p_lcb; + tBT_TRANSPORT transport = BT_TRANSPORT_BR_EDR; + +#if BLE_INCLUDED == TRUE + if (fixed_cid >= L2CAP_ATT_CID && fixed_cid <= L2CAP_SMP_CID) + transport = BT_TRANSPORT_LE; +#endif /* Is a fixed channel connected to the remote BDA ?*/ - p_lcb = l2cu_find_lcb_by_bd_addr (rem_bda); + p_lcb = l2cu_find_lcb_by_bd_addr (rem_bda, transport); if ( ((p_lcb) == NULL) || (!p_lcb->p_fixed_ccbs[fixed_cid - L2CAP_FIRST_FIXED_CHNL]) ) { L2CAP_TRACE_WARNING3 ("L2CA_SetFixedChannelTout() CID: 0x%04x BDA: %08x%04x not connected", fixed_cid, @@ -1614,7 +1673,7 @@ BOOLEAN L2CA_RegForNoCPEvt(tL2CA_NOCP_CB *p_cb, BD_ADDR p_bda) tL2C_LCB *p_lcb; /* Find the link that is associated with this remote bdaddr */ - p_lcb = l2cu_find_lcb_by_bd_addr (p_bda); + p_lcb = l2cu_find_lcb_by_bd_addr (p_bda, BT_TRANSPORT_BR_EDR); /* If no link for this handle, nothing to do. */ if (!p_lcb) diff --git a/stack/l2cap/l2c_ble.c b/stack/l2cap/l2c_ble.c index ba0d7ec28..0e6c73a69 100644 --- a/stack/l2cap/l2c_ble.c +++ b/stack/l2cap/l2c_ble.c @@ -32,6 +32,9 @@ #include "hcimsgs.h" #if (BLE_INCLUDED == TRUE) +#define L2CA_GET_UPD_ST(x) ((x) & UPD_ST_MASK) +#define L2CA_SET_UPD_ST(x, y) x = (((x) & ~UPD_ST_MASK) | (y)) + /******************************************************************************* ** @@ -68,7 +71,7 @@ BOOLEAN L2CA_CancelBleConnectReq (BD_ADDR rem_bda) if (btsnd_hcic_ble_create_conn_cancel()) { - if ((p_lcb = l2cu_find_lcb_by_bd_addr (rem_bda)) != NULL) + if ((p_lcb = l2cu_find_lcb_by_bd_addr (rem_bda, BT_TRANSPORT_LE)) != NULL) { p_lcb->disc_reason = L2CAP_CONN_CANCEL; l2cu_release_lcb (p_lcb); @@ -84,57 +87,6 @@ BOOLEAN L2CA_CancelBleConnectReq (BD_ADDR rem_bda) /******************************************************************************* ** -** Function L2CA_InternalBleConnUpdate -** -** Description update BLE connection based on status -** -** Parameters: lcb -** -** Return value: none -** -*******************************************************************************/ -static void L2CA_InternalBleConnUpdate (tL2C_LCB *p_lcb) -{ - if (p_lcb->upd_status & L2C_BLE_UPDATE_PENDING) return; - - if (p_lcb->upd_status & L2C_BLE_CONN_UPDATE_DISABLE) - { - /* application requests to disable parameters update. - If parameters are already updated, lets set them - up to what has been requested during connection establishement */ - if (p_lcb->upd_status & L2C_BLE_NOT_DEFAULT_PARAM) - { - tBTM_SEC_DEV_REC *p_dev_rec = btm_find_or_alloc_dev(p_lcb->remote_bd_addr); - - btsnd_hcic_ble_upd_ll_conn_params(p_lcb->handle, - (UINT16)((p_dev_rec->conn_params.min_conn_int != BTM_BLE_CONN_PARAM_UNDEF) ? - p_dev_rec->conn_params.min_conn_int : BTM_BLE_CONN_INT_MIN_DEF), - (UINT16)((p_dev_rec->conn_params.max_conn_int != BTM_BLE_CONN_PARAM_UNDEF) ? - p_dev_rec->conn_params.max_conn_int : BTM_BLE_CONN_INT_MAX_DEF), - (UINT16)((p_dev_rec->conn_params.slave_latency != BTM_BLE_CONN_PARAM_UNDEF) ? - p_dev_rec->conn_params.slave_latency : BTM_BLE_CONN_SLAVE_LATENCY_DEF), - (UINT16)((p_dev_rec->conn_params.supervision_tout != BTM_BLE_CONN_PARAM_UNDEF) ? - p_dev_rec->conn_params.supervision_tout : BTM_BLE_CONN_TIMEOUT_DEF), - 0, 0); - p_lcb->upd_status &= ~L2C_BLE_NOT_DEFAULT_PARAM; - p_lcb->upd_status |= (L2C_BLE_UPDATE_PENDING | L2C_BLE_NEW_CONN_PARAM); - } - } - else - { - /* application allows to do update, if we were delaying one do it now */ - if (p_lcb->upd_status & L2C_BLE_NEW_CONN_PARAM) - { - btsnd_hcic_ble_upd_ll_conn_params(p_lcb->handle, p_lcb->min_interval, - p_lcb->max_interval, p_lcb->latency, p_lcb->timeout, 0, 0); - p_lcb->upd_status &= ~L2C_BLE_NEW_CONN_PARAM; - p_lcb->upd_status |= (L2C_BLE_UPDATE_PENDING | L2C_BLE_NOT_DEFAULT_PARAM); - } - } -} - -/******************************************************************************* -** ** Function L2CA_UpdateBleConnParams ** ** Description Update BLE connection parameters. @@ -144,41 +96,54 @@ static void L2CA_InternalBleConnUpdate (tL2C_LCB *p_lcb) ** Return value: TRUE if update started ** *******************************************************************************/ -BOOLEAN L2CA_UpdateBleConnParams (BD_ADDR rem_bda, UINT16 min_int, UINT16 max_int, UINT16 latency, UINT16 timeout) +BOOLEAN L2CA_UpdateBleConnParams (BD_ADDR rem_bda, UINT16 min_int, UINT16 max_int, + UINT16 latency, UINT16 timeout) { - tL2C_LCB *p_lcb; - - /* See if we have a link control block for the remote device */ - p_lcb = l2cu_find_lcb_by_bd_addr (rem_bda); + tL2C_LCB *p_lcb; + tACL_CONN *p_acl_cb = btm_bda_to_acl(rem_bda, BT_TRANSPORT_LE); - /* If we don't have one, create one and accept the connection. */ - if (!p_lcb) - { - L2CAP_TRACE_WARNING2 ("L2CA_UpdateBleConnParams - unknown BD_ADDR %08x%04x", - (rem_bda[0]<<24)+(rem_bda[1]<<16)+(rem_bda[2]<<8)+rem_bda[3], (rem_bda[4]<<8)+rem_bda[5]); - return(FALSE); - } + /* See if we have a link control block for the remote device */ + p_lcb = l2cu_find_lcb_by_bd_addr (rem_bda, BT_TRANSPORT_LE); - if (!p_lcb->is_ble_link) - { - L2CAP_TRACE_WARNING2 ("L2CA_UpdateBleConnParams - BD_ADDR %08x%04x not LE", - (rem_bda[0]<<24)+(rem_bda[1]<<16)+(rem_bda[2]<<8)+rem_bda[3], (rem_bda[4]<<8)+rem_bda[5]); - return(FALSE); - } + /* If we don't have one, create one and accept the connection. */ + if (!p_lcb || !p_acl_cb) + { + L2CAP_TRACE_WARNING2 ("L2CA_UpdateBleConnParams - unknown BD_ADDR %08x%04x", + (rem_bda[0]<<24)+(rem_bda[1]<<16)+(rem_bda[2]<<8)+rem_bda[3], + (rem_bda[4]<<8)+rem_bda[5]); + return(FALSE); + } - if (p_lcb->link_role == HCI_ROLE_MASTER) - { - p_lcb->min_interval = min_int; - p_lcb->max_interval = max_int; - p_lcb->latency = latency; - p_lcb->timeout = timeout; - p_lcb->upd_status |= L2C_BLE_NEW_CONN_PARAM; - L2CA_InternalBleConnUpdate(p_lcb); - } - else - l2cu_send_peer_ble_par_req (p_lcb, min_int, max_int, latency, timeout); + if (p_lcb->transport != BT_TRANSPORT_LE) + { + L2CAP_TRACE_WARNING2 ("L2CA_UpdateBleConnParams - BD_ADDR %08x%04x not LE", + (rem_bda[0]<<24)+(rem_bda[1]<<16)+(rem_bda[2]<<8)+rem_bda[3], + (rem_bda[4]<<8)+rem_bda[5]); + return(FALSE); + } +#if (defined BLE_LLT_INCLUDED) && (BLE_LLT_INCLUDED == TRUE) + /* if both 4.1 compliant */ + if ((HCI_LE_CONN_PARAM_REQ_SUPPORTED(btm_cb.devcb.local_le_features) && + HCI_LE_CONN_PARAM_REQ_SUPPORTED(p_acl_cb->peer_le_features))) + { + /* TODO: CE length selection ?? */ + btsnd_hcic_ble_upd_ll_conn_params (p_lcb->handle, min_int, max_int, + latency, timeout, 0, 0); + } + else + /* if either side does not support Connection Parameters Request + Link Layer Control Procedure, + use Link Layer Connection Update procedure */ +#endif + { + if (p_lcb->link_role == HCI_ROLE_MASTER) + btsnd_hcic_ble_upd_ll_conn_params (p_lcb->handle, min_int, max_int, + latency, timeout, 0, 0); + else + l2cu_send_peer_ble_par_req (p_lcb, min_int, max_int, latency, timeout); + } + return(TRUE); - return(TRUE); } @@ -198,77 +163,69 @@ BOOLEAN L2CA_EnableUpdateBleConnParams (BD_ADDR rem_bda, BOOLEAN enable) tL2C_LCB *p_lcb; /* See if we have a link control block for the remote device */ - p_lcb = l2cu_find_lcb_by_bd_addr (rem_bda); + p_lcb = l2cu_find_lcb_by_bd_addr (rem_bda, BT_TRANSPORT_LE); - /* If we don't have one, create one and accept the connection. */ if (!p_lcb) { L2CAP_TRACE_WARNING2 ("L2CA_EnableUpdateBleConnParams - unknown BD_ADDR %08x%04x", - (rem_bda[0]<<24)+(rem_bda[1]<<16)+(rem_bda[2]<<8)+rem_bda[3], (rem_bda[4]<<8)+rem_bda[5]); + (rem_bda[0]<<24)+(rem_bda[1]<<16)+(rem_bda[2]<<8)+rem_bda[3], + (rem_bda[4]<<8)+rem_bda[5]); return (FALSE); } - L2CAP_TRACE_API4 ("L2CA_EnableUpdateBleConnParams - BD_ADDR %08x%04x enable %d upd state %d", - (rem_bda[0]<<24)+(rem_bda[1]<<16)+(rem_bda[2]<<8)+rem_bda[3], (rem_bda[4]<<8)+rem_bda[5], - enable, p_lcb->upd_status); + L2CAP_TRACE_API5 ("%s - BD_ADDR %08x%04x enable %d current upd state 0x%02x",__FUNCTION__, + (rem_bda[0]<<24)+(rem_bda[1]<<16)+(rem_bda[2]<<8)+rem_bda[3], + (rem_bda[4]<<8)+rem_bda[5], enable, p_lcb->conn_update_mask); - if (!p_lcb->is_ble_link || (p_lcb->link_role != HCI_ROLE_MASTER)) + if (p_lcb->transport != BT_TRANSPORT_LE || (p_lcb->link_role != HCI_ROLE_MASTER)) { - L2CAP_TRACE_WARNING3 ("L2CA_EnableUpdateBleConnParams - BD_ADDR %08x%04x not LE or not master %d", - (rem_bda[0]<<24)+(rem_bda[1]<<16)+(rem_bda[2]<<8)+rem_bda[3], (rem_bda[4]<<8)+rem_bda[5], p_lcb->link_role); + L2CAP_TRACE_WARNING4 ("%s - BD_ADDR %08x%04x not LE or not master %d", __FUNCTION__, + (rem_bda[0]<<24)+(rem_bda[1]<<16)+(rem_bda[2]<<8)+rem_bda[3], + (rem_bda[4]<<8)+rem_bda[5], p_lcb->link_role); return (FALSE); } if (enable) { - p_lcb->upd_status &= ~L2C_BLE_CONN_UPDATE_DISABLE; + if (L2CA_GET_UPD_ST (p_lcb->conn_update_mask) == UPD_DISABLED) + { + p_lcb->conn_param_enb.param = (TIMER_PARAM_TYPE)p_lcb; + btu_start_timer (&p_lcb->conn_param_enb, BTU_TTYPE_L2CAP_END_CONN_UPD, + L2CAP_BLE_ENB_CONN_PARAM_TOUT); + L2CA_SET_UPD_ST( p_lcb->conn_update_mask, UPD_ENB_TOUT); + } } - else + else if (L2CA_GET_UPD_ST (p_lcb->conn_update_mask) != UPD_DISABLED) { - p_lcb->upd_status |= L2C_BLE_CONN_UPDATE_DISABLE; - } - - L2CA_InternalBleConnUpdate(p_lcb); - - return (TRUE); -} - -/******************************************************************************* -** -** Function L2CA_HandleConnUpdateEvent -** -** Description This function enables the connection update request from remote -** after a successful connection update response is received. -** -** Returns void -** -*******************************************************************************/ -void L2CA_HandleConnUpdateEvent (UINT16 handle, UINT8 status) -{ - tL2C_LCB *p_lcb; - - L2CAP_TRACE_DEBUG0("L2CA_HandleConnUpdateEvent"); + btu_stop_timer(&p_lcb->conn_param_enb); - /* See if we have a link control block for the remote device */ - p_lcb = l2cu_find_lcb_by_handle(handle); - if (!p_lcb) - { - L2CAP_TRACE_WARNING1("L2CA_EnableUpdateBleConnParams: Invalid handle: %d", handle); - return; - } + if (L2CA_GET_UPD_ST(p_lcb->conn_update_mask) == UPD_ENABLED) + { - p_lcb->upd_status &= ~L2C_BLE_UPDATE_PENDING; + /* + application requests to disable parameters update.If parameters are already updated, + lets set them up to what has been requested during connection establishement + */ + if ((p_lcb->conn_update_mask & UPD_REQUEST) != 0) + { + /* revert back to default */ + btsnd_hcic_ble_upd_ll_conn_params (p_lcb->handle, + BTM_BLE_CONN_INT_MIN_DEF, + BTM_BLE_CONN_INT_MAX_DEF, + BTM_BLE_CONN_SLAVE_LATENCY_DEF, + BTM_BLE_CONN_TIMEOUT_DEF, + 0, 0); + } + } + L2CA_SET_UPD_ST( p_lcb->conn_update_mask, UPD_DISABLED); - if (status != HCI_SUCCESS) - { - L2CAP_TRACE_WARNING1("L2CA_EnableUpdateBleConnParams: Error status: %d", status); } - L2CA_InternalBleConnUpdate(p_lcb); + return (TRUE); - L2CAP_TRACE_DEBUG1("L2CA_HandleConnUpdateEvent: upd_status=%d", p_lcb->upd_status); } + /******************************************************************************* ** ** Function L2CA_GetBleConnRole @@ -284,7 +241,7 @@ UINT8 L2CA_GetBleConnRole (BD_ADDR bd_addr) tL2C_LCB *p_lcb; - if ((p_lcb = l2cu_find_lcb_by_bd_addr (bd_addr)) != NULL) + if ((p_lcb = l2cu_find_lcb_by_bd_addr (bd_addr, BT_TRANSPORT_LE)) != NULL) role = p_lcb->link_role; return role; @@ -298,12 +255,12 @@ UINT8 L2CA_GetBleConnRole (BD_ADDR bd_addr) ** Returns disconnect reason ** *******************************************************************************/ -UINT16 L2CA_GetDisconnectReason (BD_ADDR remote_bda) +UINT16 L2CA_GetDisconnectReason (BD_ADDR remote_bda, tBT_TRANSPORT transport) { tL2C_LCB *p_lcb; UINT16 reason = 0; - if ((p_lcb = l2cu_find_lcb_by_bd_addr (remote_bda)) != NULL) + if ((p_lcb = l2cu_find_lcb_by_bd_addr (remote_bda, transport)) != NULL) reason = p_lcb->disc_reason; L2CAP_TRACE_DEBUG1 ("L2CA_GetDisconnectReason=%d ",reason); @@ -333,12 +290,12 @@ void l2cble_scanner_conn_comp (UINT16 handle, BD_ADDR bda, tBLE_ADDR_TYPE type, l2cb.is_ble_connecting = FALSE; /* See if we have a link control block for the remote device */ - p_lcb = l2cu_find_lcb_by_bd_addr (bda); + p_lcb = l2cu_find_lcb_by_bd_addr (bda, BT_TRANSPORT_LE); /* If we don't have one, create one. this is auto connection complete. */ if (!p_lcb) { - p_lcb = l2cu_allocate_lcb (bda, FALSE); + p_lcb = l2cu_allocate_lcb (bda, FALSE, BT_TRANSPORT_LE); if (!p_lcb) { btm_sec_disconnect (handle, HCI_ERR_NO_CONNECTION); @@ -368,7 +325,7 @@ void l2cble_scanner_conn_comp (UINT16 handle, BD_ADDR bda, tBLE_ADDR_TYPE type, /* Connected OK. Change state to connected, we were scanning so we are master */ p_lcb->link_state = LST_CONNECTED; p_lcb->link_role = HCI_ROLE_MASTER; - p_lcb->is_ble_link = TRUE; + p_lcb->transport = BT_TRANSPORT_LE; /* If there are any preferred connection parameters, set them now */ if ( (p_dev_rec->conn_params.min_conn_int >= BTM_BLE_CONN_INT_MIN ) && @@ -394,21 +351,16 @@ void l2cble_scanner_conn_comp (UINT16 handle, BD_ADDR bda, tBLE_ADDR_TYPE type, p_dev_rec->conn_params.slave_latency, p_dev_rec->conn_params.supervision_tout, 0, 0); - p_lcb->upd_status |= L2C_BLE_UPDATE_PENDING; } /* Tell BTM Acl management about the link */ - btm_acl_created (bda, NULL, p_dev_rec->sec_bd_name, handle, p_lcb->link_role, TRUE); - - if (p_lcb->p_echo_rsp_cb) - { - L2CAP_TRACE_ERROR0 ("l2cu_send_peer_echo_req"); - l2cu_send_peer_echo_req (p_lcb, NULL, 0); - } + btm_acl_created (bda, NULL, p_dev_rec->sec_bd_name, handle, p_lcb->link_role, BT_TRANSPORT_LE); p_lcb->peer_chnl_mask[0] = L2CAP_FIXED_CHNL_ATT_BIT | L2CAP_FIXED_CHNL_BLE_SIG_BIT | L2CAP_FIXED_CHNL_SMP_BIT; l2cu_process_fixed_chnl_resp (p_lcb); + + btm_ble_set_conn_st(BLE_CONN_IDLE); } @@ -433,12 +385,12 @@ void l2cble_advertiser_conn_comp (UINT16 handle, BD_ADDR bda, tBLE_ADDR_TYPE typ UNUSED(conn_timeout); /* See if we have a link control block for the remote device */ - p_lcb = l2cu_find_lcb_by_bd_addr (bda); + p_lcb = l2cu_find_lcb_by_bd_addr (bda, BT_TRANSPORT_LE); /* If we don't have one, create one and accept the connection. */ if (!p_lcb) { - p_lcb = l2cu_allocate_lcb (bda, FALSE); + p_lcb = l2cu_allocate_lcb (bda, FALSE, BT_TRANSPORT_LE); if (!p_lcb) { btm_sec_disconnect (handle, HCI_ERR_NO_CONNECTION); @@ -462,16 +414,22 @@ void l2cble_advertiser_conn_comp (UINT16 handle, BD_ADDR bda, tBLE_ADDR_TYPE typ /* Connected OK. Change state to connected, we were advertising, so we are slave */ p_lcb->link_state = LST_CONNECTED; p_lcb->link_role = HCI_ROLE_SLAVE; - p_lcb->is_ble_link = TRUE; + p_lcb->transport = BT_TRANSPORT_LE; /* Tell BTM Acl management about the link */ p_dev_rec = btm_find_or_alloc_dev (bda); - btm_acl_created (bda, NULL, p_dev_rec->sec_bd_name, handle, p_lcb->link_role, TRUE); + btm_acl_created (bda, NULL, p_dev_rec->sec_bd_name, handle, p_lcb->link_role, BT_TRANSPORT_LE); p_lcb->peer_chnl_mask[0] = L2CAP_FIXED_CHNL_ATT_BIT | L2CAP_FIXED_CHNL_BLE_SIG_BIT | L2CAP_FIXED_CHNL_SMP_BIT; l2cu_process_fixed_chnl_resp (p_lcb); + + /* when adv and initiating are both active, cancel the direct connection */ + if (l2cb.is_ble_connecting && memcmp(bda, l2cb.ble_connecting_bda, BD_ADDR_LEN) == 0) + { + L2CA_CancelBleConnectReq(bda); + } } /******************************************************************************* @@ -561,12 +519,22 @@ void l2cble_process_sig_cmd (tL2C_LCB *p_lcb, UINT8 *p, UINT16 pkt_len) l2cu_send_peer_ble_par_rsp (p_lcb, L2CAP_CFG_OK, id); - p_lcb->min_interval = min_interval; - p_lcb->max_interval = max_interval; - p_lcb->latency = latency; - p_lcb->timeout = timeout; - p_lcb->upd_status |= L2C_BLE_NEW_CONN_PARAM; - L2CA_InternalBleConnUpdate(p_lcb); + p_lcb->min_interval = min_interval; + p_lcb->max_interval = max_interval; + p_lcb->latency = latency; + p_lcb->timeout = timeout; + p_lcb->conn_update_mask |= UPD_REQUEST; + + if (L2CA_GET_UPD_ST(p_lcb->conn_update_mask) == UPD_ENABLED) + { + btsnd_hcic_ble_upd_ll_conn_params (p_lcb->handle, min_interval, max_interval, + latency, timeout, 0, 0); + } + else + { + L2CAP_TRACE_EVENT0 ("L2CAP - LE - update currently disabled"); + } + } } else @@ -583,8 +551,47 @@ void l2cble_process_sig_cmd (tL2C_LCB *p_lcb, UINT8 *p, UINT16 pkt_len) return; } } +/******************************************************************************* +** +** Function l2c_enable_conn_param_timeout +** +** Description This function process the connection parameter enabling timeout +** +** Returns None. +** +*******************************************************************************/ +void l2c_enable_conn_param_timeout(tL2C_LCB * p_lcb) +{ + tBTM_SEC_DEV_REC *p_dev_rec = btm_find_or_alloc_dev (p_lcb->remote_bd_addr); + /* application allows to do update, if we were delaying one do it now, otherwise + just mark lcb that updates are enabled */ + if (p_lcb->conn_update_mask & UPD_REQUEST) + { + btsnd_hcic_ble_upd_ll_conn_params (p_lcb->handle, p_lcb->min_interval, p_lcb->max_interval, + p_lcb->latency, p_lcb->timeout, 0, 0); + } + else + { + /* if preferred number has been set, set to preferred conn parameter */ + if (p_dev_rec && p_dev_rec->conn_params.min_conn_int != BTM_BLE_CONN_PARAM_UNDEF) + { + btsnd_hcic_ble_upd_ll_conn_params (p_lcb->handle, + (UINT16)((p_dev_rec->conn_params.min_conn_int != BTM_BLE_CONN_PARAM_UNDEF) ? + p_dev_rec->conn_params.min_conn_int : BTM_BLE_CONN_INT_MIN_DEF), + (UINT16)((p_dev_rec->conn_params.max_conn_int != BTM_BLE_CONN_PARAM_UNDEF) ? + p_dev_rec->conn_params.max_conn_int : BTM_BLE_CONN_INT_MAX_DEF), + (UINT16)((p_dev_rec->conn_params.slave_latency != BTM_BLE_CONN_PARAM_UNDEF) ? + p_dev_rec->conn_params.slave_latency : BTM_BLE_CONN_SLAVE_LATENCY_DEF), + (UINT16) ((p_dev_rec->conn_params.supervision_tout != BTM_BLE_CONN_PARAM_UNDEF) ? + p_dev_rec->conn_params.supervision_tout : BTM_BLE_CONN_TIMEOUT_DEF), + 0, 0); + } + } + L2CA_SET_UPD_ST( p_lcb->conn_update_mask, UPD_ENABLED); + +} /******************************************************************************* ** ** Function l2cble_init_direct_conn @@ -606,7 +613,7 @@ BOOLEAN l2cble_init_direct_conn (tL2C_LCB *p_lcb) /* There can be only one BLE connection request outstanding at a time */ if (p_dev_rec == NULL) { - BTM_TRACE_WARNING0 ("unknown device, can not initate connection"); + L2CAP_TRACE_WARNING0 ("unknown device, can not initate connection"); return(FALSE); } @@ -616,14 +623,23 @@ BOOLEAN l2cble_init_direct_conn (tL2C_LCB *p_lcb) init_addr_type = p_lcb->ble_addr_type; memcpy(init_addr, p_lcb->remote_bd_addr, BD_ADDR_LEN); -#if BTM_BLE_PRIVACY_SPT == TRUE +#if BLE_PRIVACY_SPT == TRUE if (p_dev_rec->ble.active_addr_type == BTM_BLE_ADDR_RRA) { init_addr_type = BLE_ADDR_RANDOM; memcpy(init_addr, p_dev_rec->ble.cur_rand_addr, BD_ADDR_LEN); } + /* if privacy is on and current do not consider using reconnection address */ + if (btm_cb.ble_ctr_cb.privacy ) /* && p_dev_rec->ble.use_reconn_addr */ + own_addr_type = BLE_ADDR_RANDOM; #endif + if (!btm_ble_topology_check(BTM_BLE_STATE_INIT)) + { + l2cu_release_lcb (p_lcb); + L2CAP_TRACE_ERROR0("initate direct connection fail, topology limitation"); + return FALSE; + } if (!btsnd_hcic_ble_create_ll_conn (scan_int,/* UINT16 scan_int */ scan_win, /* UINT16 scan_win */ FALSE, /* UINT8 white_list */ @@ -712,4 +728,47 @@ void l2c_link_processs_ble_num_bufs (UINT16 num_lm_ble_bufs) l2cb.num_lm_ble_bufs = l2cb.controller_le_xmit_window = num_lm_ble_bufs; } +#if (defined BLE_LLT_INCLUDED) && (BLE_LLT_INCLUDED == TRUE) +/******************************************************************************* +** +** Function l2cble_process_rc_param_request_evt +** +** Description process LE Remote Connection Parameter Request Event. +** +** Returns void +** +*******************************************************************************/ +void l2cble_process_rc_param_request_evt(UINT16 handle, UINT16 int_min, UINT16 int_max, + UINT16 latency, UINT16 timeout) +{ + tL2C_LCB *p_lcb = l2cu_find_lcb_by_handle (handle); + + if (p_lcb != NULL) + { + p_lcb->min_interval = int_min; + p_lcb->max_interval = int_max; + p_lcb->latency = latency; + p_lcb->timeout = timeout; + p_lcb->conn_update_mask |= UPD_REQUEST; + + /* TODO: revisit: if update is enabled, always accept connection parameter update */ + if (L2CA_GET_UPD_ST(p_lcb->conn_update_mask) == UPD_ENABLED) + { + btsnd_hcic_ble_rc_param_req_reply(handle, int_min, int_max, latency, timeout, 0, 0); + } + else + { + L2CAP_TRACE_EVENT0 ("L2CAP - LE - update currently disabled"); + btsnd_hcic_ble_rc_param_req_neg_reply (handle,HCI_ERR_UNACCEPT_CONN_INTERVAL); + } + + } + else + { + L2CAP_TRACE_WARNING0("No link to update connection parameter") + } +} +#endif + + #endif /* (BLE_INCLUDED == TRUE) */ diff --git a/stack/l2cap/l2c_fcr.c b/stack/l2cap/l2c_fcr.c index 9685f774b..f2e72ad94 100644 --- a/stack/l2cap/l2c_fcr.c +++ b/stack/l2cap/l2c_fcr.c @@ -2246,7 +2246,7 @@ UINT8 l2c_fcr_process_peer_cfg_req(tL2C_CCB *p_ccb, tL2CAP_CFG_INFO *p_cfg) p_ccb->out_cfg_fcr_present = TRUE; } - if (p_cfg->fcr.mode == L2CAP_FCR_ERTM_MODE) + if (p_cfg->fcr.mode == L2CAP_FCR_ERTM_MODE || p_cfg->fcr.mode == L2CAP_FCR_STREAM_MODE) { /* Always respond with FCR ERTM parameters */ p_ccb->out_cfg_fcr_present = TRUE; diff --git a/stack/l2cap/l2c_int.h b/stack/l2cap/l2c_int.h index 72d554448..272d318d0 100644 --- a/stack/l2cap/l2c_int.h +++ b/stack/l2cap/l2c_int.h @@ -52,6 +52,8 @@ #define L2CAP_WAIT_UNPARK_TOUT 2 /* 2 seconds */ #define L2CAP_LINK_INFO_RESP_TOUT 2 /* 2 seconds */ #define L2CAP_BLE_LINK_CONNECT_TOUT 30 /* 30 seconds */ +#define L2CAP_BLE_CONN_PARAM_UPD_TOUT 30 /* 30 seconds */ +#define L2CAP_BLE_ENB_CONN_PARAM_TOUT 1 /* 1 seconds */ /* quick timer uses millisecond unit */ #define L2CAP_DEFAULT_RETRANS_TOUT 2000 /* 2000 milliseconds */ @@ -393,6 +395,7 @@ typedef struct t_l2c_linkcb UINT8 link_role; /* Master or slave */ UINT8 id; + UINT8 cur_echo_id; /* Current id value for echo request */ tL2CA_ECHO_RSP_CB *p_echo_rsp_cb; /* Echo response callback */ UINT16 idle_timeout; /* Idle timeout */ BOOLEAN is_bonding; /* True - link active only for bonding */ @@ -431,16 +434,17 @@ typedef struct t_l2c_linkcb UINT16 disc_reason; #endif + tBT_TRANSPORT transport; #if (BLE_INCLUDED == TRUE) - BOOLEAN is_ble_link; tBLE_ADDR_TYPE ble_addr_type; - -#define L2C_BLE_CONN_UPDATE_DISABLE 0x1 /* disable update connection parameters */ -#define L2C_BLE_NEW_CONN_PARAM 0x2 /* new connection parameter to be set */ -#define L2C_BLE_UPDATE_PENDING 0x4 /* waiting for connection update finished */ -#define L2C_BLE_NOT_DEFAULT_PARAM 0x8 /* not using default connection parameters */ - UINT8 upd_status; - + TIMER_LIST_ENT conn_param_enb; /* Timer entry for enabling connection parameter update */ + +#define UPD_ENABLED 0 /* If peer requests update, we will change params */ +#define UPD_DISABLED 1 /* application requested not to update */ +#define UPD_ENB_TOUT 2 /* while updates are disabled, peer requested new parameters */ +#define UPD_ST_MASK 0x0f +#define UPD_REQUEST 0x10 /* remote device set preferred conn param */ + UINT8 conn_update_mask; UINT16 min_interval; /* parameters as requested by peripheral */ UINT16 max_interval; UINT16 latency; @@ -578,14 +582,14 @@ extern void l2c_process_held_packets (BOOLEAN timed_out); /* Functions provided by l2c_utils.c ************************************ */ -extern tL2C_LCB *l2cu_allocate_lcb (BD_ADDR p_bd_addr, BOOLEAN is_bonding); +extern tL2C_LCB *l2cu_allocate_lcb (BD_ADDR p_bd_addr, BOOLEAN is_bonding, tBT_TRANSPORT transport); extern BOOLEAN l2cu_start_post_bond_timer (UINT16 handle); extern void l2cu_release_lcb (tL2C_LCB *p_lcb); -extern tL2C_LCB *l2cu_find_lcb_by_bd_addr (BD_ADDR p_bd_addr); +extern tL2C_LCB *l2cu_find_lcb_by_bd_addr (BD_ADDR p_bd_addr, tBT_TRANSPORT transport); extern tL2C_LCB *l2cu_find_lcb_by_handle (UINT16 handle); extern void l2cu_update_lcb_4_bonding (BD_ADDR p_bd_addr, BOOLEAN is_bonding); -extern UINT8 l2cu_get_conn_role (BD_ADDR bd_addr); +extern UINT8 l2cu_get_conn_role (tL2C_LCB *p_this_lcb); extern BOOLEAN l2cu_set_acl_priority (BD_ADDR bd_addr, UINT8 priority, BOOLEAN reset_after_rs); extern void l2cu_enqueue_ccb (tL2C_CCB *p_ccb); @@ -597,6 +601,7 @@ extern void l2cu_release_ccb (tL2C_CCB *p_ccb); extern tL2C_CCB *l2cu_find_ccb_by_cid (tL2C_LCB *p_lcb, UINT16 local_cid); extern tL2C_CCB *l2cu_find_ccb_by_remote_cid (tL2C_LCB *p_lcb, UINT16 remote_cid); extern void l2cu_adj_id (tL2C_LCB *p_lcb, UINT8 adj_mask); +extern BOOLEAN l2c_is_cmd_rejected (UINT8 cmd_code, UINT8 id, tL2C_LCB *p_lcb); extern void l2cu_send_peer_cmd_reject (tL2C_LCB *p_lcb, UINT16 reason, UINT8 rem_id,UINT16 p1, UINT16 p2); @@ -676,7 +681,7 @@ extern void l2cu_device_reset (void); extern tL2C_LCB *l2cu_find_lcb_by_state (tL2C_LINK_STATE state); extern BOOLEAN l2cu_lcb_disconnecting (void); -extern BOOLEAN l2cu_create_conn (tL2C_LCB *p_lcb); +extern BOOLEAN l2cu_create_conn (tL2C_LCB *p_lcb, tBT_TRANSPORT transport); extern BOOLEAN l2cu_create_conn_after_switch (tL2C_LCB *p_lcb); extern BT_HDR *l2cu_get_next_buffer_to_send (tL2C_LCB *p_lcb); extern void l2cu_resubmit_pending_sec_req (BD_ADDR p_bda); @@ -699,7 +704,7 @@ extern void l2c_link_process_num_completed_blocks (UINT8 controller_id, UINT extern void l2c_link_processs_num_bufs (UINT16 num_lm_acl_bufs); extern UINT8 l2c_link_pkts_rcvd (UINT16 *num_pkts, UINT16 *handles); extern void l2c_link_role_changed (BD_ADDR bd_addr, UINT8 new_role, UINT8 hci_status); -extern void l2c_link_sec_comp (BD_ADDR p_bda, void *p_ref_data, UINT8 status); +extern void l2c_link_sec_comp (BD_ADDR p_bda, tBT_TRANSPORT trasnport, void *p_ref_data, UINT8 status); extern void l2c_link_segments_xmitted (BT_HDR *p_msg); extern void l2c_pin_code_request (BD_ADDR bd_addr); extern void l2c_link_adjust_chnl_allocation (void); @@ -762,8 +767,13 @@ extern void l2cble_process_sig_cmd (tL2C_LCB *p_lcb, UINT8 *p, UINT16 pkt_len); extern void l2cble_conn_comp (UINT16 handle, UINT8 role, BD_ADDR bda, tBLE_ADDR_TYPE type, UINT16 conn_interval, UINT16 conn_latency, UINT16 conn_timeout); extern BOOLEAN l2cble_init_direct_conn (tL2C_LCB *p_lcb); - +extern void l2c_enable_conn_param_timeout(tL2C_LCB * p_lcb); +#if (defined BLE_LLT_INCLUDED) && (BLE_LLT_INCLUDED == TRUE) +extern void l2cble_process_rc_param_request_evt(UINT16 handle, UINT16 int_min, UINT16 int_max, + UINT16 latency, UINT16 timeout); +#endif #endif +extern void l2cu_process_fixed_disc_cback (tL2C_LCB *p_lcb); #ifdef __cplusplus } diff --git a/stack/l2cap/l2c_link.c b/stack/l2cap/l2c_link.c index fd38ca243..f5e829452 100644 --- a/stack/l2cap/l2c_link.c +++ b/stack/l2cap/l2c_link.c @@ -65,12 +65,12 @@ BOOLEAN l2c_link_hci_conn_req (BD_ADDR bd_addr) BOOLEAN no_links; /* See if we have a link control block for the remote device */ - p_lcb = l2cu_find_lcb_by_bd_addr (bd_addr); + p_lcb = l2cu_find_lcb_by_bd_addr (bd_addr, BT_TRANSPORT_BR_EDR); /* If we don't have one, create one and accept the connection. */ if (!p_lcb) { - p_lcb = l2cu_allocate_lcb (bd_addr, FALSE); + p_lcb = l2cu_allocate_lcb (bd_addr, FALSE, BT_TRANSPORT_BR_EDR); if (!p_lcb) { btsnd_hcic_reject_conn (bd_addr, HCI_ERR_HOST_REJECT_RESOURCES); @@ -99,7 +99,7 @@ BOOLEAN l2c_link_hci_conn_req (BD_ADDR bd_addr) if (!btm_dev_support_switch (bd_addr)) p_lcb->link_role = HCI_ROLE_SLAVE; else - p_lcb->link_role = l2cu_get_conn_role(bd_addr); + p_lcb->link_role = l2cu_get_conn_role(p_lcb); } /* Tell the other side we accept the connection */ @@ -120,7 +120,7 @@ BOOLEAN l2c_link_hci_conn_req (BD_ADDR bd_addr) if (!btm_dev_support_switch (bd_addr)) p_lcb->link_role = HCI_ROLE_SLAVE; else - p_lcb->link_role = l2cu_get_conn_role(bd_addr); + p_lcb->link_role = l2cu_get_conn_role(p_lcb); btsnd_hcic_accept_conn (bd_addr, p_lcb->link_role); @@ -168,7 +168,7 @@ BOOLEAN l2c_link_hci_conn_comp (UINT8 status, UINT16 handle, BD_ADDR p_bda) memcpy (ci.bd_addr, p_bda, BD_ADDR_LEN); /* See if we have a link control block for the remote device */ - p_lcb = l2cu_find_lcb_by_bd_addr (ci.bd_addr); + p_lcb = l2cu_find_lcb_by_bd_addr (ci.bd_addr, BT_TRANSPORT_BR_EDR); /* If we don't have one, this is an error */ if (!p_lcb) @@ -202,9 +202,9 @@ BOOLEAN l2c_link_hci_conn_comp (UINT8 status, UINT16 handle, BD_ADDR p_bda) if ((p_dev_info = btm_find_dev (p_bda)) != NULL) btm_acl_created (ci.bd_addr, p_dev_info->dev_class, p_dev_info->sec_bd_name, handle, - p_lcb->link_role, FALSE); + p_lcb->link_role, BT_TRANSPORT_BR_EDR); else - btm_acl_created (ci.bd_addr, NULL, NULL, handle, p_lcb->link_role, FALSE); + btm_acl_created (ci.bd_addr, NULL, NULL, handle, p_lcb->link_role, BT_TRANSPORT_BR_EDR); BTM_SetLinkSuperTout (ci.bd_addr, btm_cb.btm_def_link_super_tout); @@ -272,7 +272,7 @@ BOOLEAN l2c_link_hci_conn_comp (UINT8 status, UINT16 handle, BD_ADDR p_bda) } else { - l2cu_create_conn(p_lcb); + l2cu_create_conn(p_lcb, BT_TRANSPORT_BR_EDR); } } } @@ -290,7 +290,7 @@ BOOLEAN l2c_link_hci_conn_comp (UINT8 status, UINT16 handle, BD_ADDR p_bda) ** Returns void ** *******************************************************************************/ -void l2c_link_sec_comp (BD_ADDR p_bda, void *p_ref_data, UINT8 status) +void l2c_link_sec_comp (BD_ADDR p_bda, tBT_TRANSPORT transport, void *p_ref_data, UINT8 status) { tL2C_CONN_INFO ci; tL2C_LCB *p_lcb; @@ -298,6 +298,8 @@ void l2c_link_sec_comp (BD_ADDR p_bda, void *p_ref_data, UINT8 status) tL2C_CCB *p_next_ccb; UINT8 event; + UNUSED(transport); + L2CAP_TRACE_DEBUG2 ("l2c_link_sec_comp: %d, 0x%x", status, p_ref_data); if (status == BTM_SUCCESS_NO_SECURITY) @@ -307,7 +309,7 @@ void l2c_link_sec_comp (BD_ADDR p_bda, void *p_ref_data, UINT8 status) ci.status = status; memcpy (ci.bd_addr, p_bda, BD_ADDR_LEN); - p_lcb = l2cu_find_lcb_by_bd_addr (p_bda); + p_lcb = l2cu_find_lcb_by_bd_addr (p_bda, BT_TRANSPORT_BR_EDR); /* If we don't have one, this is an error */ if (!p_lcb) @@ -361,6 +363,7 @@ BOOLEAN l2c_link_hci_disc_comp (UINT16 handle, UINT8 reason) tL2C_CCB *p_ccb; BOOLEAN status = TRUE; BOOLEAN lcb_is_free = TRUE; + tBT_TRANSPORT transport = BT_TRANSPORT_BR_EDR; /* See if we have a link control block for the connection */ p_lcb = l2cu_find_lcb_by_handle (handle); @@ -401,35 +404,53 @@ BOOLEAN l2c_link_hci_disc_comp (UINT16 handle, UINT8 reason) p_ccb = pn; } -#if BTM_SCO_INCLUDED == TRUE - /* Tell SCO management to drop any SCOs on this ACL */ - btm_sco_acl_removed (p_lcb->remote_bd_addr); +#if (BTM_SCO_INCLUDED == TRUE) +#if (BLE_INCLUDED == TRUE) + if (p_lcb->transport == BT_TRANSPORT_BR_EDR) +#endif + /* Tell SCO management to drop any SCOs on this ACL */ + btm_sco_acl_removed (p_lcb->remote_bd_addr); #endif /* If waiting for disconnect and reconnect is pending start the reconnect now race condition where layer above issued connect request on link that was disconnecting */ - if (p_lcb->ccb_queue.p_first_ccb != NULL) + if (p_lcb->ccb_queue.p_first_ccb != NULL || p_lcb->p_pending_ccb) { #if (L2CAP_NUM_FIXED_CHNLS > 0) /* If we are going to re-use the LCB without dropping it, release all fixed channels here */ int xx; - for (xx = 0; xx < L2CAP_NUM_FIXED_CHNLS; xx++) { - if (p_lcb->p_fixed_ccbs[xx]) + if (p_lcb->p_fixed_ccbs[xx] && p_lcb->p_fixed_ccbs[xx] != p_lcb->p_pending_ccb) { - (*l2cb.fixed_reg[xx].pL2CA_FixedConn_Cb)(p_lcb->remote_bd_addr, FALSE, p_lcb->disc_reason); +#if BLE_INCLUDED == TRUE + (*l2cb.fixed_reg[xx].pL2CA_FixedConn_Cb)(p_lcb->remote_bd_addr, FALSE, + p_lcb->disc_reason, p_lcb->transport); +#else + (*l2cb.fixed_reg[xx].pL2CA_FixedConn_Cb)(p_lcb->remote_bd_addr, FALSE, + p_lcb->disc_reason, BT_TRANSPORT_BR_EDR); +#endif l2cu_release_ccb (p_lcb->p_fixed_ccbs[xx]); p_lcb->p_fixed_ccbs[xx] = NULL; } +#if BLE_INCLUDED == TRUE + else if (p_lcb->p_fixed_ccbs[xx] && p_lcb->p_fixed_ccbs[xx] == + p_lcb->p_pending_ccb) + { + if (p_lcb->p_fixed_ccbs[xx]->local_cid >= L2CAP_ATT_CID && + p_lcb->p_fixed_ccbs[xx]->local_cid <= L2CAP_SMP_CID) + transport = BT_TRANSPORT_LE; + } +#endif + } #endif L2CAP_TRACE_DEBUG0("l2c_link_hci_disc_comp: Restarting pending ACL request"); - if (l2cu_create_conn(p_lcb)) + if (l2cu_create_conn(p_lcb, transport)) lcb_is_free = FALSE; /* still using this lcb */ } @@ -444,7 +465,7 @@ BOOLEAN l2c_link_hci_disc_comp (UINT16 handle, UINT8 reason) if (lcb_is_free && ((p_lcb = l2cu_find_lcb_by_state(LST_CONNECT_HOLDING)) != NULL)) { /* we found one-- create a connection */ - l2cu_create_conn(p_lcb); + l2cu_create_conn(p_lcb, BT_TRANSPORT_BR_EDR); } return status; @@ -576,6 +597,7 @@ void l2c_link_timeout (tL2C_LCB *p_lcb) } else if (rc == BTM_SUCCESS) { + l2cu_process_fixed_disc_cback(p_lcb); /* BTM SEC will make sure that link is release (probably after pairing is done) */ p_lcb->link_state = LST_DISCONNECTING; timeout = 0xFFFF; @@ -588,6 +610,7 @@ void l2c_link_timeout (tL2C_LCB *p_lcb) else if ((p_lcb->is_bonding) && (btsnd_hcic_disconnect (p_lcb->handle, HCI_ERR_PEER_USER))) { + l2cu_process_fixed_disc_cback(p_lcb); p_lcb->link_state = LST_DISCONNECTING; timeout = L2CAP_LINK_DISCONNECT_TOUT; } @@ -977,7 +1000,7 @@ void l2c_link_role_changed (BD_ADDR bd_addr, UINT8 new_role, UINT8 hci_status) if (bd_addr) { /* If here came form hci role change event */ - p_lcb = l2cu_find_lcb_by_bd_addr (bd_addr); + p_lcb = l2cu_find_lcb_by_bd_addr (bd_addr, BT_TRANSPORT_BR_EDR); if (p_lcb) { p_lcb->link_role = new_role; @@ -1013,7 +1036,7 @@ void l2c_link_role_changed (BD_ADDR bd_addr, UINT8 new_role, UINT8 hci_status) *******************************************************************************/ void l2c_pin_code_request (BD_ADDR bd_addr) { - tL2C_LCB *p_lcb = l2cu_find_lcb_by_bd_addr (bd_addr); + tL2C_LCB *p_lcb = l2cu_find_lcb_by_bd_addr (bd_addr, BT_TRANSPORT_BR_EDR); if ( (p_lcb) && (!p_lcb->ccb_queue.p_first_ccb) ) { @@ -1129,11 +1152,11 @@ void l2c_link_check_send_pkts (tL2C_LCB *p_lcb, tL2C_CCB *p_ccb, BT_HDR *p_buf) /* If controller window is full, nothing to do */ if ( (l2cb.controller_xmit_window == 0 #if (BLE_INCLUDED == TRUE) - && !p_lcb->is_ble_link + && (p_lcb->transport == BT_TRANSPORT_BR_EDR) #endif ) #if (BLE_INCLUDED == TRUE) - || (p_lcb->is_ble_link && l2cb.controller_le_xmit_window == 0 ) + || (p_lcb->transport == BT_TRANSPORT_LE && l2cb.controller_le_xmit_window == 0 ) #endif || (l2cb.round_robin_unacked >= l2cb.round_robin_quota) ) break; @@ -1168,8 +1191,8 @@ void l2c_link_check_send_pkts (tL2C_LCB *p_lcb, tL2C_CCB *p_ccb, BT_HDR *p_buf) /* If we finished without using up our quota, no need for a safety check */ #if (BLE_INCLUDED == TRUE) - if ( ((l2cb.controller_xmit_window > 0 && !p_lcb->is_ble_link) || - (l2cb.controller_le_xmit_window > 0 && p_lcb->is_ble_link)) + if ( ((l2cb.controller_xmit_window > 0 && (p_lcb->transport == BT_TRANSPORT_BR_EDR)) || + (l2cb.controller_le_xmit_window > 0 && (p_lcb->transport == BT_TRANSPORT_LE))) && (l2cb.round_robin_unacked < l2cb.round_robin_quota) ) #else if ( (l2cb.controller_xmit_window > 0) @@ -1188,8 +1211,8 @@ void l2c_link_check_send_pkts (tL2C_LCB *p_lcb, tL2C_CCB *p_ccb, BT_HDR *p_buf) /* See if we can send anything from the link queue */ #if (BLE_INCLUDED == TRUE) - while ( ((l2cb.controller_xmit_window != 0 && !p_lcb->is_ble_link) || - (l2cb.controller_le_xmit_window != 0 && p_lcb->is_ble_link)) + while ( ((l2cb.controller_xmit_window != 0 && (p_lcb->transport == BT_TRANSPORT_BR_EDR)) || + (l2cb.controller_le_xmit_window != 0 && (p_lcb->transport == BT_TRANSPORT_LE))) && (p_lcb->sent_not_acked < p_lcb->link_xmit_quota)) #else while ( (l2cb.controller_xmit_window != 0) @@ -1207,8 +1230,8 @@ void l2c_link_check_send_pkts (tL2C_LCB *p_lcb, tL2C_CCB *p_ccb, BT_HDR *p_buf) { /* See if we can send anything for any channel */ #if (BLE_INCLUDED == TRUE) - while ( ((l2cb.controller_xmit_window != 0 && !p_lcb->is_ble_link) || - (l2cb.controller_le_xmit_window != 0 && p_lcb->is_ble_link)) + while ( ((l2cb.controller_xmit_window != 0 && (p_lcb->transport == BT_TRANSPORT_BR_EDR)) || + (l2cb.controller_le_xmit_window != 0 && (p_lcb->transport == BT_TRANSPORT_LE))) && (p_lcb->sent_not_acked < p_lcb->link_xmit_quota)) #else while ((l2cb.controller_xmit_window != 0) && (p_lcb->sent_not_acked < p_lcb->link_xmit_quota)) @@ -1245,12 +1268,14 @@ static BOOLEAN l2c_link_send_to_lower (tL2C_LCB *p_lcb, BT_HDR *p_buf) UINT16 num_segs; UINT16 xmit_window, acl_data_size; + if ((p_buf->len <= btu_cb.hcit_acl_pkt_size #if (BLE_INCLUDED == TRUE) - if ((!p_lcb->is_ble_link && (p_buf->len <= btu_cb.hcit_acl_pkt_size)) || - (p_lcb->is_ble_link && (p_buf->len <= btu_cb.hcit_ble_acl_pkt_size))) + && (p_lcb->transport == BT_TRANSPORT_BR_EDR)) || + ((p_lcb->transport == BT_TRANSPORT_LE) && (p_buf->len <= btu_cb.hcit_ble_acl_pkt_size)) #else - if (p_buf->len <= btu_cb.hcit_acl_pkt_size) + ) #endif + ) { if (p_lcb->link_xmit_quota == 0) l2cb.round_robin_unacked++; @@ -1259,7 +1284,7 @@ static BOOLEAN l2c_link_send_to_lower (tL2C_LCB *p_lcb, BT_HDR *p_buf) p_buf->layer_specific = 0; #if (BLE_INCLUDED == TRUE) - if (p_lcb->is_ble_link) + if (p_lcb->transport == BT_TRANSPORT_LE) { l2cb.controller_le_xmit_window--; L2C_LINK_SEND_BLE_ACL_DATA (p_buf); @@ -1274,7 +1299,7 @@ static BOOLEAN l2c_link_send_to_lower (tL2C_LCB *p_lcb, BT_HDR *p_buf) else { #if BLE_INCLUDED == TRUE - if (p_lcb->is_ble_link) + if (p_lcb->transport == BT_TRANSPORT_LE) { acl_data_size = btu_cb.hcit_ble_acl_data_size; xmit_window = l2cb.controller_le_xmit_window; @@ -1313,7 +1338,7 @@ static BOOLEAN l2c_link_send_to_lower (tL2C_LCB *p_lcb, BT_HDR *p_buf) p_buf->layer_specific = num_segs; #if BLE_INCLUDED == TRUE - if (p_lcb->is_ble_link) + if (p_lcb->transport == BT_TRANSPORT_LE) { l2cb.controller_le_xmit_window -= num_segs; @@ -1327,7 +1352,7 @@ static BOOLEAN l2c_link_send_to_lower (tL2C_LCB *p_lcb, BT_HDR *p_buf) p_lcb->sent_not_acked += num_segs; #if BLE_INCLUDED == TRUE - if (p_lcb->is_ble_link) + if (p_lcb->transport == BT_TRANSPORT_LE) { L2C_LINK_SEND_BLE_ACL_DATA(p_buf); } @@ -1340,7 +1365,7 @@ static BOOLEAN l2c_link_send_to_lower (tL2C_LCB *p_lcb, BT_HDR *p_buf) #if (L2CAP_HCI_FLOW_CONTROL_DEBUG == TRUE) #if (BLE_INCLUDED == TRUE) - if (p_lcb->is_ble_link) + if (p_lcb->transport == BT_TRANSPORT_LE) { L2CAP_TRACE_DEBUG6 ("TotalWin=%d,Hndl=0x%x,Quota=%d,Unack=%d,RRQuota=%d,RRUnack=%d", l2cb.controller_le_xmit_window, @@ -1400,11 +1425,9 @@ void l2c_link_process_num_completed_pkts (UINT8 *p) if (p_lcb) { #if (BLE_INCLUDED == TRUE) - if (p_lcb->is_ble_link) - { - l2cb.controller_le_xmit_window += num_sent; - } - else + if (p_lcb && (p_lcb->transport == BT_TRANSPORT_LE)) + l2cb.controller_le_xmit_window += num_sent; + else #endif { /* Maintain the total window to the controller */ @@ -1441,7 +1464,7 @@ void l2c_link_process_num_completed_pkts (UINT8 *p) if (p_lcb) { #if (BLE_INCLUDED == TRUE) - if (p_lcb->is_ble_link) + if (p_lcb->transport == BT_TRANSPORT_LE) { L2CAP_TRACE_DEBUG5 ("TotalWin=%d,LinkUnack(0x%x)=%d,RRCheck=%d,RRUnack=%d", l2cb.controller_le_xmit_window, diff --git a/stack/l2cap/l2c_main.c b/stack/l2cap/l2c_main.c index 49dd8113e..2795d8c00 100644 --- a/stack/l2cap/l2c_main.c +++ b/stack/l2cap/l2c_main.c @@ -320,17 +320,29 @@ static void process_l2cap_cmd (tL2C_LCB *p_lcb, UINT8 *p, UINT16 pkt_len) tL2CAP_CFG_INFO cfg_info; UINT16 rej_reason, rej_mtu, lcid, rcid, info_type; tL2C_CCB *p_ccb; - tL2C_RCB *p_rcb; - BOOLEAN cfg_rej; + tL2C_RCB *p_rcb, *p_rcb2; + BOOLEAN cfg_rej, pkt_size_rej = FALSE; UINT16 cfg_rej_len, cmd_len; UINT16 result; tL2C_CONN_INFO ci; #if (defined BLE_INCLUDED && BLE_INCLUDED == TRUE) /* if l2cap command received in CID 1 on top of an LE link, ignore this command */ - if (p_lcb->is_ble_link) + if (p_lcb->transport == BT_TRANSPORT_LE) return; #endif + + /* Reject the packet if it exceeds the default Signalling Channel MTU */ + if (pkt_len > L2CAP_DEFAULT_MTU) + { + /* Core Spec requires a single response to the first command found in a multi-command + ** L2cap packet. If only responses in the packet, then it will be ignored. + ** Here we simply mark the bad packet and decide which cmd ID to reject later + */ + pkt_size_rej = TRUE; + L2CAP_TRACE_ERROR1 ("L2CAP SIG MTU Pkt Len Exceeded (672) -> pkt_len: %d", pkt_len); + } + p_next_cmd = p; p_pkt_end = p + pkt_len; @@ -355,6 +367,18 @@ static void process_l2cap_cmd (tL2C_LCB *p_lcb, UINT8 *p, UINT16 pkt_len) break; } + L2CAP_TRACE_DEBUG3 ("cmd_code: %d, id:%d, cmd_len:%d", cmd_code, id, cmd_len); + + /* Bad L2CAP packet length, look or cmd to reject */ + if (pkt_size_rej) + { + /* If command found rejected it and we're done, otherwise keep looking */ + if (l2c_is_cmd_rejected(cmd_code, id, p_lcb)) + return; + else + continue; /* Look for next cmd/response in current packet */ + } + switch (cmd_code) { case L2CAP_CMD_REJECT: @@ -911,6 +935,11 @@ void l2c_process_timeout (TIMER_LIST_ENT *p_tle) l2c_info_timeout((tL2C_LCB *)p_tle->param); break; +#if (BLE_INCLUDED == TRUE) + case BTU_TTYPE_L2CAP_END_CONN_UPD: + l2c_enable_conn_param_timeout((tL2C_LCB *)p_tle->param); + break; +#endif } } diff --git a/stack/l2cap/l2c_ucd.c b/stack/l2cap/l2c_ucd.c index 4dfc8042d..4f907ad2b 100644 --- a/stack/l2cap/l2c_ucd.c +++ b/stack/l2cap/l2c_ucd.c @@ -343,7 +343,7 @@ BOOLEAN L2CA_UcdDiscover ( UINT16 psm, BD_ADDR rem_bda, UINT8 info_type ) /* First, see if we already have a link to the remote */ /* then find the channel control block for UCD. */ - if (((p_lcb = l2cu_find_lcb_by_bd_addr (rem_bda)) == NULL) + if (((p_lcb = l2cu_find_lcb_by_bd_addr (rem_bda, BT_TRANSPORT_BR_EDR)) == NULL) ||((p_ccb = l2cu_find_ccb_by_cid (p_lcb, L2CAP_CONNECTIONLESS_CID)) == NULL)) { if ( l2c_ucd_connect (rem_bda) == FALSE ) @@ -411,7 +411,7 @@ UINT16 L2CA_UcdDataWrite (UINT16 psm, BD_ADDR rem_bda, BT_HDR *p_buf, UINT16 fla /* First, see if we already have a link to the remote */ /* then find the channel control block for UCD */ - if (((p_lcb = l2cu_find_lcb_by_bd_addr (rem_bda)) == NULL) + if (((p_lcb = l2cu_find_lcb_by_bd_addr (rem_bda, BT_TRANSPORT_BR_EDR)) == NULL) ||((p_ccb = l2cu_find_ccb_by_cid (p_lcb, L2CAP_CONNECTIONLESS_CID)) == NULL)) { if ( l2c_ucd_connect (rem_bda) == FALSE ) @@ -421,7 +421,7 @@ UINT16 L2CA_UcdDataWrite (UINT16 psm, BD_ADDR rem_bda, BT_HDR *p_buf, UINT16 fla } /* If we still don't have lcb and ccb after connect attempt, then can't proceed */ - if (((p_lcb = l2cu_find_lcb_by_bd_addr (rem_bda)) == NULL) + if (((p_lcb = l2cu_find_lcb_by_bd_addr (rem_bda, BT_TRANSPORT_BR_EDR)) == NULL) || ((p_ccb = l2cu_find_ccb_by_cid (p_lcb, L2CAP_CONNECTIONLESS_CID)) == NULL)) { GKI_freebuf (p_buf); @@ -490,7 +490,7 @@ BOOLEAN L2CA_UcdSetIdleTimeout ( BD_ADDR rem_bda, UINT16 timeout ) /* First, see if we already have a link to the remote */ /* then find the channel control block. */ - if (((p_lcb = l2cu_find_lcb_by_bd_addr (rem_bda)) == NULL) + if (((p_lcb = l2cu_find_lcb_by_bd_addr (rem_bda, BT_TRANSPORT_BR_EDR)) == NULL) ||((p_ccb = l2cu_find_ccb_by_cid (p_lcb, L2CAP_CONNECTIONLESS_CID)) == NULL)) { L2CAP_TRACE_WARNING0 ("L2CAP - no UCD channel"); @@ -521,7 +521,7 @@ BOOLEAN L2CA_UCDSetTxPriority ( BD_ADDR rem_bda, tL2CAP_CHNL_PRIORITY priority ) (rem_bda[0]<<24)+(rem_bda[1]<<16)+(rem_bda[2]<<8)+rem_bda[3], (rem_bda[4]<<8)+rem_bda[5]); - if ((p_lcb = l2cu_find_lcb_by_bd_addr (rem_bda)) == NULL) + if ((p_lcb = l2cu_find_lcb_by_bd_addr (rem_bda, BT_TRANSPORT_BR_EDR)) == NULL) { L2CAP_TRACE_WARNING0 ("L2CAP - no LCB for L2CA_UCDSetTxPriority"); return (FALSE); @@ -569,11 +569,11 @@ static BOOLEAN l2c_ucd_connect ( BD_ADDR rem_bda ) } /* First, see if we already have a link to the remote */ - if ((p_lcb = l2cu_find_lcb_by_bd_addr (rem_bda)) == NULL) + if ((p_lcb = l2cu_find_lcb_by_bd_addr (rem_bda, BT_TRANSPORT_BR_EDR)) == NULL) { /* No link. Get an LCB and start link establishment */ - if ( ((p_lcb = l2cu_allocate_lcb (rem_bda, FALSE)) == NULL) - || (l2cu_create_conn(p_lcb) == FALSE) ) + if ( ((p_lcb = l2cu_allocate_lcb (rem_bda, FALSE, BT_TRANSPORT_BR_EDR)) == NULL) + || (l2cu_create_conn(p_lcb, BT_TRANSPORT_BR_EDR) == FALSE) ) { L2CAP_TRACE_WARNING0 ("L2CAP - conn not started l2c_ucd_connect"); return (FALSE); diff --git a/stack/l2cap/l2c_utils.c b/stack/l2cap/l2c_utils.c index 05d5e5d63..23b75845d 100644 --- a/stack/l2cap/l2c_utils.c +++ b/stack/l2cap/l2c_utils.c @@ -37,6 +37,7 @@ #include "btm_int.h" #include "hcidefs.h" #include "bd.h" +#include "bt_utils.h" /******************************************************************************* ** @@ -47,7 +48,7 @@ ** Returns LCB address or NULL if none found ** *******************************************************************************/ -tL2C_LCB *l2cu_allocate_lcb (BD_ADDR p_bd_addr, BOOLEAN is_bonding) +tL2C_LCB *l2cu_allocate_lcb (BD_ADDR p_bd_addr, BOOLEAN is_bonding, tBT_TRANSPORT transport) { int xx; tL2C_LCB *p_lcb = &l2cb.lcb_pool[0]; @@ -69,7 +70,9 @@ tL2C_LCB *l2cu_allocate_lcb (BD_ADDR p_bd_addr, BOOLEAN is_bonding) p_lcb->idle_timeout = l2cb.idle_timeout; p_lcb->id = 1; /* spec does not allow '0' */ p_lcb->is_bonding = is_bonding; - +#if BLE_INCLUDED == TRUE + p_lcb->transport = transport; +#endif l2cb.num_links_active++; l2c_link_adjust_allocation(); @@ -93,7 +96,7 @@ tL2C_LCB *l2cu_allocate_lcb (BD_ADDR p_bd_addr, BOOLEAN is_bonding) *******************************************************************************/ void l2cu_update_lcb_4_bonding (BD_ADDR p_bd_addr, BOOLEAN is_bonding) { - tL2C_LCB *p_lcb = l2cu_find_lcb_by_bd_addr (p_bd_addr); + tL2C_LCB *p_lcb = l2cu_find_lcb_by_bd_addr (p_bd_addr, BT_TRANSPORT_BR_EDR); if (p_lcb) { @@ -133,14 +136,17 @@ void l2cu_release_lcb (tL2C_LCB *p_lcb) } #if BTM_SCO_INCLUDED == TRUE - /* Release all SCO links */ - btm_remove_sco_links(p_lcb->remote_bd_addr); +#if (BLE_INCLUDED == TRUE) + if (p_lcb->transport == BT_TRANSPORT_BR_EDR) +#endif + /* Release all SCO links */ + btm_remove_sco_links(p_lcb->remote_bd_addr); #endif if (p_lcb->sent_not_acked > 0) { #if (BLE_INCLUDED == TRUE) - if (p_lcb->is_ble_link) + if (p_lcb->transport == BT_TRANSPORT_LE) { l2cb.controller_le_xmit_window += p_lcb->sent_not_acked; if (l2cb.controller_le_xmit_window > l2cb.num_lm_ble_bufs) @@ -160,7 +166,6 @@ void l2cu_release_lcb (tL2C_LCB *p_lcb) } #if (BLE_INCLUDED == TRUE) - p_lcb->is_ble_link = FALSE; l2cb.is_ble_connecting = FALSE; #endif @@ -174,11 +179,11 @@ void l2cu_release_lcb (tL2C_LCB *p_lcb) { l2cu_release_ccb (p_lcb->p_fixed_ccbs[xx]); p_lcb->p_fixed_ccbs[xx] = NULL; - (*l2cb.fixed_reg[xx].pL2CA_FixedConn_Cb)(p_lcb->remote_bd_addr, FALSE, p_lcb->disc_reason); + (*l2cb.fixed_reg[xx].pL2CA_FixedConn_Cb)(p_lcb->remote_bd_addr, FALSE, p_lcb->disc_reason, p_lcb->transport); } else if ( (p_lcb->peer_chnl_mask[0] & (1 << (xx + L2CAP_FIRST_FIXED_CHNL))) && (l2cb.fixed_reg[xx].pL2CA_FixedConn_Cb != NULL) ) - (*l2cb.fixed_reg[xx].pL2CA_FixedConn_Cb)(p_lcb->remote_bd_addr, FALSE, p_lcb->disc_reason); + (*l2cb.fixed_reg[xx].pL2CA_FixedConn_Cb)(p_lcb->remote_bd_addr, FALSE, p_lcb->disc_reason, p_lcb->transport); } } #endif @@ -191,8 +196,11 @@ void l2cu_release_lcb (tL2C_LCB *p_lcb) /* Tell BTM Acl management the link was removed */ if ((p_lcb->link_state == LST_CONNECTED) || (p_lcb->link_state == LST_DISCONNECTING)) - btm_acl_removed (p_lcb->remote_bd_addr); - +#if (BLE_INCLUDED == TRUE) + btm_acl_removed (p_lcb->remote_bd_addr, p_lcb->transport); +#else + btm_acl_removed (p_lcb->remote_bd_addr, BT_TRANSPORT_BR_EDR); +#endif /* Release any held buffers */ while (p_lcb->link_xmit_data_q.p_first) GKI_freebuf (GKI_dequeue (&p_lcb->link_xmit_data_q)); @@ -231,14 +239,18 @@ void l2cu_release_lcb (tL2C_LCB *p_lcb) ** Returns pointer to matched LCB, or NULL if no match ** *******************************************************************************/ -tL2C_LCB *l2cu_find_lcb_by_bd_addr (BD_ADDR p_bd_addr) +tL2C_LCB *l2cu_find_lcb_by_bd_addr (BD_ADDR p_bd_addr, tBT_TRANSPORT transport) { int xx; tL2C_LCB *p_lcb = &l2cb.lcb_pool[0]; for (xx = 0; xx < MAX_L2CAP_LINKS; xx++, p_lcb++) { - if ((p_lcb->in_use) && (!memcmp (p_lcb->remote_bd_addr, p_bd_addr, BD_ADDR_LEN))) + if ((p_lcb->in_use) && +#if BLE_INCLUDED == TRUE + p_lcb->transport == transport && +#endif + (!memcmp (p_lcb->remote_bd_addr, p_bd_addr, BD_ADDR_LEN))) { return (p_lcb); } @@ -253,8 +265,6 @@ tL2C_LCB *l2cu_find_lcb_by_bd_addr (BD_ADDR p_bd_addr) ** Function l2cu_get_conn_role ** ** Description Determine the desired role (master or slave) of a link. -** If it is the previous connected remote device, use the same -** role as previous used role. ** If already got a slave link, this one must be a master. If ** already got at least 1 link where we are the master, make this ** also a master. @@ -262,12 +272,12 @@ tL2C_LCB *l2cu_find_lcb_by_bd_addr (BD_ADDR p_bd_addr) ** Returns HCI_ROLE_MASTER or HCI_ROLE_SLAVE ** *******************************************************************************/ -UINT8 l2cu_get_conn_role (BD_ADDR bd_addr) +UINT8 l2cu_get_conn_role (tL2C_LCB *p_this_lcb) { UINT8 i; for (i = 0; i < BTM_ROLE_DEVICE_NUM; i++) { if ((btm_cb.previous_connected_role[i] != BTM_ROLE_UNDEFINED) && - (!bdcmp(bd_addr, btm_cb.previous_connected_remote_addr[i]))) { + (!bdcmp(p_this_lcb->remote_bd_addr, btm_cb.previous_connected_remote_addr[i]))) { L2CAP_TRACE_WARNING1 ("l2cu_get_conn_role %d", btm_cb.previous_connected_role[i]); return btm_cb.previous_connected_role[i]; @@ -278,6 +288,39 @@ UINT8 l2cu_get_conn_role (BD_ADDR bd_addr) /******************************************************************************* ** +** Function l2c_is_cmd_rejected +** +** Description Checks if cmd_code is command or response +** If a command it will be rejected per spec. +** This function is used when a illegal packet length is detected +** +** Returns BOOLEAN - TRUE if cmd_code is a command and it is rejected, +** FALSE if response code. (command not rejected) +** +*******************************************************************************/ +BOOLEAN l2c_is_cmd_rejected (UINT8 cmd_code, UINT8 id, tL2C_LCB *p_lcb) +{ + switch(cmd_code) + { + case L2CAP_CMD_CONN_REQ: + case L2CAP_CMD_CONFIG_REQ: + case L2CAP_CMD_DISC_REQ: + case L2CAP_CMD_ECHO_REQ: + case L2CAP_CMD_INFO_REQ: + case L2CAP_CMD_AMP_CONN_REQ: + case L2CAP_CMD_AMP_MOVE_REQ: + case L2CAP_CMD_BLE_UPDATE_REQ: + l2cu_send_peer_cmd_reject (p_lcb, L2CAP_CMD_REJ_MTU_EXCEEDED, id, L2CAP_DEFAULT_MTU, 0); + L2CAP_TRACE_WARNING1 ("Dumping first Command (%d)", cmd_code); + return TRUE; + + default: /* Otherwise a response */ + return FALSE; + } +} + +/******************************************************************************* +** ** Function l2cu_build_header ** ** Description Builds the L2CAP command packet header @@ -311,7 +354,7 @@ BT_HDR *l2cu_build_header (tL2C_LCB *p_lcb, UINT16 len, UINT8 cmd, UINT8 id) UINT16_TO_STREAM (p, len + L2CAP_CMD_OVERHEAD); #if (BLE_INCLUDED == TRUE) - if (p_lcb->is_ble_link) + if (p_lcb->transport == BT_TRANSPORT_LE) { UINT16_TO_STREAM (p, L2CAP_BLE_SIGNALLING_CID); } @@ -717,11 +760,24 @@ void l2cu_send_peer_config_rsp (tL2C_CCB *p_ccb, tL2CAP_CFG_INFO *p_cfg) *******************************************************************************/ void l2cu_send_peer_config_rej (tL2C_CCB *p_ccb, UINT8 *p_data, UINT16 data_len, UINT16 rej_len) { - BT_HDR *p_buf = (BT_HDR *)GKI_getpoolbuf (L2CAP_CMD_POOL_ID); - UINT16 len, cfg_len; + BT_HDR *p_buf; + UINT16 len, cfg_len, buf_space, len1; UINT8 *p, *p_hci_len, *p_data_end; UINT8 cfg_code; + L2CAP_TRACE_DEBUG2("l2cu_send_peer_config_rej: data_len=%d, rej_len=%d", data_len, rej_len); + + + len = BT_HDR_SIZE + HCI_DATA_PREAMBLE_SIZE + L2CAP_PKT_OVERHEAD + L2CAP_CMD_OVERHEAD + L2CAP_CONFIG_RSP_LEN; + len1 = 0xFFFF - len; + if (rej_len > len1) + { + L2CAP_TRACE_ERROR0 ("L2CAP - cfg_rej pkt size exceeds buffer design max limit."); + return; + } + + p_buf = (BT_HDR *)GKI_getbuf (len + rej_len); + if (!p_buf) { L2CAP_TRACE_ERROR0 ("L2CAP - no buffer for cfg_rej"); @@ -761,6 +817,8 @@ void l2cu_send_peer_config_rej (tL2C_CCB *p_ccb, UINT8 *p_data, UINT16 data_len, UINT16_TO_STREAM (p, 0); /* Flags = 0 (no continuation) */ UINT16_TO_STREAM (p, L2CAP_CFG_UNKNOWN_OPTIONS); + buf_space = rej_len; + /* Now, put the rejected options */ p_data_end = p_data + data_len; while (p_data < p_data_end) @@ -784,8 +842,18 @@ void l2cu_send_peer_config_rej (tL2C_CCB *p_ccb, UINT8 *p_data, UINT16 data_len, { if ((cfg_code & 0x80) == 0) { - memcpy(p, p_data, cfg_len + L2CAP_CFG_OPTION_OVERHEAD); - p += cfg_len + L2CAP_CFG_OPTION_OVERHEAD; + if (buf_space >= (cfg_len + L2CAP_CFG_OPTION_OVERHEAD)) + { + memcpy(p, p_data, cfg_len + L2CAP_CFG_OPTION_OVERHEAD); + p += cfg_len + L2CAP_CFG_OPTION_OVERHEAD; + buf_space -= (cfg_len + L2CAP_CFG_OPTION_OVERHEAD); + } + else + { + L2CAP_TRACE_WARNING0("L2CAP - cfg_rej exceeds allocated buffer"); + p_data = p_data_end; /* force loop exit */ + break; + } } p_data += cfg_len + L2CAP_CFG_OPTION_OVERHEAD; } @@ -803,6 +871,9 @@ void l2cu_send_peer_config_rej (tL2C_CCB *p_ccb, UINT8 *p_data, UINT16 data_len, p_buf->len = len + 4; + L2CAP_TRACE_DEBUG2 ("L2CAP - cfg_rej pkt hci_len=%d, l2cap_len=%d", + len, (L2CAP_CMD_OVERHEAD+L2CAP_CONFIG_RSP_LEN+rej_len)); + l2c_link_check_send_pkts (p_ccb->p_lcb, NULL, p_buf); } @@ -941,6 +1012,21 @@ void l2cu_send_peer_echo_rsp (tL2C_LCB *p_lcb, UINT8 id, UINT8 *p_data, UINT16 d BT_HDR *p_buf; UINT8 *p; UINT16 maxlen; + /* Filter out duplicate IDs or if available buffers are low (intruder checking) */ + if (!id || id == p_lcb->cur_echo_id) + { + /* Dump this request since it is illegal */ + L2CAP_TRACE_WARNING1 ("L2CAP ignoring duplicate echo request (%d)", id); + return; + } + else + p_lcb->cur_echo_id = id; + /* Don't respond if we more than 10% of our buffers are used */ + if (GKI_poolutilization (L2CAP_CMD_POOL_ID) > 10) + { + L2CAP_TRACE_WARNING0 ("L2CAP gki pool used up to more than 10%%, ignore echo response"); + return; + } /* Don't return data if it does not fit in ACL and L2CAP MTU */ maxlen = (GKI_get_pool_bufsize(L2CAP_CMD_POOL_ID) > btu_cb.hcit_acl_pkt_size) ? @@ -1069,7 +1155,7 @@ void l2cu_send_peer_info_rsp (tL2C_LCB *p_lcb, UINT8 remote_id, UINT16 info_type { UINT16_TO_STREAM (p, L2CAP_INFO_RESP_RESULT_SUCCESS); #if (BLE_INCLUDED == TRUE) - if (p_lcb->is_ble_link) + if (p_lcb->transport == BT_TRANSPORT_LE) { /* optional data are not added for now */ UINT32_TO_STREAM (p, L2CAP_BLE_EXTFEA_MASK); @@ -2104,7 +2190,7 @@ extern UINT16 tcs_wug_get_clk_offset( BD_ADDR addr ) ; ** Returns TRUE if successful, FALSE if gki get buffer fails. ** *******************************************************************************/ -BOOLEAN l2cu_create_conn (tL2C_LCB *p_lcb) +BOOLEAN l2cu_create_conn (tL2C_LCB *p_lcb, tBT_TRANSPORT transport) { int xx; tL2C_LCB *p_lcb_cur = &l2cb.lcb_pool[0]; @@ -2116,15 +2202,16 @@ BOOLEAN l2cu_create_conn (tL2C_LCB *p_lcb) tBT_DEVICE_TYPE dev_type; tBLE_ADDR_TYPE addr_type; + BTM_ReadDevInfo(p_lcb->remote_bd_addr, &dev_type, &addr_type); - if (dev_type == BT_DEVICE_TYPE_BLE) + if (transport == BT_TRANSPORT_LE) { if (!HCI_LE_HOST_SUPPORTED(btm_cb.devcb.local_lmp_features[HCI_EXT_FEATURES_PAGE_1])) return FALSE; p_lcb->ble_addr_type = addr_type; - p_lcb->is_ble_link = TRUE; + p_lcb->transport = BT_TRANSPORT_LE; return (l2cble_create_conn(p_lcb)); } @@ -2154,7 +2241,7 @@ BOOLEAN l2cu_create_conn (tL2C_LCB *p_lcb) if (is_sco_active == TRUE) continue; /* No Master Slave switch not allowed when SCO Active */ #endif - + /*4_1_TODO check if btm_cb.devcb.local_features to be used instead */ if (HCI_SWITCH_SUPPORTED(BTM_ReadLocalFeatures())) { /* mark this lcb waiting for switch to be completed and @@ -2394,7 +2481,7 @@ BOOLEAN l2cu_set_acl_priority (BD_ADDR bd_addr, UINT8 priority, BOOLEAN reset_af APPL_TRACE_EVENT1("SET ACL PRIORITY %d", priority); /* Find the link control block for the acl channel */ - if ((p_lcb = l2cu_find_lcb_by_bd_addr(bd_addr)) == NULL) + if ((p_lcb = l2cu_find_lcb_by_bd_addr(bd_addr, BT_TRANSPORT_BR_EDR)) == NULL) { L2CAP_TRACE_WARNING0 ("L2CAP - no LCB for L2CA_SetAclPriority"); return (FALSE); @@ -2468,7 +2555,7 @@ void l2cu_resubmit_pending_sec_req (BD_ADDR p_bda) /* If we are called with a BDA, only resubmit for that BDA */ if (p_bda) { - p_lcb = l2cu_find_lcb_by_bd_addr (p_bda); + p_lcb = l2cu_find_lcb_by_bd_addr (p_bda, BT_TRANSPORT_BR_EDR); /* If we don't have one, this is an error */ if (p_lcb) @@ -2663,11 +2750,13 @@ void l2cu_no_dynamic_ccbs (tL2C_LCB *p_lcb) rc = btm_sec_disconnect (p_lcb->handle, HCI_ERR_PEER_USER); if (rc == BTM_CMD_STARTED) { + l2cu_process_fixed_disc_cback(p_lcb); p_lcb->link_state = LST_DISCONNECTING; timeout = L2CAP_LINK_DISCONNECT_TOUT; } else if (rc == BTM_SUCCESS) { + l2cu_process_fixed_disc_cback(p_lcb); /* BTM SEC will make sure that link is release (probably after pairing is done) */ p_lcb->link_state = LST_DISCONNECTING; timeout = 0xFFFF; @@ -2675,6 +2764,7 @@ void l2cu_no_dynamic_ccbs (tL2C_LCB *p_lcb) else if ( (p_lcb->is_bonding) && (btsnd_hcic_disconnect (p_lcb->handle, HCI_ERR_PEER_USER)) ) { + l2cu_process_fixed_disc_cback(p_lcb); p_lcb->link_state = LST_DISCONNECTING; timeout = L2CAP_LINK_DISCONNECT_TOUT; } @@ -2709,27 +2799,43 @@ void l2cu_no_dynamic_ccbs (tL2C_LCB *p_lcb) void l2cu_process_fixed_chnl_resp (tL2C_LCB *p_lcb) { int xx; -#if BLE_INCLUDED == TRUE - UINT16 reason = (p_lcb->is_ble_link ) ? 1 : 0; -#else - UINT16 reason =0; +#if (BLE_INCLUDED == TRUE) + /* always exclude LE fixed channel on BR/EDR fix channel capability */ + if (p_lcb->transport == BT_TRANSPORT_BR_EDR) + p_lcb->peer_chnl_mask[0] &= ~(L2CAP_FIXED_CHNL_ATT_BIT| \ + L2CAP_FIXED_CHNL_BLE_SIG_BIT| \ + L2CAP_FIXED_CHNL_SMP_BIT); #endif /* Tell all registered fixed channels about the connection */ for (xx = 0; xx < L2CAP_NUM_FIXED_CHNLS; xx++) { +#if BLE_INCLUDED == TRUE + /* skip sending LE fix channel callbacks on BR/EDR links */ + if (p_lcb->transport == BT_TRANSPORT_BR_EDR && + xx + L2CAP_FIRST_FIXED_CHNL >= L2CAP_ATT_CID && + xx + L2CAP_FIRST_FIXED_CHNL <= L2CAP_SMP_CID) + continue; +#endif if (l2cb.fixed_reg[xx].pL2CA_FixedConn_Cb != NULL) { if (p_lcb->peer_chnl_mask[0] & (1 << (xx + L2CAP_FIRST_FIXED_CHNL))) { if (p_lcb->p_fixed_ccbs[xx]) p_lcb->p_fixed_ccbs[xx]->chnl_state = CST_OPEN; - - (*l2cb.fixed_reg[xx].pL2CA_FixedConn_Cb)(p_lcb->remote_bd_addr, TRUE, reason); +#if BLE_INCLUDED == TRUE + (*l2cb.fixed_reg[xx].pL2CA_FixedConn_Cb)(p_lcb->remote_bd_addr, TRUE, 0, p_lcb->transport); +#else + (*l2cb.fixed_reg[xx].pL2CA_FixedConn_Cb)(p_lcb->remote_bd_addr, TRUE, 0, BT_TRANSPORT_BR_EDR); +#endif } else { - (*l2cb.fixed_reg[xx].pL2CA_FixedConn_Cb)(p_lcb->remote_bd_addr, FALSE, p_lcb->disc_reason); +#if BLE_INCLUDED == TRUE + (*l2cb.fixed_reg[xx].pL2CA_FixedConn_Cb)(p_lcb->remote_bd_addr, FALSE, p_lcb->disc_reason, p_lcb->transport); +#else + (*l2cb.fixed_reg[xx].pL2CA_FixedConn_Cb)(p_lcb->remote_bd_addr, FALSE, p_lcb->disc_reason, BT_TRANSPORT_BR_EDR); +#endif if (p_lcb->p_fixed_ccbs[xx]) { @@ -2742,6 +2848,45 @@ void l2cu_process_fixed_chnl_resp (tL2C_LCB *p_lcb) } #endif + +/******************************************************************************* +** +** Function l2cu_process_fixed_disc_cback +** +** Description send l2cap fixed channel disconnection callback to application +** +** +** Returns void +** +*******************************************************************************/ +void l2cu_process_fixed_disc_cback (tL2C_LCB *p_lcb) +{ +#if (L2CAP_NUM_FIXED_CHNLS > 0) + int xx; + + for (xx = 0; xx < L2CAP_NUM_FIXED_CHNLS; xx++) + { + if (p_lcb->p_fixed_ccbs[xx]) + { + l2cu_release_ccb (p_lcb->p_fixed_ccbs[xx]); + p_lcb->p_fixed_ccbs[xx] = NULL; +#if BLE_INCLUDED == TRUE + (*l2cb.fixed_reg[xx].pL2CA_FixedConn_Cb)(p_lcb->remote_bd_addr, FALSE, p_lcb->disc_reason, p_lcb->transport); +#else + (*l2cb.fixed_reg[xx].pL2CA_FixedConn_Cb)(p_lcb->remote_bd_addr, FALSE, p_lcb->disc_reason, BT_TRANSPORT_BR_EDR); +#endif + } + else if ( (p_lcb->peer_chnl_mask[0] & (1 << (xx + L2CAP_FIRST_FIXED_CHNL))) + && (l2cb.fixed_reg[xx].pL2CA_FixedConn_Cb != NULL) ) +#if BLE_INCLUDED == TRUE + (*l2cb.fixed_reg[xx].pL2CA_FixedConn_Cb)(p_lcb->remote_bd_addr, FALSE, p_lcb->disc_reason, p_lcb->transport); +#else + (*l2cb.fixed_reg[xx].pL2CA_FixedConn_Cb)(p_lcb->remote_bd_addr, FALSE, p_lcb->disc_reason, BT_TRANSPORT_BR_EDR); +#endif + } +#endif +} + #if (BLE_INCLUDED == TRUE) /******************************************************************************* ** @@ -3193,7 +3338,7 @@ void l2cu_set_acl_hci_header (BT_HDR *p_buf, tL2C_CCB *p_ccb) UINT16_TO_STREAM (p, p_ccb->p_lcb->handle | (L2CAP_PKT_START << L2CAP_PKT_TYPE_SHIFT)); #endif #if (BLE_INCLUDED == TRUE) - if (p_ccb->p_lcb->is_ble_link) + if (p_ccb->p_lcb->transport == BT_TRANSPORT_LE) { /* The HCI transport will segment the buffers. */ if (p_buf->len > btu_cb.hcit_ble_acl_data_size) diff --git a/stack/mcap/mca_l2c.c b/stack/mcap/mca_l2c.c index bc6fe09dd..d792bfcfc 100644 --- a/stack/mcap/mca_l2c.c +++ b/stack/mcap/mca_l2c.c @@ -70,12 +70,14 @@ const tL2CAP_FCR_OPTS mca_l2c_fcr_opts_def = ** Returns void ** *******************************************************************************/ -static void mca_sec_check_complete_term (BD_ADDR bd_addr, void *p_ref_data, UINT8 res) +static void mca_sec_check_complete_term (BD_ADDR bd_addr, tBT_TRANSPORT transport, void *p_ref_data, UINT8 res) { tMCA_TC_TBL *p_tbl = (tMCA_TC_TBL *)p_ref_data; tL2CAP_CFG_INFO cfg; tL2CAP_ERTM_INFO ertm_info; + UNUSED(transport); + MCA_TRACE_DEBUG1("mca_sec_check_complete_term res: %d", res); if ( res == BTM_SUCCESS ) @@ -115,11 +117,12 @@ static void mca_sec_check_complete_term (BD_ADDR bd_addr, void *p_ref_data, UINT ** Returns void ** *******************************************************************************/ -static void mca_sec_check_complete_orig (BD_ADDR bd_addr, void *p_ref_data, UINT8 res) +static void mca_sec_check_complete_orig (BD_ADDR bd_addr, tBT_TRANSPORT transport, void *p_ref_data, UINT8 res) { tMCA_TC_TBL *p_tbl = (tMCA_TC_TBL *)p_ref_data; tL2CAP_CFG_INFO cfg; UNUSED(bd_addr); + UNUSED(transport); MCA_TRACE_DEBUG1("mca_sec_check_complete_orig res: %d", res); diff --git a/stack/rfcomm/rfc_int.h b/stack/rfcomm/rfc_int.h index 83a63e3ab..302a8af6c 100644 --- a/stack/rfcomm/rfc_int.h +++ b/stack/rfcomm/rfc_int.h @@ -315,7 +315,7 @@ tRFC_MCB *rfc_find_lcid_mcb (UINT16 lcid); extern void rfc_save_lcid_mcb (tRFC_MCB *p_rfc_mcb, UINT16 lcid); extern void rfc_check_mcb_active (tRFC_MCB *p_mcb); extern void rfc_port_closed (tPORT *p_port); -extern void rfc_sec_check_complete (BD_ADDR bd_addr, void *p_ref_data, UINT8 res); +extern void rfc_sec_check_complete (BD_ADDR bd_addr, tBT_TRANSPORT transport,void *p_ref_data, UINT8 res); extern void rfc_inc_credit (tPORT *p_port, UINT8 credit); extern void rfc_dec_credit (tPORT *p_port); extern void rfc_check_send_cmd(tRFC_MCB *p_mcb, BT_HDR *p_buf); diff --git a/stack/rfcomm/rfc_utils.c b/stack/rfcomm/rfc_utils.c index d2b02fc39..47b093f4a 100644 --- a/stack/rfcomm/rfc_utils.c +++ b/stack/rfcomm/rfc_utils.c @@ -350,10 +350,11 @@ void rfcomm_process_timeout (TIMER_LIST_ENT *p_tle) ** Returns void ** *******************************************************************************/ -void rfc_sec_check_complete (BD_ADDR bd_addr, void *p_ref_data, UINT8 res) +void rfc_sec_check_complete (BD_ADDR bd_addr, tBT_TRANSPORT transport, void *p_ref_data, UINT8 res) { tPORT *p_port = (tPORT *)p_ref_data; UNUSED(bd_addr); + UNUSED(transport); /* Verify that PORT is still waiting for Security to complete */ if (!p_port->in_use diff --git a/stack/smp/aes.c b/stack/smp/aes.c index 65cddf5bb..d3d8ff610 100644 --- a/stack/smp/aes.c +++ b/stack/smp/aes.c @@ -510,6 +510,7 @@ return_type aes_set_key( const unsigned char key[], length_type keylen, aes_cont keylen = 24; break; case 32: + /* case 256: length in bits (256 = 8*32) */ keylen = 32; break; default: diff --git a/stack/smp/smp_act.c b/stack/smp/smp_act.c index 47cd2c909..7543eb7c6 100644 --- a/stack/smp/smp_act.c +++ b/stack/smp/smp_act.c @@ -26,6 +26,7 @@ #include "l2c_api.h" #include "smp_int.h" +#define MAX_KEY_DISTRIBUTION_TYPES 3 const UINT8 smp_association_table[2][SMP_IO_CAP_MAX][SMP_IO_CAP_MAX] = { @@ -108,6 +109,7 @@ void smp_send_app_cback(tSMP_CB *p_cb, tSMP_INT_DATA *p_data) { p_cb->loc_auth_req = cb_data.io_req.auth_req; p_cb->loc_io_caps = cb_data.io_req.io_cap; + #if (defined(BLE_PERIPHERAL_DISPLAYONLY) && (BLE_PERIPHERAL_DISPLAYONLY == TRUE)) if (p_cb->role == HCI_ROLE_SLAVE) { @@ -165,7 +167,11 @@ void smp_send_pair_req(tSMP_CB *p_cb, tSMP_INT_DATA *p_data) some peripherals are not able to revert to fast connection parameters during the start of service discovery. Connection paramter updates get enabled again once service discovery completes. */ - L2CA_EnableUpdateBleConnParams(p_cb->pairing_bda, FALSE); + if (L2CA_EnableUpdateBleConnParams(p_cb->pairing_bda, FALSE) == FALSE) + { + SMP_TRACE_ERROR0 ("smp pair failed...!"); + return; + } #endif /* erase all keys when master sends pairing req*/ @@ -616,7 +622,7 @@ void smp_proc_sl_key(tSMP_CB *p_cb, tSMP_INT_DATA *p_data) *******************************************************************************/ void smp_start_enc(tSMP_CB *p_cb, tSMP_INT_DATA *p_data) { - BOOLEAN cmd; + tBTM_STATUS cmd; UINT8 reason = SMP_ENC_FAIL; SMP_TRACE_DEBUG0 ("smp_start_enc "); @@ -625,7 +631,7 @@ void smp_start_enc(tSMP_CB *p_cb, tSMP_INT_DATA *p_data) else cmd = btm_ble_start_encrypt(p_cb->pairing_bda, FALSE, NULL); - if (!cmd) + if (cmd != BTM_CMD_STARTED && cmd != BTM_BUSY) smp_sm_event(p_cb, SMP_AUTH_CMPL_EVT, &reason); } @@ -729,7 +735,7 @@ void smp_key_pick_key(tSMP_CB *p_cb, tSMP_INT_DATA *p_data) UINT8 i = 0; SMP_TRACE_DEBUG1 ("smp_key_pick_key key_to_dist=0x%x", key_to_dist); - while (i < 3) + while (i < MAX_KEY_DISTRIBUTION_TYPES) { SMP_TRACE_DEBUG2("key to send = %02x, i = %d", key_to_dist, i); @@ -899,6 +905,7 @@ void smp_pairing_cmpl(tSMP_CB *p_cb, tSMP_INT_DATA *p_data) SMP_TRACE_DEBUG0 ("smp_pairing_cmpl "); + (void)L2CA_EnableUpdateBleConnParams(p_cb->pairing_bda, TRUE); if ((p_cb->status == SMP_SUCCESS) || (p_cb->status <= SMP_REPEATED_ATTEMPTS && p_cb->status != SMP_SUCCESS)) { @@ -960,6 +967,18 @@ void smp_idle_terminate(tSMP_CB *p_cb, tSMP_INT_DATA *p_data) smp_proc_pairing_cmpl(p_cb); } } + +/******************************************************************************* +** Function smp_fast_conn_param +** Description apply default connection parameter for pairing process +*******************************************************************************/ +void smp_fast_conn_param(tSMP_CB *p_cb, tSMP_INT_DATA *p_data) +{ + /* disable connection parameter update */ + (void)L2CA_EnableUpdateBleConnParams(p_cb->pairing_bda, FALSE); +} + + /******************************************************************************* ** ** Function smp_link_encrypted diff --git a/stack/smp/smp_int.h b/stack/smp/smp_int.h index 51cdbb3cd..70c09a5ef 100644 --- a/stack/smp/smp_int.h +++ b/stack/smp/smp_int.h @@ -202,6 +202,8 @@ typedef struct BD_ADDR local_bda; BOOLEAN is_pair_cancel; BOOLEAN discard_sec_req; + UINT8 rcvd_cmd_code; + UINT8 rcvd_cmd_len; #if SMP_CONFORMANCE_TESTING == TRUE BOOLEAN enable_test_confirm_val; BT_OCTET16 test_confirm; @@ -288,6 +290,8 @@ extern void smp_key_distribution(tSMP_CB *p_cb, tSMP_INT_DATA *p_data); extern void smp_proc_srk_info(tSMP_CB *p_cb, tSMP_INT_DATA *p_data); extern void smp_generate_csrk(tSMP_CB *p_cb, tSMP_INT_DATA *p_data); extern void smp_delay_terminate(tSMP_CB *p_cb, tSMP_INT_DATA *p_data); +extern void smp_fast_conn_param(tSMP_CB *p_cb, tSMP_INT_DATA *p_data); + /* smp_l2c */ extern void smp_l2cap_if_init (void); @@ -314,6 +318,7 @@ extern void smp_genenrate_rand_cont(tSMP_CB *p_cb, tSMP_INT_DATA *p_data); /* smp main util */ extern void smp_set_state(tSMP_STATE state); extern tSMP_STATE smp_get_state(void); +extern void smp_reject_unexp_pair_req(BD_ADDR bd_addr); #endif /* SMP_INT_H */ diff --git a/stack/smp/smp_l2c.c b/stack/smp/smp_l2c.c index 54b78b451..02ec38eb6 100644 --- a/stack/smp/smp_l2c.c +++ b/stack/smp/smp_l2c.c @@ -34,7 +34,7 @@ -static void smp_connect_cback (BD_ADDR bd_addr, BOOLEAN connected, UINT16 reason); +static void smp_connect_cback (BD_ADDR bd_addr, BOOLEAN connected, UINT16 reason, tBT_TRANSPORT transport); static void smp_data_ind (BD_ADDR bd_addr, BT_HDR *p_buf); /******************************************************************************* @@ -73,13 +73,20 @@ void smp_l2cap_if_init (void) ** connected (conn = TRUE)/disconnected (conn = FALSE). ** *******************************************************************************/ -static void smp_connect_cback (BD_ADDR bd_addr, BOOLEAN connected, UINT16 reason) +static void smp_connect_cback (BD_ADDR bd_addr, BOOLEAN connected, UINT16 reason, + tBT_TRANSPORT transport) { tSMP_CB *p_cb = &smp_cb; tSMP_INT_DATA int_data; SMP_TRACE_EVENT0 ("SMDBG l2c smp_connect_cback "); + if (transport == BT_TRANSPORT_BR_EDR) + { + SMP_TRACE_ERROR0 ("smp_connect_cback : Wrong transport"); + return; + } + if (memcmp(bd_addr, p_cb->pairing_bda, BD_ADDR_LEN) == 0) { SMP_TRACE_EVENT3 ("smp_connect_cback() for pairing BDA: %08x%04x Event: %s", @@ -132,6 +139,13 @@ static void smp_data_ind (BD_ADDR bd_addr, BT_HDR *p_buf) STREAM_TO_UINT8(cmd, p); + /* sanity check */ + if ((SMP_OPCODE_MAX <= cmd) || (cmd == 0)) + { + SMP_TRACE_WARNING1( "Ignore received command with RESERVED code 0x%02x", cmd); + GKI_freebuf (p_buf); + return; + } /* reject the pairing request if there is an on-going SMP pairing */ if (SMP_OPCODE_PAIRING_REQ == cmd || SMP_OPCODE_SEC_REQ == cmd) @@ -143,14 +157,21 @@ static void smp_data_ind (BD_ADDR bd_addr, BT_HDR *p_buf) } else if (memcmp(&bd_addr[0], p_cb->pairing_bda, BD_ADDR_LEN)) { - p_cb->failure = SMP_PAIR_NOT_SUPPORT; - smp_send_cmd(SMP_OPCODE_PAIRING_FAILED, p_cb); + GKI_freebuf (p_buf); + smp_reject_unexp_pair_req(bd_addr); + return; } + /* else, out of state pairing request/security request received, passed into SM */ } if (memcmp(&bd_addr[0], p_cb->pairing_bda, BD_ADDR_LEN) == 0) { - btu_stop_timer (&p_cb->rsp_timer_ent); + if (p_cb->state != SMP_ST_RELEASE_DELAY) + { + btu_stop_timer (&p_cb->rsp_timer_ent); + } + p_cb->rcvd_cmd_code = cmd; + p_cb->rcvd_cmd_len = (UINT8) p_buf->len; smp_sm_event(p_cb, cmd, p); } diff --git a/stack/smp/smp_main.c b/stack/smp/smp_main.c index f8e450c30..dd40a7126 100644 --- a/stack/smp/smp_main.c +++ b/stack/smp/smp_main.c @@ -114,6 +114,8 @@ enum SMP_PROC_REL_DELAY, SMP_PROC_REL_DELAY_TOUT, SMP_DELAY_TERMINATE, + SMP_IDLE_TERMINATE, + SMP_FAST_CONN_PARAM, SMP_SM_NO_ACTION }; @@ -156,6 +158,8 @@ static const tSMP_ACT smp_sm_action[] = smp_proc_release_delay, smp_proc_release_delay_tout, smp_delay_terminate, + smp_idle_terminate, + smp_fast_conn_param }; /************ SMP Master FSM State/Event Indirection Table **************/ static const UINT8 smp_ma_entry_map[][SMP_ST_MAX] = @@ -176,7 +180,7 @@ static const UINT8 smp_ma_entry_map[][SMP_ST_MAX] = /* KEY_READY */{ 0, 3, 0, 3, 1, 0, 2, 1, 6, 0 }, /* ENC_CMPL */{ 0, 0, 0, 0, 0, 0, 0, 2, 0, 0 }, /* L2C_CONN */{ 1, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, -/* L2C_DISC */{ 0x83, 0x83, 0, 0x83, 0x83,0x83, 0x83,0x83, 0x83, 3 }, +/* L2C_DISC */{ 3, 0x83, 0, 0x83, 0x83,0x83, 0x83,0x83, 0x83, 3 }, /* IO_RSP */{ 0, 2, 0, 0, 0, 0, 0, 0, 0, 0 }, /* SEC_GRANT */{ 0, 1, 0, 0, 0, 0, 0, 0, 0, 0 }, /* TK_REQ */{ 0, 0, 0, 2, 0, 0, 0, 0, 0, 0 }, @@ -198,15 +202,16 @@ static const UINT8 smp_all_table[][SMP_SM_NUM_COLS] = { static const UINT8 smp_ma_idle_table[][SMP_SM_NUM_COLS] = { /* Event Action Next State */ /* L2C_CONN */ {SMP_SEND_APP_CBACK, SMP_SM_NO_ACTION, SMP_ST_WAIT_APP_RSP}, -/* SEC_REQ */ {SMP_PROC_SEC_REQ, SMP_SEND_APP_CBACK, SMP_ST_WAIT_APP_RSP} +/* SEC_REQ */ {SMP_PROC_SEC_REQ, SMP_SEND_APP_CBACK, SMP_ST_WAIT_APP_RSP}, +/* L2C_DISC */ {SMP_IDLE_TERMINATE, SMP_SM_NO_ACTION, SMP_ST_IDLE} }; static const UINT8 smp_ma_wait_app_rsp_table[][SMP_SM_NUM_COLS] = { /* Event Action Next State */ /* SEC_GRANT */ { SMP_PROC_SEC_GRANT, SMP_SEND_APP_CBACK, SMP_ST_WAIT_APP_RSP}, -/* IO_RSP */ { SMP_SEND_PAIR_REQ, SMP_SM_NO_ACTION, SMP_ST_PAIR_REQ_RSP}, +/* IO_RSP */ { SMP_SEND_PAIR_REQ, SMP_FAST_CONN_PARAM, SMP_ST_PAIR_REQ_RSP}, /* KEY_READY */ { SMP_GENERATE_CONFIRM, SMP_SM_NO_ACTION, SMP_ST_WAIT_CONFIRM},/* TK ready */ -/* ENC_REQ */ { SMP_START_ENC, SMP_SM_NO_ACTION, SMP_ST_ENC_PENDING},/* start enc mode setup */ +/* ENC_REQ */ { SMP_START_ENC, SMP_FAST_CONN_PARAM, SMP_ST_ENC_PENDING},/* start enc mode setup */ /* DISCARD_SEC_REQ */ { SMP_PROC_DISCARD, SMP_SM_NO_ACTION, SMP_ST_IDLE} }; diff --git a/stack/smp/smp_utils.c b/stack/smp/smp_utils.c index dac0cc02e..38b2be860 100644 --- a/stack/smp/smp_utils.c +++ b/stack/smp/smp_utils.c @@ -621,6 +621,35 @@ void smp_proc_pairing_cmpl(tSMP_CB *p_cb) smp_reset_control_value(p_cb); } +/******************************************************************************* +** +** Function smp_reject_unexp_pair_req +** +** Description send pairing failure to an unexpected pairing request during +** an active pairing process. +** +** Returns void +** +*******************************************************************************/ +void smp_reject_unexp_pair_req(BD_ADDR bd_addr) +{ + BT_HDR *p_buf; + UINT8 *p; + + if ((p_buf = (BT_HDR *)GKI_getbuf(sizeof(BT_HDR) + SMP_PAIR_FAIL_SIZE + L2CAP_MIN_OFFSET)) != NULL) + { + p = (UINT8 *)(p_buf + 1) + L2CAP_MIN_OFFSET; + + UINT8_TO_STREAM (p, SMP_OPCODE_PAIRING_FAILED); + UINT8_TO_STREAM (p, SMP_PAIR_NOT_SUPPORT); + + p_buf->offset = L2CAP_MIN_OFFSET; + p_buf->len = SMP_PAIR_FAIL_SIZE; + + smp_send_msg_to_L2CAP(bd_addr, p_buf); + } +} + #if SMP_CONFORMANCE_TESTING == TRUE /******************************************************************************* ** diff --git a/stack/srvc/srvc_dis.c b/stack/srvc/srvc_dis.c index 90b4acddc..7c4df0d83 100644 --- a/stack/srvc/srvc_dis.c +++ b/stack/srvc/srvc_dis.c @@ -443,14 +443,14 @@ BOOLEAN DIS_ReadDISInfo(BD_ADDR peer_bda, tDIS_READ_CBACK *p_cback) (peer_bda[4]<<8)+peer_bda[5], dis_attr_uuid[dis_cb.dis_read_uuid_idx]); - GATT_GetConnIdIfConnected(srvc_eng_cb.gatt_if, peer_bda, &conn_id); + GATT_GetConnIdIfConnected(srvc_eng_cb.gatt_if, peer_bda, &conn_id, BT_TRANSPORT_LE); /* need to enhance it as multiple service is needed */ srvc_eng_request_channel(peer_bda, SRVC_ID_DIS); if (conn_id == GATT_INVALID_CONN_ID) { - return GATT_Connect(srvc_eng_cb.gatt_if, peer_bda, TRUE); + return GATT_Connect(srvc_eng_cb.gatt_if, peer_bda, TRUE, BT_TRANSPORT_LE); } return dis_gatt_c_read_dis_req(conn_id); diff --git a/stack/srvc/srvc_eng.c b/stack/srvc/srvc_eng.c index 459873881..bf730aa7d 100644 --- a/stack/srvc/srvc_eng.c +++ b/stack/srvc/srvc_eng.c @@ -30,7 +30,8 @@ #include "srvc_battery_int.h" static void srvc_eng_s_request_cback (UINT16 conn_id, UINT32 trans_id, UINT8 op_code, tGATTS_DATA *p_data); -static void srvc_eng_connect_cback (tGATT_IF gatt_if, BD_ADDR bda, UINT16 conn_id, BOOLEAN connected, tGATT_DISCONN_REASON reason); +static void srvc_eng_connect_cback (tGATT_IF gatt_if, BD_ADDR bda, UINT16 conn_id, BOOLEAN connected, + tGATT_DISCONN_REASON reason, tBT_TRANSPORT transport); static void srvc_eng_c_cmpl_cback (UINT16 conn_id, tGATTC_OPTYPE op, tGATT_STATUS status, tGATT_CL_COMPLETE *p_data); static tGATT_CBACK srvc_gatt_cback = @@ -341,9 +342,10 @@ static void srvc_eng_c_cmpl_cback (UINT16 conn_id, tGATTC_OPTYPE op, tGATT_STATU ** *******************************************************************************/ static void srvc_eng_connect_cback (tGATT_IF gatt_if, BD_ADDR bda, UINT16 conn_id, - BOOLEAN connected, tGATT_DISCONN_REASON reason) + BOOLEAN connected, tGATT_DISCONN_REASON reason, tBT_TRANSPORT transport) { UNUSED(gatt_if); + UNUSED (transport); GATT_TRACE_EVENT5 ("srvc_eng_connect_cback: from %08x%04x connected:%d conn_id=%d reason = 0x%04x", (bda[0]<<24)+(bda[1]<<16)+(bda[2]<<8)+bda[3], -- 2.11.0