diff --git a/system/bta/dm/bta_dm_act.cc b/system/bta/dm/bta_dm_act.cc index f0e6e5f1a106d65828d3c5e9d8aea7e49a72a336..9341946f0dad81c28c10eb92cb94339e9d47dfe8 100644 --- a/system/bta/dm/bta_dm_act.cc +++ b/system/bta/dm/bta_dm_act.cc @@ -999,8 +999,6 @@ void bta_dm_sdp_result(tBTA_DM_MSG* p_data) { uint16_t service = 0xFFFF; tSDP_PROTOCOL_ELEM pe; - tBTA_DM_SEARCH result; - std::vector<Uuid> uuid_list; if ((p_data->sdp_event.sdp_result == SDP_SUCCESS) || @@ -1025,6 +1023,9 @@ void bta_dm_sdp_result(tBTA_DM_MSG* p_data) { * service UUID */ if (bta_dm_search_cb.service_index == BTA_MAX_SERVICE_ID) { /* all GATT based services */ + + std::vector<Uuid> gatt_uuids; + do { /* find a service record, report it */ p_sdp_rec = @@ -1032,16 +1033,23 @@ void bta_dm_sdp_result(tBTA_DM_MSG* p_data) { if (p_sdp_rec) { Uuid service_uuid; if (SDP_FindServiceUUIDInRec(p_sdp_rec, &service_uuid)) { - /* send result back to app now, one by one */ - result.disc_ble_res.bd_addr = bta_dm_search_cb.peer_bdaddr; - strlcpy((char*)result.disc_ble_res.bd_name, bta_dm_get_remname(), - BD_NAME_LEN + 1); - - result.disc_ble_res.service = service_uuid; - bta_dm_search_cb.p_search_cback(BTA_DM_DISC_BLE_RES_EVT, &result); + gatt_uuids.push_back(service_uuid); } } } while (p_sdp_rec); + + if (!gatt_uuids.empty()) { + LOG_INFO("GATT services discovered using SDP"); + + // send all result back to app + tBTA_DM_SEARCH result; + result.disc_ble_res.bd_addr = bta_dm_search_cb.peer_bdaddr; + strlcpy((char*)result.disc_ble_res.bd_name, bta_dm_get_remname(), + BD_NAME_LEN + 1); + + result.disc_ble_res.services = &gatt_uuids; + bta_dm_search_cb.p_search_cback(BTA_DM_DISC_BLE_RES_EVT, &result); + } } else { /* SDP_DB_FULL means some records with the required attributes were received */ @@ -1194,7 +1202,46 @@ void bta_dm_sdp_result(tBTA_DM_MSG* p_data) { ******************************************************************************/ void bta_dm_search_cmpl() { bta_dm_search_set_state(BTA_DM_SEARCH_IDLE); - bta_dm_search_cb.p_search_cback(BTA_DM_DISC_CMPL_EVT, NULL); + + uint16_t conn_id = bta_dm_search_cb.conn_id; + + /* no BLE connection, i.e. Classic service discovery end */ + if (conn_id == GATT_INVALID_CONN_ID) { + bta_dm_search_cb.p_search_cback(BTA_DM_DISC_CMPL_EVT, nullptr); + return; + } + + btgatt_db_element_t* db = NULL; + int count = 0; + BTA_GATTC_GetGattDb(conn_id, 0x0000, 0xFFFF, &db, &count); + + if (count == 0) { + LOG_INFO("Empty GATT database - no BLE services discovered"); + bta_dm_search_cb.p_search_cback(BTA_DM_DISC_CMPL_EVT, nullptr); + return; + } + + std::vector<Uuid> gatt_services; + + for (int i = 0; i < count; i++) { + // we process service entries only + if (db[i].type == BTGATT_DB_PRIMARY_SERVICE) { + gatt_services.push_back(db[i].uuid); + } + } + osi_free(db); + + tBTA_DM_SEARCH result; + result.disc_ble_res.services = &gatt_services; + result.disc_ble_res.bd_addr = bta_dm_search_cb.peer_bdaddr; + strlcpy((char*)result.disc_ble_res.bd_name, (char*)bta_dm_search_cb.peer_name, + BD_NAME_LEN + 1); + + LOG_INFO("GATT services discovered using LE Transport"); + // send all result back to app + bta_dm_search_cb.p_search_cback(BTA_DM_DISC_BLE_RES_EVT, &result); + + bta_dm_search_cb.p_search_cback(BTA_DM_DISC_CMPL_EVT, nullptr); } /******************************************************************************* @@ -3588,37 +3635,6 @@ static void bta_dm_gattc_register(void) { } } -/******************************************************************************* - * - * Function bta_dm_gatt_disc_result - * - * Description This function process the GATT service search result. - * - * Parameters: - * - ******************************************************************************/ -static void bta_dm_gatt_disc_result(tBTA_GATT_ID service_id) { - tBTA_DM_SEARCH result; - - /* - * This logic will not work for gatt case. We are checking against the - * bluetooth profiles here - * just copy the GATTID in raw data field and send it across. - */ - - LOG_INFO("%s service_id_uuid_len=%zu", __func__, - service_id.uuid.GetShortestRepresentationSize()); - if (bta_dm_search_cb.state != BTA_DM_SEARCH_IDLE) { - /* send result back to app now, one by one */ - result.disc_ble_res.bd_addr = bta_dm_search_cb.peer_bdaddr; - strlcpy((char*)result.disc_ble_res.bd_name, bta_dm_get_remname(), - BD_NAME_LEN + 1); - result.disc_ble_res.service = service_id.uuid; - - bta_dm_search_cb.p_search_cback(BTA_DM_DISC_BLE_RES_EVT, &result); - } -} - /******************************************************************************* * * Function bta_dm_gatt_disc_complete @@ -3768,7 +3784,6 @@ static void bta_dm_gattc_callback(tBTA_GATTC_EVT event, tBTA_GATTC* p_data) { break; case BTA_GATTC_SEARCH_RES_EVT: - bta_dm_gatt_disc_result(p_data->srvc_res.service_uuid); break; case BTA_GATTC_SEARCH_CMPL_EVT: diff --git a/system/bta/include/bta_api.h b/system/bta/include/bta_api.h index 3c58ea7fd93fcc74deda2e1cb1a26e1e0ebca6ce..cbe9706f852f3b7fef9e09d7ad9ff35e6fddfa9a 100644 --- a/system/bta/include/bta_api.h +++ b/system/bta/include/bta_api.h @@ -419,7 +419,8 @@ typedef struct { typedef struct { RawAddress bd_addr; /* BD address peer device. */ BD_NAME bd_name; /* Name of peer device. */ - bluetooth::Uuid service; /* GATT based Services UUID found on peer device. */ + std::vector<bluetooth::Uuid>* + services; /* GATT based Services UUID found on peer device. */ } tBTA_DM_DISC_BLE_RES; /* Union of all search callback structures */ diff --git a/system/btif/src/btif_dm.cc b/system/btif/src/btif_dm.cc index 13fbae8ee76c62fdd252b7a1d0a094d7057ce73b..9918f9a519b5eb3bc65719a2ae39d9cd65cbb9f1 100644 --- a/system/btif/src/btif_dm.cc +++ b/system/btif/src/btif_dm.cc @@ -1236,6 +1236,11 @@ static void btif_dm_search_devices_evt(tBTA_DM_SEARCH_EVT event, } } +/* Returns true if |uuid| should be passed as device property */ +static bool btif_is_interesting_le_service(bluetooth::Uuid uuid) { + return uuid.As16Bit() == UUID_SERVCLASS_LE_HID || uuid == UUID_HEARING_AID; +} + /******************************************************************************* * * Function btif_dm_search_services_evt @@ -1334,45 +1339,52 @@ static void btif_dm_search_services_evt(tBTA_DM_SEARCH_EVT event, break; case BTA_DM_DISC_BLE_RES_EVT: { - LOG_VERBOSE("service %s", - p_data->disc_ble_res.service.ToString().c_str()); int num_properties = 0; - if (p_data->disc_ble_res.service.As16Bit() == UUID_SERVCLASS_LE_HID || - p_data->disc_ble_res.service == UUID_HEARING_AID) { - LOG_INFO("Found HOGP or HEARING AID UUID"); - bt_property_t prop[2]; - bt_status_t ret; - - const auto& arr = p_data->disc_ble_res.service.To128BitBE(); - - RawAddress& bd_addr = p_data->disc_ble_res.bd_addr; - prop[0].type = BT_PROPERTY_UUIDS; - prop[0].val = (void*)arr.data(); - prop[0].len = Uuid::kNumBytes128; + bt_property_t prop[2]; + std::vector<uint8_t> property_value; + int num_uuids = 0; + + for (Uuid uuid : *p_data->disc_ble_res.services) { + LOG_VERBOSE("service %s", uuid.ToString().c_str()); + if (btif_is_interesting_le_service(uuid)) { + num_uuids++; + auto valAsBe = uuid.To128BitBE(); + property_value.insert(property_value.end(), valAsBe.begin(), + valAsBe.end()); + } + } - /* Also write this to the NVRAM */ - ret = btif_storage_set_remote_device_property(&bd_addr, &prop[0]); - ASSERTC(ret == BT_STATUS_SUCCESS, "storing remote services failed", - ret); - num_properties++; + if (num_uuids == 0) { + LOG_INFO("No well known BLE services discovered"); + return; + } - /* Remote name update */ - if (strnlen((const char*)p_data->disc_ble_res.bd_name, BD_NAME_LEN)) { - prop[1].type = BT_PROPERTY_BDNAME; - prop[1].val = p_data->disc_ble_res.bd_name; - prop[1].len = - strnlen((char*)p_data->disc_ble_res.bd_name, BD_NAME_LEN); + RawAddress& bd_addr = p_data->disc_ble_res.bd_addr; + prop[0].type = BT_PROPERTY_UUIDS; + prop[0].val = (void*)property_value.data(); + prop[0].len = Uuid::kNumBytes128 * num_uuids; - ret = btif_storage_set_remote_device_property(&bd_addr, &prop[1]); - ASSERTC(ret == BT_STATUS_SUCCESS, - "failed to save remote device property", ret); - num_properties++; - } + /* Also write this to the NVRAM */ + bt_status_t ret = + btif_storage_set_remote_device_property(&bd_addr, &prop[0]); + ASSERTC(ret == BT_STATUS_SUCCESS, "storing remote services failed", ret); + num_properties++; - /* Send the event to the BTIF */ - invoke_remote_device_properties_cb(BT_STATUS_SUCCESS, bd_addr, - num_properties, prop); + /* Remote name update */ + if (strnlen((const char*)p_data->disc_ble_res.bd_name, BD_NAME_LEN)) { + prop[1].type = BT_PROPERTY_BDNAME; + prop[1].val = p_data->disc_ble_res.bd_name; + prop[1].len = strnlen((char*)p_data->disc_ble_res.bd_name, BD_NAME_LEN); + + ret = btif_storage_set_remote_device_property(&bd_addr, &prop[1]); + ASSERTC(ret == BT_STATUS_SUCCESS, + "failed to save remote device property", ret); + num_properties++; } + + /* Send the event to the BTIF */ + invoke_remote_device_properties_cb(BT_STATUS_SUCCESS, bd_addr, + num_properties, prop); } break; default: { ASSERTC(0, "unhandled search services event", event); } break;