From f107e4f9e841152e5b94fa2f9d68c558d8c1b055 Mon Sep 17 00:00:00 2001 From: Jakub Pawlowski Date: Thu, 12 Apr 2018 05:42:31 -0700 Subject: [PATCH] GATT: fix 32 bit UUID handling When writing UUID into stream with gatt_build_uuid_to_stream, we always use 16bit or 128bit representation. In GATT code returning service UUID, we were returning 32bit representation lenght, even though 128bit representation was being returned in the stream. This resulted in invalid GATT database content being returned, and the service not being visible. Bug: 66912853 Test: create GATT database with 32bit UUID, discover from remote device Change-Id: I791a518ab080bd99db0a8be18d97e865c838fc7e --- stack/gatt/gatt_db.cc | 10 +++++----- stack/gatt/gatt_int.h | 1 + stack/gatt/gatt_sr.cc | 2 +- stack/gatt/gatt_utils.cc | 8 ++++++++ 4 files changed, 15 insertions(+), 6 deletions(-) diff --git a/stack/gatt/gatt_db.cc b/stack/gatt/gatt_db.cc index 8c334539e..31a262d4f 100644 --- a/stack/gatt/gatt_db.cc +++ b/stack/gatt/gatt_db.cc @@ -148,13 +148,13 @@ static tGATT_STATUS gatts_check_attr_readability(const tGATT_ATTR& attr, * * Description Utility function to read an attribute value. * - * Parameter p_attr: pointer to the attribute to read. + * Parameter attr16: pointer to the attribute to read. * offset: read offset. - * p_value: output parameter to carry out the attribute value. - * p_len: output parameter to carry out the attribute length. + * p_data: output parameter to carry out the attribute value. * read_long: this is a read blob request. * mtu: MTU - * sec_flag: current link security status. + * p_len: output parameter to carry out the attribute length. + * sec_flag: current link security status. * key_size: encryption key size. * * Returns status of operation. @@ -182,7 +182,7 @@ static tGATT_STATUS read_attr_value(tGATT_ATTR& attr16, uint16_t offset, uint16_t uuid16 = attr16.uuid.As16Bit(); if (uuid16 == GATT_UUID_PRI_SERVICE || uuid16 == GATT_UUID_SEC_SERVICE) { - *p_len = attr16.p_value->uuid.GetShortestRepresentationSize(); + *p_len = gatt_build_uuid_to_stream_len(attr16.p_value->uuid); if (mtu < *p_len) return GATT_NO_RESOURCES; gatt_build_uuid_to_stream(&p, attr16.p_value->uuid); diff --git a/stack/gatt/gatt_int.h b/stack/gatt/gatt_int.h index a542b051e..50529188d 100644 --- a/stack/gatt/gatt_int.h +++ b/stack/gatt/gatt_int.h @@ -436,6 +436,7 @@ extern uint32_t gatt_add_sdp_record(const bluetooth::Uuid& uuid, uint16_t start_hdl, uint16_t end_hdl); extern bool gatt_parse_uuid_from_cmd(bluetooth::Uuid* p_uuid, uint16_t len, uint8_t** p_data); +extern uint8_t gatt_build_uuid_to_stream_len(const bluetooth::Uuid& uuid); extern uint8_t gatt_build_uuid_to_stream(uint8_t** p_dst, const bluetooth::Uuid& uuid); extern void gatt_sr_get_sec_info(const RawAddress& rem_bda, diff --git a/stack/gatt/gatt_sr.cc b/stack/gatt/gatt_sr.cc index 877a88149..d71b60da2 100644 --- a/stack/gatt/gatt_sr.cc +++ b/stack/gatt/gatt_sr.cc @@ -459,7 +459,7 @@ static tGATT_STATUS gatt_build_primary_service_rsp( if (!p_uuid) continue; if (op_code == GATT_REQ_READ_BY_GRP_TYPE) - handle_len = 4 + p_uuid->GetShortestRepresentationSize(); + handle_len = 4 + gatt_build_uuid_to_stream_len(*p_uuid); /* get the length byte in the repsonse */ if (p_msg->offset == 0) { diff --git a/stack/gatt/gatt_utils.cc b/stack/gatt/gatt_utils.cc index fd2762186..9fa48f8bf 100644 --- a/stack/gatt/gatt_utils.cc +++ b/stack/gatt/gatt_utils.cc @@ -453,6 +453,14 @@ tGATT_TCB* gatt_allocate_tcb_by_bdaddr(const RawAddress& bda, return NULL; } +/** gatt_build_uuid_to_stream will convert 32bit UUIDs to 128bit. This function + * will return lenght required to build uuid, either |UUID:kNumBytes16| or + * |UUID::kNumBytes128| */ +uint8_t gatt_build_uuid_to_stream_len(const Uuid& uuid) { + size_t len = uuid.GetShortestRepresentationSize(); + return len == Uuid::kNumBytes32 ? Uuid::kNumBytes128 : len; +} + /** Add UUID into stream. Returns UUID length. */ uint8_t gatt_build_uuid_to_stream(uint8_t** p_dst, const Uuid& uuid) { uint8_t* p = *p_dst; -- 2.11.0