nrf51822/source/nRF5xCharacteristicDescriptorDiscoverer.h

229 lines
8.8 KiB
C
Raw Normal View History

/* mbed Microcontroller Library
* Copyright (c) 2006-2015 ARM Limited
*
* 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
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* 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.
*/
#ifndef __NRF_CHARACTERISTIC_DESCRIPTOR_DISCOVERY_H__
#define __NRF_CHARACTERISTIC_DESCRIPTOR_DISCOVERY_H__
#include "ble/Gap.h"
#include "ble/DiscoveredCharacteristic.h"
#include "ble/CharacteristicDescriptorDiscovery.h"
#include "ble/GattClient.h"
#include "ble_gattc.h"
/**
* @brief Manage the discovery of Characteristic descriptors
* @details is a bridge between BLE API and Nordic stack regarding Characteristic
* Descriptor discovery. The BLE API can launch, monitor and ask for termination
* of a discovery. The Nordic stack will provide new descriptors and indicate when
* the discovery is done.
*/
class nRF5xCharacteristicDescriptorDiscoverer
{
typedef CharacteristicDescriptorDiscovery::DiscoveryCallback_t DiscoveryCallback_t;
typedef CharacteristicDescriptorDiscovery::TerminationCallback_t TerminationCallback_t;
public:
/**
* @brief Construct a new characteristic descriptor discoverer.
*/
nRF5xCharacteristicDescriptorDiscoverer();
/**
* @brief Destroy a characteristic descriptor discoverer.
*/
~nRF5xCharacteristicDescriptorDiscoverer();
/**
* Launch a new characteristic descriptor discovery for a given DiscoveredCharacteristic.
* @param characteristic The characteristic owning the descriptors to discover.
* @param discoveryCallback The callback called when a descriptor is discovered.
* @param terminationCallback The callback called when the discovery process end.
* @return BLE_ERROR_NONE if characteristic descriptor discovery is launched successfully;
* else an appropriate error.
* @note: this will be called by BLE API side.
*/
ble_error_t launch(
const DiscoveredCharacteristic& characteristic,
const DiscoveryCallback_t& discoveryCallback,
const TerminationCallback_t& terminationCallback
);
/**
* @brief indicate if a characteristic descriptor discovery is active for a
* given DiscoveredCharacteristic.
* @param characteristic The characteristic for whom the descriptor might be
* currently discovered.
* @return true if descriptors of characteristic are discovered, false otherwise.
* @note: this will be called by BLE API side.
*/
bool isActive(const DiscoveredCharacteristic& characteristic) const;
/**
* @brief request the termination of characteristic descriptor discovery
* for a give DiscoveredCharacteristic
* @param characteristic The characteristic for whom the descriptor discovery
* should be stopped.
* @note: this will be called by BLE API side.
*/
void requestTerminate(const DiscoveredCharacteristic& characteristic);
/**
* @brief process descriptors discovered from the Nordic stack.
* @param connectionHandle The connection handle upon which descriptors has been
* discovered.
* @param descriptors Discovered descriptors.
* @note This will be called by the Nordic stack.
*/
void process(uint16_t connectionHandle, const ble_gattc_evt_desc_disc_rsp_t& descriptors);
/**
* @brief Called by the Nordic stack when the discovery is over.
* @param The connection handle upon which the discovery process is done.
* @param err An error if the termination is due to an error.
*/
void terminate(uint16_t connectionHandle, ble_error_t err);
private:
// protection against copy construction and assignment
nRF5xCharacteristicDescriptorDiscoverer(const nRF5xCharacteristicDescriptorDiscoverer&);
nRF5xCharacteristicDescriptorDiscoverer& operator=(const nRF5xCharacteristicDescriptorDiscoverer&);
/**
* @brief Discovery process, it store the DiscoveredCharacteristic, the
* discovery callback and the termination callback.
*/
struct Discovery {
/**
* @brief Construct an empty discovery, such can be considerate as a not running discovery.
* @note #isEmpty function will return true
*/
Discovery() : characteristic(), onDiscovery(), onTerminate() { }
/**
* @brief Construct a valid discovery process.
*
* @param c the characteristic from whom descriptors will be discovered.
* @param dCb The discovery callback called each time a descriptor is discovered.
* @param tCb The termination callback called when the discovery terminate.
*
* @note #isEmpty function will return false
*/
Discovery(const DiscoveredCharacteristic& c, const DiscoveryCallback_t& dCb, const TerminationCallback_t& tCb) :
characteristic(c),
onDiscovery(dCb),
onTerminate(tCb) {
}
DiscoveredCharacteristic characteristic;
DiscoveryCallback_t onDiscovery;
TerminationCallback_t onTerminate;
/**
* @brief Process the discovery of a descriptor.
*
* @param handle The attribute handle of the descriptor found
* @param uuid The UUID of the descriptor found.
*/
void process(GattAttribute::Handle_t handle, const UUID& uuid) {
CharacteristicDescriptorDiscovery::DiscoveryCallbackParams_t params = {
characteristic,
DiscoveredCharacteristicDescriptor(
characteristic.getGattClient(),
characteristic.getConnectionHandle(),
handle,
uuid
)
};
onDiscovery.call(&params);
}
/**
* @brief Terminate the discovery process.
*
* @param err Error associate with the termination
*
* @note after this call #isEmpty function will return true.
*/
void terminate(ble_error_t err) {
CharacteristicDescriptorDiscovery::TerminationCallbackParams_t params = {
characteristic,
err
};
onTerminate.call(&params);
}
/**
* @brief check if the discovery process is empty or not. Empty discovery are
* not running.
* @detail Discovery are empty after:
* - a default construction
* - a copy construction form a default constructed
* - an assignment from a default constructed Discovery
* @return true if the Discovery is empty and false otherwise.
*/
bool isEmpty() const {
return *this == Discovery();
}
/**
* @brief equal to operator, test if two discovery process are equal
* @param lhs left hand side of the expression
* @param rhs right hand side of the expression
* @return true if lhs == rhs
*/
friend bool operator==(const Discovery& lhs, const Discovery& rhs) {
return lhs.characteristic == rhs.characteristic &&
lhs.onDiscovery == rhs.onDiscovery &&
lhs.onTerminate == rhs.onTerminate;
}
/**
* @brief not equal to operator, test if two discovery process are not equal
* @param lhs left hand side of the expression
* @param rhs right hand side of the expression
* @return true if lhs != rhs
*/
friend bool operator!=(const Discovery& lhs, const Discovery& rhs) {
return !(lhs == rhs);
}
};
// find a running discovery process
Discovery* findRunningDiscovery(const DiscoveredCharacteristic& characteristic);
Discovery* findRunningDiscovery(uint16_t handle);
// Called to terminate a discovery is over.
void terminate(Discovery* discovery, ble_error_t err);
// get one slot for a discovery process
Discovery* getAvailableDiscoverySlot();
// indicate if a connection is already running a discovery
bool isConnectionInUse(uint16_t connHandle);
// low level start of a discovery
static ble_error_t gattc_descriptors_discover(uint16_t connection_handle, uint16_t start_handle, uint16_t end_handle);
// count of concurrent connections which can run a descriptor discovery process
static const size_t MAXIMUM_CONCURRENT_CONNECTIONS_COUNT = 3;
// array of running discoveries
Discovery discoveryRunning[MAXIMUM_CONCURRENT_CONNECTIONS_COUNT];
};
#endif /*__NRF_CHARACTERISTIC_DESCRIPTOR_DISCOVERY_H__*/