summaryrefslogtreecommitdiff
path: root/src/BLECharacteristic.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/BLECharacteristic.cpp')
-rw-r--r--src/BLECharacteristic.cpp760
1 files changed, 0 insertions, 760 deletions
diff --git a/src/BLECharacteristic.cpp b/src/BLECharacteristic.cpp
deleted file mode 100644
index e340287..0000000
--- a/src/BLECharacteristic.cpp
+++ /dev/null
@@ -1,760 +0,0 @@
-/*
- * BLECharacteristic.cpp
- *
- * Created on: Jun 22, 2017
- * Author: kolban
- */
-#include "sdkconfig.h"
-#if defined(CONFIG_BT_ENABLED)
-#include <sstream>
-#include <string.h>
-#include <iomanip>
-#include <stdlib.h>
-#include "sdkconfig.h"
-#include <esp_err.h>
-#include "BLECharacteristic.h"
-#include "BLEService.h"
-#include "BLEDevice.h"
-#include "BLEUtils.h"
-#include "BLE2902.h"
-#include "GeneralUtils.h"
-#if defined(ARDUINO_ARCH_ESP32) && defined(CONFIG_ARDUHAL_ESP_LOG)
-#include "esp32-hal-log.h"
-#define LOG_TAG ""
-#else
-#include "esp_log.h"
-static const char* LOG_TAG = "BLECharacteristic";
-#endif
-
-#define NULL_HANDLE (0xffff)
-
-
-/**
- * @brief Construct a characteristic
- * @param [in] uuid - UUID (const char*) for the characteristic.
- * @param [in] properties - Properties for the characteristic.
- */
-BLECharacteristic::BLECharacteristic(const char* uuid, uint32_t properties) : BLECharacteristic(BLEUUID(uuid), properties) {
-}
-
-/**
- * @brief Construct a characteristic
- * @param [in] uuid - UUID for the characteristic.
- * @param [in] properties - Properties for the characteristic.
- */
-BLECharacteristic::BLECharacteristic(BLEUUID uuid, uint32_t properties) {
- m_bleUUID = uuid;
- m_handle = NULL_HANDLE;
- m_properties = (esp_gatt_char_prop_t)0;
- m_pCallbacks = nullptr;
-
- setBroadcastProperty((properties & PROPERTY_BROADCAST) != 0);
- setReadProperty((properties & PROPERTY_READ) != 0);
- setWriteProperty((properties & PROPERTY_WRITE) != 0);
- setNotifyProperty((properties & PROPERTY_NOTIFY) != 0);
- setIndicateProperty((properties & PROPERTY_INDICATE) != 0);
- setWriteNoResponseProperty((properties & PROPERTY_WRITE_NR) != 0);
-} // BLECharacteristic
-
-/**
- * @brief Destructor.
- */
-BLECharacteristic::~BLECharacteristic() {
- //free(m_value.attr_value); // Release the storage for the value.
-} // ~BLECharacteristic
-
-
-/**
- * @brief Associate a descriptor with this characteristic.
- * @param [in] pDescriptor
- * @return N/A.
- */
-void BLECharacteristic::addDescriptor(BLEDescriptor* pDescriptor) {
- ESP_LOGD(LOG_TAG, ">> addDescriptor(): Adding %s to %s", pDescriptor->toString().c_str(), toString().c_str());
- m_descriptorMap.setByUUID(pDescriptor->getUUID(), pDescriptor);
- ESP_LOGD(LOG_TAG, "<< addDescriptor()");
-} // addDescriptor
-
-
-/**
- * @brief Register a new characteristic with the ESP runtime.
- * @param [in] pService The service with which to associate this characteristic.
- */
-void BLECharacteristic::executeCreate(BLEService* pService) {
- ESP_LOGD(LOG_TAG, ">> executeCreate()");
-
- if (m_handle != NULL_HANDLE) {
- ESP_LOGE(LOG_TAG, "Characteristic already has a handle.");
- return;
- }
-
- m_pService = pService; // Save the service to which this characteristic belongs.
-
- ESP_LOGD(LOG_TAG, "Registering characteristic (esp_ble_gatts_add_char): uuid: %s, service: %s",
- getUUID().toString().c_str(),
- m_pService->toString().c_str());
-
- esp_attr_control_t control;
- control.auto_rsp = ESP_GATT_RSP_BY_APP;
-
- m_semaphoreCreateEvt.take("executeCreate");
- esp_err_t errRc = ::esp_ble_gatts_add_char(
- m_pService->getHandle(),
- getUUID().getNative(),
- static_cast<esp_gatt_perm_t>(m_permissions),
- getProperties(),
- nullptr,
- &control); // Whether to auto respond or not.
-
- if (errRc != ESP_OK) {
- ESP_LOGE(LOG_TAG, "<< esp_ble_gatts_add_char: rc=%d %s", errRc, GeneralUtils::errorToString(errRc));
- return;
- }
- m_semaphoreCreateEvt.wait("executeCreate");
-
- BLEDescriptor* pDescriptor = m_descriptorMap.getFirst();
- while (pDescriptor != nullptr) {
- pDescriptor->executeCreate(this);
- pDescriptor = m_descriptorMap.getNext();
- } // End while
-
- ESP_LOGD(LOG_TAG, "<< executeCreate");
-} // executeCreate
-
-
-/**
- * @brief Return the BLE Descriptor for the given UUID if associated with this characteristic.
- * @param [in] descriptorUUID The UUID of the descriptor that we wish to retrieve.
- * @return The BLE Descriptor. If no such descriptor is associated with the characteristic, nullptr is returned.
- */
-BLEDescriptor* BLECharacteristic::getDescriptorByUUID(const char* descriptorUUID) {
- return m_descriptorMap.getByUUID(BLEUUID(descriptorUUID));
-} // getDescriptorByUUID
-
-
-/**
- * @brief Return the BLE Descriptor for the given UUID if associated with this characteristic.
- * @param [in] descriptorUUID The UUID of the descriptor that we wish to retrieve.
- * @return The BLE Descriptor. If no such descriptor is associated with the characteristic, nullptr is returned.
- */
-BLEDescriptor* BLECharacteristic::getDescriptorByUUID(BLEUUID descriptorUUID) {
- return m_descriptorMap.getByUUID(descriptorUUID);
-} // getDescriptorByUUID
-
-
-/**
- * @brief Get the handle of the characteristic.
- * @return The handle of the characteristic.
- */
-uint16_t BLECharacteristic::getHandle() {
- return m_handle;
-} // getHandle
-
-void BLECharacteristic::setAccessPermissions(esp_gatt_perm_t perm) {
- m_permissions = perm;
-}
-
-esp_gatt_char_prop_t BLECharacteristic::getProperties() {
- return m_properties;
-} // getProperties
-
-
-/**
- * @brief Get the service associated with this characteristic.
- */
-BLEService* BLECharacteristic::getService() {
- return m_pService;
-} // getService
-
-
-/**
- * @brief Get the UUID of the characteristic.
- * @return The UUID of the characteristic.
- */
-BLEUUID BLECharacteristic::getUUID() {
- return m_bleUUID;
-} // getUUID
-
-
-/**
- * @brief Retrieve the current value of the characteristic.
- * @return A pointer to storage containing the current characteristic value.
- */
-std::string BLECharacteristic::getValue() {
- return m_value.getValue();
-} // getValue
-
-/**
- * @brief Retrieve the current raw data of the characteristic.
- * @return A pointer to storage containing the current characteristic data.
- */
-uint8_t* BLECharacteristic::getData() {
- return m_value.getData();
-} // getData
-
-
-/**
- * Handle a GATT server event.
- */
-void BLECharacteristic::handleGATTServerEvent(
- esp_gatts_cb_event_t event,
- esp_gatt_if_t gatts_if,
- esp_ble_gatts_cb_param_t* param) {
- ESP_LOGD(LOG_TAG, ">> handleGATTServerEvent: %s", BLEUtils::gattServerEventTypeToString(event).c_str());
-
- switch(event) {
- // Events handled:
- //
- // ESP_GATTS_ADD_CHAR_EVT
- // ESP_GATTS_CONF_EVT
- // ESP_GATTS_CONNECT_EVT
- // ESP_GATTS_DISCONNECT_EVT
- // ESP_GATTS_EXEC_WRITE_EVT
- // ESP_GATTS_READ_EVT
- // ESP_GATTS_WRITE_EVT
-
- //
- // ESP_GATTS_EXEC_WRITE_EVT
- // When we receive this event it is an indication that a previous write long needs to be committed.
- //
- // exec_write:
- // - uint16_t conn_id
- // - uint32_t trans_id
- // - esp_bd_addr_t bda
- // - uint8_t exec_write_flag - Either ESP_GATT_PREP_WRITE_EXEC or ESP_GATT_PREP_WRITE_CANCEL
- //
- case ESP_GATTS_EXEC_WRITE_EVT: {
- if (param->exec_write.exec_write_flag == ESP_GATT_PREP_WRITE_EXEC) {
- m_value.commit();
- if (m_pCallbacks != nullptr) {
- m_pCallbacks->onWrite(this); // Invoke the onWrite callback handler.
- }
- } else {
- m_value.cancel();
- }
-// ???
- esp_err_t errRc = ::esp_ble_gatts_send_response(
- gatts_if,
- param->write.conn_id,
- param->write.trans_id, ESP_GATT_OK, nullptr);
- if (errRc != ESP_OK) {
- ESP_LOGE(LOG_TAG, "esp_ble_gatts_send_response: rc=%d %s", errRc, GeneralUtils::errorToString(errRc));
- }
- break;
- } // ESP_GATTS_EXEC_WRITE_EVT
-
-
- // ESP_GATTS_ADD_CHAR_EVT - Indicate that a characteristic was added to the service.
- // add_char:
- // - esp_gatt_status_t status
- // - uint16_t attr_handle
- // - uint16_t service_handle
- // - esp_bt_uuid_t char_uuid
- case ESP_GATTS_ADD_CHAR_EVT: {
- if (getHandle() == param->add_char.attr_handle) {
- // we have created characteristic, now we can create descriptors
- // BLEDescriptor* pDescriptor = m_descriptorMap.getFirst();
- // while (pDescriptor != nullptr) {
- // pDescriptor->executeCreate(this);
- // pDescriptor = m_descriptorMap.getNext();
- // } // End while
- m_semaphoreCreateEvt.give();
- }
- break;
- } // ESP_GATTS_ADD_CHAR_EVT
-
-
- // ESP_GATTS_WRITE_EVT - A request to write the value of a characteristic has arrived.
- //
- // write:
- // - uint16_t conn_id
- // - uint16_t trans_id
- // - esp_bd_addr_t bda
- // - uint16_t handle
- // - uint16_t offset
- // - bool need_rsp
- // - bool is_prep
- // - uint16_t len
- // - uint8_t *value
- //
- case ESP_GATTS_WRITE_EVT: {
-// We check if this write request is for us by comparing the handles in the event. If it is for us
-// we save the new value. Next we look at the need_rsp flag which indicates whether or not we need
-// to send a response. If we do, then we formulate a response and send it.
- if (param->write.handle == m_handle) {
- if (param->write.is_prep) {
- m_value.addPart(param->write.value, param->write.len);
- } else {
- setValue(param->write.value, param->write.len);
- }
-
- ESP_LOGD(LOG_TAG, " - Response to write event: New value: handle: %.2x, uuid: %s",
- getHandle(), getUUID().toString().c_str());
-
- char* pHexData = BLEUtils::buildHexData(nullptr, param->write.value, param->write.len);
- ESP_LOGD(LOG_TAG, " - Data: length: %d, data: %s", param->write.len, pHexData);
- free(pHexData);
-
- if (param->write.need_rsp) {
- esp_gatt_rsp_t rsp;
-
- rsp.attr_value.len = param->write.len;
- rsp.attr_value.handle = m_handle;
- rsp.attr_value.offset = param->write.offset;
- rsp.attr_value.auth_req = ESP_GATT_AUTH_REQ_NONE;
- memcpy(rsp.attr_value.value, param->write.value, param->write.len);
-
- esp_err_t errRc = ::esp_ble_gatts_send_response(
- gatts_if,
- param->write.conn_id,
- param->write.trans_id, ESP_GATT_OK, &rsp);
- if (errRc != ESP_OK) {
- ESP_LOGE(LOG_TAG, "esp_ble_gatts_send_response: rc=%d %s", errRc, GeneralUtils::errorToString(errRc));
- }
- } // Response needed
-
- if (m_pCallbacks != nullptr && param->write.is_prep != true) {
- m_pCallbacks->onWrite(this); // Invoke the onWrite callback handler.
- }
- } // Match on handles.
- break;
- } // ESP_GATTS_WRITE_EVT
-
-
- // ESP_GATTS_READ_EVT - A request to read the value of a characteristic has arrived.
- //
- // read:
- // - uint16_t conn_id
- // - uint32_t trans_id
- // - esp_bd_addr_t bda
- // - uint16_t handle
- // - uint16_t offset
- // - bool is_long
- // - bool need_rsp
- //
- case ESP_GATTS_READ_EVT: {
- if (param->read.handle == m_handle) {
-
-
-
-// Here's an interesting thing. The read request has the option of saying whether we need a response
-// or not. What would it "mean" to receive a read request and NOT send a response back? That feels like
-// a very strange read.
-//
-// We have to handle the case where the data we wish to send back to the client is greater than the maximum
-// packet size of 22 bytes. In this case, we become responsible for chunking the data into units of 22 bytes.
-// The apparent algorithm is as follows:
-//
-// If the is_long flag is set then this is a follow on from an original read and we will already have sent at least 22 bytes.
-// If the is_long flag is not set then we need to check how much data we are going to send. If we are sending LESS than
-// 22 bytes, then we "just" send it and thats the end of the story.
-// If we are sending 22 bytes exactly, we just send it BUT we will get a follow on request.
-// If we are sending more than 22 bytes, we send the first 22 bytes and we will get a follow on request.
-// Because of follow on request processing, we need to maintain an offset of how much data we have already sent
-// so that when a follow on request arrives, we know where to start in the data to send the next sequence.
-// Note that the indication that the client will send a follow on request is that we sent exactly 22 bytes as a response.
-// If our payload is divisible by 22 then the last response will be a response of 0 bytes in length.
-//
-// The following code has deliberately not been factored to make it fewer statements because this would cloud the
-// the logic flow comprehension.
-//
-
- // get mtu for peer device that we are sending read request to
- uint16_t maxOffset = getService()->getServer()->getPeerMTU(param->read.conn_id) - 1;
- ESP_LOGD(LOG_TAG, "mtu value: %d", maxOffset);
- if (param->read.need_rsp) {
- ESP_LOGD(LOG_TAG, "Sending a response (esp_ble_gatts_send_response)");
- esp_gatt_rsp_t rsp;
-
- if (param->read.is_long) {
- std::string value = m_value.getValue();
-
- if (value.length() - m_value.getReadOffset() < maxOffset) {
- // This is the last in the chain
- rsp.attr_value.len = value.length() - m_value.getReadOffset();
- rsp.attr_value.offset = m_value.getReadOffset();
- memcpy(rsp.attr_value.value, value.data() + rsp.attr_value.offset, rsp.attr_value.len);
- m_value.setReadOffset(0);
- } else {
- // There will be more to come.
- rsp.attr_value.len = maxOffset;
- rsp.attr_value.offset = m_value.getReadOffset();
- memcpy(rsp.attr_value.value, value.data() + rsp.attr_value.offset, rsp.attr_value.len);
- m_value.setReadOffset(rsp.attr_value.offset + maxOffset);
- }
- } else { // read.is_long == false
-
- std::string value = m_value.getValue();
-
- if (value.length() + 1 > maxOffset) {
- // Too big for a single shot entry.
- m_value.setReadOffset(maxOffset);
- rsp.attr_value.len = maxOffset;
- rsp.attr_value.offset = 0;
- memcpy(rsp.attr_value.value, value.data(), rsp.attr_value.len);
- } else {
- // Will fit in a single packet with no callbacks required.
- rsp.attr_value.len = value.length();
- rsp.attr_value.offset = 0;
- memcpy(rsp.attr_value.value, value.data(), rsp.attr_value.len);
- }
-
- if (m_pCallbacks != nullptr) { // If is.long is false then this is the first (or only) request to read data, so invoke the callback
- m_pCallbacks->onRead(this); // Invoke the read callback.
- }
- }
- rsp.attr_value.handle = param->read.handle;
- rsp.attr_value.auth_req = ESP_GATT_AUTH_REQ_NONE;
-
- char *pHexData = BLEUtils::buildHexData(nullptr, rsp.attr_value.value, rsp.attr_value.len);
- ESP_LOGD(LOG_TAG, " - Data: length=%d, data=%s, offset=%d", rsp.attr_value.len, pHexData, rsp.attr_value.offset);
- free(pHexData);
-
- esp_err_t errRc = ::esp_ble_gatts_send_response(
- gatts_if, param->read.conn_id,
- param->read.trans_id,
- ESP_GATT_OK,
- &rsp);
- if (errRc != ESP_OK) {
- ESP_LOGE(LOG_TAG, "esp_ble_gatts_send_response: rc=%d %s", errRc, GeneralUtils::errorToString(errRc));
- }
- } // Response needed
- } // Handle matches this characteristic.
- break;
- } // ESP_GATTS_READ_EVT
-
-
- // ESP_GATTS_CONF_EVT
- //
- // conf:
- // - esp_gatt_status_t status – The status code.
- // - uint16_t conn_id – The connection used.
- //
- case ESP_GATTS_CONF_EVT: {
- // ESP_LOGD(LOG_TAG, "m_handle = %d, conf->handle = %d", m_handle, param->conf.handle);
- if(param->conf.conn_id == getService()->getServer()->getConnId()) // && param->conf.handle == m_handle) // bug in esp-idf and not implemented in arduino yet
- m_semaphoreConfEvt.give(param->conf.status);
- break;
- }
-
- case ESP_GATTS_CONNECT_EVT: {
- break;
- }
-
- case ESP_GATTS_DISCONNECT_EVT: {
- m_semaphoreConfEvt.give();
- break;
- }
-
- default: {
- break;
- } // default
-
- } // switch event
-
- // Give each of the descriptors associated with this characteristic the opportunity to handle the
- // event.
-
- m_descriptorMap.handleGATTServerEvent(event, gatts_if, param);
- ESP_LOGD(LOG_TAG, "<< handleGATTServerEvent");
-} // handleGATTServerEvent
-
-
-/**
- * @brief Send an indication.
- * An indication is a transmission of up to the first 20 bytes of the characteristic value. An indication
- * will block waiting a positive confirmation from the client.
- * @return N/A
- */
-void BLECharacteristic::indicate() {
-
- ESP_LOGD(LOG_TAG, ">> indicate: length: %d", m_value.getValue().length());
- notify(false);
- ESP_LOGD(LOG_TAG, "<< indicate");
-} // indicate
-
-
-/**
- * @brief Send a notify.
- * A notification is a transmission of up to the first 20 bytes of the characteristic value. An notification
- * will not block; it is a fire and forget.
- * @return N/A.
- */
-void BLECharacteristic::notify(bool is_notification) {
- ESP_LOGD(LOG_TAG, ">> notify: length: %d", m_value.getValue().length());
-
- assert(getService() != nullptr);
- assert(getService()->getServer() != nullptr);
-
- GeneralUtils::hexDump((uint8_t*)m_value.getValue().data(), m_value.getValue().length());
-
- if (getService()->getServer()->getConnectedCount() == 0) {
- ESP_LOGD(LOG_TAG, "<< notify: No connected clients.");
- return;
- }
-
- // Test to see if we have a 0x2902 descriptor. If we do, then check to see if notification is enabled
- // and, if not, prevent the notification.
-
- BLE2902 *p2902 = (BLE2902*)getDescriptorByUUID((uint16_t)0x2902);
- if(is_notification) {
- if (p2902 != nullptr && !p2902->getNotifications()) {
- ESP_LOGD(LOG_TAG, "<< notifications disabled; ignoring");
- return;
- }
- }
- else{
- if (p2902 != nullptr && !p2902->getIndications()) {
- ESP_LOGD(LOG_TAG, "<< indications disabled; ignoring");
- return;
- }
- }
- for (auto &myPair : getService()->getServer()->getPeerDevices(false)) {
- uint16_t _mtu = (myPair.second.mtu);
- if (m_value.getValue().length() > _mtu - 3) {
- ESP_LOGW(LOG_TAG, "- Truncating to %d bytes (maximum notify size)", _mtu - 3);
- }
-
- size_t length = m_value.getValue().length();
- if(!is_notification)
- m_semaphoreConfEvt.take("indicate");
- esp_err_t errRc = ::esp_ble_gatts_send_indicate(
- getService()->getServer()->getGattsIf(),
- myPair.first,
- getHandle(), length, (uint8_t*)m_value.getValue().data(), !is_notification); // The need_confirm = false makes this a notify.
- if (errRc != ESP_OK) {
- ESP_LOGE(LOG_TAG, "<< esp_ble_gatts_send_ %s: rc=%d %s",is_notification?"notify":"indicate", errRc, GeneralUtils::errorToString(errRc));
- m_semaphoreConfEvt.give();
- return;
- }
- if(!is_notification)
- m_semaphoreConfEvt.wait("indicate");
- }
- ESP_LOGD(LOG_TAG, "<< notify");
-} // Notify
-
-
-/**
- * @brief Set the permission to broadcast.
- * A characteristics has properties associated with it which define what it is capable of doing.
- * One of these is the broadcast flag.
- * @param [in] value The flag value of the property.
- * @return N/A
- */
-void BLECharacteristic::setBroadcastProperty(bool value) {
- //ESP_LOGD(LOG_TAG, "setBroadcastProperty(%d)", value);
- if (value) {
- m_properties = (esp_gatt_char_prop_t)(m_properties | ESP_GATT_CHAR_PROP_BIT_BROADCAST);
- } else {
- m_properties = (esp_gatt_char_prop_t)(m_properties & ~ESP_GATT_CHAR_PROP_BIT_BROADCAST);
- }
-} // setBroadcastProperty
-
-
-/**
- * @brief Set the callback handlers for this characteristic.
- * @param [in] pCallbacks An instance of a callbacks structure used to define any callbacks for the characteristic.
- */
-void BLECharacteristic::setCallbacks(BLECharacteristicCallbacks* pCallbacks) {
- ESP_LOGD(LOG_TAG, ">> setCallbacks: 0x%x", (uint32_t)pCallbacks);
- m_pCallbacks = pCallbacks;
- ESP_LOGD(LOG_TAG, "<< setCallbacks");
-} // setCallbacks
-
-
-/**
- * @brief Set the BLE handle associated with this characteristic.
- * A user program will request that a characteristic be created against a service. When the characteristic has been
- * registered, the service will be given a "handle" that it knows the characteristic as. This handle is unique to the
- * server/service but it is told to the service, not the characteristic associated with the service. This internally
- * exposed function can be invoked by the service against this model of the characteristic to allow the characteristic
- * to learn its own handle. Once the characteristic knows its own handle, it will be able to see incoming GATT events
- * that will be propagated down to it which contain a handle value and now know that the event is destined for it.
- * @param [in] handle The handle associated with this characteristic.
- */
-void BLECharacteristic::setHandle(uint16_t handle) {
- ESP_LOGD(LOG_TAG, ">> setHandle: handle=0x%.2x, characteristic uuid=%s", handle, getUUID().toString().c_str());
- m_handle = handle;
- ESP_LOGD(LOG_TAG, "<< setHandle");
-} // setHandle
-
-
-/**
- * @brief Set the Indicate property value.
- * @param [in] value Set to true if we are to allow indicate messages.
- */
-void BLECharacteristic::setIndicateProperty(bool value) {
- //ESP_LOGD(LOG_TAG, "setIndicateProperty(%d)", value);
- if (value) {
- m_properties = (esp_gatt_char_prop_t)(m_properties | ESP_GATT_CHAR_PROP_BIT_INDICATE);
- } else {
- m_properties = (esp_gatt_char_prop_t)(m_properties & ~ESP_GATT_CHAR_PROP_BIT_INDICATE);
- }
-} // setIndicateProperty
-
-
-/**
- * @brief Set the Notify property value.
- * @param [in] value Set to true if we are to allow notification messages.
- */
-void BLECharacteristic::setNotifyProperty(bool value) {
- //ESP_LOGD(LOG_TAG, "setNotifyProperty(%d)", value);
- if (value) {
- m_properties = (esp_gatt_char_prop_t)(m_properties | ESP_GATT_CHAR_PROP_BIT_NOTIFY);
- } else {
- m_properties = (esp_gatt_char_prop_t)(m_properties & ~ESP_GATT_CHAR_PROP_BIT_NOTIFY);
- }
-} // setNotifyProperty
-
-
-/**
- * @brief Set the Read property value.
- * @param [in] value Set to true if we are to allow reads.
- */
-void BLECharacteristic::setReadProperty(bool value) {
- //ESP_LOGD(LOG_TAG, "setReadProperty(%d)", value);
- if (value) {
- m_properties = (esp_gatt_char_prop_t)(m_properties | ESP_GATT_CHAR_PROP_BIT_READ);
- } else {
- m_properties = (esp_gatt_char_prop_t)(m_properties & ~ESP_GATT_CHAR_PROP_BIT_READ);
- }
-} // setReadProperty
-
-
-/**
- * @brief Set the value of the characteristic.
- * @param [in] data The data to set for the characteristic.
- * @param [in] length The length of the data in bytes.
- */
-void BLECharacteristic::setValue(uint8_t* data, size_t length) {
- char* pHex = BLEUtils::buildHexData(nullptr, data, length);
- ESP_LOGD(LOG_TAG, ">> setValue: length=%d, data=%s, characteristic UUID=%s", length, pHex, getUUID().toString().c_str());
- free(pHex);
- if (length > ESP_GATT_MAX_ATTR_LEN) {
- ESP_LOGE(LOG_TAG, "Size %d too large, must be no bigger than %d", length, ESP_GATT_MAX_ATTR_LEN);
- return;
- }
- m_value.setValue(data, length);
- ESP_LOGD(LOG_TAG, "<< setValue");
-} // setValue
-
-
-/**
- * @brief Set the value of the characteristic from string data.
- * We set the value of the characteristic from the bytes contained in the
- * string.
- * @param [in] Set the value of the characteristic.
- * @return N/A.
- */
-void BLECharacteristic::setValue(std::string value) {
- setValue((uint8_t*)(value.data()), value.length());
-} // setValue
-
-void BLECharacteristic::setValue(uint16_t& data16) {
- uint8_t temp[2];
- temp[0] = data16;
- temp[1] = data16 >> 8;
- setValue(temp, 2);
-} // setValue
-
-void BLECharacteristic::setValue(uint32_t& data32) {
- uint8_t temp[4];
- temp[0] = data32;
- temp[1] = data32 >> 8;
- temp[2] = data32 >> 16;
- temp[3] = data32 >> 24;
- setValue(temp, 4);
-} // setValue
-
-void BLECharacteristic::setValue(int& data32) {
- uint8_t temp[4];
- temp[0] = data32;
- temp[1] = data32 >> 8;
- temp[2] = data32 >> 16;
- temp[3] = data32 >> 24;
- setValue(temp, 4);
-} // setValue
-
-void BLECharacteristic::setValue(float& data32) {
- uint8_t temp[4];
- *((float*)temp) = data32;
- setValue(temp, 4);
-} // setValue
-
-void BLECharacteristic::setValue(double& data64) {
- uint8_t temp[8];
- *((double*)temp) = data64;
- setValue(temp, 8);
-} // setValue
-
-
-/**
- * @brief Set the Write No Response property value.
- * @param [in] value Set to true if we are to allow writes with no response.
- */
-void BLECharacteristic::setWriteNoResponseProperty(bool value) {
- //ESP_LOGD(LOG_TAG, "setWriteNoResponseProperty(%d)", value);
- if (value) {
- m_properties = (esp_gatt_char_prop_t)(m_properties | ESP_GATT_CHAR_PROP_BIT_WRITE_NR);
- } else {
- m_properties = (esp_gatt_char_prop_t)(m_properties & ~ESP_GATT_CHAR_PROP_BIT_WRITE_NR);
- }
-} // setWriteNoResponseProperty
-
-
-/**
- * @brief Set the Write property value.
- * @param [in] value Set to true if we are to allow writes.
- */
-void BLECharacteristic::setWriteProperty(bool value) {
- //ESP_LOGD(LOG_TAG, "setWriteProperty(%d)", value);
- if (value) {
- m_properties = (esp_gatt_char_prop_t)(m_properties | ESP_GATT_CHAR_PROP_BIT_WRITE);
- } else {
- m_properties = (esp_gatt_char_prop_t)(m_properties & ~ESP_GATT_CHAR_PROP_BIT_WRITE);
- }
-} // setWriteProperty
-
-
-/**
- * @brief Return a string representation of the characteristic.
- * @return A string representation of the characteristic.
- */
-std::string BLECharacteristic::toString() {
- std::stringstream stringstream;
- stringstream << std::hex << std::setfill('0');
- stringstream << "UUID: " << m_bleUUID.toString() + ", handle: 0x" << std::setw(2) << m_handle;
- stringstream << " " <<
- ((m_properties & ESP_GATT_CHAR_PROP_BIT_READ) ? "Read " : "") <<
- ((m_properties & ESP_GATT_CHAR_PROP_BIT_WRITE) ? "Write " : "") <<
- ((m_properties & ESP_GATT_CHAR_PROP_BIT_WRITE_NR) ? "WriteNoResponse " : "") <<
- ((m_properties & ESP_GATT_CHAR_PROP_BIT_BROADCAST) ? "Broadcast " : "") <<
- ((m_properties & ESP_GATT_CHAR_PROP_BIT_NOTIFY) ? "Notify " : "") <<
- ((m_properties & ESP_GATT_CHAR_PROP_BIT_INDICATE) ? "Indicate " : "");
- return stringstream.str();
-} // toString
-
-
-BLECharacteristicCallbacks::~BLECharacteristicCallbacks() {}
-
-
-/**
- * @brief Callback function to support a read request.
- * @param [in] pCharacteristic The characteristic that is the source of the event.
- */
-void BLECharacteristicCallbacks::onRead(BLECharacteristic* pCharacteristic) {
- ESP_LOGD("BLECharacteristicCallbacks", ">> onRead: default");
- ESP_LOGD("BLECharacteristicCallbacks", "<< onRead");
-} // onRead
-
-
-/**
- * @brief Callback function to support a write request.
- * @param [in] pCharacteristic The characteristic that is the source of the event.
- */
-void BLECharacteristicCallbacks::onWrite(BLECharacteristic* pCharacteristic) {
- ESP_LOGD("BLECharacteristicCallbacks", ">> onWrite: default");
- ESP_LOGD("BLECharacteristicCallbacks", "<< onWrite");
-} // onWrite
-
-#endif /* CONFIG_BT_ENABLED */