From 2534e7f55791d9b8d6dccfec5ad91ef8edf01306 Mon Sep 17 00:00:00 2001 From: Matthias Ringwald Date: Sun, 24 May 2015 00:58:45 +0200 Subject: [PATCH] preparing to read/write characteristics - arduino --- platforms/arduino/BTstack.cpp | 55 ++++++++++++++++--- platforms/arduino/BTstack.h | 6 +- .../examples/LEPeripheral/LEPeripheral.ino | 20 +++---- 3 files changed, 56 insertions(+), 25 deletions(-) diff --git a/platforms/arduino/BTstack.cpp b/platforms/arduino/BTstack.cpp index d10f7b78e..66e580ba9 100644 --- a/platforms/arduino/BTstack.cpp +++ b/platforms/arduino/BTstack.cpp @@ -491,6 +491,41 @@ int BLEDevice::unsubscribeFromIndications(BLECharacteristic * characteristic){ } + +static uint16_t (*gattReadCallback)(uint16_t characteristic_id, uint8_t * buffer, uint16_t buffer_size); +static int (*gattWriteCallback)(uint16_t characteristic_id, uint8_t *buffer, uint16_t buffer_size); + +// ATT Client Read Callback for Dynamic Data +// - if buffer == NULL, don't copy data, just return size of value +// - if buffer != NULL, copy data and return number bytes copied +// @param offset defines start of attribute value +static uint16_t att_read_callback(uint16_t con_handle, uint16_t att_handle, uint16_t offset, uint8_t * buffer, uint16_t buffer_size){ + if (gattReadCallback){ + gattReadCallback(att_handle, buffer, buffer_size); + } + return 0; +} +/* LISTING_END */ + + +/* + * @section ATT Write + * + * @text The only valid ATT write in this example is to the Client Characteristic Configuration, which configures notification + * and indication. If the ATT handle matches the client configuration handle, the new configuration value is stored and used + * in the heartbeat handler to decide if a new value should be sent. See Listing attWrite. + */ + +/* LISTING_START(attWrite): ATT Write */ +static int att_write_callback(uint16_t con_handle, uint16_t att_handle, uint16_t transaction_mode, uint16_t offset, uint8_t *buffer, uint16_t buffer_size){ + if (gattWriteCallback){ + gattWriteCallback(att_handle, buffer, buffer_size); + } + return 0; +} + + + BTstackManager::BTstackManager(void){ // client_packet_handler = NULL; have_custom_addr = false; @@ -658,7 +693,7 @@ void BTstackManager::setup(void){ sm_init(); - att_server_init(att_db_util_get_address(), NULL, NULL); + att_server_init(att_db_util_get_address(),att_read_callback, att_write_callback); att_server_register_packet_handler(packet_handler); gatt_client_init(); @@ -693,21 +728,23 @@ void BTstackManager::bleStopScanning(void){ le_central_stop_scan(); } -void BTstackManager::setGATTCharacteristicRead(uint16_t (*)(uint16_t characteristic_id, uint8_t * buffer, uint16_t buffer_size)){ +void BTstackManager::setGATTCharacteristicRead(uint16_t (*cb)(uint16_t characteristic_id, uint8_t * buffer, uint16_t buffer_size)){ + gattReadCallback = cb; } -void BTstackManager::setGATTCharacteristicWrite(int (*)(uint16_t characteristic_id, uint8_t *buffer, uint16_t buffer_size)){ +void BTstackManager::setGATTCharacteristicWrite(int (*cb)(uint16_t characteristic_id, uint8_t *buffer, uint16_t buffer_size)){ + gattWriteCallback = cb; } void BTstackManager::addGATTService(UUID * uuid){ att_db_util_add_service_uuid128((uint8_t*)uuid->getUuid()); } -void BTstackManager::addGATTCharacteristic(UUID * uuid, uint16_t flags, const char * text){ - att_db_util_add_characteristic_uuid128((uint8_t*)uuid->getUuid(), flags, (uint8_t*)text, strlen(text)); +uint16_t BTstackManager::addGATTCharacteristic(UUID * uuid, uint16_t flags, const char * text){ + return att_db_util_add_characteristic_uuid128((uint8_t*)uuid->getUuid(), flags, (uint8_t*)text, strlen(text)); } -void BTstackManager::addGATTCharacteristic(UUID * uuid, uint16_t flags, uint8_t * data, uint16_t data_len){ - att_db_util_add_characteristic_uuid128((uint8_t*)uuid->getUuid(), flags, data, data_len); +uint16_t BTstackManager::addGATTCharacteristic(UUID * uuid, uint16_t flags, uint8_t * data, uint16_t data_len){ + return att_db_util_add_characteristic_uuid128((uint8_t*)uuid->getUuid(), flags, data, data_len); } -void BTstackManager::addGATTCharacteristicDynamic(UUID * uuid, uint16_t flags, uint16_t characteristic_id){ - att_db_util_add_characteristic_uuid128((uint8_t*)uuid->getUuid(), flags | ATT_PROPERTY_DYNAMIC, NULL, 0); +uint16_t BTstackManager::addGATTCharacteristicDynamic(UUID * uuid, uint16_t flags, uint16_t characteristic_id){ + return att_db_util_add_characteristic_uuid128((uint8_t*)uuid->getUuid(), flags | ATT_PROPERTY_DYNAMIC, NULL, 0); } void BTstackManager::setAdvData(uint16_t size, const uint8_t * data){ memcpy(adv_data, data, size); diff --git a/platforms/arduino/BTstack.h b/platforms/arduino/BTstack.h index b58665b02..1f5eb3964 100644 --- a/platforms/arduino/BTstack.h +++ b/platforms/arduino/BTstack.h @@ -178,9 +178,9 @@ public: void setGATTCharacteristicWrite(int (*)(uint16_t characteristic_id, uint8_t *buffer, uint16_t buffer_size)); void addGATTService(UUID * uuid); - void addGATTCharacteristic(UUID * uuid, uint16_t flags, const char * text); - void addGATTCharacteristic(UUID * uuid, uint16_t flags, uint8_t * data, uint16_t data_len); - void addGATTCharacteristicDynamic(UUID * uuid, uint16_t flags, uint16_t characteristic_id); + uint16_t addGATTCharacteristic(UUID * uuid, uint16_t flags, const char * text); + uint16_t addGATTCharacteristic(UUID * uuid, uint16_t flags, uint8_t * data, uint16_t data_len); + uint16_t addGATTCharacteristicDynamic(UUID * uuid, uint16_t flags, uint16_t characteristic_id); }; extern BTstackManager BTstack; \ No newline at end of file diff --git a/platforms/arduino/examples/LEPeripheral/LEPeripheral.ino b/platforms/arduino/examples/LEPeripheral/LEPeripheral.ino index eed5684cb..ffd333d9e 100644 --- a/platforms/arduino/examples/LEPeripheral/LEPeripheral.ino +++ b/platforms/arduino/examples/LEPeripheral/LEPeripheral.ino @@ -2,8 +2,6 @@ #include #include -#define GATT_CHARACTERISTIC_TEMP_ID 0 - // setup printf static FILE uartout = {0} ; static int uart_putchar (char c, FILE *stream) { @@ -16,6 +14,8 @@ static void setup_printf(int baud) { stdout = &uartout; } +static uint16_t value_handle; + void setup(void){ setup_printf(9600); @@ -31,9 +31,7 @@ void setup(void){ uint8_t * data = NULL; uint16_t data_len = 0; BTstack.addGATTService(new UUID("B8E06067-62AD-41BA-9231-206AE80AB550")); - BTstack.addGATTCharacteristic(new UUID("f897177b-aee8-4767-8ecc-cc694fd5fcee"), flags, "This is a String!"); - BTstack.addGATTCharacteristicDynamic(new UUID("f897177b-aee8-4767-8ecc-cc694fd5fcee"), flags, GATT_CHARACTERISTIC_TEMP_ID); - // .. + value_handle = BTstack.addGATTCharacteristic(new UUID("f897177b-aee8-4767-8ecc-cc694fd5fcee"), flags, "This is a String!"); // startup Bluetooth and activate advertisements BTstack.setup(); @@ -65,11 +63,8 @@ void deviceDisconnectedCallback(BLEDevice * device){ // @param characteristic_id to be read // @param buffer // @param buffer_size -uint16_t gattReadCallback(uint16_t characteristic_id, uint8_t * buffer, uint16_t buffer_size){ - switch (characteristic_id){ - case GATT_CHARACTERISTIC_TEMP_ID: - break; - } +uint16_t gattReadCallback(uint16_t value_handle, uint8_t * buffer, uint16_t buffer_size){ + printf("gattReadCallback, handle %u\n", value_handle); return 0; } @@ -78,9 +73,8 @@ uint16_t gattReadCallback(uint16_t characteristic_id, uint8_t * buffer, uint16_t // @param buffer // @param buffer_size // @returns 0 if write was ok, ATT_ERROR_INVALID_OFFSET if offset is larger than max buffer -int gattWriteCallback(uint16_t characteristic_id, uint8_t *buffer, uint16_t buffer_size){ - switch (characteristic_id){ - } +int gattWriteCallback(uint16_t value_handle, uint8_t *buffer, uint16_t buffer_size){ + printf("gattWriteCallback, handle %u\n", value_handle); return 0; }