From 40f8d8f21f6e40da7dc986a8b1f082cc8fba9f10 Mon Sep 17 00:00:00 2001 From: Matthias Ringwald Date: Mon, 5 Jun 2023 16:16:57 +0200 Subject: [PATCH] att_server: add att_server_multiple_notify --- src/ble/att_server.c | 60 ++++++++++++++++++++++++++++++++++++++++++++ src/ble/att_server.h | 12 +++++++++ 2 files changed, 72 insertions(+) diff --git a/src/ble/att_server.c b/src/ble/att_server.c index ea7c61df0..75bdc2845 100644 --- a/src/ble/att_server.c +++ b/src/ble/att_server.c @@ -120,6 +120,7 @@ typedef struct { uint8_t * receive_buffer; uint8_t * send_buffer; } att_server_eatt_bearer_t; +static att_server_eatt_bearer_t * att_server_eatt_bearer_for_con_handle(hci_con_handle_t con_handle); static btstack_linked_list_t att_server_eatt_bearer_pool; static btstack_linked_list_t att_server_eatt_bearer_active; #endif @@ -560,6 +561,7 @@ att_server_send_prepared(const att_server_t *att_server, const att_connection_t switch (att_server->bearer_type) { case ATT_BEARER_UNENHANCED_LE: status = l2cap_send_prepared_connectionless(att_connection->con_handle, L2CAP_CID_ATTRIBUTE_PROTOCOL, size); + break; #ifdef ENABLE_GATT_OVER_CLASSIC case ATT_BEARER_UNENHANCED_CLASSIC: status = l2cap_send_prepared(att_server->l2cap_cid, size); @@ -1359,6 +1361,52 @@ uint8_t att_server_notify(hci_con_handle_t con_handle, uint16_t attribute_handle return att_server_send_prepared(att_server, att_connection, NULL, size); } +/** + * @brief notify client about multiple attribute value changes + * @param con_handle + * @param num_attributes + * @param attribute_handles[] + * @param values_data[] + * @param values_len[] + * @return 0 if ok, error otherwise + */ +uint8_t att_server_multiple_notify(hci_con_handle_t con_handle, uint8_t num_attributes, + const uint16_t * attribute_handles, const uint8_t ** values_data, const uint16_t * values_len){ + + att_server_t * att_server = NULL; + att_connection_t * att_connection = NULL; + uint8_t * packet_buffer = NULL; + + // prfer enhanced bearer +#ifdef ENABLE_GATT_OVER_EATT + att_server_eatt_bearer_t * eatt_bearer = att_server_eatt_bearer_for_con_handle(con_handle); + if (eatt_bearer != NULL){ + att_server = &eatt_bearer->att_server; + att_connection = &eatt_bearer->att_connection; + packet_buffer = eatt_bearer->send_buffer; + } else +#endif + { + hci_connection_t *hci_connection = hci_connection_for_handle(con_handle); + if (hci_connection != NULL) { + att_server = &hci_connection->att_server; + att_connection = &hci_connection->att_connection; + } + } + + if (att_server == NULL) return ERROR_CODE_UNKNOWN_CONNECTION_IDENTIFIER; + if (!att_server_can_send_packet(att_server, att_connection)) return BTSTACK_ACL_BUFFERS_FULL; + + if (packet_buffer == NULL){ + l2cap_reserve_packet_buffer(); + packet_buffer = l2cap_get_outgoing_buffer(); + } + + uint16_t size = att_prepare_handle_value_multiple_notification(att_connection, num_attributes, attribute_handles, values_data, values_len, packet_buffer); + + return att_server_send_prepared(att_server, att_connection, packet_buffer, size); +} + uint8_t att_server_indicate(hci_con_handle_t con_handle, uint16_t attribute_handle, const uint8_t *value, uint16_t value_len){ hci_connection_t * hci_connection = hci_connection_for_handle(con_handle); if (!hci_connection) return ERROR_CODE_UNKNOWN_CONNECTION_IDENTIFIER; @@ -1414,6 +1462,18 @@ static att_server_eatt_bearer_t * att_server_eatt_bearer_for_cid(uint16_t cid){ return NULL; } +static att_server_eatt_bearer_t * att_server_eatt_bearer_for_con_handle(hci_con_handle_t con_handle){ + btstack_linked_list_iterator_t it; + btstack_linked_list_iterator_init(&it, &att_server_eatt_bearer_active); + while(btstack_linked_list_iterator_has_next(&it)){ + att_server_eatt_bearer_t * eatt_bearer = (att_server_eatt_bearer_t *) btstack_linked_list_iterator_next(&it); + if (eatt_bearer->att_connection.con_handle == con_handle) { + return eatt_bearer; + } + } + return NULL; +} + static void att_server_eatt_handler(uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size){ uint16_t cid; uint8_t status; diff --git a/src/ble/att_server.h b/src/ble/att_server.h index 52643257d..626aa284c 100644 --- a/src/ble/att_server.h +++ b/src/ble/att_server.h @@ -130,6 +130,18 @@ uint8_t att_server_request_to_send_indication(btstack_context_callback_registrat */ uint8_t att_server_notify(hci_con_handle_t con_handle, uint16_t attribute_handle, const uint8_t *value, uint16_t value_len); +/** + * @brief notify client about multiple attribute value changes + * @param con_handle + * @param num_attributes + * @param attribute_handles[] + * @param values_data[] + * @param values_len[] + * @return 0 if ok, error otherwise + */ +uint8_t att_server_multiple_notify(hci_con_handle_t con_handle, uint8_t num_attributes, + const uint16_t * attribute_handles, const uint8_t ** values_data, const uint16_t * values_len); + /** * @brief indicate value change to client. client is supposed to reply with an indication_response * @param con_handle