mirror of
https://github.com/bluekitchen/btstack.git
synced 2025-02-09 12:39:56 +00:00
att: ENABLE_ATT_DELAYED_READ_RESPONSE -> ENABLE_ATT_DELAYED_RESPONSE, example/att_delayed_read_response.c -> example/att_delayed_response.c
This commit is contained in:
parent
1cd21c0571
commit
beb202884a
@ -85,7 +85,7 @@ ENABLE_MICRO_ECC_FOR_LE_SECURE_CONNECTIONS | Use [micro-ecc library](https://git
|
||||
ENABLE_LE_DATA_CHANNELS | Enable LE Data Channels in credit-based flow control mode
|
||||
ENABLE_LE_DATA_LENGTH_EXTENSION | Enable LE Data Length Extension support
|
||||
ENABLE_LE_SIGNED_WRITE | Enable LE Signed Writes in ATT/GATT
|
||||
ENABLE_ATT_DELAYED_READ_RESPONSE | Enable support for delayed ATT Read operations, see [GATT Server](profiles/#sec:GATTServerProfile)
|
||||
ENABLE_ATT_DELAYED_RESPONSE | Enable support for delayed ATT operations, see [GATT Server](profiles/#sec:GATTServerProfile)
|
||||
ENABLE_L2CAP_ENHANCED_RETRANSMISSION_MODE | Enable L2CAP Enhanced Retransmission Mode. Mandatory for AVRCP Browsing
|
||||
ENABLE_HCI_CONTROLLER_TO_HOST_FLOW_CONTROL | Enable HCI Controller to Host Flow Control, see below
|
||||
ENABLE_CC256X_BAUDRATE_CHANGE_FLOWCONTROL_BUG_WORKAROUND | Enable workaround for bug in CC256x Flow Control during baud rate change, see chipset docs.
|
||||
|
@ -469,7 +469,7 @@ To send a Notification, you can call *att_server_request_can_send_now*
|
||||
to receive a ATT_EVENT_CAN_SEND_NOW event.
|
||||
|
||||
If your application cannot handle an ATT Read Request in the *att_read_callback*
|
||||
in some situations, you can enable support for this by adding ENABLE_ATT_DELAYED_READ_RESPONSE
|
||||
in some situations, you can enable support for this by adding ENABLE_ATT_DELAYED_RESPONSE
|
||||
to *btstack_config.h*. Now, you can store the requested attribute handle and return
|
||||
*ATT_READ_RESPONSE_PENDING* instead of the length of the provided data when you don't have the data ready.
|
||||
For ATT operations that read more than one attribute, your *att_read_callback*
|
||||
@ -477,7 +477,7 @@ might get called multiple times as well. To let you know that all necessary
|
||||
attribute handles have been 'requested' by the *att_server*, you'll get a final
|
||||
*att_read_callback* with the attribute handle of *ATT_READ_RESPONSE_PENDING*.
|
||||
When you've got the data for all requested attributes ready, you can call
|
||||
*att_server_read_response_ready*, which will trigger processing of the current request.
|
||||
*att_server_response_ready*, which will trigger processing of the current request.
|
||||
Please keep in mind that there is only one active ATT operation and that it has a 30 second
|
||||
timeout after which the ATT server is considered defunct by the GATT Client.
|
||||
|
||||
|
@ -108,7 +108,7 @@ HXCMOD_PLAYER = \
|
||||
${BTSTACK_ROOT}/3rd-party/hxcmod-player/mods/nao-deceased_by_disease.c \
|
||||
|
||||
EXAMPLES = \
|
||||
att_delayed_read_response \
|
||||
att_delayed_response \
|
||||
a2dp_sink_demo \
|
||||
a2dp_source_demo \
|
||||
ancs_client_demo \
|
||||
@ -207,8 +207,8 @@ spp_counter: ${CORE_OBJ} ${COMMON_OBJ} ${CLASSIC_OBJ} spp_counter.c
|
||||
le_counter: le_counter.h ${CORE_OBJ} ${COMMON_OBJ} ${ATT_OBJ} ${GATT_SERVER_OBJ} ${SM_OBJ} battery_service_server.o le_counter.c
|
||||
${CC} $(filter-out le_counter.h,$^) ${CFLAGS} ${LDFLAGS} -o $@
|
||||
|
||||
att_delayed_read_response: att_delayed_read_response.h ${CORE_OBJ} ${COMMON_OBJ} ${ATT_OBJ} ${GATT_SERVER_OBJ} ${SM_OBJ} att_delayed_read_response.c
|
||||
${CC} $(filter-out att_delayed_read_response.h,$^) ${CFLAGS} ${LDFLAGS} -o $@
|
||||
att_delayed_response: att_delayed_response.h ${CORE_OBJ} ${COMMON_OBJ} ${ATT_OBJ} ${GATT_SERVER_OBJ} ${SM_OBJ} att_delayed_response.c
|
||||
${CC} $(filter-out att_delayed_response.h,$^) ${CFLAGS} ${LDFLAGS} -o $@
|
||||
|
||||
hog_keyboard_demo: hog_keyboard_demo.h ${CORE_OBJ} ${COMMON_OBJ} ${ATT_OBJ} ${GATT_SERVER_OBJ} ${SM_OBJ} battery_service_server.o device_information_service_server.o hids_device.o btstack_ring_buffer.o hog_keyboard_demo.c
|
||||
${CC} $(filter-out hog_keyboard_demo.h,$^) ${CFLAGS} ${LDFLAGS} -o $@
|
||||
|
@ -1,10 +0,0 @@
|
||||
PRIMARY_SERVICE, GAP_SERVICE
|
||||
CHARACTERISTIC, GAP_DEVICE_NAME, READ, "LE Counter"
|
||||
|
||||
PRIMARY_SERVICE, GATT_SERVICE
|
||||
CHARACTERISTIC, GATT_SERVICE_CHANGED, READ,
|
||||
|
||||
// Counter Service
|
||||
PRIMARY_SERVICE, 0000FF10-0000-1000-8000-00805F9B34FB
|
||||
// Counter Characteristic, with read and notify
|
||||
CHARACTERISTIC, 0000FF11-0000-1000-8000-00805F9B34FB, READ | NOTIFY | DYNAMIC,
|
@ -35,14 +35,18 @@
|
||||
*
|
||||
*/
|
||||
|
||||
#define __BTSTACK_FILE__ "att_delayed_read_response.c"
|
||||
#define __BTSTACK_FILE__ "att_delayed_response.c"
|
||||
|
||||
// *****************************************************************************
|
||||
/* EXAMPLE_START(att_delayed_read_response): LE Peripheral - Delayed Read Response
|
||||
/* EXAMPLE_START(att_delayed_response): LE Peripheral - Delayed Response
|
||||
*
|
||||
* @text If the value for a GATT Chararacteristic isn't available, the value
|
||||
* ATT_READ_RESPONSE_PENDING can be returned. When the value is available,
|
||||
* att_server_read_response_ready is then called to complete the ATT request.
|
||||
* @text If the value for a GATT Chararacteristic isn't availabl for read,
|
||||
* the value ATT_READ_RESPONSE_PENDING can be returned. When the value is available,
|
||||
* att_server_response_ready is then called to complete the ATT request.
|
||||
*
|
||||
* Similarly, the error code ATT_ERROR_WRITE_RESPONSE_PENING can be returned when
|
||||
* it is unclear if a write can be performed or not. When the decision was made,
|
||||
* att_server_response_ready is is then called to complete the ATT request.
|
||||
*/
|
||||
// *****************************************************************************
|
||||
|
||||
@ -51,7 +55,7 @@
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "att_delayed_read_response.h"
|
||||
#include "att_delayed_response.h"
|
||||
#include "btstack.h"
|
||||
|
||||
#define ATT_VALUE_DELAY_MS 3000
|
||||
@ -69,19 +73,20 @@
|
||||
*/
|
||||
|
||||
/* LISTING_START(MainConfiguration): Init L2CAP SM ATT Server */
|
||||
#ifdef ENABLE_ATT_DELAYED_READ_RESPONSE
|
||||
#ifdef ENABLE_ATT_DELAYED_RESPONSE
|
||||
static btstack_timer_source_t att_timer;
|
||||
static hci_con_handle_t con_handle;
|
||||
static int value_ready;
|
||||
#endif
|
||||
|
||||
static uint16_t att_read_callback(hci_con_handle_t con_handle, uint16_t att_handle, uint16_t offset, uint8_t * buffer, uint16_t buffer_size);
|
||||
static int att_write_callback(hci_con_handle_t connection_handle, uint16_t att_handle, uint16_t transaction_mode, uint16_t offset, uint8_t *buffer, uint16_t buffer_size);
|
||||
|
||||
const uint8_t adv_data[] = {
|
||||
// Flags general discoverable, BR/EDR not supported
|
||||
0x02, 0x01, 0x06,
|
||||
// Name
|
||||
0x0b, 0x09, 'L', 'E', ' ', 'C', 'o', 'u', 'n', 't', 'e', 'r',
|
||||
0x08, 0x09, 'D', 'e', 'l', 'a', 'y', 'e', 'd',
|
||||
};
|
||||
const uint8_t adv_data_len = sizeof(adv_data);
|
||||
|
||||
@ -98,7 +103,7 @@ static void example_setup(void){
|
||||
sm_init();
|
||||
|
||||
// setup ATT server
|
||||
att_server_init(profile_data, att_read_callback, NULL);
|
||||
att_server_init(profile_data, att_read_callback, att_write_callback);
|
||||
|
||||
// setup advertisements
|
||||
uint16_t adv_int_min = 0x0030;
|
||||
@ -117,7 +122,7 @@ static void example_setup(void){
|
||||
*
|
||||
* @text The att_invalidate_value handler 'invalidates' the value of the single Characteristic provided in this example
|
||||
*/
|
||||
#ifdef ENABLE_ATT_DELAYED_READ_RESPONSE
|
||||
#ifdef ENABLE_ATT_DELAYED_RESPONSE
|
||||
static void att_invalidate_value(struct btstack_timer_source *ts){
|
||||
UNUSED(ts);
|
||||
printf("Value got stale\n");
|
||||
@ -132,14 +137,13 @@ static void att_invalidate_value(struct btstack_timer_source *ts){
|
||||
*/
|
||||
|
||||
/* LISTING_START(att_read_delay): ATT Read Delay Handler */
|
||||
#ifdef ENABLE_ATT_DELAYED_READ_RESPONSE
|
||||
#ifdef ENABLE_ATT_DELAYED_RESPONSE
|
||||
static void att_update_value(struct btstack_timer_source *ts){
|
||||
UNUSED(ts);
|
||||
value_ready = 1;
|
||||
|
||||
|
||||
// trigger ATT Server to try request again
|
||||
int status = att_server_read_response_ready(con_handle);
|
||||
int status = att_server_response_ready(con_handle);
|
||||
|
||||
printf("Value updated -> complete ATT request - status %02x\n", status);
|
||||
|
||||
@ -169,7 +173,7 @@ static void att_update_value(struct btstack_timer_source *ts){
|
||||
// @param offset defines start of attribute value
|
||||
static uint16_t att_read_callback(hci_con_handle_t connection_handle, uint16_t att_handle, uint16_t offset, uint8_t * buffer, uint16_t buffer_size){
|
||||
|
||||
#ifdef ENABLE_ATT_DELAYED_READ_RESPONSE
|
||||
#ifdef ENABLE_ATT_DELAYED_RESPONSE
|
||||
switch (att_handle){
|
||||
case ATT_CHARACTERISTIC_0000FF11_0000_1000_8000_00805F9B34FB_01_VALUE_HANDLE:
|
||||
if (value_ready){
|
||||
@ -193,15 +197,50 @@ static uint16_t att_read_callback(hci_con_handle_t connection_handle, uint16_t a
|
||||
}
|
||||
#else
|
||||
UNUSED(connection_handle);
|
||||
// useless code when ENABLE_ATT_DELAYED_READ_RESPONSE is not defined - but avoids built errors
|
||||
// useless code when ENABLE_ATT_DELAYED_RESPONSE is not defined - but avoids built errors
|
||||
if (att_handle == ATT_CHARACTERISTIC_0000FF11_0000_1000_8000_00805F9B34FB_01_VALUE_HANDLE){
|
||||
printf("ENABLE_ATT_DELAYED_READ_RESPONSE not defined in btstack_config.h, responding right away");
|
||||
printf("ENABLE_ATT_DELAYED_RESPONSE not defined in btstack_config.h, responding right away");
|
||||
return att_read_callback_handle_blob((const uint8_t *)test_string, strlen(test_string), offset, buffer, buffer_size);
|
||||
}
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* @section ATT Write
|
||||
* */
|
||||
|
||||
/* LISTING_START(attWrite): ATT Write */
|
||||
static int att_write_callback(hci_con_handle_t connection_handle, uint16_t att_handle, uint16_t transaction_mode, uint16_t offset, uint8_t *buffer, uint16_t buffer_size){
|
||||
UNUSED(transaction_mode);
|
||||
UNUSED(offset);
|
||||
UNUSED(buffer_size);
|
||||
UNUSED(connection_handle);
|
||||
|
||||
if (att_handle == ATT_CHARACTERISTIC_0000FF11_0000_1000_8000_00805F9B34FB_01_VALUE_HANDLE) {
|
||||
printf("Write request, value: ");
|
||||
printf_hexdump(buffer, buffer_size);
|
||||
#ifdef ENABLE_ATT_DELAYED_RESPONSE
|
||||
if (value_ready){
|
||||
printf("Write callback, value ready\n");
|
||||
return 0;
|
||||
} else {
|
||||
printf("Write callback for handle %02x, but not ready -> return response pending\n", att_handle);
|
||||
}
|
||||
// simulated delayed response for example
|
||||
att_timer.process = &att_update_value;
|
||||
btstack_run_loop_set_timer(&att_timer, ATT_VALUE_DELAY_MS);
|
||||
btstack_run_loop_add_timer(&att_timer);
|
||||
return ATT_ERROR_WRITE_RESPONSE_PENDING;
|
||||
#else
|
||||
printf("ENABLE_ATT_DELAYED_RESPONSE not defined in btstack_config.h, responding right away");
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* LISTING_END */
|
||||
|
||||
int btstack_main(void);
|
10
example/att_delayed_response.gatt
Normal file
10
example/att_delayed_response.gatt
Normal file
@ -0,0 +1,10 @@
|
||||
PRIMARY_SERVICE, GAP_SERVICE
|
||||
CHARACTERISTIC, GAP_DEVICE_NAME, READ, "Delayed Response"
|
||||
|
||||
PRIMARY_SERVICE, GATT_SERVICE
|
||||
CHARACTERISTIC, GATT_SERVICE_CHANGED, READ,
|
||||
|
||||
// Some Service
|
||||
PRIMARY_SERVICE, 0000FF10-0000-1000-8000-00805F9B34FB
|
||||
// Some Characteristic, with read and write
|
||||
CHARACTERISTIC, 0000FF11-0000-1000-8000-00805F9B34FB, READ | WRITE | DYNAMIC,
|
5
port/libusb/.gitignore
vendored
5
port/libusb/.gitignore
vendored
@ -61,6 +61,5 @@ spp_and_le_streamer.h
|
||||
spp_counter
|
||||
spp_streamer
|
||||
spp_streamer_client
|
||||
spp_streamer_client
|
||||
att_delayed_read_response
|
||||
att_delayed_read_response.h
|
||||
att_delayed_response
|
||||
att_delayed_response.h
|
||||
|
@ -21,7 +21,7 @@
|
||||
#define ENABLE_LE_DATA_CHANNELS
|
||||
#define ENABLE_MICRO_ECC_FOR_LE_SECURE_CONNECTIONS
|
||||
#define ENABLE_LE_DATA_LENGTH_EXTENSION
|
||||
#define ENABLE_ATT_DELAYED_READ_RESPONSE
|
||||
#define ENABLE_ATT_DELAYED_RESPONSE
|
||||
#define ENABLE_LOG_ERROR
|
||||
#define ENABLE_LOG_INFO
|
||||
#define ENABLE_SCO_OVER_HCI
|
||||
|
2
port/posix-h4-da14581/.gitignore
vendored
2
port/posix-h4-da14581/.gitignore
vendored
@ -47,5 +47,5 @@ le_streamer_client
|
||||
pbap_client_demo
|
||||
sm_pairing_central
|
||||
sm_pairing_peripheral
|
||||
|
||||
att_delayed_read_response
|
||||
att_delayed_read_response.h
|
||||
|
15
port/posix-h4-da14585/.gitignore
vendored
15
port/posix-h4-da14585/.gitignore
vendored
@ -1,5 +1,6 @@
|
||||
ancs_client_demo
|
||||
ancs_client_demo.h
|
||||
att_delayed_response.h
|
||||
ble_central_test
|
||||
ble_peripheral
|
||||
ble_peripheral_sm_minimal
|
||||
@ -16,7 +17,9 @@ gap_inquiry
|
||||
gap_inquiry_and_bond
|
||||
gap_le_advertisements
|
||||
gatt_battery_query
|
||||
gatt_battery_query.h
|
||||
gatt_browser
|
||||
gatt_browser.h
|
||||
hfp_ag_demo
|
||||
hfp_hf_demo
|
||||
hsp_ag_demo
|
||||
@ -28,12 +31,16 @@ le_counter
|
||||
le_counter.h
|
||||
le_streamer
|
||||
le_streamer.h
|
||||
le_streamer_client
|
||||
led_counter
|
||||
pbap_client_demo
|
||||
profile.h
|
||||
sco_input.wav
|
||||
sdp_bnep_query
|
||||
sdp_general_query
|
||||
sdp_rfcomm_query
|
||||
sm_pairing_central
|
||||
sm_pairing_peripheral
|
||||
sm_pairing_peripheral.h
|
||||
spp_and_le_counter
|
||||
spp_and_le_counter.h
|
||||
@ -41,11 +48,3 @@ spp_counter
|
||||
spp_streamer
|
||||
TIInit_12.10.28.c
|
||||
TIInit_12.8.32.c
|
||||
gatt_battery_query.h
|
||||
gatt_browser.h
|
||||
le_streamer_client
|
||||
pbap_client_demo
|
||||
sm_pairing_central
|
||||
sm_pairing_peripheral
|
||||
|
||||
att_delayed_read_response.h
|
||||
|
@ -22,7 +22,7 @@
|
||||
#define ENABLE_MICRO_ECC_FOR_LE_SECURE_CONNECTIONS
|
||||
#define ENABLE_LE_DATA_CHANNELS
|
||||
#define ENABLE_LE_DATA_LENGTH_EXTENSION
|
||||
#define ENABLE_ATT_DELAYED_READ_RESPONSE
|
||||
#define ENABLE_ATT_DELAYED_RESPONSE
|
||||
#define ENABLE_LOG_ERROR
|
||||
#define ENABLE_LOG_INFO
|
||||
#define ENABLE_SCO_OVER_HCI
|
||||
|
@ -54,8 +54,9 @@ extern "C" {
|
||||
// custom BTstack ATT error codes
|
||||
#define ATT_ERROR_DATA_MISMATCH 0x7e
|
||||
#define ATT_ERROR_TIMEOUT 0x7F
|
||||
#define ATT_ERROR_WRITE_RESPONSE_PENDING 0x100
|
||||
|
||||
// custom BTstack ATT Response Pending
|
||||
// custom BTstack ATT Response Pending for att_read_callback
|
||||
#define ATT_READ_RESPONSE_PENDING 0xffff
|
||||
|
||||
typedef struct att_connection {
|
||||
|
@ -386,10 +386,10 @@ static int att_server_process_validated_request(att_server_t * att_server){
|
||||
uint8_t * att_response_buffer = l2cap_get_outgoing_buffer();
|
||||
uint16_t att_response_size = att_handle_request(&att_server->connection, att_server->request_buffer, att_server->request_size, att_response_buffer);
|
||||
|
||||
#ifdef ENABLE_ATT_DELAYED_READ_RESPONSE
|
||||
#ifdef ENABLE_ATT_DELAYED_RESPONSE
|
||||
if (att_response_size == ATT_READ_RESPONSE_PENDING){
|
||||
// update state
|
||||
att_server->state = ATT_SERVER_READ_RESPONSE_PENDING;
|
||||
att_server->state = ATT_SERVER_RESPONSE_PENDING;
|
||||
|
||||
// callback with handle ATT_READ_RESPONSE_PENDING
|
||||
att_server_client_read_callback(att_server->connection.con_handle, ATT_READ_RESPONSE_PENDING, 0, NULL, 0);
|
||||
@ -434,11 +434,11 @@ static int att_server_process_validated_request(att_server_t * att_server){
|
||||
return 1;
|
||||
}
|
||||
|
||||
#ifdef ENABLE_ATT_DELAYED_READ_RESPONSE
|
||||
int att_server_read_response_ready(hci_con_handle_t con_handle){
|
||||
#ifdef ENABLE_ATT_DELAYED_RESPONSE
|
||||
int att_server_response_ready(hci_con_handle_t con_handle){
|
||||
att_server_t * att_server = att_server_for_handle(con_handle);
|
||||
if (!att_server) return ERROR_CODE_UNKNOWN_CONNECTION_IDENTIFIER;
|
||||
if (att_server->state != ATT_SERVER_READ_RESPONSE_PENDING) return ERROR_CODE_COMMAND_DISALLOWED;
|
||||
if (!att_server) return ERROR_CODE_UNKNOWN_CONNECTION_IDENTIFIER;
|
||||
if (att_server->state != ATT_SERVER_RESPONSE_PENDING) return ERROR_CODE_COMMAND_DISALLOWED;
|
||||
|
||||
att_server->state = ATT_SERVER_REQUEST_RECEIVED_AND_VALIDATED;
|
||||
att_dispatch_server_request_can_send_now_event(con_handle);
|
||||
|
@ -135,14 +135,15 @@ int att_server_notify(hci_con_handle_t con_handle, uint16_t attribute_handle, ui
|
||||
*/
|
||||
int att_server_indicate(hci_con_handle_t con_handle, uint16_t attribute_handle, uint8_t *value, uint16_t value_len);
|
||||
|
||||
#ifdef ENABLE_ATT_DELAYED_READ_RESPONSE
|
||||
#ifdef ENABLE_ATT_DELAYED_RESPONSE
|
||||
/*
|
||||
* @brief read response ready - called after returning ATT_READ_RESPONSE_PENDING in an att_read_callback before
|
||||
* @brief response ready - called after returning ATT_READ__RESPONSE_PENDING in an att_read_callback or
|
||||
* ATT_ERROR_WRITE_REQUEST_PENDING IN att_write_callback before to trigger callback again and complete the transaction
|
||||
* @nore The ATT Server will retry handling the current ATT request
|
||||
* @param con_handle
|
||||
* @return 0 if ok, error otherwise
|
||||
*/
|
||||
int att_server_read_response_ready(hci_con_handle_t con_handle);
|
||||
int att_server_response_ready(hci_con_handle_t con_handle);
|
||||
#endif
|
||||
|
||||
/* API_END */
|
||||
|
Loading…
x
Reference in New Issue
Block a user