Loading system/bta/gatt/bta_gattc_act.cc +6 −0 Original line number Diff line number Diff line Loading @@ -722,6 +722,12 @@ void bta_gattc_disc_cmpl(tBTA_GATTC_CLCB* p_clcb, */ if (p_q_cmd != p_clcb->p_q_cmd) osi_free_and_reset((void**)&p_q_cmd); } if (p_clcb->p_rcb->p_cback) { tBTA_GATTC bta_gattc; bta_gattc.remote_bda = p_clcb->p_srcb->server_bda; (*p_clcb->p_rcb->p_cback)(BTA_GATTC_SRVC_DISC_DONE_EVT, &bta_gattc); } } /** Read an attribute */ Loading system/bta/hearing_aid/hearing_aid.cc +103 −33 Original line number Diff line number Diff line Loading @@ -521,14 +521,17 @@ class HearingAidImpl : public HearingAid { DVLOG(2) << __func__ << " " << address; if (!hearingDevice->first_connection) { // Use cached data, jump to connecting socket ConnectSocket(hearingDevice); return; } if (hearingDevice->audio_control_point_handle && hearingDevice->audio_status_handle && hearingDevice->audio_status_ccc_handle && hearingDevice->volume_handle && hearingDevice->read_psm_handle) { // Use cached data, jump to read PSM ReadPSM(hearingDevice); } else { hearingDevice->first_connection = true; BTA_GATTC_ServiceSearchRequest(hearingDevice->conn_id, &HEARING_AID_UUID); } } void OnServiceChangeEvent(const RawAddress& address) { HearingDevice* hearingDevice = hearingDevices.FindByAddress(address); Loading @@ -537,16 +540,23 @@ class HearingAidImpl : public HearingAid { return; } LOG(INFO) << __func__ << ": address=" << address; hearingDevice->first_connection = true; hearingDevice->service_changed_rcvd = true; BtaGattQueue::Clean(hearingDevice->conn_id); if (hearingDevice->gap_handle) { GAP_ConnClose(hearingDevice->gap_handle); hearingDevice->gap_handle = 0; } } /* Re-register the Audio Status Notification since the Service Change will * clear it */ tGATT_STATUS register_status; register_status = BTA_GATTC_RegisterForNotifications( gatt_if, address, hearingDevice->audio_status_handle); if (register_status != GATT_SUCCESS) { LOG(INFO) << __func__ << ": BTA_GATTC_RegisterForNotifications failed, status=" << loghex(register_status); void OnServiceDiscDoneEvent(const RawAddress& address) { HearingDevice* hearingDevice = hearingDevices.FindByAddress(address); if (!hearingDevice) { VLOG(2) << "Skipping unknown device" << address; return; } if (hearingDevice->service_changed_rcvd) { BTA_GATTC_ServiceSearchRequest(hearingDevice->conn_id, &HEARING_AID_UUID); } } Loading Loading @@ -574,10 +584,15 @@ class HearingAidImpl : public HearingAid { const gatt::Service* service = nullptr; for (const gatt::Service& tmp : *services) { if (tmp.uuid != HEARING_AID_UUID) continue; if (tmp.uuid == Uuid::From16Bit(UUID_SERVCLASS_GATT_SERVER)) { LOG(INFO) << "Found UUID_SERVCLASS_GATT_SERVER, handle=" << loghex(tmp.handle); const gatt::Service* service_changed_service = &tmp; find_server_changed_ccc_handle(conn_id, service_changed_service); } else if (tmp.uuid == HEARING_AID_UUID) { LOG(INFO) << "Found Hearing Aid service, handle=" << loghex(tmp.handle); service = &tmp; break; } } if (!service) { Loading @@ -587,7 +602,6 @@ class HearingAidImpl : public HearingAid { return; } uint16_t psm_handle = 0x0000; for (const gatt::Characteristic& charac : service->characteristics) { if (charac.uuid == READ_ONLY_PROPERTIES_UUID) { DVLOG(2) << "Reading read only properties " Loading @@ -614,16 +628,26 @@ class HearingAidImpl : public HearingAid { } else if (charac.uuid == VOLUME_UUID) { hearingDevice->volume_handle = charac.value_handle; } else if (charac.uuid == LE_PSM_UUID) { psm_handle = charac.value_handle; hearingDevice->read_psm_handle = charac.value_handle; } else { LOG(WARNING) << "Unknown characteristic found:" << charac.uuid; } } if (psm_handle) { DVLOG(2) << "Reading PSM " << loghex(psm_handle); if (hearingDevice->service_changed_rcvd) { hearingDevice->service_changed_rcvd = false; } ReadPSM(hearingDevice); } void ReadPSM(HearingDevice* hearingDevice) { if (hearingDevice->read_psm_handle) { LOG(INFO) << "Reading PSM " << loghex(hearingDevice->read_psm_handle) << ", device=" << hearingDevice->address; BtaGattQueue::ReadCharacteristic( conn_id, psm_handle, HearingAidImpl::OnPsmReadStatic, nullptr); hearingDevice->conn_id, hearingDevice->read_psm_handle, HearingAidImpl::OnPsmReadStatic, nullptr); } } Loading Loading @@ -790,24 +814,25 @@ class HearingAidImpl : public HearingAid { return; } uint16_t psm_val = *((uint16_t*)value); hearingDevice->psm = psm_val; VLOG(2) << "read psm:" << loghex(hearingDevice->psm); uint16_t psm = *((uint16_t*)value); VLOG(2) << "read psm:" << loghex(psm); ConnectSocket(hearingDevice); ConnectSocket(hearingDevice, psm); } void ConnectSocket(HearingDevice* hearingDevice) { void ConnectSocket(HearingDevice* hearingDevice, uint16_t psm) { tL2CAP_CFG_INFO cfg_info = tL2CAP_CFG_INFO{.mtu = 512}; SendEnableServiceChangedInd(hearingDevice); uint8_t service_id = hearingDevice->isLeft() ? BTM_SEC_SERVICE_HEARING_AID_LEFT : BTM_SEC_SERVICE_HEARING_AID_RIGHT; uint16_t gap_handle = GAP_ConnOpen( "", service_id, false, &hearingDevice->address, hearingDevice->psm, 514 /* MPS */, &cfg_info, nullptr, BTM_SEC_NONE /* TODO: request security ? */, L2CAP_FCR_LE_COC_MODE, HearingAidImpl::GapCallbackStatic, BT_TRANSPORT_LE); "", service_id, false, &hearingDevice->address, psm, 514 /* MPS */, &cfg_info, nullptr, BTM_SEC_NONE /* TODO: request security ? */, L2CAP_FCR_LE_COC_MODE, HearingAidImpl::GapCallbackStatic, BT_TRANSPORT_LE); if (gap_handle == GAP_INVALID_HANDLE) { LOG(ERROR) << "UNABLE TO GET gap_handle"; return; Loading Loading @@ -993,6 +1018,17 @@ class HearingAidImpl : public HearingAid { return (OTHER_SIDE_NOT_STREAMING); } void SendEnableServiceChangedInd(HearingDevice* device) { VLOG(2) << __func__ << " Enable " << device->address << "service changed ind."; std::vector<uint8_t> value(2); uint8_t* ptr = value.data(); UINT16_TO_STREAM(ptr, GATT_CHAR_CLIENT_CONFIG_INDICTION); BtaGattQueue::WriteDescriptor( device->conn_id, device->service_changed_ccc_handle, std::move(value), GATT_WRITE, nullptr, nullptr); } void SendStart(HearingDevice* device) { std::vector<uint8_t> start({CONTROL_POINT_OP_START, codec_in_use, AUDIOTYPE_UNKNOWN, (uint8_t)current_volume, Loading Loading @@ -1462,6 +1498,29 @@ class HearingAidImpl : public HearingAid { HearingDevices hearingDevices; void find_server_changed_ccc_handle(uint16_t conn_id, const gatt::Service* service) { HearingDevice* hearingDevice = hearingDevices.FindByConnId(conn_id); if (!hearingDevice) { DVLOG(2) << "Skipping unknown device, conn_id=" << loghex(conn_id); return; } for (const gatt::Characteristic& charac : service->characteristics) { if (charac.uuid == Uuid::From16Bit(GATT_UUID_GATT_SRV_CHGD)) { hearingDevice->service_changed_ccc_handle = find_ccc_handle(conn_id, charac.value_handle); if (!hearingDevice->service_changed_ccc_handle) { LOG(ERROR) << __func__ << ": cannot find service changed CCC descriptor"; continue; } LOG(INFO) << __func__ << " service_changed_ccc=" << loghex(hearingDevice->service_changed_ccc_handle); break; } } } // Find the handle for the client characteristics configuration of a given // characteristics uint16_t find_ccc_handle(uint16_t conn_id, uint16_t char_handle) { Loading @@ -1483,6 +1542,12 @@ class HearingAidImpl : public HearingAid { void send_state_change(HearingDevice* device, std::vector<uint8_t> payload) { if (device->conn_id != 0) { if (device->service_changed_rcvd) { LOG(INFO) << __func__ << ": service discover is in progress, skip send State Change cmd."; return; } // Send the data packet LOG(INFO) << __func__ << ": Send State Change. device=" << device->address << ", status=" << loghex(payload[1]); Loading Loading @@ -1583,6 +1648,11 @@ void hearingaid_gattc_callback(tBTA_GATTC_EVT event, tBTA_GATTC* p_data) { instance->OnServiceChangeEvent(p_data->remote_bda); break; case BTA_GATTC_SRVC_DISC_DONE_EVT: if (!instance) return; instance->OnServiceDiscDoneEvent(p_data->remote_bda); break; default: break; } Loading system/bta/include/bta_gatt_api.h +1 −0 Original line number Diff line number Diff line Loading @@ -54,6 +54,7 @@ typedef struct { #define BTA_GATTC_CLOSE_EVT 5 /* GATTC close request status event */ #define BTA_GATTC_SEARCH_CMPL_EVT 6 /* GATT discovery complete event */ #define BTA_GATTC_SEARCH_RES_EVT 7 /* GATT discovery result event */ #define BTA_GATTC_SRVC_DISC_DONE_EVT 8 /* GATT service discovery done event */ #define BTA_GATTC_NOTIF_EVT 10 /* GATT attribute notification event */ #define BTA_GATTC_EXEC_EVT 12 /* execute write complete event */ #define BTA_GATTC_ACL_EVT 13 /* ACL up event */ Loading system/bta/include/bta_hearing_aid_api.h +17 −6 Original line number Diff line number Diff line Loading @@ -24,6 +24,8 @@ #include <future> #include <vector> constexpr uint16_t HEARINGAID_MAX_NUM_UUIDS = 1; constexpr uint16_t HA_INTERVAL_10_MS = 10; constexpr uint16_t HA_INTERVAL_20_MS = 20; Loading Loading @@ -82,6 +84,7 @@ struct HearingDevice { /* This is true only during first connection to profile, until we store the * device */ bool first_connection; bool service_changed_rcvd; /* we are making active attempt to connect to this device, 'direct connect'. * This is true only during initial phase of first connection. */ Loading @@ -107,8 +110,9 @@ struct HearingDevice { uint16_t audio_control_point_handle; uint16_t audio_status_handle; uint16_t audio_status_ccc_handle; uint16_t service_changed_ccc_handle; uint16_t volume_handle; uint16_t psm; uint16_t read_psm_handle; uint8_t capabilities; uint64_t hi_sync_id; Loading @@ -131,11 +135,15 @@ struct HearingDevice { int read_rssi_count; int num_intervals_since_last_rssi_read; HearingDevice(const RawAddress& address, uint16_t psm, uint8_t capabilities, uint16_t codecs, uint16_t audio_control_point_handle, uint16_t audio_status_handle, uint16_t audio_status_ccc_handle, uint16_t volume_handle, uint64_t hiSyncId, uint16_t render_delay, uint16_t preparation_delay) HearingDevice(const RawAddress& address, uint8_t capabilities, uint16_t codecs, uint16_t audio_control_point_handle, uint16_t audio_status_handle, uint16_t audio_status_ccc_handle, uint16_t service_changed_ccc_handle, uint16_t volume_handle, uint16_t read_psm_handle, uint64_t hiSyncId, uint16_t render_delay, uint16_t preparation_delay) : address(address), first_connection(false), service_changed_rcvd(false), connecting_actively(false), connection_update_status(NONE), accepting_audio(false), Loading @@ -144,8 +152,9 @@ struct HearingDevice { audio_control_point_handle(audio_control_point_handle), audio_status_handle(audio_status_handle), audio_status_ccc_handle(audio_status_ccc_handle), service_changed_ccc_handle(service_changed_ccc_handle), volume_handle(volume_handle), psm(psm), read_psm_handle(read_psm_handle), capabilities(capabilities), hi_sync_id(hiSyncId), render_delay(render_delay), Loading @@ -158,6 +167,7 @@ struct HearingDevice { HearingDevice(const RawAddress& address, bool first_connection) : address(address), first_connection(first_connection), service_changed_rcvd(false), connecting_actively(first_connection), connection_update_status(NONE), accepting_audio(false), Loading @@ -165,7 +175,8 @@ struct HearingDevice { gap_handle(0), audio_status_handle(0), audio_status_ccc_handle(0), psm(0), service_changed_ccc_handle(0), read_psm_handle(0), playback_started(false), command_acked(false), read_rssi_count(0) {} Loading system/btif/src/btif_storage.cc +45 −10 Original line number Diff line number Diff line Loading @@ -1423,7 +1423,7 @@ bt_status_t btif_storage_remove_hid_info(RawAddress* remote_bd_addr) { return BT_STATUS_SUCCESS; } constexpr char HEARING_AID_PSM[] = "HearingAidPsm"; constexpr char HEARING_AID_READ_PSM_HANDLE[] = "HearingAidReadPsmHandle"; constexpr char HEARING_AID_CAPABILITIES[] = "HearingAidCapabilities"; constexpr char HEARING_AID_CODECS[] = "HearingAidCodecs"; constexpr char HEARING_AID_AUDIO_CONTROL_POINT[] = Loading @@ -1433,6 +1433,8 @@ constexpr char HEARING_AID_AUDIO_STATUS_HANDLE[] = "HearingAidAudioStatusHandle"; constexpr char HEARING_AID_AUDIO_STATUS_CCC_HANDLE[] = "HearingAidAudioStatusCccHandle"; constexpr char HEARING_AID_SERVICE_CHANGED_CCC_HANDLE[] = "HearingAidServiceChangedCccHandle"; constexpr char HEARING_AID_SYNC_ID[] = "HearingAidSyncId"; constexpr char HEARING_AID_RENDER_DELAY[] = "HearingAidRenderDelay"; constexpr char HEARING_AID_PREPARATION_DELAY[] = "HearingAidPreparationDelay"; Loading @@ -1445,7 +1447,10 @@ void btif_storage_add_hearing_aid(const HearingDevice& dev_info) { [](const HearingDevice& dev_info) { std::string bdstr = dev_info.address.ToString(); VLOG(2) << "saving hearing aid device: " << bdstr; btif_config_set_int(bdstr, HEARING_AID_PSM, dev_info.psm); btif_config_set_int(bdstr, HEARING_AID_SERVICE_CHANGED_CCC_HANDLE, dev_info.service_changed_ccc_handle); btif_config_set_int(bdstr, HEARING_AID_READ_PSM_HANDLE, dev_info.read_psm_handle); btif_config_set_int(bdstr, HEARING_AID_CAPABILITIES, dev_info.capabilities); btif_config_set_int(bdstr, HEARING_AID_CODECS, dev_info.codecs); Loading Loading @@ -1477,11 +1482,26 @@ void btif_storage_load_bonded_hearing_aids() { const std::string& name = section.name; if (!RawAddress::IsValidAddress(name)) continue; BTIF_TRACE_DEBUG("Remote device:%s", name.c_str()); int size = STORAGE_UUID_STRING_SIZE * HEARINGAID_MAX_NUM_UUIDS; char uuid_str[size]; bool isHearingaidDevice = false; if (btif_config_get_str(name, BTIF_STORAGE_PATH_REMOTE_SERVICE, uuid_str, &size)) { Uuid p_uuid[HEARINGAID_MAX_NUM_UUIDS]; size_t num_uuids = btif_split_uuids_string(uuid_str, p_uuid, HEARINGAID_MAX_NUM_UUIDS); for (size_t i = 0; i < num_uuids; i++) { if (p_uuid[i] == Uuid::FromString("FDF0")) { isHearingaidDevice = true; break; } } } if (!isHearingaidDevice) { continue; } int value; if (!btif_config_get_int(name, HEARING_AID_PSM, &value)) continue; uint16_t psm = value; BTIF_TRACE_DEBUG("Remote device:%s", name.c_str()); if (btif_in_fetch_bonded_device(name) != BT_STATUS_SUCCESS) { RawAddress bd_addr; Loading @@ -1490,6 +1510,7 @@ void btif_storage_load_bonded_hearing_aids() { continue; } int value; uint8_t capabilities = 0; if (btif_config_get_int(name, HEARING_AID_CAPABILITIES, &value)) capabilities = value; Loading @@ -1509,10 +1530,19 @@ void btif_storage_load_bonded_hearing_aids() { if (btif_config_get_int(name, HEARING_AID_AUDIO_STATUS_CCC_HANDLE, &value)) audio_status_ccc_handle = value; uint16_t service_changed_ccc_handle = 0; if (btif_config_get_int(name, HEARING_AID_SERVICE_CHANGED_CCC_HANDLE, &value)) service_changed_ccc_handle = value; uint16_t volume_handle = 0; if (btif_config_get_int(name, HEARING_AID_VOLUME_HANDLE, &value)) volume_handle = value; uint16_t read_psm_handle = 0; if (btif_config_get_int(name, HEARING_AID_READ_PSM_HANDLE, &value)) read_psm_handle = value; uint64_t lvalue; uint64_t hi_sync_id = 0; if (btif_config_get_uint64(name, HEARING_AID_SYNC_ID, &lvalue)) Loading @@ -1537,9 +1567,10 @@ void btif_storage_load_bonded_hearing_aids() { do_in_main_thread( FROM_HERE, Bind(&HearingAid::AddFromStorage, HearingDevice(bd_addr, psm, capabilities, codecs, HearingDevice(bd_addr, capabilities, codecs, audio_control_point_handle, audio_status_handle, audio_status_ccc_handle, volume_handle, hi_sync_id, audio_status_ccc_handle, service_changed_ccc_handle, volume_handle, read_psm_handle, hi_sync_id, render_delay, preparation_delay), is_white_listed)); } Loading @@ -1548,13 +1579,17 @@ void btif_storage_load_bonded_hearing_aids() { /** Deletes the bonded hearing aid device info from NVRAM */ void btif_storage_remove_hearing_aid(const RawAddress& address) { std::string addrstr = address.ToString(); btif_config_remove(addrstr, HEARING_AID_PSM); btif_config_remove(addrstr, HEARING_AID_READ_PSM_HANDLE); btif_config_remove(addrstr, HEARING_AID_CAPABILITIES); btif_config_remove(addrstr, HEARING_AID_CODECS); btif_config_remove(addrstr, HEARING_AID_AUDIO_CONTROL_POINT); btif_config_remove(addrstr, HEARING_AID_VOLUME_HANDLE); btif_config_remove(addrstr, HEARING_AID_AUDIO_STATUS_HANDLE); btif_config_remove(addrstr, HEARING_AID_AUDIO_STATUS_CCC_HANDLE); btif_config_remove(addrstr, HEARING_AID_SERVICE_CHANGED_CCC_HANDLE); btif_config_remove(addrstr, HEARING_AID_SYNC_ID); btif_config_remove(addrstr, HEARING_AID_RENDER_DELAY); btif_config_remove(addrstr, HEARING_AID_PREPARATION_DELAY); btif_config_remove(addrstr, HEARING_AID_IS_WHITE_LISTED); btif_config_save(); } Loading Loading
system/bta/gatt/bta_gattc_act.cc +6 −0 Original line number Diff line number Diff line Loading @@ -722,6 +722,12 @@ void bta_gattc_disc_cmpl(tBTA_GATTC_CLCB* p_clcb, */ if (p_q_cmd != p_clcb->p_q_cmd) osi_free_and_reset((void**)&p_q_cmd); } if (p_clcb->p_rcb->p_cback) { tBTA_GATTC bta_gattc; bta_gattc.remote_bda = p_clcb->p_srcb->server_bda; (*p_clcb->p_rcb->p_cback)(BTA_GATTC_SRVC_DISC_DONE_EVT, &bta_gattc); } } /** Read an attribute */ Loading
system/bta/hearing_aid/hearing_aid.cc +103 −33 Original line number Diff line number Diff line Loading @@ -521,14 +521,17 @@ class HearingAidImpl : public HearingAid { DVLOG(2) << __func__ << " " << address; if (!hearingDevice->first_connection) { // Use cached data, jump to connecting socket ConnectSocket(hearingDevice); return; } if (hearingDevice->audio_control_point_handle && hearingDevice->audio_status_handle && hearingDevice->audio_status_ccc_handle && hearingDevice->volume_handle && hearingDevice->read_psm_handle) { // Use cached data, jump to read PSM ReadPSM(hearingDevice); } else { hearingDevice->first_connection = true; BTA_GATTC_ServiceSearchRequest(hearingDevice->conn_id, &HEARING_AID_UUID); } } void OnServiceChangeEvent(const RawAddress& address) { HearingDevice* hearingDevice = hearingDevices.FindByAddress(address); Loading @@ -537,16 +540,23 @@ class HearingAidImpl : public HearingAid { return; } LOG(INFO) << __func__ << ": address=" << address; hearingDevice->first_connection = true; hearingDevice->service_changed_rcvd = true; BtaGattQueue::Clean(hearingDevice->conn_id); if (hearingDevice->gap_handle) { GAP_ConnClose(hearingDevice->gap_handle); hearingDevice->gap_handle = 0; } } /* Re-register the Audio Status Notification since the Service Change will * clear it */ tGATT_STATUS register_status; register_status = BTA_GATTC_RegisterForNotifications( gatt_if, address, hearingDevice->audio_status_handle); if (register_status != GATT_SUCCESS) { LOG(INFO) << __func__ << ": BTA_GATTC_RegisterForNotifications failed, status=" << loghex(register_status); void OnServiceDiscDoneEvent(const RawAddress& address) { HearingDevice* hearingDevice = hearingDevices.FindByAddress(address); if (!hearingDevice) { VLOG(2) << "Skipping unknown device" << address; return; } if (hearingDevice->service_changed_rcvd) { BTA_GATTC_ServiceSearchRequest(hearingDevice->conn_id, &HEARING_AID_UUID); } } Loading Loading @@ -574,10 +584,15 @@ class HearingAidImpl : public HearingAid { const gatt::Service* service = nullptr; for (const gatt::Service& tmp : *services) { if (tmp.uuid != HEARING_AID_UUID) continue; if (tmp.uuid == Uuid::From16Bit(UUID_SERVCLASS_GATT_SERVER)) { LOG(INFO) << "Found UUID_SERVCLASS_GATT_SERVER, handle=" << loghex(tmp.handle); const gatt::Service* service_changed_service = &tmp; find_server_changed_ccc_handle(conn_id, service_changed_service); } else if (tmp.uuid == HEARING_AID_UUID) { LOG(INFO) << "Found Hearing Aid service, handle=" << loghex(tmp.handle); service = &tmp; break; } } if (!service) { Loading @@ -587,7 +602,6 @@ class HearingAidImpl : public HearingAid { return; } uint16_t psm_handle = 0x0000; for (const gatt::Characteristic& charac : service->characteristics) { if (charac.uuid == READ_ONLY_PROPERTIES_UUID) { DVLOG(2) << "Reading read only properties " Loading @@ -614,16 +628,26 @@ class HearingAidImpl : public HearingAid { } else if (charac.uuid == VOLUME_UUID) { hearingDevice->volume_handle = charac.value_handle; } else if (charac.uuid == LE_PSM_UUID) { psm_handle = charac.value_handle; hearingDevice->read_psm_handle = charac.value_handle; } else { LOG(WARNING) << "Unknown characteristic found:" << charac.uuid; } } if (psm_handle) { DVLOG(2) << "Reading PSM " << loghex(psm_handle); if (hearingDevice->service_changed_rcvd) { hearingDevice->service_changed_rcvd = false; } ReadPSM(hearingDevice); } void ReadPSM(HearingDevice* hearingDevice) { if (hearingDevice->read_psm_handle) { LOG(INFO) << "Reading PSM " << loghex(hearingDevice->read_psm_handle) << ", device=" << hearingDevice->address; BtaGattQueue::ReadCharacteristic( conn_id, psm_handle, HearingAidImpl::OnPsmReadStatic, nullptr); hearingDevice->conn_id, hearingDevice->read_psm_handle, HearingAidImpl::OnPsmReadStatic, nullptr); } } Loading Loading @@ -790,24 +814,25 @@ class HearingAidImpl : public HearingAid { return; } uint16_t psm_val = *((uint16_t*)value); hearingDevice->psm = psm_val; VLOG(2) << "read psm:" << loghex(hearingDevice->psm); uint16_t psm = *((uint16_t*)value); VLOG(2) << "read psm:" << loghex(psm); ConnectSocket(hearingDevice); ConnectSocket(hearingDevice, psm); } void ConnectSocket(HearingDevice* hearingDevice) { void ConnectSocket(HearingDevice* hearingDevice, uint16_t psm) { tL2CAP_CFG_INFO cfg_info = tL2CAP_CFG_INFO{.mtu = 512}; SendEnableServiceChangedInd(hearingDevice); uint8_t service_id = hearingDevice->isLeft() ? BTM_SEC_SERVICE_HEARING_AID_LEFT : BTM_SEC_SERVICE_HEARING_AID_RIGHT; uint16_t gap_handle = GAP_ConnOpen( "", service_id, false, &hearingDevice->address, hearingDevice->psm, 514 /* MPS */, &cfg_info, nullptr, BTM_SEC_NONE /* TODO: request security ? */, L2CAP_FCR_LE_COC_MODE, HearingAidImpl::GapCallbackStatic, BT_TRANSPORT_LE); "", service_id, false, &hearingDevice->address, psm, 514 /* MPS */, &cfg_info, nullptr, BTM_SEC_NONE /* TODO: request security ? */, L2CAP_FCR_LE_COC_MODE, HearingAidImpl::GapCallbackStatic, BT_TRANSPORT_LE); if (gap_handle == GAP_INVALID_HANDLE) { LOG(ERROR) << "UNABLE TO GET gap_handle"; return; Loading Loading @@ -993,6 +1018,17 @@ class HearingAidImpl : public HearingAid { return (OTHER_SIDE_NOT_STREAMING); } void SendEnableServiceChangedInd(HearingDevice* device) { VLOG(2) << __func__ << " Enable " << device->address << "service changed ind."; std::vector<uint8_t> value(2); uint8_t* ptr = value.data(); UINT16_TO_STREAM(ptr, GATT_CHAR_CLIENT_CONFIG_INDICTION); BtaGattQueue::WriteDescriptor( device->conn_id, device->service_changed_ccc_handle, std::move(value), GATT_WRITE, nullptr, nullptr); } void SendStart(HearingDevice* device) { std::vector<uint8_t> start({CONTROL_POINT_OP_START, codec_in_use, AUDIOTYPE_UNKNOWN, (uint8_t)current_volume, Loading Loading @@ -1462,6 +1498,29 @@ class HearingAidImpl : public HearingAid { HearingDevices hearingDevices; void find_server_changed_ccc_handle(uint16_t conn_id, const gatt::Service* service) { HearingDevice* hearingDevice = hearingDevices.FindByConnId(conn_id); if (!hearingDevice) { DVLOG(2) << "Skipping unknown device, conn_id=" << loghex(conn_id); return; } for (const gatt::Characteristic& charac : service->characteristics) { if (charac.uuid == Uuid::From16Bit(GATT_UUID_GATT_SRV_CHGD)) { hearingDevice->service_changed_ccc_handle = find_ccc_handle(conn_id, charac.value_handle); if (!hearingDevice->service_changed_ccc_handle) { LOG(ERROR) << __func__ << ": cannot find service changed CCC descriptor"; continue; } LOG(INFO) << __func__ << " service_changed_ccc=" << loghex(hearingDevice->service_changed_ccc_handle); break; } } } // Find the handle for the client characteristics configuration of a given // characteristics uint16_t find_ccc_handle(uint16_t conn_id, uint16_t char_handle) { Loading @@ -1483,6 +1542,12 @@ class HearingAidImpl : public HearingAid { void send_state_change(HearingDevice* device, std::vector<uint8_t> payload) { if (device->conn_id != 0) { if (device->service_changed_rcvd) { LOG(INFO) << __func__ << ": service discover is in progress, skip send State Change cmd."; return; } // Send the data packet LOG(INFO) << __func__ << ": Send State Change. device=" << device->address << ", status=" << loghex(payload[1]); Loading Loading @@ -1583,6 +1648,11 @@ void hearingaid_gattc_callback(tBTA_GATTC_EVT event, tBTA_GATTC* p_data) { instance->OnServiceChangeEvent(p_data->remote_bda); break; case BTA_GATTC_SRVC_DISC_DONE_EVT: if (!instance) return; instance->OnServiceDiscDoneEvent(p_data->remote_bda); break; default: break; } Loading
system/bta/include/bta_gatt_api.h +1 −0 Original line number Diff line number Diff line Loading @@ -54,6 +54,7 @@ typedef struct { #define BTA_GATTC_CLOSE_EVT 5 /* GATTC close request status event */ #define BTA_GATTC_SEARCH_CMPL_EVT 6 /* GATT discovery complete event */ #define BTA_GATTC_SEARCH_RES_EVT 7 /* GATT discovery result event */ #define BTA_GATTC_SRVC_DISC_DONE_EVT 8 /* GATT service discovery done event */ #define BTA_GATTC_NOTIF_EVT 10 /* GATT attribute notification event */ #define BTA_GATTC_EXEC_EVT 12 /* execute write complete event */ #define BTA_GATTC_ACL_EVT 13 /* ACL up event */ Loading
system/bta/include/bta_hearing_aid_api.h +17 −6 Original line number Diff line number Diff line Loading @@ -24,6 +24,8 @@ #include <future> #include <vector> constexpr uint16_t HEARINGAID_MAX_NUM_UUIDS = 1; constexpr uint16_t HA_INTERVAL_10_MS = 10; constexpr uint16_t HA_INTERVAL_20_MS = 20; Loading Loading @@ -82,6 +84,7 @@ struct HearingDevice { /* This is true only during first connection to profile, until we store the * device */ bool first_connection; bool service_changed_rcvd; /* we are making active attempt to connect to this device, 'direct connect'. * This is true only during initial phase of first connection. */ Loading @@ -107,8 +110,9 @@ struct HearingDevice { uint16_t audio_control_point_handle; uint16_t audio_status_handle; uint16_t audio_status_ccc_handle; uint16_t service_changed_ccc_handle; uint16_t volume_handle; uint16_t psm; uint16_t read_psm_handle; uint8_t capabilities; uint64_t hi_sync_id; Loading @@ -131,11 +135,15 @@ struct HearingDevice { int read_rssi_count; int num_intervals_since_last_rssi_read; HearingDevice(const RawAddress& address, uint16_t psm, uint8_t capabilities, uint16_t codecs, uint16_t audio_control_point_handle, uint16_t audio_status_handle, uint16_t audio_status_ccc_handle, uint16_t volume_handle, uint64_t hiSyncId, uint16_t render_delay, uint16_t preparation_delay) HearingDevice(const RawAddress& address, uint8_t capabilities, uint16_t codecs, uint16_t audio_control_point_handle, uint16_t audio_status_handle, uint16_t audio_status_ccc_handle, uint16_t service_changed_ccc_handle, uint16_t volume_handle, uint16_t read_psm_handle, uint64_t hiSyncId, uint16_t render_delay, uint16_t preparation_delay) : address(address), first_connection(false), service_changed_rcvd(false), connecting_actively(false), connection_update_status(NONE), accepting_audio(false), Loading @@ -144,8 +152,9 @@ struct HearingDevice { audio_control_point_handle(audio_control_point_handle), audio_status_handle(audio_status_handle), audio_status_ccc_handle(audio_status_ccc_handle), service_changed_ccc_handle(service_changed_ccc_handle), volume_handle(volume_handle), psm(psm), read_psm_handle(read_psm_handle), capabilities(capabilities), hi_sync_id(hiSyncId), render_delay(render_delay), Loading @@ -158,6 +167,7 @@ struct HearingDevice { HearingDevice(const RawAddress& address, bool first_connection) : address(address), first_connection(first_connection), service_changed_rcvd(false), connecting_actively(first_connection), connection_update_status(NONE), accepting_audio(false), Loading @@ -165,7 +175,8 @@ struct HearingDevice { gap_handle(0), audio_status_handle(0), audio_status_ccc_handle(0), psm(0), service_changed_ccc_handle(0), read_psm_handle(0), playback_started(false), command_acked(false), read_rssi_count(0) {} Loading
system/btif/src/btif_storage.cc +45 −10 Original line number Diff line number Diff line Loading @@ -1423,7 +1423,7 @@ bt_status_t btif_storage_remove_hid_info(RawAddress* remote_bd_addr) { return BT_STATUS_SUCCESS; } constexpr char HEARING_AID_PSM[] = "HearingAidPsm"; constexpr char HEARING_AID_READ_PSM_HANDLE[] = "HearingAidReadPsmHandle"; constexpr char HEARING_AID_CAPABILITIES[] = "HearingAidCapabilities"; constexpr char HEARING_AID_CODECS[] = "HearingAidCodecs"; constexpr char HEARING_AID_AUDIO_CONTROL_POINT[] = Loading @@ -1433,6 +1433,8 @@ constexpr char HEARING_AID_AUDIO_STATUS_HANDLE[] = "HearingAidAudioStatusHandle"; constexpr char HEARING_AID_AUDIO_STATUS_CCC_HANDLE[] = "HearingAidAudioStatusCccHandle"; constexpr char HEARING_AID_SERVICE_CHANGED_CCC_HANDLE[] = "HearingAidServiceChangedCccHandle"; constexpr char HEARING_AID_SYNC_ID[] = "HearingAidSyncId"; constexpr char HEARING_AID_RENDER_DELAY[] = "HearingAidRenderDelay"; constexpr char HEARING_AID_PREPARATION_DELAY[] = "HearingAidPreparationDelay"; Loading @@ -1445,7 +1447,10 @@ void btif_storage_add_hearing_aid(const HearingDevice& dev_info) { [](const HearingDevice& dev_info) { std::string bdstr = dev_info.address.ToString(); VLOG(2) << "saving hearing aid device: " << bdstr; btif_config_set_int(bdstr, HEARING_AID_PSM, dev_info.psm); btif_config_set_int(bdstr, HEARING_AID_SERVICE_CHANGED_CCC_HANDLE, dev_info.service_changed_ccc_handle); btif_config_set_int(bdstr, HEARING_AID_READ_PSM_HANDLE, dev_info.read_psm_handle); btif_config_set_int(bdstr, HEARING_AID_CAPABILITIES, dev_info.capabilities); btif_config_set_int(bdstr, HEARING_AID_CODECS, dev_info.codecs); Loading Loading @@ -1477,11 +1482,26 @@ void btif_storage_load_bonded_hearing_aids() { const std::string& name = section.name; if (!RawAddress::IsValidAddress(name)) continue; BTIF_TRACE_DEBUG("Remote device:%s", name.c_str()); int size = STORAGE_UUID_STRING_SIZE * HEARINGAID_MAX_NUM_UUIDS; char uuid_str[size]; bool isHearingaidDevice = false; if (btif_config_get_str(name, BTIF_STORAGE_PATH_REMOTE_SERVICE, uuid_str, &size)) { Uuid p_uuid[HEARINGAID_MAX_NUM_UUIDS]; size_t num_uuids = btif_split_uuids_string(uuid_str, p_uuid, HEARINGAID_MAX_NUM_UUIDS); for (size_t i = 0; i < num_uuids; i++) { if (p_uuid[i] == Uuid::FromString("FDF0")) { isHearingaidDevice = true; break; } } } if (!isHearingaidDevice) { continue; } int value; if (!btif_config_get_int(name, HEARING_AID_PSM, &value)) continue; uint16_t psm = value; BTIF_TRACE_DEBUG("Remote device:%s", name.c_str()); if (btif_in_fetch_bonded_device(name) != BT_STATUS_SUCCESS) { RawAddress bd_addr; Loading @@ -1490,6 +1510,7 @@ void btif_storage_load_bonded_hearing_aids() { continue; } int value; uint8_t capabilities = 0; if (btif_config_get_int(name, HEARING_AID_CAPABILITIES, &value)) capabilities = value; Loading @@ -1509,10 +1530,19 @@ void btif_storage_load_bonded_hearing_aids() { if (btif_config_get_int(name, HEARING_AID_AUDIO_STATUS_CCC_HANDLE, &value)) audio_status_ccc_handle = value; uint16_t service_changed_ccc_handle = 0; if (btif_config_get_int(name, HEARING_AID_SERVICE_CHANGED_CCC_HANDLE, &value)) service_changed_ccc_handle = value; uint16_t volume_handle = 0; if (btif_config_get_int(name, HEARING_AID_VOLUME_HANDLE, &value)) volume_handle = value; uint16_t read_psm_handle = 0; if (btif_config_get_int(name, HEARING_AID_READ_PSM_HANDLE, &value)) read_psm_handle = value; uint64_t lvalue; uint64_t hi_sync_id = 0; if (btif_config_get_uint64(name, HEARING_AID_SYNC_ID, &lvalue)) Loading @@ -1537,9 +1567,10 @@ void btif_storage_load_bonded_hearing_aids() { do_in_main_thread( FROM_HERE, Bind(&HearingAid::AddFromStorage, HearingDevice(bd_addr, psm, capabilities, codecs, HearingDevice(bd_addr, capabilities, codecs, audio_control_point_handle, audio_status_handle, audio_status_ccc_handle, volume_handle, hi_sync_id, audio_status_ccc_handle, service_changed_ccc_handle, volume_handle, read_psm_handle, hi_sync_id, render_delay, preparation_delay), is_white_listed)); } Loading @@ -1548,13 +1579,17 @@ void btif_storage_load_bonded_hearing_aids() { /** Deletes the bonded hearing aid device info from NVRAM */ void btif_storage_remove_hearing_aid(const RawAddress& address) { std::string addrstr = address.ToString(); btif_config_remove(addrstr, HEARING_AID_PSM); btif_config_remove(addrstr, HEARING_AID_READ_PSM_HANDLE); btif_config_remove(addrstr, HEARING_AID_CAPABILITIES); btif_config_remove(addrstr, HEARING_AID_CODECS); btif_config_remove(addrstr, HEARING_AID_AUDIO_CONTROL_POINT); btif_config_remove(addrstr, HEARING_AID_VOLUME_HANDLE); btif_config_remove(addrstr, HEARING_AID_AUDIO_STATUS_HANDLE); btif_config_remove(addrstr, HEARING_AID_AUDIO_STATUS_CCC_HANDLE); btif_config_remove(addrstr, HEARING_AID_SERVICE_CHANGED_CCC_HANDLE); btif_config_remove(addrstr, HEARING_AID_SYNC_ID); btif_config_remove(addrstr, HEARING_AID_RENDER_DELAY); btif_config_remove(addrstr, HEARING_AID_PREPARATION_DELAY); btif_config_remove(addrstr, HEARING_AID_IS_WHITE_LISTED); btif_config_save(); } Loading