From 1d3c1f7fa08e9939ba4288001f77d87257e587fd Mon Sep 17 00:00:00 2001 From: Matthias Ringwald Date: Wed, 25 Sep 2024 15:58:52 +0200 Subject: [PATCH] gatt-service/dis-client: update for dis v1.2 --- CHANGELOG.md | 2 + .../device_information_service_client.c | 58 +++++++++++++++++-- .../device_information_service_client.h | 4 +- 3 files changed, 57 insertions(+), 7 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index e7424669a..7086bf67a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -48,6 +48,8 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0. - GOEP Client: remove goep_client_create_connection. Use goep_client_connect instead. - HID Parser: cleanup of function names and signatures - HIDS Client: use error code instead of att status in conencted event +- Device Information Service Server: update for v1.2 +- Device Information Service Client: update for v1.2 ## Release v1.6.1 diff --git a/src/ble/gatt-service/device_information_service_client.c b/src/ble/gatt-service/device_information_service_client.c index 6b4a32fad..193162ea0 100644 --- a/src/ble/gatt-service/device_information_service_client.c +++ b/src/ble/gatt-service/device_information_service_client.c @@ -84,6 +84,9 @@ typedef struct { uint8_t characteristic_index; } device_information_service_client_t; + +static btstack_context_callback_registration_t device_information_service_handle_can_send_now; + static device_information_service_client_t device_information_service_client; static void handle_gatt_client_event(uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size); @@ -91,6 +94,7 @@ static void device_information_service_emit_string_value(device_information_serv static void device_information_service_emit_system_id(device_information_service_client_t * client, uint8_t subevent, uint8_t att_status, const uint8_t * value, uint16_t value_len); static void device_information_service_emit_certification_data_list(device_information_service_client_t * client, uint8_t subevent, uint8_t att_status, const uint8_t * value, uint16_t value_len); static void device_information_service_emit_pnp_id(device_information_service_client_t * client, uint8_t subevent, uint8_t att_status, const uint8_t * value, uint16_t value_len); +static void device_information_service_emit_udi_for_medical_devices(device_information_service_client_t * client, uint8_t subevent, uint8_t att_status, const uint8_t * value, uint16_t value_len); // list of uuids and how they are reported as events static const struct device_information_characteristic { @@ -107,9 +111,21 @@ static const struct device_information_characteristic { {ORG_BLUETOOTH_CHARACTERISTIC_SYSTEM_ID, GATTSERVICE_SUBEVENT_DEVICE_INFORMATION_SYSTEM_ID, device_information_service_emit_system_id}, {ORG_BLUETOOTH_CHARACTERISTIC_IEEE_11073_20601_REGULATORY_CERTIFICATION_DATA_LIST, GATTSERVICE_SUBEVENT_DEVICE_INFORMATION_IEEE_REGULATORY_CERTIFICATION, device_information_service_emit_certification_data_list}, - {ORG_BLUETOOTH_CHARACTERISTIC_PNP_ID, GATTSERVICE_SUBEVENT_DEVICE_INFORMATION_PNP_ID, device_information_service_emit_pnp_id} + {ORG_BLUETOOTH_CHARACTERISTIC_PNP_ID, GATTSERVICE_SUBEVENT_DEVICE_INFORMATION_PNP_ID, device_information_service_emit_pnp_id}, + {ORG_BLUETOOTH_CHARACTERISTIC_UDI_FOR_MEDICAL_DEVICES, GATTSERVICE_SUBEVENT_DEVICE_INFORMATION_UDI_FOR_MEDICAL_DEVICES, device_information_service_emit_udi_for_medical_devices} }; +static uint8_t device_informatiom_client_request_send_gatt_query(device_information_service_client_t * client){ + uint8_t status = gatt_client_request_to_send_gatt_query(&device_information_service_handle_can_send_now, client->con_handle); + if (status != ERROR_CODE_SUCCESS){ + if (client->state >= DEVICE_INFORMATION_SERVICE_CLIENT_STATE_W2_QUERY_SERVICE){ + client->state = DEVICE_INFORMATION_SERVICE_CLIENT_STATE_IDLE; + } + + } + return status; +} + #ifdef ENABLE_TESTING_SUPPORT static struct device_information_characteristic_handles{ uint16_t uuid; @@ -169,6 +185,10 @@ static char * device_information_characteristic_name(uint16_t uuid){ case ORG_BLUETOOTH_CHARACTERISTIC_PNP_ID: return "PNP_ID"; + + case ORG_BLUETOOTH_CHARACTERISTIC_UDI_FOR_MEDICAL_DEVICES: + return "ORG_BLUETOOTH_CHARACTERISTIC_UDI_FOR_MEDICAL_DEVICES"; + default: return "UKNOWN"; } @@ -282,8 +302,34 @@ static void device_information_service_emit_pnp_id(device_information_service_cl (*client->client_handler)(HCI_EVENT_PACKET, 0, event, pos); } +static void device_information_service_emit_udi_for_medical_devices(device_information_service_client_t * client, uint8_t subevent, uint8_t att_status, const uint8_t * value, uint16_t value_len){ + uint16_t max_udi_length = 1 + 4 * DEVICE_INFORMATION_MAX_STRING_LEN; + + if (value_len > max_udi_length) return; + + uint8_t event[6 + 1 + 4 * DEVICE_INFORMATION_MAX_STRING_LEN]; + uint16_t pos = 0; + event[pos++] = HCI_EVENT_GATTSERVICE_META; + event[pos++] = sizeof(event) - 2; + event[pos++] = subevent; + little_endian_store_16(event, pos, client->con_handle); + pos += 2; + event[pos++] = att_status; + memcpy(event + pos, value, value_len); + pos += value_len; + + (*client->client_handler)(HCI_EVENT_PACKET, 0, event, pos); +} + + +static void device_information_service_send_next_query(void * context){ + UNUSED(context); + device_information_service_client_t * client = device_information_service_client_get_client(); + + if (client == NULL){ + return; + } -static void device_information_service_run_for_client(device_information_service_client_t * client){ uint8_t att_status; switch (client->state){ @@ -440,10 +486,9 @@ static void handle_gatt_client_event(uint8_t packet_type, uint16_t channel, uint break; } - if (client != NULL){ - device_information_service_run_for_client(client); + if (client && client->state != DEVICE_INFORMATION_SERVICE_CLIENT_STATE_IDLE){ + device_informatiom_client_request_send_gatt_query(client); } - } uint8_t device_information_service_client_query(hci_con_handle_t con_handle, btstack_packet_handler_t packet_handler){ @@ -464,7 +509,7 @@ uint8_t device_information_service_client_query(hci_con_handle_t con_handle, bts client->client_handler = packet_handler; client->state = DEVICE_INFORMATION_SERVICE_CLIENT_STATE_W2_QUERY_SERVICE; - device_information_service_run_for_client(client); + device_informatiom_client_request_send_gatt_query(client); return ERROR_CODE_SUCCESS; } @@ -472,6 +517,7 @@ uint8_t device_information_service_client_query(hci_con_handle_t con_handle, bts void device_information_service_client_init(void){ device_information_service_client_t * client = device_information_service_client_get_client(); device_information_service_finalize_client(client); + device_information_service_handle_can_send_now.callback = &device_information_service_send_next_query; } void device_information_service_client_deinit(void){} diff --git a/src/ble/gatt-service/device_information_service_client.h b/src/ble/gatt-service/device_information_service_client.h index 03affd871..ce58151fd 100644 --- a/src/ble/gatt-service/device_information_service_client.h +++ b/src/ble/gatt-service/device_information_service_client.h @@ -63,6 +63,7 @@ extern "C" { * - system ID * - IEEE regulatory certification * - PNP ID + * - UDI for medical devices */ /* API_START */ @@ -83,7 +84,8 @@ void device_information_service_client_init(void); * - GATTSERVICE_SUBEVENT_DEVICE_INFORMATION_SOFTWARE_REVISION * - GATTSERVICE_SUBEVENT_DEVICE_INFORMATION_SYSTEM_ID * - GATTSERVICE_SUBEVENT_DEVICE_INFORMATION_IEEE_REGULATORY_CERTIFICATION - * - GATTSERVICE_SUBEVENT_DEVICE_INFORMATION_PNP_ID + * - GATTSERVICE_SUBEVENT_DEVICE_INFORMATION_PNP_ID + * - GATTSERVICE_SUBEVENT_DEVICE_INFORMATION_UDI_FOR_MEDICAL_DEVICES * * Event GATTSERVICE_SUBEVENT_DEVICE_INFORMATION_DONE is received when all queries are done, of if service was not found. * The status field of this event indicated ATT errors (see bluetooth.h).