2020-03-29 17:44:20 -06:00
|
|
|
/*
|
2024-12-12 19:21:03 -07:00
|
|
|
* Copyright 2020-2024 Ryan Powell <ryan@nable-embedded.io> and
|
|
|
|
* esp-nimble-cpp, NimBLE-Arduino contributors.
|
2020-03-29 17:44:20 -06:00
|
|
|
*
|
2024-12-12 19:21:03 -07:00
|
|
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
|
|
* you may not use this file except in compliance with the License.
|
|
|
|
* You may obtain a copy of the License at
|
2020-05-13 22:03:56 -06:00
|
|
|
*
|
2024-12-12 19:21:03 -07:00
|
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
2020-03-29 17:44:20 -06:00
|
|
|
*
|
2024-12-12 19:21:03 -07:00
|
|
|
* Unless required by applicable law or agreed to in writing, software
|
|
|
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
|
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
|
|
* See the License for the specific language governing permissions and
|
|
|
|
* limitations under the License.
|
2020-03-29 17:44:20 -06:00
|
|
|
*/
|
|
|
|
|
2020-05-13 22:03:56 -06:00
|
|
|
#include "nimconfig.h"
|
2021-09-06 21:14:43 -06:00
|
|
|
#if defined(CONFIG_BT_ENABLED) && defined(CONFIG_BT_NIMBLE_ROLE_PERIPHERAL)
|
2020-05-13 22:03:56 -06:00
|
|
|
|
2024-07-26 14:47:36 -06:00
|
|
|
# include "NimBLECharacteristic.h"
|
|
|
|
# include "NimBLE2904.h"
|
|
|
|
# include "NimBLEDevice.h"
|
|
|
|
# include "NimBLELog.h"
|
2020-03-29 17:44:20 -06:00
|
|
|
|
|
|
|
static NimBLECharacteristicCallbacks defaultCallback;
|
2024-07-26 14:47:36 -06:00
|
|
|
static const char* LOG_TAG = "NimBLECharacteristic";
|
2020-07-27 21:11:38 -06:00
|
|
|
|
2020-03-29 17:44:20 -06:00
|
|
|
/**
|
|
|
|
* @brief Construct a characteristic
|
|
|
|
* @param [in] uuid - UUID (const char*) for the characteristic.
|
|
|
|
* @param [in] properties - Properties for the characteristic.
|
2024-11-25 18:41:10 -07:00
|
|
|
* @param [in] maxLen - The maximum length in bytes that the characteristic value can hold. (Default: 512 bytes for esp32, 20 for all others).
|
2020-06-07 18:42:28 -06:00
|
|
|
* @param [in] pService - pointer to the service instance this characteristic belongs to.
|
2020-03-29 17:44:20 -06:00
|
|
|
*/
|
2024-11-25 18:41:10 -07:00
|
|
|
NimBLECharacteristic::NimBLECharacteristic(const char* uuid, uint16_t properties, uint16_t maxLen, NimBLEService* pService)
|
|
|
|
: NimBLECharacteristic(NimBLEUUID(uuid), properties, maxLen, pService) {}
|
2020-03-29 17:44:20 -06:00
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief Construct a characteristic
|
|
|
|
* @param [in] uuid - UUID for the characteristic.
|
|
|
|
* @param [in] properties - Properties for the characteristic.
|
2024-11-25 18:41:10 -07:00
|
|
|
* @param [in] maxLen - The maximum length in bytes that the characteristic value can hold. (Default: 512 bytes for esp32, 20 for all others).
|
2020-06-07 18:42:28 -06:00
|
|
|
* @param [in] pService - pointer to the service instance this characteristic belongs to.
|
2020-03-29 17:44:20 -06:00
|
|
|
*/
|
2024-11-25 18:41:10 -07:00
|
|
|
NimBLECharacteristic::NimBLECharacteristic(const NimBLEUUID& uuid, uint16_t properties, uint16_t maxLen, NimBLEService* pService)
|
|
|
|
: NimBLELocalValueAttribute{uuid, 0, maxLen}, m_pCallbacks{&defaultCallback}, m_pService{pService} {
|
2024-07-26 14:47:36 -06:00
|
|
|
setProperties(properties);
|
2020-03-29 17:44:20 -06:00
|
|
|
} // NimBLECharacteristic
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief Destructor.
|
|
|
|
*/
|
|
|
|
NimBLECharacteristic::~NimBLECharacteristic() {
|
2024-07-26 14:47:36 -06:00
|
|
|
for (const auto& dsc : m_vDescriptors) {
|
|
|
|
delete dsc;
|
2020-07-13 21:24:07 -06:00
|
|
|
}
|
2020-06-07 18:42:28 -06:00
|
|
|
} // ~NimBLECharacteristic
|
2020-03-29 17:44:20 -06:00
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief Create a new BLE Descriptor associated with this characteristic.
|
|
|
|
* @param [in] uuid - The UUID of the descriptor.
|
|
|
|
* @param [in] properties - The properties of the descriptor.
|
2024-11-25 18:41:10 -07:00
|
|
|
* @param [in] maxLen - The max length in bytes of the descriptor value.
|
2020-03-29 17:44:20 -06:00
|
|
|
* @return The new BLE descriptor.
|
|
|
|
*/
|
2024-11-25 18:41:10 -07:00
|
|
|
NimBLEDescriptor* NimBLECharacteristic::createDescriptor(const char* uuid, uint32_t properties, uint16_t maxLen) {
|
|
|
|
return createDescriptor(NimBLEUUID(uuid), properties, maxLen);
|
2020-03-29 17:44:20 -06:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief Create a new BLE Descriptor associated with this characteristic.
|
|
|
|
* @param [in] uuid - The UUID of the descriptor.
|
|
|
|
* @param [in] properties - The properties of the descriptor.
|
2024-11-25 18:41:10 -07:00
|
|
|
* @param [in] maxLen - The max length in bytes of the descriptor value.
|
2020-03-29 17:44:20 -06:00
|
|
|
* @return The new BLE descriptor.
|
|
|
|
*/
|
2024-11-25 18:41:10 -07:00
|
|
|
NimBLEDescriptor* NimBLECharacteristic::createDescriptor(const NimBLEUUID& uuid, uint32_t properties, uint16_t maxLen) {
|
2020-05-13 22:03:56 -06:00
|
|
|
NimBLEDescriptor* pDescriptor = nullptr;
|
2024-11-29 18:14:51 -07:00
|
|
|
if (uuid == NimBLEUUID(static_cast<uint16_t>(0x2904))) {
|
|
|
|
NIMBLE_LOGW(LOG_TAG, "0x2904 descriptor should be created with create2904()");
|
|
|
|
pDescriptor = create2904();
|
2020-05-13 22:03:56 -06:00
|
|
|
} else {
|
2024-11-25 18:41:10 -07:00
|
|
|
pDescriptor = new NimBLEDescriptor(uuid, properties, maxLen, this);
|
2020-05-13 22:03:56 -06:00
|
|
|
}
|
2020-06-07 18:42:28 -06:00
|
|
|
|
2021-05-23 13:07:00 -06:00
|
|
|
addDescriptor(pDescriptor);
|
2020-05-13 22:03:56 -06:00
|
|
|
return pDescriptor;
|
2021-05-23 13:07:00 -06:00
|
|
|
} // createDescriptor
|
|
|
|
|
2024-11-29 18:14:51 -07:00
|
|
|
/**
|
|
|
|
* @brief Create a Characteristic Presentation Format Descriptor for this characteristic.
|
|
|
|
* @return A pointer to a NimBLE2904 descriptor.
|
|
|
|
*/
|
|
|
|
NimBLE2904* NimBLECharacteristic::create2904() {
|
|
|
|
NimBLE2904* pDescriptor = new NimBLE2904(this);
|
|
|
|
addDescriptor(pDescriptor);
|
|
|
|
return pDescriptor;
|
|
|
|
} // create2904
|
|
|
|
|
2021-05-23 13:07:00 -06:00
|
|
|
/**
|
|
|
|
* @brief Add a descriptor to the characteristic.
|
2021-07-30 20:56:52 -06:00
|
|
|
* @param [in] pDescriptor A pointer to the descriptor to add.
|
2021-05-23 13:07:00 -06:00
|
|
|
*/
|
2024-07-26 14:47:36 -06:00
|
|
|
void NimBLECharacteristic::addDescriptor(NimBLEDescriptor* pDescriptor) {
|
2021-07-30 20:56:52 -06:00
|
|
|
bool foundRemoved = false;
|
2024-07-26 14:47:36 -06:00
|
|
|
if (pDescriptor->getRemoved() > 0) {
|
|
|
|
for (const auto& dsc : m_vDescriptors) {
|
|
|
|
if (dsc == pDescriptor) {
|
2021-07-30 20:56:52 -06:00
|
|
|
foundRemoved = true;
|
2024-07-26 14:47:36 -06:00
|
|
|
pDescriptor->setRemoved(0);
|
2021-07-30 20:56:52 -06:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2024-07-26 14:47:36 -06:00
|
|
|
// Check if the descriptor is already in the vector and if so, return.
|
|
|
|
for (const auto& dsc : m_vDescriptors) {
|
|
|
|
if (dsc == pDescriptor) {
|
|
|
|
pDescriptor->setCharacteristic(this); // Update the characteristic pointer in the descriptor.
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!foundRemoved) {
|
|
|
|
m_vDescriptors.push_back(pDescriptor);
|
2021-07-30 20:56:52 -06:00
|
|
|
}
|
|
|
|
|
2021-05-23 13:07:00 -06:00
|
|
|
pDescriptor->setCharacteristic(this);
|
2021-07-30 20:56:52 -06:00
|
|
|
NimBLEDevice::getServer()->serviceChanged();
|
2021-05-23 13:07:00 -06:00
|
|
|
}
|
2020-03-29 17:44:20 -06:00
|
|
|
|
2021-07-30 20:56:52 -06:00
|
|
|
/**
|
2022-07-31 11:00:12 -06:00
|
|
|
* @brief Remove a descriptor from the characteristic.
|
|
|
|
* @param[in] pDescriptor A pointer to the descriptor instance to remove from the characteristic.
|
2021-07-30 20:56:52 -06:00
|
|
|
* @param[in] deleteDsc If true it will delete the descriptor instance and free it's resources.
|
|
|
|
*/
|
2024-07-26 14:47:36 -06:00
|
|
|
void NimBLECharacteristic::removeDescriptor(NimBLEDescriptor* pDescriptor, bool deleteDsc) {
|
2021-07-30 20:56:52 -06:00
|
|
|
// Check if the descriptor was already removed and if so, check if this
|
|
|
|
// is being called to delete the object and do so if requested.
|
|
|
|
// Otherwise, ignore the call and return.
|
2024-07-26 14:47:36 -06:00
|
|
|
if (pDescriptor->getRemoved() > 0) {
|
|
|
|
if (deleteDsc) {
|
|
|
|
for (auto it = m_vDescriptors.begin(); it != m_vDescriptors.end(); ++it) {
|
2021-07-30 20:56:52 -06:00
|
|
|
if ((*it) == pDescriptor) {
|
2024-07-26 14:47:36 -06:00
|
|
|
delete (*it);
|
|
|
|
m_vDescriptors.erase(it);
|
2021-07-30 20:56:52 -06:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2024-07-26 14:47:36 -06:00
|
|
|
pDescriptor->setRemoved(deleteDsc ? NIMBLE_ATT_REMOVE_DELETE : NIMBLE_ATT_REMOVE_HIDE);
|
2021-07-30 20:56:52 -06:00
|
|
|
NimBLEDevice::getServer()->serviceChanged();
|
|
|
|
} // removeDescriptor
|
|
|
|
|
2020-03-29 17:44:20 -06:00
|
|
|
/**
|
2021-02-08 15:28:32 +00:00
|
|
|
* @brief Return the BLE Descriptor for the given UUID.
|
|
|
|
* @param [in] uuid The UUID of the descriptor.
|
|
|
|
* @return A pointer to the descriptor object or nullptr if not found.
|
2020-03-29 17:44:20 -06:00
|
|
|
*/
|
2024-07-26 14:47:36 -06:00
|
|
|
NimBLEDescriptor* NimBLECharacteristic::getDescriptorByUUID(const char* uuid) const {
|
2020-06-07 18:42:28 -06:00
|
|
|
return getDescriptorByUUID(NimBLEUUID(uuid));
|
2020-03-29 17:44:20 -06:00
|
|
|
} // getDescriptorByUUID
|
|
|
|
|
|
|
|
/**
|
2021-02-08 15:28:32 +00:00
|
|
|
* @brief Return the BLE Descriptor for the given UUID.
|
|
|
|
* @param [in] uuid The UUID of the descriptor.
|
|
|
|
* @return A pointer to the descriptor object or nullptr if not found.
|
2020-03-29 17:44:20 -06:00
|
|
|
*/
|
2024-07-26 14:47:36 -06:00
|
|
|
NimBLEDescriptor* NimBLECharacteristic::getDescriptorByUUID(const NimBLEUUID& uuid) const {
|
|
|
|
for (const auto& dsc : m_vDescriptors) {
|
|
|
|
if (dsc->getUUID() == uuid) {
|
|
|
|
return dsc;
|
2020-06-07 18:42:28 -06:00
|
|
|
}
|
|
|
|
}
|
|
|
|
return nullptr;
|
2020-03-29 17:44:20 -06:00
|
|
|
} // getDescriptorByUUID
|
|
|
|
|
2021-02-08 15:28:32 +00:00
|
|
|
/**
|
|
|
|
* @brief Return the BLE Descriptor for the given handle.
|
2021-02-08 11:46:11 -07:00
|
|
|
* @param [in] handle The handle of the descriptor.
|
2021-02-08 15:28:32 +00:00
|
|
|
* @return A pointer to the descriptor object or nullptr if not found.
|
|
|
|
*/
|
2024-07-26 14:47:36 -06:00
|
|
|
NimBLEDescriptor* NimBLECharacteristic::getDescriptorByHandle(uint16_t handle) const {
|
|
|
|
for (const auto& dsc : m_vDescriptors) {
|
|
|
|
if (dsc->getHandle() == handle) {
|
|
|
|
return dsc;
|
2021-02-08 15:28:32 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
return nullptr;
|
2024-07-26 14:47:36 -06:00
|
|
|
} // getDescriptorByHandle
|
2020-03-29 17:44:20 -06:00
|
|
|
|
2020-07-08 19:27:26 -06:00
|
|
|
/**
|
|
|
|
* @brief Get the properties of the characteristic.
|
|
|
|
* @return The properties of the characteristic.
|
|
|
|
*/
|
2024-07-26 14:47:36 -06:00
|
|
|
uint16_t NimBLECharacteristic::getProperties() const {
|
2020-05-13 22:03:56 -06:00
|
|
|
return m_properties;
|
2020-03-29 17:44:20 -06:00
|
|
|
} // getProperties
|
|
|
|
|
|
|
|
/**
|
2024-07-26 14:47:36 -06:00
|
|
|
* @brief Get the service that owns this characteristic.
|
2020-03-29 17:44:20 -06:00
|
|
|
*/
|
2024-07-26 14:47:36 -06:00
|
|
|
NimBLEService* NimBLECharacteristic::getService() const {
|
2020-05-13 22:03:56 -06:00
|
|
|
return m_pService;
|
2020-03-29 17:44:20 -06:00
|
|
|
} // getService
|
|
|
|
|
2024-07-26 14:47:36 -06:00
|
|
|
void NimBLECharacteristic::setService(NimBLEService* pService) {
|
2021-05-23 13:07:00 -06:00
|
|
|
m_pService = pService;
|
2024-07-26 14:47:36 -06:00
|
|
|
} // setService
|
2020-03-29 17:44:20 -06:00
|
|
|
|
|
|
|
/**
|
2022-01-16 20:11:18 -07:00
|
|
|
* @brief Send an indication.
|
2024-11-25 18:41:10 -07:00
|
|
|
* @param[in] connHandle Connection handle to send an individual indication, or BLE_HS_CONN_HANDLE_NONE to send
|
2024-07-26 14:47:36 -06:00
|
|
|
* the indication to all subscribed clients.
|
2024-11-25 18:41:10 -07:00
|
|
|
* @return True if the indication was sent successfully, false otherwise.
|
2020-03-29 17:44:20 -06:00
|
|
|
*/
|
2024-11-25 18:41:10 -07:00
|
|
|
bool NimBLECharacteristic::indicate(uint16_t connHandle) const {
|
|
|
|
return sendValue(nullptr, 0, false, connHandle);
|
2020-03-29 17:44:20 -06:00
|
|
|
} // indicate
|
2020-05-13 22:03:56 -06:00
|
|
|
|
2020-03-29 17:44:20 -06:00
|
|
|
/**
|
2022-01-16 20:11:18 -07:00
|
|
|
* @brief Send an indication.
|
|
|
|
* @param[in] value A pointer to the data to send.
|
|
|
|
* @param[in] length The length of the data to send.
|
2024-11-25 18:41:10 -07:00
|
|
|
* @param[in] connHandle Connection handle to send an individual indication, or BLE_HS_CONN_HANDLE_NONE to send
|
2024-07-26 14:47:36 -06:00
|
|
|
* the indication to all subscribed clients.
|
2024-11-25 18:41:10 -07:00
|
|
|
* @return True if the indication was sent successfully, false otherwise.
|
2022-01-16 20:11:18 -07:00
|
|
|
*/
|
2024-11-25 18:41:10 -07:00
|
|
|
bool NimBLECharacteristic::indicate(const uint8_t* value, size_t length, uint16_t connHandle) const {
|
|
|
|
return sendValue(value, length, false, connHandle);
|
2022-01-16 20:11:18 -07:00
|
|
|
} // indicate
|
|
|
|
|
|
|
|
/**
|
2024-07-26 14:47:36 -06:00
|
|
|
* @brief Send a notification.
|
2024-11-25 18:41:10 -07:00
|
|
|
* @param[in] connHandle Connection handle to send an individual notification, or BLE_HS_CONN_HANDLE_NONE to send
|
2024-07-26 14:47:36 -06:00
|
|
|
* the notification to all subscribed clients.
|
2024-11-25 18:41:10 -07:00
|
|
|
* @return True if the notification was sent successfully, false otherwise.
|
2020-03-29 17:44:20 -06:00
|
|
|
*/
|
2024-11-25 18:41:10 -07:00
|
|
|
bool NimBLECharacteristic::notify(uint16_t connHandle) const {
|
|
|
|
return sendValue(nullptr, 0, true, connHandle);
|
2022-01-16 20:11:18 -07:00
|
|
|
} // notify
|
|
|
|
|
2024-07-26 14:47:36 -06:00
|
|
|
/**
|
|
|
|
* @brief Send a notification.
|
|
|
|
* @param[in] value A pointer to the data to send.
|
|
|
|
* @param[in] length The length of the data to send.
|
2024-11-25 18:41:10 -07:00
|
|
|
* @param[in] connHandle Connection handle to send an individual notification, or BLE_HS_CONN_HANDLE_NONE to send
|
2024-07-26 14:47:36 -06:00
|
|
|
* the notification to all subscribed clients.
|
2024-11-25 18:41:10 -07:00
|
|
|
* @return True if the notification was sent successfully, false otherwise.
|
2024-07-26 14:47:36 -06:00
|
|
|
*/
|
2024-11-25 18:41:10 -07:00
|
|
|
bool NimBLECharacteristic::notify(const uint8_t* value, size_t length, uint16_t connHandle) const {
|
|
|
|
return sendValue(value, length, true, connHandle);
|
2024-07-26 14:47:36 -06:00
|
|
|
} // indicate
|
2022-01-16 20:11:18 -07:00
|
|
|
|
2021-12-29 03:11:37 +00:00
|
|
|
/**
|
2024-07-26 14:47:36 -06:00
|
|
|
* @brief Sends a notification or indication.
|
2022-01-16 20:11:18 -07:00
|
|
|
* @param[in] value A pointer to the data to send.
|
|
|
|
* @param[in] length The length of the data to send.
|
2024-11-25 18:41:10 -07:00
|
|
|
* @param[in] isNotification if true sends a notification, false sends an indication.
|
|
|
|
* @param[in] connHandle Connection handle to send to a specific peer.
|
|
|
|
* @return True if the value was sent successfully, false otherwise.
|
2021-12-29 03:11:37 +00:00
|
|
|
*/
|
2024-11-25 18:41:10 -07:00
|
|
|
bool NimBLECharacteristic::sendValue(const uint8_t* value, size_t length, bool isNotification, uint16_t connHandle) const {
|
|
|
|
int rc = 0;
|
|
|
|
|
|
|
|
if (value != nullptr && length > 0) { // custom notification value
|
|
|
|
// Notify all connected peers unless a specific handle is provided
|
|
|
|
for (const auto& ch : NimBLEDevice::getServer()->getPeerDevices()) {
|
|
|
|
if (connHandle != BLE_HS_CONN_HANDLE_NONE && ch != connHandle) {
|
|
|
|
continue; // only send to the specific handle, minor inefficiency but saves code.
|
2020-06-21 20:26:16 -06:00
|
|
|
}
|
|
|
|
|
2024-11-25 18:41:10 -07:00
|
|
|
// Must re-create the data buffer on each iteration because it is freed by the calls bellow.
|
|
|
|
os_mbuf* om = ble_hs_mbuf_from_flat(value, length);
|
|
|
|
if (!om) {
|
|
|
|
NIMBLE_LOGE(LOG_TAG, "<< sendValue: failed to allocate mbuf");
|
|
|
|
return false;
|
|
|
|
}
|
2020-05-13 22:03:56 -06:00
|
|
|
|
2024-11-25 18:41:10 -07:00
|
|
|
if (isNotification) {
|
|
|
|
rc = ble_gattc_notify_custom(ch, m_handle, om);
|
|
|
|
} else {
|
|
|
|
rc = ble_gattc_indicate_custom(ch, m_handle, om);
|
2021-05-17 14:08:02 -06:00
|
|
|
}
|
2020-06-11 08:06:16 -06:00
|
|
|
|
2024-11-25 18:41:10 -07:00
|
|
|
if (rc != 0) {
|
|
|
|
NIMBLE_LOGE(LOG_TAG, "<< sendValue: failed to send value, rc=%d %s", rc, NimBLEUtils::returnCodeToString(rc));
|
|
|
|
break;
|
2020-03-29 17:44:20 -06:00
|
|
|
}
|
|
|
|
}
|
2024-11-25 18:41:10 -07:00
|
|
|
} else if (connHandle != BLE_HS_CONN_HANDLE_NONE) { // only sending to specific peer
|
|
|
|
// Null buffer will read the value from the characteristic
|
|
|
|
if (isNotification) {
|
|
|
|
rc = ble_gattc_notify_custom(connHandle, m_handle, NULL);
|
|
|
|
} else {
|
|
|
|
rc = ble_gattc_indicate_custom(connHandle, m_handle, NULL);
|
|
|
|
}
|
|
|
|
} else { // Notify or indicate to all connected peers the characteristic value
|
|
|
|
ble_gatts_chr_updated(m_handle);
|
2020-05-13 22:03:56 -06:00
|
|
|
}
|
2020-03-29 17:44:20 -06:00
|
|
|
|
2024-11-25 18:41:10 -07:00
|
|
|
return rc == 0;
|
2024-07-26 14:47:36 -06:00
|
|
|
} // sendValue
|
2020-03-29 17:44:20 -06:00
|
|
|
|
2024-07-26 14:47:36 -06:00
|
|
|
void NimBLECharacteristic::readEvent(NimBLEConnInfo& connInfo) {
|
|
|
|
m_pCallbacks->onRead(this, connInfo);
|
2024-11-25 18:41:10 -07:00
|
|
|
} // readEvent
|
2024-07-26 14:47:36 -06:00
|
|
|
|
|
|
|
void NimBLECharacteristic::writeEvent(const uint8_t* val, uint16_t len, NimBLEConnInfo& connInfo) {
|
|
|
|
setValue(val, len);
|
|
|
|
m_pCallbacks->onWrite(this, connInfo);
|
2024-11-25 18:41:10 -07:00
|
|
|
} // writeEvent
|
2020-03-29 17:44:20 -06:00
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief Set the callback handlers for this characteristic.
|
2020-07-08 19:27:26 -06:00
|
|
|
* @param [in] pCallbacks An instance of a NimBLECharacteristicCallbacks class\n
|
|
|
|
* used to define any callbacks for the characteristic.
|
2020-03-29 17:44:20 -06:00
|
|
|
*/
|
|
|
|
void NimBLECharacteristic::setCallbacks(NimBLECharacteristicCallbacks* pCallbacks) {
|
2024-07-26 14:47:36 -06:00
|
|
|
if (pCallbacks != nullptr) {
|
2020-05-13 22:03:56 -06:00
|
|
|
m_pCallbacks = pCallbacks;
|
|
|
|
} else {
|
|
|
|
m_pCallbacks = &defaultCallback;
|
|
|
|
}
|
2020-03-29 17:44:20 -06:00
|
|
|
} // setCallbacks
|
|
|
|
|
2021-05-19 22:21:05 -06:00
|
|
|
/**
|
|
|
|
* @brief Get the callback handlers for this characteristic.
|
|
|
|
*/
|
2024-07-26 14:47:36 -06:00
|
|
|
NimBLECharacteristicCallbacks* NimBLECharacteristic::getCallbacks() const {
|
2021-05-19 22:21:05 -06:00
|
|
|
return m_pCallbacks;
|
2024-07-26 14:47:36 -06:00
|
|
|
} // getCallbacks
|
2020-03-29 17:44:20 -06:00
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief Return a string representation of the characteristic.
|
|
|
|
* @return A string representation of the characteristic.
|
|
|
|
*/
|
2024-07-26 14:47:36 -06:00
|
|
|
std::string NimBLECharacteristic::toString() const {
|
2020-05-13 22:03:56 -06:00
|
|
|
std::string res = "UUID: " + m_uuid.toString() + ", handle : 0x";
|
2024-07-26 14:47:36 -06:00
|
|
|
char hex[5];
|
|
|
|
snprintf(hex, sizeof(hex), "%04x", getHandle());
|
2020-05-13 22:03:56 -06:00
|
|
|
res += hex;
|
|
|
|
res += " ";
|
2024-07-26 14:47:36 -06:00
|
|
|
if (m_properties & BLE_GATT_CHR_PROP_READ) res += "Read ";
|
2020-05-13 22:03:56 -06:00
|
|
|
if (m_properties & BLE_GATT_CHR_PROP_WRITE) res += "Write ";
|
|
|
|
if (m_properties & BLE_GATT_CHR_PROP_WRITE_NO_RSP) res += "WriteNoResponse ";
|
|
|
|
if (m_properties & BLE_GATT_CHR_PROP_BROADCAST) res += "Broadcast ";
|
|
|
|
if (m_properties & BLE_GATT_CHR_PROP_NOTIFY) res += "Notify ";
|
|
|
|
if (m_properties & BLE_GATT_CHR_PROP_INDICATE) res += "Indicate ";
|
|
|
|
return res;
|
2020-03-29 17:44:20 -06:00
|
|
|
} // toString
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief Callback function to support a read request.
|
|
|
|
* @param [in] pCharacteristic The characteristic that is the source of the event.
|
2022-08-27 08:28:15 -06:00
|
|
|
* @param [in] connInfo A reference to a NimBLEConnInfo instance containing the peer info.
|
2020-03-29 17:44:20 -06:00
|
|
|
*/
|
2022-08-27 08:28:15 -06:00
|
|
|
void NimBLECharacteristicCallbacks::onRead(NimBLECharacteristic* pCharacteristic, NimBLEConnInfo& connInfo) {
|
2020-05-13 22:03:56 -06:00
|
|
|
NIMBLE_LOGD("NimBLECharacteristicCallbacks", "onRead: default");
|
2020-03-29 17:44:20 -06:00
|
|
|
} // onRead
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief Callback function to support a write request.
|
|
|
|
* @param [in] pCharacteristic The characteristic that is the source of the event.
|
2022-08-27 08:28:15 -06:00
|
|
|
* @param [in] connInfo A reference to a NimBLEConnInfo instance containing the peer info.
|
2020-03-29 17:44:20 -06:00
|
|
|
*/
|
2022-08-27 08:28:15 -06:00
|
|
|
void NimBLECharacteristicCallbacks::onWrite(NimBLECharacteristic* pCharacteristic, NimBLEConnInfo& connInfo) {
|
2020-05-13 22:03:56 -06:00
|
|
|
NIMBLE_LOGD("NimBLECharacteristicCallbacks", "onWrite: default");
|
2020-03-29 17:44:20 -06:00
|
|
|
} // onWrite
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief Callback function to support a Notify/Indicate Status report.
|
|
|
|
* @param [in] pCharacteristic The characteristic that is the source of the event.
|
2022-08-26 20:40:21 -06:00
|
|
|
* @param [in] code Status return code from the NimBLE stack.
|
|
|
|
* @details The status code for success is 0 for notifications and BLE_HS_EDONE for indications,
|
|
|
|
* any other value is an error.
|
2020-03-29 17:44:20 -06:00
|
|
|
*/
|
2022-08-26 20:40:21 -06:00
|
|
|
void NimBLECharacteristicCallbacks::onStatus(NimBLECharacteristic* pCharacteristic, int code) {
|
2020-05-13 22:03:56 -06:00
|
|
|
NIMBLE_LOGD("NimBLECharacteristicCallbacks", "onStatus: default");
|
2020-03-29 17:44:20 -06:00
|
|
|
} // onStatus
|
|
|
|
|
2020-07-27 21:11:38 -06:00
|
|
|
/**
|
|
|
|
* @brief Callback function called when a client changes subscription status.
|
|
|
|
* @param [in] pCharacteristic The characteristic that is the source of the event.
|
2022-08-27 08:28:15 -06:00
|
|
|
* @param [in] connInfo A reference to a NimBLEConnInfo instance containing the peer info.
|
2020-07-27 21:11:38 -06:00
|
|
|
* @param [in] subValue The subscription status:
|
|
|
|
* * 0 = Un-Subscribed
|
|
|
|
* * 1 = Notifications
|
|
|
|
* * 2 = Indications
|
|
|
|
* * 3 = Notifications and Indications
|
|
|
|
*/
|
|
|
|
void NimBLECharacteristicCallbacks::onSubscribe(NimBLECharacteristic* pCharacteristic,
|
2024-11-25 18:41:10 -07:00
|
|
|
NimBLEConnInfo& connInfo,
|
2024-07-26 14:47:36 -06:00
|
|
|
uint16_t subValue) {
|
2020-07-27 21:11:38 -06:00
|
|
|
NIMBLE_LOGD("NimBLECharacteristicCallbacks", "onSubscribe: default");
|
|
|
|
}
|
|
|
|
|
2021-09-06 21:14:43 -06:00
|
|
|
#endif /* CONFIG_BT_ENABLED && CONFIG_BT_NIMBLE_ROLE_PERIPHERAL */
|