Merge pull request #5392 from pan-/improve-ble-docs

Improve ble docs
pull/5358/merge
Martin Kojtal 2017-11-16 16:21:50 +00:00 committed by GitHub
commit 81dbd035ab
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
27 changed files with 5705 additions and 2707 deletions

View File

@ -20,28 +20,67 @@
#include <stddef.h>
#include <stdint.h>
/**
* @addtogroup ble
* @{
* @addtogroup common
* @{
*/
/**
* @file
*/
namespace ble {
/**
* Immutable view to an array.
*
* Array views encapsulate the pointer to an array and its size into a single
* object; however, it does not manage the lifetime of the array viewed.
* You can use instances of ArrayView to replace the traditional pair of pointer
* and size arguments in function calls.
*
* You can use the size member function to query the number of elements present
* in the array, and overloads of the subscript operator allow code using
* this object to access to the content of the array viewed.
*
* @note You can create ArrayView instances with the help of the function
* template make_ArrayView() and make_const_ArrayView().
*
* @tparam T type of objects held by the array.
*/
template<typename T>
struct ArrayView {
/**
* construct an array view to an empty array
* Construct a view to an empty array.
*
* @post a call to size() will return 0, and data() will return NULL.
*/
ArrayView() : _array(0), _size(0) { }
/**
* construct an array view from a pointer.
* and its size.
* Construct an array view from a pointer to a buffer and its size.
*
* @param array_ptr Pointer to the array data
* @param array_size Number of elements of T present in the array.
*
* @post a call to size() will return array_size and data() will return
* array_tpr.
*/
ArrayView(T* array_ptr, size_t array_size) :
_array(array_ptr), _size(array_size) { }
/**
* Construct an array view from the reference to an array.
*
* @param elements Reference to the array viewed.
*
* @tparam Size Number of elements of T presents in the array.
*
* @post a call to size() will return Size, and data() will return
* a pointer to elements.
*/
template<size_t Size>
ArrayView(T (&elements)[Size]):
@ -49,43 +88,73 @@ struct ArrayView {
/**
* Return the size of the array viewed.
*
* @return The number of elements present in the array viewed.
*/
size_t size() const {
size_t size() const
{
return _size;
}
/**
* Access to a mutable element of the array.
*
* @param index Element index to access.
*
* @return A reference to the element at the index specified in input.
*
* @pre index shall be less than size().
*/
T& operator[](size_t index) {
T& operator[](size_t index)
{
return _array[index];
}
/**
* Access to an immutable element of the array.
*
* @param index Element index to access.
*
* @return A const reference to the element at the index specified in input.
*
* @pre index shall be less than size().
*/
const T& operator[](size_t index) const {
const T& operator[](size_t index) const
{
return _array[index];
}
/**
* Get the pointer to the array
* Get the raw pointer to the array.
*
* @return The raw pointer to the array.
*/
T* data() {
T* data()
{
return _array;
}
/**
* Get the pointer to the const array
* Get the raw const pointer to the array.
*
* @return The raw pointer to the array.
*/
const T* data() const {
const T* data() const
{
return _array;
}
/**
* Equality operator
* Equality operator.
*
* @param lhs Left hand side of the binary operation.
* @param rhs Right hand side of the binary operation.
*
* @return True if arrays in input have the same size and the same content
* and false otherwise.
*/
friend bool operator==(const ArrayView& lhs, const ArrayView& rhs) {
friend bool operator==(const ArrayView& lhs, const ArrayView& rhs)
{
if (lhs.size() != rhs.size()) {
return false;
}
@ -99,8 +168,15 @@ struct ArrayView {
/**
* Not equal operator
*
* @param lhs Left hand side of the binary operation.
* @param rhs Right hand side of the binary operation.
*
* @return True if arrays in input do not have the same size or the same
* content and false otherwise.
*/
friend bool operator!=(const ArrayView& lhs, const ArrayView& rhs) {
friend bool operator!=(const ArrayView& lhs, const ArrayView& rhs)
{
return !(lhs == rhs);
}
@ -111,55 +187,86 @@ private:
/**
* Generate an array view from a C/C++ array.
* This helper avoid the typing of template parameter when ArrayView are
* Generate an array view from a reference to a C/C++ array.
*
* @tparam T Type of elements held in elements.
* @tparam Size Number of items held in elements.
*
* @param elements The reference to the array viewed.
*
* @return The ArrayView to elements.
*
* @note This helper avoids the typing of template parameter when ArrayView is
* created 'inline'.
* @param elements The array viewed.
* @return The array_view to elements.
*/
template<typename T, size_t Size>
ArrayView<T> make_ArrayView(T (&elements)[Size]) {
ArrayView<T> make_ArrayView(T (&elements)[Size])
{
return ArrayView<T>(elements);
}
/**
* Generate an array view from a C/C++ pointer and the size of the array.
* This helper avoid the typing of template parameter when ArrayView are
*
* @tparam T Type of elements held in array_ptr.
*
* @param array_ptr The pointer to the array to viewed.
* @param array_size The number of T elements in the array.
*
* @return The ArrayView to array_ptr with a size of array_size.
*
* @note This helper avoids the typing of template parameter when ArrayView is
* created 'inline'.
* @param array_ptr The pointer to the array to view.
* @param array_size The size of the array.
* @return The array_view to array_ptr with a size of array_size.
*/
template<typename T>
ArrayView<T> make_ArrayView(T* array_ptr, size_t array_size) {
ArrayView<T> make_ArrayView(T* array_ptr, size_t array_size)
{
return ArrayView<T>(array_ptr, array_size);
}
/**
* Generate a const array view from a C/C++ array.
* This helper avoid the typing of template parameter when ArrayView are
* created 'inline'.
* Generate a const array view from a reference to a C/C++ array.
*
* @tparam T Type of elements held in elements.
* @tparam Size Number of items held in elements.
*
* @param elements The array viewed.
* @return The ArrayView to elements.
*
* @note This helper avoids the typing of template parameter when ArrayView is
* created 'inline'.
*/
template<typename T, size_t Size>
ArrayView<const T> make_const_ArrayView(T (&elements)[Size]) {
ArrayView<const T> make_const_ArrayView(T (&elements)[Size])
{
return ArrayView<const T>(elements);
}
/**
* Generate a const array view from a C/C++ pointer and the size of the array.
* This helper avoid the typing of template parameter when ArrayView are
* created 'inline'.
* @param array_ptr The pointer to the array to view.
* @param array_size The size of the array.
*
* @tparam T Type of elements held in array_ptr.
*
* @param array_ptr The pointer to the array to viewed.
* @param array_size The number of T elements in the array.
*
* @return The ArrayView to array_ptr with a size of array_size.
*
* @note This helper avoids the typing of template parameter when ArrayView is
* created 'inline'.
*/
template<typename T>
ArrayView<const T> make_const_ArrayView(T* array_ptr, size_t array_size) {
ArrayView<const T> make_const_ArrayView(T* array_ptr, size_t array_size)
{
return ArrayView<const T>(array_ptr, array_size);
}
} // namespace ble
/**
* @}
* @}
*/
#endif /* BLE_ARRAY_VIEW_H_ */

File diff suppressed because it is too large Load Diff

View File

@ -14,8 +14,12 @@
* limitations under the License.
*/
#ifndef __BLE_DEVICE_INSTANCE_BASE__
#define __BLE_DEVICE_INSTANCE_BASE__
/**
* @file
*/
#ifndef MBED_BLE_DEVICE_INSTANCE_BASE__
#define MBED_BLE_DEVICE_INSTANCE_BASE__
#include "Gap.h"
#include "ble/SecurityManager.h"
@ -26,16 +30,33 @@ class GattServer;
class GattClient;
/**
* The interface for the transport object to be created by the target library's
* createBLEInstance().
* @addtogroup ble
* @{
* @addtogroup porting
* @{
*/
/**
* Private interface used to implement the BLE class.
*
* @note This class is part of the interface of BLE API with the implementation;
* therefore, it is meant to be used only by porters rather than normal
* BLE API users.
* The BLE class delegates all its abstract operations to an instance of this
* abstract class, which every vendor port of Mbed BLE shall implement.
*
* The vendor port shall also define an implementation of the freestanding function
* createBLEInstance(). The BLE API uses this singleton function to gain
* access to a concrete implementation of this class defined in the vendor port.
*
* @important This class is part of the porting API and is not meant to be used
* by end users of BLE API.
*
* @see BLE
*/
class BLEInstanceBase
{
public:
/**
* Base constructor.
*/
BLEInstanceBase() {}
/**
@ -44,133 +65,206 @@ public:
virtual ~BLEInstanceBase();
/**
* Initialize the underlying BLE stack. This should be called before
* anything else in the BLE API.
* Process ALL pending events living in the vendor BLE subsystem.
*
* @param[in] instanceID
* The ID of the instance to initialize.
* @param[in] initCallback
* A callback for when initialization completes for a BLE
* instance. This is an optional parameter set to NULL when not
* supplied.
* Return once all pending events have been consumed.
*
* @return BLE_ERROR_NONE if the initialization procedure was started
* successfully.
*/
virtual ble_error_t init(BLE::InstanceID_t instanceID,
FunctionPointerWithContext<BLE::InitializationCompleteCallbackContext *> initCallback) = 0;
/**
* Check whether the underlying stack has already been initialized,
* possible with a call to init().
*
* @return true if the initialization has completed for the underlying BLE
* stack.
*/
virtual bool hasInitialized(void) const = 0;
/**
* Shutdown the underlying BLE stack. This includes purging the stack of
* GATT and GAP state and clearing all state from other BLE components
* such as the SecurityManager. init() must be called afterwards to
* re-instantiate services and GAP state.
*
* @return BLE_ERROR_NONE if the underlying stack and all other services of
* the BLE API were shutdown correctly.
*/
virtual ble_error_t shutdown(void) = 0;
/**
* Fetches a string representation of the underlying BLE stack's version.
*
* @return A pointer to the string representation of the underlying
* BLE stack's version.
*/
virtual const char * getVersion(void) = 0;
/**
* Accessor to Gap. This function is used by BLE::gap().
*
* @return A reference to a Gap object associated to this BLE instance.
*/
virtual Gap& getGap() = 0;
/**
* A const alternative to getGap().
*
* @return A const reference to a Gap object associated to this BLE instance.
*/
virtual const Gap& getGap() const = 0;
/**
* Accessor to GattServer. This function is used by BLE::gattServer().
*
* @return A reference to a GattServer object associated to this BLE instance.
*/
virtual GattServer& getGattServer() = 0;
/**
* A const alternative to getGattServer().
*
* @return A const reference to a GattServer object associated to this BLE instance.
*/
virtual const GattServer& getGattServer() const = 0;
/**
* Accessors to GattClient. This function is used by BLE::gattClient().
*
* @return A reference to a GattClient object associated to this BLE instance.
*/
virtual GattClient& getGattClient() = 0;
/**
* Accessors to SecurityManager. This function is used by BLE::securityManager().
*
* @return A reference to a SecurityManager object associated to this BLE instance.
*/
virtual SecurityManager& getSecurityManager() = 0;
/**
* A const alternative to getSecurityManager().
*
* @return A const reference to a SecurityManager object associated to this BLE instance.
*/
virtual const SecurityManager& getSecurityManager() const = 0;
/**
* Yield control to the BLE stack or to other tasks waiting for events.
* refer to BLE::waitForEvent().
*/
virtual void waitForEvent(void) = 0;
/**
* Process ALL pending events living in the BLE stack .
* Return once all events have been consumed.
* @see BLE::processEvents()
*/
virtual void processEvents() = 0;
/**
* This function allow the BLE stack to signal that their is work to do and
* event processing should be done (BLE::processEvent()).
* @param id: The ID of the BLE instance which does have events to process.
* Signal to BLE that events needing processing are available.
*
* The vendor port shall call this function whenever there are events
* ready to be processed in the internal stack or BLE subsystem. As a result
* of this call, the callback registered by the end user via
* BLE::onEventsToProcess will be invoked.
*
* @param[in] id: Identifier of the BLE instance, which does have events to
* ready to be processed.
*/
void signalEventsToProcess(BLE::InstanceID_t id);
/**
* Start the initialization of the vendor BLE subsystem.
*
* Calls to this function are initiated by BLE::init, instanceID identify
* the BLE instance which issue that call while the initCallback is used to
* signal asynchronously the completion of the initialization process.
*
* @param[in] instanceID Identifier of the BLE instance requesting
* initialization.
* @param[in] initCallback Callback which the vendor port shall invoke
* when the initialization completes.
*
* This is an optional parameter set to NULL when not supplied.
*
* @return BLE_ERROR_NONE if the initialization procedure started
* successfully.
*
* @post initCallback shall be invoked upon completion of the initialization
* process.
*
* @post hasInitialized() shall return false until the initialization is
* complete, and it shall return true after succesful completion of the
* initialization process.
*
* @see BLE::init()
*/
virtual ble_error_t init(
BLE::InstanceID_t instanceID,
FunctionPointerWithContext<BLE::InitializationCompleteCallbackContext*> initCallback
) = 0;
/**
* Check whether the vendor BLE subsystem has been initialized or not.
*
* @return true if the initialization has completed for the vendor BLE
* subsystem.
*
* @note this function is invoked by BLE::hasInitialized()
*
* @see BLE::init() BLE::hasInitialized()
*/
virtual bool hasInitialized(void) const = 0;
/**
* Shutdown the vendor BLE subsystem.
*
* This operation includes purging the stack of GATT and GAP state and
* clearing all state from other BLE components, such as the SecurityManager.
* Clearing all states may be realized by a call to Gap::reset(),
* GattClient::reset(), GattServer::reset() and SecurityManager::reset().
*
* BLE::init() must be called afterward to reinstantiate services and GAP
* state.
*
* @return BLE_ERROR_NONE if the underlying stack and all other services of
* the BLE API were shut down correctly.
*
* @post hasInitialized() shall return false.
*
* @note This function is invoked by BLE::shutdown().
*
* @see BLE::shutdown() BLE::init() BLE::hasInitialized() Gap::reset()
* GattClient::reset() GattServer::reset() SecurityManager::reset() .
*/
virtual ble_error_t shutdown(void) = 0;
/**
* Fetches a NULL terminated string representation of the underlying BLE
* vendor subsystem.
*
* @return A pointer to the NULL terminated string representation of the
* underlying BLE stack's version.
*
* @see BLE::getVersion()
*/
virtual const char *getVersion(void) = 0;
/**
* Accessor to the vendor implementation of the Gap interface.
*
* @return A reference to a Gap object associated to this BLEInstanceBase
* instance.
*
* @see BLE::gap() Gap
*/
virtual Gap &getGap(void) = 0;
/**
* Const alternative to getGap().
*
* @return A const reference to a Gap object associated to this
* BLEInstanceBase instance.
*
* @see BLE::gap() Gap
*/
virtual const Gap &getGap(void) const = 0;
/**
* Accessor to the vendor implementation of the GattServer interface.
*
* @return A reference to a GattServer object associated to this
* BLEInstanceBase instance.
*
* @see BLE::gattServer() GattServer
*/
virtual GattServer &getGattServer(void) = 0;
/**
* A const alternative to getGattServer().
*
* @return A const reference to a GattServer object associated to this
* BLEInstanceBase instance.
*
* @see BLE::gattServer() GattServer
*/
virtual const GattServer &getGattServer(void) const = 0;
/**
* Accessor to the vendor implementation of the GattClient interface.
*
* @return A reference to a GattClient object associated to this
* BLEInstanceBase instance.
*
* @see BLE::gattClient() GattClient
*/
virtual GattClient &getGattClient(void) = 0;
/**
* Accessor to the vendor implementation of the SecurityManager interface.
*
* @return A reference to a SecurityManager object associated to this
* BLEInstanceBase instance.
*
* @see BLE::securityManager() SecurityManager
*/
virtual SecurityManager &getSecurityManager(void) = 0;
/**
* A const alternative to getSecurityManager().
*
* @return A const reference to a SecurityManager object associated to this
* BLEInstancebase instance.
*
* @see BLE::securityManager() SecurityManager
*/
virtual const SecurityManager &getSecurityManager(void) const = 0;
/**
* Process pending events present in the vendor subsystem; then, put the MCU
* to sleep until an external source wakes it up.
*
* @important This function is deprecated in the BLE class. It will be
* removed from this interface once it is removed from BLE.
*
* @see BLE::waitForEvent() BLE::processEvents()
*/
virtual void waitForEvent(void) = 0;
private:
// this class is not a value type.
// prohibit copy construction and copy assignement
BLEInstanceBase(const BLEInstanceBase&);
BLEInstanceBase& operator=(const BLEInstanceBase&);
BLEInstanceBase &operator=(const BLEInstanceBase&);
};
/**
* BLE uses composition to hide an interface object encapsulating the
* backend transport.
* Return the instance of the vendor implementation of BLEInstanceBase.
*
* The following API is used to create the singleton interface object. An
* implementation for this function must be provided by the device-specific
* library, otherwise there will be a linker error.
* @important Contrary to its name, this function does not return a new instance
* at each call. It rather acts like an accessor to a singleton.
*
* @important The vendor library must provide an implementation for this function
* library. Otherwise, there will be a linker error.
*/
extern BLEInstanceBase *createBLEInstance(void);
#endif // ifndef __BLE_DEVICE_INSTANCE_BASE__
/**
* @}
* @}
*/
#endif // ifndef MBED_BLE_DEVICE_INSTANCE_BASE__

View File

@ -14,67 +14,130 @@
* limitations under the License.
*/
#ifndef __BLE_PROTOCOL_H__
#define __BLE_PROTOCOL_H__
#ifndef MBED_BLE_PROTOCOL_H__
#define MBED_BLE_PROTOCOL_H__
#include <stddef.h>
#include <stdint.h>
#include <algorithm>
/**
* A common namespace for types and constants used everywhere in BLE API.
* @addtogroup ble
* @{
* @addtogroup common
* @{
*/
/**
* Common namespace for types and constants used everywhere in BLE API.
*/
namespace BLEProtocol {
/**
* A simple container for the enumeration of address-types for Protocol addresses.
* Container for the enumeration of BLE address types.
*
* Adding a struct to encapsulate the contained enumeration prevents
* @note Adding a struct to encapsulate the contained enumeration prevents
* polluting the BLEProtocol namespace with the enumerated values. It also
* allows type-aliases for the enumeration while retaining the enumerated
* values. i.e. doing:
*
* @code
* typedef AddressType AliasedType;
* @endcode
*
* would allow the use of AliasedType::PUBLIC in code.
*
* @note see Bluetooth Standard version 4.2 [Vol 6, Part B] section 1.3 .
*/
struct AddressType {
/** Address-types for Protocol addresses. */
/**
* Address-types for Protocol addresses.
*/
enum Type {
/**
* Public device address.
*/
PUBLIC = 0,
/**
* Random static device address.
*/
RANDOM_STATIC,
/**
* Private resolvable device address.
*/
RANDOM_PRIVATE_RESOLVABLE,
/**
* Private non-resolvable device address.
*/
RANDOM_PRIVATE_NON_RESOLVABLE
};
};
typedef AddressType::Type AddressType_t; /**< Alias for AddressType::Type */
static const size_t ADDR_LEN = 6; /**< Length (in octets) of the BLE MAC address. */
typedef uint8_t AddressBytes_t[ADDR_LEN]; /**< 48-bit address, in LSB format. */
/**
* BLE address. It contains an address-type (AddressType_t) and bytes (AddressBytes_t).
* Alias for AddressType::Type
*/
typedef AddressType::Type AddressType_t;
/**
* Length (in octets) of the BLE MAC address.
*/
static const size_t ADDR_LEN = 6;
/**
* 48-bit address, in LSB format.
*/
typedef uint8_t AddressBytes_t[ADDR_LEN];
/**
* BLE address representation.
*
* It contains an address-type (::AddressType_t) and the address value
* (::AddressBytes_t).
*/
struct Address_t {
AddressType_t type; /**< The type of the BLE address. */
AddressBytes_t address; /**< The BLE address. */
/**
* Construct an Address_t object with the supplied type and address.
*
* @param[in] typeIn
* The BLE address type.
* @param[in] addressIn
* The BLE address.
* @param[in] typeIn The BLE address type.
* @param[in] addressIn The BLE address.
*
* @post type is equal to typeIn and address is equal to the content
* present in addressIn.
*/
Address_t(AddressType_t typeIn, const AddressBytes_t& addressIn) : type(typeIn) {
Address_t(AddressType_t typeIn, const AddressBytes_t &addressIn) :
type(typeIn) {
std::copy(addressIn, addressIn + ADDR_LEN, address);
}
/**
* Empty constructor.
*
* @note The address constructed with the empty constructor is not
* valid.
*
* @post type is equal to PUBLIC and the address value is equal to
* 00:00:00:00:00:00
*/
Address_t() : type(), address() {
}
Address_t(void) : type(), address() { }
/**
* Type of the BLE device address.
*/
AddressType_t type;
/**
* Value of the device address.
*/
AddressBytes_t address;
};
};
#endif /* __BLE_PROTOCOL_H__ */
/**
* @}
* @}
*/
#endif /* MBED_BLE_PROTOCOL_H__ */

View File

@ -20,36 +20,73 @@
#include <stddef.h>
#include <stdint.h>
/**
* @addtogroup ble
* @{
* @addtogroup common
* @{
*/
namespace ble {
/**
* A connection handle is an unsigned integer capable of holding a pointer.
* The real type (either a pointer to an object or an integer) is opaque and
* platform dependent.
* Opaque reference to a connection.
*
* Internally a connection handle is an unsigned integer capable of holding a
* pointer.
*
* The real type (either a pointer to an object or an integer) is opaque for
* users and platform dependent.
*/
typedef uintptr_t connection_handle_t;
/**
* Model an attribute handle in a GATT database.
* Reference to an attribute in a GATT database.
*/
typedef uint16_t attribute_handle_t;
/**
* Model an inclusive range of GATT attributes handles.
* Inclusive range of GATT attributes handles.
*
* @note Instances can be constructed with the help of the factory function
* attribute_handle_range().
*/
struct attribute_handle_range_t {
/**
* Begining of the range.
*/
attribute_handle_t begin;
/**
* End of the range.
*/
attribute_handle_t end;
/**
* Equal operator for attribute_handle_range_t.
*
* @param[in] lhs Left hand side of the expression.
* @param[in] rhs Right hand side of the expression.
*
* @return true if lhs is equal to rhs and false otherwise.
*/
friend bool operator==(
const attribute_handle_range_t& lhs, const attribute_handle_range_t& rhs
const attribute_handle_range_t &lhs, const attribute_handle_range_t &rhs
) {
return (lhs.begin == rhs.begin) && (lhs.end == rhs.end);
}
/**
* Not equal operator for attribute_handle_range_t.
*
* @param[in] lhs Left hand side of the expression.
* @param[in] rhs Right hand side of the expression.
*
* @return true if lhs is not equal to rhs and false otherwise.
*/
friend bool operator!=(
const attribute_handle_range_t& lhs, const attribute_handle_range_t& rhs
const attribute_handle_range_t &lhs, const attribute_handle_range_t &rhs
) {
return !(lhs == rhs);
}
@ -57,7 +94,15 @@ struct attribute_handle_range_t {
/**
* Construct an attribute_handle_range_t from its start and end handle.
* Construct an attribute_handle_range_t from its first and last attribute handle.
*
* @param begin Handle at the begining of the range.
* @param end Handle at the end of the range.
*
* @return An instance of attribute_handle_range_t where
* attribute_handle_range_t::begin is equal to begin and
* attribute_handle_range_t::end is equal to end.
*
* @note This function is defined instead of a constructor to keep "POD-ness"
* of attribute_handle_range_t.
*/
@ -74,4 +119,9 @@ static inline attribute_handle_range_t attribute_handle_range(
} // namespace ble
/**
* @}
* @}
*/
#endif /* BLE_TYPES_H_ */

View File

@ -20,10 +20,22 @@
#include "FunctionPointerWithContext.h"
#include "SafeBool.h"
/**
* @addtogroup ble
* @{
* @addtogroup common
* @{
*/
/** Group one or more functions in an instance of a CallChainOfFunctionPointersWithContext, then call them in
* sequence using CallChainOfFunctionPointersWithContext::call(). Used mostly by the interrupt chaining code,
* but can be used for other purposes.
/**
* Function like object hosting a list of FunctionPointerWithContext.
*
* Upon call, each FunctionPointerWithContext instance present in the object will
* be called in sequence with the initial parameters.
*
* It can be seen as a variation of the observer pattern this object being the
* observable, instances of the FunctionPointerWithContext being the observable
* and the notify/update operation being the function call.
*
* Example:
* @code
@ -51,81 +63,96 @@
* chain.add(second);
* chain.add_front(first);
* chain.add(&test, &Test::f);
*
* // will print:
* // 'second' function.
* // 'first' function.
* // A::f (class member).
* chain.call();
* }
* @endcode
*
* @note memory allocation is used to add new function like objects into the
* call chain.
*
* @tparam ContextType Type of the parameter accepted by the callbacks hosted
* in the object.
*/
template <typename ContextType>
class CallChainOfFunctionPointersWithContext : public SafeBool<CallChainOfFunctionPointersWithContext<ContextType> > {
class CallChainOfFunctionPointersWithContext :
public SafeBool<CallChainOfFunctionPointersWithContext<ContextType> > {
public:
/**
* The type of each callback in the callchain.
* Alias of the FunctionPointerWithContext type this object can store.
*/
typedef FunctionPointerWithContext<ContextType> *pFunctionPointerWithContext_t;
public:
/**
* Create an empty chain.
* Create an empty callchain.
*/
CallChainOfFunctionPointersWithContext() : chainHead(NULL) {
/* empty */
}
CallChainOfFunctionPointersWithContext() : chainHead(NULL) { }
virtual ~CallChainOfFunctionPointersWithContext() {
/**
* Destruction of the callchain.
*/
virtual ~CallChainOfFunctionPointersWithContext()
{
clear();
}
/**
* Add a function at the front of the chain.
* Add a function pointer at the front of the chain.
*
* @param[in] function
* A pointer to a void function.
* @param[in] function A pointer to a void function.
*
* @return The function object created for @p function.
* @return The FunctionPointerWithContext object created from @p function.
*/
pFunctionPointerWithContext_t add(void (*function)(ContextType context)) {
pFunctionPointerWithContext_t add(void (*function)(ContextType context))
{
return common_add(new FunctionPointerWithContext<ContextType>(function));
}
/**
* Add a function at the front of the chain.
* Add a member function bound to its instance at the front of the chain.
*
* @param[in] tptr
* Pointer to the object to call the member function on.
* @param[in] mptr
* Pointer to the member function to be called.
* @param[in] tptr Pointer to the object to call the member function on.
* @param[in] mptr Pointer to the member function to be called.
*
* @return The function object created for @p tptr and @p mptr.
* @return The FunctionPointerWithContext object created from @p tptr and
* @p mptr.
*/
template<typename T>
pFunctionPointerWithContext_t add(T *tptr, void (T::*mptr)(ContextType context)) {
pFunctionPointerWithContext_t add(T *tptr, void (T::*mptr)(ContextType context))
{
return common_add(new FunctionPointerWithContext<ContextType>(tptr, mptr));
}
/**
* Add a function at the front of the chain.
* Add a FunctionPointerWithContext at the front of the chain.
*
* @param[in] func
* The FunctionPointerWithContext to add.
* @param[in] func The FunctionPointerWithContext to add.
*
* @return The function object created for @p func.
*/
pFunctionPointerWithContext_t add(const FunctionPointerWithContext<ContextType>& func) {
pFunctionPointerWithContext_t add(const FunctionPointerWithContext<ContextType> &func)
{
return common_add(new FunctionPointerWithContext<ContextType>(func));
}
/**
* Detach a function pointer from a callchain.
*
* @param[in] toDetach
* FunctionPointerWithContext to detach from this callchain.
* @param[in] toDetach FunctionPointerWithContext instance to detach from
* this callchain.
*
* @return true if a function pointer has been detached and false otherwise.
*
* @note It is safe to remove a function pointer while the chain is
* traversed by call(ContextType).
* @note It is safe to remove a function pointer while
* call(ContextType) is traversing the chain.
*/
bool detach(const FunctionPointerWithContext<ContextType>& toDetach) {
bool detach(const FunctionPointerWithContext<ContextType> &toDetach)
{
pFunctionPointerWithContext_t current = chainHead;
pFunctionPointerWithContext_t previous = NULL;
@ -154,9 +181,10 @@ public:
}
/**
* Clear the call chain (remove all functions in the chain).
* Remove all functions registered in the chain.
*/
void clear(void) {
void clear(void)
{
pFunctionPointerWithContext_t fptr = chainHead;
while (fptr) {
pFunctionPointerWithContext_t deadPtr = fptr;
@ -172,21 +200,28 @@ public:
*
* @return true if the callchain is not empty and false otherwise.
*/
bool hasCallbacksAttached(void) const {
bool hasCallbacksAttached(void) const
{
return (chainHead != NULL);
}
/**
* Call all the functions in the chain in sequence.
* Call sequentially each member of the chain.
*
* @param[in] context Parameter to pass to the functions called.
*/
void call(ContextType context) {
void call(ContextType context)
{
((const CallChainOfFunctionPointersWithContext*) this)->call(context);
}
/**
* Same as call() above, but const.
* Call sequentially each member of the chain.
*
* @param[in] context Parameter to pass to the functions called.
*/
void call(ContextType context) const {
void call(ContextType context) const
{
currentCalled = chainHead;
while(currentCalled) {
@ -201,7 +236,10 @@ public:
}
/**
* Same as call(), but with function call operator.
* Call sequentially each member of the chain.
*
* @param[in] context Parameter to pass to the functions called.
*
* @code
*
* void first(bool);
@ -217,16 +255,33 @@ public:
*
* @endcode
*/
void operator()(ContextType context) const {
void operator()(ContextType context) const
{
call(context);
}
/**
* Bool conversion operation.
* Test if the callchain is empty or not.
*
* @return true if the callchain is not empty and false otherwise.
*
* @note used by SafeBool to offer a safe boolean conversion.
*
* @code
* CallChainOfFunctionPointersWithContext<void *> chain;
*
* if (!chain) {
* // Do something if the chain is empty.
* }
*
* if (chain) {
* // Do something if the chain is not empty.
* }
* @endcode
*
*/
bool toBool() const {
bool toBool() const
{
return chainHead != NULL;
}
@ -236,7 +291,8 @@ private:
*
* @return A pointer to the head of the callchain.
*/
pFunctionPointerWithContext_t common_add(pFunctionPointerWithContext_t pf) {
pFunctionPointerWithContext_t common_add(pFunctionPointerWithContext_t pf)
{
if (chainHead == NULL) {
chainHead = pf;
} else {
@ -249,23 +305,37 @@ private:
private:
/**
* A pointer to the first callback in the callchain or NULL if the callchain is empty.
* Pointer to the first callback of the callchain or NULL if the callchain
* is empty.
*/
pFunctionPointerWithContext_t chainHead;
/**
* Iterator during a function call, this has to be mutable because the call function is const.
* Pointer to the function being called.
*
* @note Mutable is the correct behaviour here, the iterator never leaks outside the object.
* so the object can still be seen as logically const even if it is modified.
* It is used to maintain the data structure integrity if a function is
* removed during the call() operation.
*
* @note It has to be mutable to accomodate the const version of call(). The
* iterator doesn't leak outside the object; therefore, it remains seen as
* const from an external standpoint.
*/
mutable pFunctionPointerWithContext_t currentCalled;
/* Disallow copy constructor and assignment operators. */
private:
CallChainOfFunctionPointersWithContext(const CallChainOfFunctionPointersWithContext &);
CallChainOfFunctionPointersWithContext & operator = (const CallChainOfFunctionPointersWithContext &);
CallChainOfFunctionPointersWithContext(
const CallChainOfFunctionPointersWithContext&
);
CallChainOfFunctionPointersWithContext &operator=(
const CallChainOfFunctionPointersWithContext&
);
};
/**
* @}
* @}
*/
#endif

View File

@ -14,8 +14,8 @@
* limitations under the License.
*/
#ifndef __CHARACTERISTIC_DESCRIPTOR_DISCOVERY_H__
#define __CHARACTERISTIC_DESCRIPTOR_DISCOVERY_H__
#ifndef MBED_CHARACTERISTIC_DESCRIPTOR_DISCOVERY_H__
#define MBED_CHARACTERISTIC_DESCRIPTOR_DISCOVERY_H__
#include "FunctionPointerWithContext.h"
@ -23,82 +23,118 @@ class DiscoveredCharacteristic; // forward declaration
class DiscoveredCharacteristicDescriptor; // forward declaration
/**
* @brief Contain all definitions of callbacks and callbacks parameters types
* related to characteristic descriptor discovery.
* @addtogroup ble
* @{
* @addtogroup gatt
* @{
*/
/**
* Definitions of events and event handlers that the characteristic descriptor
* discovery procedure uses.
*
* @details This class act like a namespace for characteristic descriptor discovery
* types. It act like ServiceDiscovery by providing callbacks and callbacks
* parameters types related to the characteristic descriptor discovery process but
* contrary to ServiceDiscovery class, it does not force the porter to use a
* specific interface for the characteristic descriptor discovery process.
* This class acts like a namespace for characteristic descriptor discovery
* types. Like ServiceDiscovery, it provides callbacks and callbacks parameters
* types related to the characteristic descriptor discovery process, but contrary
* to the ServiceDiscovery class, it does not force the porter to use a specific
* interface for the characteristic descriptor discovery process.
*/
class CharacteristicDescriptorDiscovery {
public:
/**
* @brief Parameter type of CharacteristicDescriptorDiscovery::DiscoveryCallback_t.
* @details Every time a characteristic descriptor has been discovered, the callback
* registered for the discovery operation through GattClient::discoverCharacteristicDescriptors
* or DiscoveredCharacteristic::discoverDescriptors will be called with this parameter.
* Characteristic descriptor discovered event.
*
* When a characteristic descriptor has been discovered, the callback
* registered for the discovery operation through
* GattClient::discoverCharacteristicDescriptors or
* DiscoveredCharacteristic::discoverDescriptors is called with an instance
* of this type.
*
* The values reported to the user are the descriptor discovered and the
* characteristic owning that descriptor.
*
* @see GattClient::discoverCharacteristicDescriptors
* DiscoveredCharacteristic::discoverDescriptors
*/
struct DiscoveryCallbackParams_t {
/**
* The characteristic owning the DiscoveredCharacteristicDescriptor
* Characteristic owning the descriptor discovered.
*/
const DiscoveredCharacteristic& characteristic;
const DiscoveredCharacteristic &characteristic;
/**
* The characteristic descriptor discovered
* Characteristic descriptor discovered.
*/
const DiscoveredCharacteristicDescriptor& descriptor;
const DiscoveredCharacteristicDescriptor &descriptor;
};
/**
* @brief Parameter type of CharacteristicDescriptorDiscovery::TerminationCallback_t.
* @details Once a characteristic descriptor discovery process terminate, the termination
* callback registered for the discovery operation through
* GattClient::discoverCharacteristicDescriptors or DiscoveredCharacteristic::discoverDescriptors
* will be called with this parameter.
* Characteristic descriptor discovery ended event.
*
* When the characteristic descriptor discovery process ends, the
* termination callback registered for the discovery operation through
* GattClient::discoverCharacteristicDescriptors or
* DiscoveredCharacteristic::discoverDescriptors will be called with an
* instance of this type.
*
* @see GattClient::discoverCharacteristicDescriptors
* DiscoveredCharacteristic::discoverDescriptors
*/
struct TerminationCallbackParams_t {
/**
* The characteristic for which the descriptors has been discovered
* Characteristic for which descriptors has been discovered.
*/
const DiscoveredCharacteristic& characteristic;
/**
* status of the discovery operation
* Status of the discovery operation.
*/
ble_error_t status;
/**
* error code associated with the status if any.
* Error code associated with the status if any.
*/
uint8_t error_code;
};
/**
* @brief Callback type for when a matching characteristic descriptor is found during
* characteristic descriptor discovery.
* Characteristic descriptor discovered event handler.
*
* @param param A pointer to a DiscoveryCallbackParams_t object which will remain
* valid for the lifetime of the callback. Memory for this object is owned by
* the BLE_API eventing framework. The application can safely make a persistent
* shallow-copy of this object in order to work with the service beyond the
* callback.
* As a parameter, it expects a pointer to a DiscoveryCallbackParams_t instance.
*
* @note The object passed in parameter will remain valid for the lifetime
* of the callback. The BLE_API eventing framework owns memory for this
* object. The application can safely make a persistent shallow-copy of
* this object to work with the service beyond the callback.
*
* @see DiscoveryCallbackParams_t
* GattClient::discoverCharacteristicDescriptors
* DiscoveredCharacteristic::discoverDescriptors
*/
typedef FunctionPointerWithContext<const DiscoveryCallbackParams_t*> DiscoveryCallback_t;
typedef FunctionPointerWithContext<const DiscoveryCallbackParams_t*>
DiscoveryCallback_t;
/**
* @brief Callback type for when characteristic descriptor discovery terminates.
* Handler of Characteristic descriptor discovery ended event.
*
* @param param A pointer to a TerminationCallbackParams_t object which will remain
* valid for the lifetime of the callback. Memory for this object is owned by
* the BLE_API eventing framework. The application can safely make a persistent
* shallow-copy of this object in order to work with the service beyond the
* callback.
* As a parameter, it expects a pointer to a TerminationCallbackParams_t instance.
*
* @note The object passed in parameter will remain valid for the lifetime
* of the callback. The BLE_API eventing framework owns the memory for this
* object. The application can safely make a persistent shallow-copy of
* this object to work with the service beyond the callback.
*
* @see TerminationCallbackParams_t
* GattClient::discoverCharacteristicDescriptors
* DiscoveredCharacteristic::discoverDescriptors
*/
typedef FunctionPointerWithContext<const TerminationCallbackParams_t*> TerminationCallback_t;
typedef FunctionPointerWithContext<const TerminationCallbackParams_t*>
TerminationCallback_t;
};
#endif // ifndef __CHARACTERISTIC_DESCRIPTOR_DISCOVERY_H__
/**
* @}
* @}
*/
#endif // ifndef MBED_CHARACTERISTIC_DESCRIPTOR_DISCOVERY_H__

View File

@ -14,8 +14,8 @@
* limitations under the License.
*/
#ifndef __DISCOVERED_CHARACTERISTIC_H__
#define __DISCOVERED_CHARACTERISTIC_H__
#ifndef MBED_DISCOVERED_CHARACTERISTIC_H__
#define MBED_DISCOVERED_CHARACTERISTIC_H__
#include "UUID.h"
#include "Gap.h"
@ -25,116 +25,230 @@
#include "DiscoveredCharacteristicDescriptor.h"
/**
* @brief Representation of a characteristic discovered during a GattClient
* discovery procedure (see GattClient::launchServiceDiscovery ).
* @addtogroup ble
* @{
* @addtogroup gatt
* @{
* @addtogroup client
* @{
*/
/**
* Representation of a characteristic discovered.
*
* @details Provide detailed informations about a discovered characteristic like:
* - Its UUID (see getUUID()).
* - The most important handles of the characteristic definition
* (see getDeclHandle(), getValueHandle(), getLastHandle())
* - Its properties (see getProperties()).
* This class also provide functions to operate on the characteristic:
* - Read the characteristic value (see read())
* - Writing a characteristic value (see write() or writeWoResponse())
* - Discover descriptors inside the characteristic definition. These descriptors
* extends the characteristic. More information about descriptor usage is
* available in DiscoveredCharacteristicDescriptor class.
* The GattClient discovery procedure initiated with
* GattClient::launchServiceDiscovery() generates instances of this class.
*
* It exposes the main attributes of the discovered characteristic:
* - The UUID of the characteristic, it can be retrieved by a call to the
* function getUUID(). This UUID is the type of the characteristic.
* - Attribute Handles of the characteristic are present as the triplet
* declaration handle, value handle and last handle. The value handle is
* used to read or write the content of the characteristic.
* - The properties contain the set of operations the characteristic can
* handle, for instance being read or written.
*
* It important to note that the value of the characteristic - if it is
* accessible - is not fetched at discovery time.
*
* The main operations the class offers are reading, writing and discovering
* the descriptors of the characteristic discovered.
*
* Reading a discovered characteristic can be accomplished in two different
* fashions:
*
* If the user has a callback registered for the data read operation in the
* GattClient, then a call to the read(uint16_t) function will initiate a read of
* the characteristic. Results of the operation will be pass on the callback
* registered by GattClient::onDataRead(), which processes all the responses to
* read requests. The read request for a given characteristic can be identified
* by the connection handle and the attribute handle, which are present in
* GattReadCallbackParams.
*
* Another overload (read(uint16_t, const GattClient::ReadCallback_t&)) of the
* read function accepts a completion callback as a last parameter. That
* completion callback will be invoked automatically once the response to the
* read request for that given characteristic has been received. However,
* convenience came at the expense of dynamic memory usage for the time of the
* transaction.
*
* Similarly, two versions of the write() API are exposed. One where the user
* has to register a callback handling write response through the function
* GattClient::onDataWritten() and another one that accepts a completion
* callback in input.
*
* It is also possible to send a write command, which is not acknowledged by the
* peer server by using the function writeWoResponse().
*
* Finally, descriptors of the characteristic can be discovered by invoking the
* function discoverDescriptors, which is shorthand for calling
* GattClient::discoverCharacteristicDescriptors. That discovery is necessary to
* enable or disable characteristic notification or indication that is achieved
* by writing on the Client Characteristic Configuration Descriptor (CCCD).
*/
class DiscoveredCharacteristic {
public:
/**
* Structure that encapsulates the properties of a discovered
* characteristic.
* Properties of a discovered characteristic.
*/
struct Properties_t {
uint8_t _broadcast :1; /**< Broadcasting the value permitted. */
uint8_t _read :1; /**< Reading the value permitted. */
uint8_t _writeWoResp :1; /**< Writing the value with Write Command permitted. */
uint8_t _write :1; /**< Writing the value with Write Request permitted. */
uint8_t _notify :1; /**< Notifications of the value permitted. */
uint8_t _indicate :1; /**< Indications of the value permitted. */
uint8_t _authSignedWrite :1; /**< Writing the value with Signed Write Command permitted. */
/**
* Permits broadcasts of the characteristic value using the character
* the Server Characteristic Configuration Descriptor.
*
* @note If set, descriptors of the characteristic contain a Server
* Characteristic Configuration Descriptor.
*/
uint8_t _broadcast :1;
/**
* If set, the value of the characteristic can be read.
*/
uint8_t _read :1;
/**
* If set, a write command can write the characteristic value
* (write without response).
*/
uint8_t _writeWoResp :1;
/**
* If set, clients can issue requests to write the characteristic.
*/
uint8_t _write :1;
/**
* If set, the server can emit notifications of the Characteristic Value
* (without client acknowledgment).
*
* @note If set, descriptors of the characteristic contain a Client
* Characteristic Configuration Descriptor.
*/
uint8_t _notify :1;
/**
* If set, the server can emit indication of the Characteristic Value
* (with client acknowledgement).
*
* @note If set, descriptors of the characteristic contain a Client
* Characteristic Configuration Descriptor.
*/
uint8_t _indicate :1;
/**
* If set, signed write of the Characteristic Value is supported.
*/
uint8_t _authSignedWrite :1;
public:
/**
* @brief Check if broadcasting is permitted.
* Return the value of the broadcast propertie.
*
* @return true if broadcasting the value is permitted, and false
* otherwise.
* @return true if the Server Characteristic Configuration Descriptor
* of the characteristic can be configured to broadcast the
* characteristic value during broadcast procedure.
*
* @see _broadcast
*/
bool broadcast(void) const {
bool broadcast(void) const
{
return _broadcast;
}
/**
* @brief Check reading is permitted.
* Return the value of the read property
*
* @return true if reading the value is permitted, and false
* otherwise.
* @return true if the characteristic value can be read and false
* otherwise.
*
* @see _read
*/
bool read(void) const {
bool read(void) const
{
return _read;
}
/**
* @brief Check if writing with Write Command is permitted.
* Return the value of the write without response property.
*
* @return true if writing the value with Write Command is permitted,
* false otherwise.
* @return true if the characteristic accepts write without response
* commands and false otherwise.
*
* @see _writeWoResp
*/
bool writeWoResp(void) const {
bool writeWoResp(void) const
{
return _writeWoResp;
}
/**
* @brief Check if writing with Write Request is permitted.
* Return the value of the write property.
*
* @return true if writing the value with Write Request is permitted,
* false otherwise.
* @return true if writing the characteristic accepts write requests and
* false otherwise.
*
* @see _write
*/
bool write(void) const {
bool write(void) const
{
return _write;
}
/**
* @brief Check notifications are permitted.
* Return the value of the notification property.
*
* @return true if notifications of the value are permitted, false
* otherwise.
* @return true if the Client Characteristic Configuration Descriptor
* can be configured to notify the characteristic value to a given
* client and false otherwise.
*
* @note unlike indication, the notification procedure does not require
* acknowledgement from the client.
*
* @see _notify
*/
bool notify(void) const {
bool notify(void) const
{
return _notify;
}
/**
* @brief Check if indications are permitted.
* Return the value of the indicate property.
*
* @return true if indications of the value are permitted, false
* otherwise.
* @return true if the Client Characteristic Configuration Descriptor
* can be configured to indicate the characteristic value to a given
* client and false otherwise.
*
* @note unlike notification the indication procedure does require
* acknowledgment from the client.
*
* @see _indicate
*/
bool indicate(void) const {
bool indicate(void) const
{
return _indicate;
}
/**
* @brief Check if writing with Signed Write Command is permitted.
* Return the value of the authenticated signed writes property.
*
* @return true if writing the value with Signed Write Command is
* permitted, false otherwise.
* @return true if the characteristic accepts authenticated signed write
* and false otherwise.
*/
bool authSignedWrite(void) const {
bool authSignedWrite(void) const
{
return _authSignedWrite;
}
/**
* @brief "Equal to" operator for DiscoveredCharacteristic::Properties_t
* Equal to operator for DiscoveredCharacteristic::Properties_t.
*
* @param[in] lhs The left hand side of the equality expression
* @param[in] rhs The right hand side of the equality expression
* @param[in] lhs The left hand side of the equality expression.
* @param[in] rhs The right hand side of the equality expression.
*
* @return true if operands are equals, false otherwise.
* @return true if operands are equals and false otherwise.
*/
friend bool operator==(Properties_t lhs, Properties_t rhs) {
friend bool operator==(Properties_t lhs, Properties_t rhs)
{
return lhs._broadcast == rhs._broadcast &&
lhs._read == rhs._read &&
lhs._writeWoResp == rhs._writeWoResp &&
@ -145,121 +259,178 @@ public:
}
/**
* @brief "Not equal to" operator for DiscoveredCharacteristic::Properties_t
* Not equal to operator for DiscoveredCharacteristic::Properties_t.
*
* @param lhs The right hand side of the expression
* @param rhs The left hand side of the expression
* @param lhs The left hand side of the expression.
* @param rhs The right hand side of the expression.
*
* @return true if operands are not equals, false otherwise.
*/
friend bool operator!=(Properties_t lhs, Properties_t rhs) {
friend bool operator!=(Properties_t lhs, Properties_t rhs)
{
return !(lhs == rhs);
}
private:
operator uint8_t() const; /* Disallow implicit conversion into an integer. */
operator unsigned() const; /* Disallow implicit conversion into an integer. */
/* Disallow implicit conversion to integer types. */
operator uint8_t() const;
operator unsigned() const;
};
/**
* Initiate (or continue) a read for the value attribute, optionally at a
* given offset. If the characteristic or descriptor to be read is longer
* than ATT_MTU - 1, this function must be called multiple times with
* appropriate offset to read the complete value.
* Initiate a read of the characteristic value.
*
* @param[in] offset
* The position - in the characteristic value bytes stream - where
* the read operation begin.
* The characteristic value is read in its entirety from the value attribute
* of the characteristic.
*
* @return BLE_ERROR_NONE if a read has been initiated, or
* BLE_ERROR_INVALID_STATE if some internal state about the connection is invalid, or
* BLE_STACK_BUSY if some client procedure is already in progress, or
* BLE_ERROR_OPERATION_NOT_PERMITTED due to the characteristic's properties.
* Read responses will be passed to the callback registered in
* GattClient::onDataRead(). Read responses to read requests that this function
* call initiates will have their GattReadCallbackParams::connHandle
* field equal to the value returned by getConnectionHandle() and their
* GattReadCallbackParams::handle field equal to the value returned by
* getValueHandle().
*
* @param[in] offset The position - in the characteristic value bytes stream
* - where the read operation begin. This parameter is optional.
*
* @return BLE_ERROR_NONE if a read has been initiated.
* @return BLE_ERROR_INVALID_STATE if some internal state about the
* connection is invalid.
* @return BLE_STACK_BUSY if some client procedure is already in progress.
* @return BLE_ERROR_OPERATION_NOT_PERMITTED due to the characteristic's
* properties.
*/
ble_error_t read(uint16_t offset = 0) const;
/**
* @brief Same as #read(uint16_t) const but allow the user to register a callback
* which will be fired once the read is done.
* Initiate a read of the characteristic value and pass the response to its
* completion callback.
*
* @param[in] offset
* The position - in the characteristic value bytes stream - where
* the read operation begin.
* @param[in] onRead
* Continuation of the read operation
* @param[in] offset The position - in the characteristic value bytes stream
* - where the read operation begin.
*
* @param[in] onRead Completion callback which will accept the response of
* the read request. The callback is copied; it is unnecessary to keep it
* in memory after the call.
*
* @return BLE_ERROR_NONE if a read has been initiated.
* @return BLE_ERROR_INVALID_STATE if some internal state about the
* connection is invalid.
* @return BLE_STACK_BUSY if some client procedure is already in progress.
* @return BLE_ERROR_OPERATION_NOT_PERMITTED due to the characteristic's
* properties.
*
* @note This function is similar to read(uint16_t) const; however, it uses
* dynamic memory to store the use completion callback.
*/
ble_error_t read(uint16_t offset, const GattClient::ReadCallback_t& onRead) const;
ble_error_t read(
uint16_t offset,
const GattClient::ReadCallback_t &onRead
) const;
/**
* Perform a write without response procedure.
*
* @param[in] length
* The amount of data being written.
* @param[in] value
* The bytes being written.
* @note The server does not acknowledge write without responses.
* Therefore, they won't generate any event on the client side.
*
* @note It is important to note that a write without response will generate
* an onDataSent() callback when the packet has been transmitted. There
* will be a BLE-stack specific limit to the number of pending
* writeWoResponse operations; the user may want to use the onDataSent()
* callback for flow-control.
* @param[in] length The amount of data being written.
* @param[in] value The bytes being written.
*
* @retval BLE_ERROR_NONE Successfully started the Write procedure, or
* BLE_ERROR_INVALID_STATE if some internal state about the connection is invalid, or
* BLE_STACK_BUSY if some client procedure is already in progress, or
* BLE_ERROR_NO_MEM if there are no available buffers left to process the request, or
* BLE_ERROR_OPERATION_NOT_PERMITTED due to the characteristic's properties.
* @return BLE_ERROR_NONE Successfully started the Write procedure.
* @return BLE_ERROR_INVALID_STATE if some internal state about the
* connection is invalid.
* @return BLE_STACK_BUSY if some client procedure is already in progress.
* @return BLE_ERROR_NO_MEM if there are no available buffers left to
* process the request.
* @return BLE_ERROR_OPERATION_NOT_PERMITTED due to the characteristic's
* properties.
*/
ble_error_t writeWoResponse(uint16_t length, const uint8_t *value) const;
/**
* Initiate a GATT Characteristic Descriptor Discovery procedure for descriptors within this characteristic.
* Initiate a discovery of the characteristic descriptors.
*
* @param[in] onDescriptorDiscovered This callback will be called every time a descriptor is discovered
* @param[in] onTermination This callback will be called when the discovery process is over.
* When a descriptor is discovered, the callback onDescriptorDiscovered is
* invoked with the descriptor discovered as parameter. When the process
* ends, the callback onTermination is invoked.
*
* @return BLE_ERROR_NONE if descriptor discovery is launched successfully; else an appropriate error.
* @param[in] onDescriptorDiscovered Callback is invoked when a descriptor is
* discovered.
*
* @param[in] onTermination Callback is invoked when the discovery process ends.
*
* @return BLE_ERROR_NONE if descriptor discovery is launched successfully;
* else an appropriate error.
*
* @note This function is shorthand for
* GattClient::discoverCharacteristicDescriptors; therefore,
* GattClient::isCharacteristicDescriptorDiscoveryActive can be used to
* determine the descriptor discovery and
* GattClient::terminateCharacteristicDescriptorDiscovery can be used to
* end the discovery process.
*/
ble_error_t discoverDescriptors(const CharacteristicDescriptorDiscovery::DiscoveryCallback_t& onDescriptorDiscovered,
const CharacteristicDescriptorDiscovery::TerminationCallback_t& onTermination) const;
ble_error_t discoverDescriptors(
const CharacteristicDescriptorDiscovery::DiscoveryCallback_t &onDescriptorDiscovered,
const CharacteristicDescriptorDiscovery::TerminationCallback_t &onTermination
) const;
/**
* Perform a write procedure.
* Initiate a write procedure of the characteristic value.
*
* @param[in] length
* The amount of data being written.
* @param[in] value
* The bytes being written.
* Unlike write without responses (see writeWoResponse()), an acknowledgment
* is expected for this procedure. The response of the peer GATT server to
* the write request is passed to callbacks registered in
* GattClient::onDataWritten().
*
* @note It is important to note that a write will generate
* an onDataWritten() callback when the peer acknowledges the request.
* Similarly to read responses, responses to write request of this
* characteristic can be identified by their connection handle (
* GattWriteCallbackParams::connHandle), which is equal to the value
* returned by getConnectionHandle() and their attribute handle (
* GattWriteCallbackParams::handle), which is equal to the value
* returned by getValueHandle().
*
* @retval BLE_ERROR_NONE Successfully started the Write procedure, or
* BLE_ERROR_INVALID_STATE if some internal state about the connection is invalid, or
* BLE_STACK_BUSY if some client procedure is already in progress, or
* BLE_ERROR_NO_MEM if there are no available buffers left to process the request, or
* BLE_ERROR_OPERATION_NOT_PERMITTED due to the characteristic's properties.
* @param[in] length The amount of data being written.
* @param[in] value The bytes being written.
*
* @return BLE_ERROR_NONE Successfully started the Write procedure.
* @return BLE_ERROR_INVALID_STATE If some internal state about the
* connection is invalid.
* @return BLE_STACK_BUSY If some client procedure is already in progress.
* @return BLE_ERROR_NO_MEM If there are no available buffers left to
* process the request.
* @return BLE_ERROR_OPERATION_NOT_PERMITTED due to the characteristic's
* properties.
*
* @note Internally, the API uses the write or long write procedure, depending
* on the number of bytes to write and the MTU size.
*/
ble_error_t write(uint16_t length, const uint8_t *value) const;
/**
* Same as write(uint16_t, const uint8_t *) const but register a callback
* which will be called once the data has been written.
* Initiate a write procedure of the characteristic value.
*
* @param[in] length
* The amount of bytes to write.
* @param[in] value
* The bytes to write.
* @param[in] onWrite
* Continuation callback for the write operation
* Same as write(uint16_t, const uint8_t *) const but accepts a completion
* callback, which is invoked when the server response is received.
*
* @retval BLE_ERROR_NONE Successfully started the Write procedure, or
* BLE_ERROR_INVALID_STATE if some internal state about the connection is invalid, or
* BLE_STACK_BUSY if some client procedure is already in progress, or
* BLE_ERROR_NO_MEM if there are no available buffers left to process the request, or
* BLE_ERROR_OPERATION_NOT_PERMITTED due to the characteristic's properties.
* @param[in] length The amount of bytes to write.
* @param[in] value The bytes to write.
* @param[in] onWrite Continuation callback of the write procedure.
*
* @return BLE_ERROR_NONE Successfully started the Write procedure.
* @return BLE_ERROR_INVALID_STATE if some internal state about the
* connection is invalid.
* @return BLE_STACK_BUSY if some client procedure is already in progress.
* @return BLE_ERROR_NO_MEM if there are no available buffers left to
* process the request.
* @return BLE_ERROR_OPERATION_NOT_PERMITTED due to the characteristic's
* properties.
*/
ble_error_t write(uint16_t length, const uint8_t *value, const GattClient::WriteCallback_t& onWrite) const;
ble_error_t write(
uint16_t length,
const uint8_t *value,
const GattClient::WriteCallback_t &onWrite
) const;
void setupLongUUID(UUID::LongUUIDBytes_t longUUID, UUID::ByteOrder_t order = UUID::MSB) {
uuid.setupLong(longUUID, order);
@ -267,24 +438,29 @@ public:
public:
/**
* @brief Get the UUID of the discovered characteristic
* @return the UUID of this characteristic
* Get the UUID of the discovered characteristic.
*
* @return The UUID of this characteristic.
*/
const UUID& getUUID(void) const {
const UUID &getUUID(void) const
{
return uuid;
}
/**
* @brief Get the properties of this characteristic
* @return the set of properties of this characteristic
* Get the properties of this characteristic.
*
* @return The set of properties of this characteristic.
*/
const Properties_t& getProperties(void) const {
const Properties_t &getProperties(void) const
{
return props;
}
/**
* @brief Get the declaration handle of this characteristic.
* @details The declaration handle is the first handle of a characteristic
* Get the declaration handle of this characteristic.
*
* The declaration handle is the first handle of a characteristic
* definition. The value accessible at this handle contains the following
* informations:
* - The characteristics properties (see Properties_t). This value can
@ -293,74 +469,90 @@ public:
* by using #getValueHandle .
* - The characteristic UUID, this value can be accessed by using the
* function #getUUID .
*
* @return the declaration handle of this characteristic.
*/
GattAttribute::Handle_t getDeclHandle(void) const {
GattAttribute::Handle_t getDeclHandle(void) const
{
return declHandle;
}
/**
* @brief Return the handle used to access the value of this characteristic.
* @details This handle is the one provided in the characteristic declaration
* value. Usually, it is equal to #getDeclHandle() + 1. But it is not always
* the case. Anyway, users are allowed to use #getDeclHandle() + 1 to access
* the value of a characteristic.
* Get the attribute handle of the characteristic value.
*
* This handle is used to read or write the value of the characteristic.
*
* @return The handle to access the value of this characteristic.
*/
GattAttribute::Handle_t getValueHandle(void) const {
GattAttribute::Handle_t getValueHandle(void) const
{
return valueHandle;
}
/**
* @brief Return the last handle of the characteristic definition.
* @details A Characteristic definition can contain a lot of handles:
* - one for the declaration (see #getDeclHandle)
* - one for the value (see #getValueHandle)
* - zero of more for the characteristic descriptors.
* This handle is the last handle of the characteristic definition.
* Return the last attribute handle of the characteristic definition.
*
* The attribute layout of a characteristic definition is:
* - Declaration attribute (see #getDeclHandle).
* - Value attribute (see #getValueHandle).
* - Zero or more characteristic descriptors attribute.
*
* The last attribute handle is used internally to discover characteristic
* descriptors. The discovery operates on the range [ValueHandle + 1 :
* LastHandle].
*
* @return The last handle of this characteristic definition.
*
* @note This function is public for informative purposes.
*/
GattAttribute::Handle_t getLastHandle(void) const {
GattAttribute::Handle_t getLastHandle(void) const
{
return lastHandle;
}
/**
* @brief Return the GattClient which can operate on this characteristic.
* @return The GattClient which can operate on this characteristic.
* Get the GattClient, which can operate on this characteristic.
*
* @return The GattClient, which can operate on this characteristic.
*/
GattClient* getGattClient() {
GattClient* getGattClient()
{
return gattc;
}
/**
* @brief Return the GattClient which can operate on this characteristic.
* @return The GattClient which can operate on this characteristic.
* Get the GattClient, which can operate on this characteristic.
*
* @return The GattClient, which can operate on this characteristic.
*/
const GattClient* getGattClient() const {
const GattClient* getGattClient() const
{
return gattc;
}
/**
* @brief Return the connection handle to the GattServer which contain
* this characteristic.
* @return the connection handle to the GattServer which contain
* this characteristic.
* @brief Get the connection handle to the GattServer containing this
* characteristic.
*
* @return Connection handle to the GattServer, which contains this
* characteristic.
*/
Gap::Handle_t getConnectionHandle() const {
Gap::Handle_t getConnectionHandle() const
{
return connHandle;
}
/**
* @brief "Equal to" operator for DiscoveredCharacteristic
* "Equal to" operator for DiscoveredCharacteristic.
*
* @param[in] lhs
* The left hand side of the equality expression
* @param[in] rhs
* The right hand side of the equality expression
* @param[in] lhs The left hand side of the equality expression.
* @param[in] rhs The right hand side of the equality expression.
*
* @return true if operands are equals, false otherwise.
* @return true if operands are equals and false otherwise.
*/
friend bool operator==(const DiscoveredCharacteristic& lhs, const DiscoveredCharacteristic& rhs) {
friend bool operator==(
const DiscoveredCharacteristic& lhs, const DiscoveredCharacteristic& rhs
) {
return lhs.gattc == rhs.gattc &&
lhs.uuid == rhs.uuid &&
lhs.props == rhs.props &&
@ -371,63 +563,75 @@ public:
}
/**
* @brief "Not equal to" operator for DiscoveredCharacteristic
* "Not equal to" operator for DiscoveredCharacteristic.
*
* @param[in] lhs
* The right hand side of the expression
* @param[in] rhs
* The left hand side of the expression
* @param[in] lhs The right hand side of the expression.
* @param[in] rhs The left hand side of the expression.
*
* @return true if operands are not equal, false otherwise.
* @return true if operands are not equal and false otherwise.
*/
friend bool operator !=(const DiscoveredCharacteristic& lhs, const DiscoveredCharacteristic& rhs) {
friend bool operator !=(
const DiscoveredCharacteristic& lhs, const DiscoveredCharacteristic& rhs
) {
return !(lhs == rhs);
}
public:
DiscoveredCharacteristic() : gattc(NULL),
uuid(UUID::ShortUUIDBytes_t(0)),
props(),
declHandle(GattAttribute::INVALID_HANDLE),
valueHandle(GattAttribute::INVALID_HANDLE),
lastHandle(GattAttribute::INVALID_HANDLE),
connHandle() {
/* empty */
DiscoveredCharacteristic() :
gattc(NULL),
uuid(UUID::ShortUUIDBytes_t(0)),
props(),
declHandle(GattAttribute::INVALID_HANDLE),
valueHandle(GattAttribute::INVALID_HANDLE),
lastHandle(GattAttribute::INVALID_HANDLE),
connHandle() {
}
protected:
/**
* Pointer to the underlying GattClient for this DiscoveredCharacteristic object.
* Pointer to the underlying GattClient for this DiscoveredCharacteristic
* object.
*/
GattClient *gattc;
GattClient *gattc;
protected:
/**
* Discovered characteristic's UUID.
*/
UUID uuid;
UUID uuid;
/**
* Hold the configured properties of the discovered characteristic.
* For more information refer to Properties_t.
*
* @see Properties_t.
*/
Properties_t props;
Properties_t props;
/**
* Value handle of the discovered characteristic's declaration attribute.
*/
GattAttribute::Handle_t declHandle;
GattAttribute::Handle_t declHandle;
/**
* Value handle of the discovered characteristic's value attribute.
*/
GattAttribute::Handle_t valueHandle;
GattAttribute::Handle_t valueHandle;
/**
* Value handle of the discovered characteristic's last attribute.
*/
GattAttribute::Handle_t lastHandle;
GattAttribute::Handle_t lastHandle;
/**
* Handle for the connection where the characteristic was discovered.
* Handle of the connection where the characteristic was discovered.
*/
Gap::Handle_t connHandle;
Gap::Handle_t connHandle;
};
#endif /*__DISCOVERED_CHARACTERISTIC_H__*/
/**
* @}
* @}
* @}
*/
#endif /*MBED_DISCOVERED_CHARACTERISTIC_H__*/

View File

@ -14,8 +14,8 @@
* limitations under the License.
*/
#ifndef __DISCOVERED_CHARACTERISTIC_DESCRIPTOR_H__
#define __DISCOVERED_CHARACTERISTIC_DESCRIPTOR_H__
#ifndef MBED_DISCOVERED_CHARACTERISTIC_DESCRIPTOR_H__
#define MBED_DISCOVERED_CHARACTERISTIC_DESCRIPTOR_H__
#include "UUID.h"
#include "Gap.h"
@ -24,16 +24,32 @@
#include "CharacteristicDescriptorDiscovery.h"
/**
* @brief Representation of a descriptor discovered during a GattClient
* discovery procedure (see GattClient::discoverCharacteristicDescriptors or
* DiscoveredCharacteristic::discoverDescriptors ).
* @addtogroup ble
* @{
* @addtogroup gatt
* @{
* @addtogroup client
* @{
*/
/**
* Representation of a characteristic descriptor discovered.
*
* @details Provide detailed informations about a discovered characteristic descriptor
* like:
* - Its UUID (see #getUUID).
* - Its handle (see #getAttributeHandle)
* Basic read (see GattClient::read) and write (see GattClient::write) procedure from
* GattClient can be used access the value of the descriptor.
* Characteristic descriptors can be seen as the metadata of the characteristic.
* They can contain things such as the unit of the characteristic value, extra
* permission informations or the Client Configuration state in regard to
* notification or indication.
*
* The descriptors of a characterstic are discovered by a Characteristic
* Descriptor Discovery Procedure, which can be initiated by either
* GattClient::discoverCharacteristicDescriptors() or
* DiscoveredCharacteristic::discoverDescriptors().
*
* The discovery procedure returns the UUID of the descriptor (its type) and its
* handle.
*
* Read and write of the descriptor value can be initiated by
* GattClient::read and GattClient::write.
*
* @todo read member function
* @todo write member function
@ -44,60 +60,80 @@ class DiscoveredCharacteristicDescriptor {
public:
/**
* @brief construct a new instance of a DiscoveredCharacteristicDescriptor
* Construct a new instance of a DiscoveredCharacteristicDescriptor.
*
* @param client The client from where the descriptor has been discovered
* @param connectionHandle The connection handle on which the descriptor has
* been discovered
* @param attributeHandle The handle of the attribute containing this descriptor
* @param uuid The UUID of the descriptor
* @param[in] client The client that has discovered the descriptor.
* @param[in] connectionHandle Handle of the connection to the GATT server
* containing the descriptor.
* @param[in] attributeHandle GATT attribute handle of the descriptor.
* @param[in] uuid UUID of the descriptor.
*
* @note This constructor is not meant to be called directly by application
* code. The Gattclient class generates descriptors discovered.
*/
DiscoveredCharacteristicDescriptor(
GattClient* client, Gap::Handle_t connectionHandle, GattAttribute::Handle_t attributeHandle, const UUID& uuid) :
_client(client), _connectionHandle(connectionHandle), _uuid(uuid), _gattHandle(attributeHandle) {
GattClient *client,
Gap::Handle_t connectionHandle,
GattAttribute::Handle_t attributeHandle,
const UUID &uuid
) : _client(client),
_connectionHandle(connectionHandle),
_uuid(uuid),
_gattHandle(attributeHandle) {
}
/**
* @brief Return the GattClient which can operate on this descriptor.
* @return The GattClient which can operate on this descriptor.
* Return the GattClient, which can operate on this descriptor.
*
* @return GattClient, which can operate on this descriptor.
*/
GattClient* getGattClient() {
GattClient* getGattClient()
{
return _client;
}
/**
* @brief Return the GattClient which can operate on this descriptor.
* @return The GattClient which can operate on this descriptor.
* Return the GattClient, which can operate on this descriptor.
*
* @return GattClient, which can operate on this descriptor.
*/
const GattClient* getGattClient() const {
const GattClient* getGattClient() const
{
return _client;
}
/**
* @brief Return the connection handle to the GattServer which contain
* this descriptor.
* @return the connection handle to the GattServer which contain
* this descriptor.
* Return the connection handle to the GattServer containing this
* descriptor.
*
* @return the connection handle to the GattServer containing this
* descriptor.
*/
Gap::Handle_t getConnectionHandle() const {
Gap::Handle_t getConnectionHandle() const
{
return _connectionHandle;
}
/**
* @brief Return the UUID of this descriptor
* @return the UUID of this descriptor
* Return the UUID of this descriptor.
*
* @return UUID of this descriptor.
*/
const UUID& getUUID(void) const {
const UUID& getUUID(void) const
{
return _uuid;
}
/**
* @brief Return the attribute handle to use to access to this descriptor
* on the gatt server.
* @return The attribute handle of the descriptor
* Return the attribute handle of this descriptor.
*
* This attribute handle can be used to interact with the descriptor on its
* gatt server.
*
* @return Attribute handle of the descriptor
*/
GattAttribute::Handle_t getAttributeHandle() const {
GattAttribute::Handle_t getAttributeHandle() const
{
return _gattHandle;
}
@ -108,4 +144,10 @@ private:
GattAttribute::Handle_t _gattHandle;
};
#endif /*__DISCOVERED_CHARACTERISTIC_DESCRIPTOR_H__*/
/**
* @}
* @}
* @}
*/
#endif /* MBED_DISCOVERED_CHARACTERISTIC_DESCRIPTOR_H__ */

View File

@ -14,106 +14,168 @@
* limitations under the License.
*/
#ifndef __DISCOVERED_SERVICE_H__
#define __DISCOVERED_SERVICE_H__
#ifndef MBED_DISCOVERED_SERVICE_H__
#define MBED_DISCOVERED_SERVICE_H__
#include "UUID.h"
#include "GattAttribute.h"
/**@brief Type for holding information about the service and the characteristics found during
* the discovery process.
/**
* @addtogroup ble
* @{
* @addtogroup gatt
* @{
* @addtogroup client
* @{
*/
/**
* Representation of a GATT service discovered.
*
* The discovery procedure discovers GATT Services are discovered on distant
* GATT servers, which can be initiated by calling
* GattClient::launchServiceDiscovery() or GattClient::discoverServices(). The
* discovery process passes instances of this class to the callback handling
* service discovered.
*
* Discovered services are characterized by the UUID of the service discovered
* and the range of the GATT attributes belonging to the service.
*
* The UUID can be queried by calling getUUID() while the begining of the
* attribute range can be obtained through getStartHandle() and the end of the
* attribute range with a call to getEndHandle().
*
* The characteristics composing the service may be discovered by the function
* GattClient::launchServiceDiscovery().
*/
class DiscoveredService {
public:
/**
* Set information about the discovered service.
*
* @param[in] uuidIn
* The UUID of the discovered service.
* @param[in] startHandleIn
* The start handle of the discovered service in the peer's
* ATT table.
* @param[in] endHandleIn
* The end handle of the discovered service in the peer's
* ATT table.
*/
void setup(UUID uuidIn, GattAttribute::Handle_t startHandleIn, GattAttribute::Handle_t endHandleIn) {
uuid = uuidIn;
startHandle = startHandleIn;
endHandle = endHandleIn;
}
/**
* Set the start and end handle of the discovered service.
* @param[in] startHandleIn
* The start handle of the discovered service in the peer's
* ATT table.
* @param[in] endHandleIn
* The end handle of the discovered service in the peer's
* ATT table.
*/
void setup(GattAttribute::Handle_t startHandleIn, GattAttribute::Handle_t endHandleIn) {
startHandle = startHandleIn;
endHandle = endHandleIn;
}
/**
* Set the long UUID of the discovered service.
*
* @param[in] longUUID
* The long UUID of the discovered service.
* @param[in] order
* The byte ordering of @p longUUID.
*/
void setupLongUUID(UUID::LongUUIDBytes_t longUUID, UUID::ByteOrder_t order = UUID::MSB) {
uuid.setupLong(longUUID, order);
}
public:
/**
* Get the UUID of the discovered service.
*
* @return A reference to the UUID of the discovered service.
*/
const UUID &getUUID(void) const {
const UUID &getUUID(void) const
{
return uuid;
}
/**
* Get the start handle of the discovered service in the peer's ATT table.
* Get the start handle of the discovered service in the peer's GATT server.
*
* @return A reference to the start handle.
*/
const GattAttribute::Handle_t& getStartHandle(void) const {
const GattAttribute::Handle_t& getStartHandle(void) const
{
return startHandle;
}
/**
* Get the end handle of the discovered service in the peer's ATT table.
* Get the end handle of the discovered service in the peer's GATT server.
*
* @return A reference to the end handle.
*/
const GattAttribute::Handle_t& getEndHandle(void) const {
const GattAttribute::Handle_t& getEndHandle(void) const
{
return endHandle;
}
public:
/**
* Construct a DiscoveredService instance.
*
* @important This API is not meant to be used publicly. It is meant to be
* used by internal APIs of Mbed BLE.
*/
DiscoveredService() : uuid(UUID::ShortUUIDBytes_t(0)),
startHandle(GattAttribute::INVALID_HANDLE),
endHandle(GattAttribute::INVALID_HANDLE) {
/* empty */
DiscoveredService() :
uuid(UUID::ShortUUIDBytes_t(0)),
startHandle(GattAttribute::INVALID_HANDLE),
endHandle(GattAttribute::INVALID_HANDLE) {
}
/**
* Set information about the discovered service.
*
* @important This API is not meant to be used publicly. It is meant to be
* used by internal APIs of Mbed BLE.
*
* @param[in] uuidIn The UUID of the discovered service.
* @param[in] startHandleIn The start handle of the discovered service in
* the peer's GATT server.
* @param[in] endHandleIn The end handle of the discovered service in the
* peer's GATT server.
*/
void setup(
UUID uuidIn,
GattAttribute::Handle_t startHandleIn,
GattAttribute::Handle_t endHandleIn
) {
uuid = uuidIn;
startHandle = startHandleIn;
endHandle = endHandleIn;
}
/**
* Set the start and end handle of the discovered service.
*
* @important This API is not meant to be used publicly. It is meant to be
* used by internal APIs of Mbed BLE.
*
* @param[in] startHandleIn The start handle of the discovered service in
* the peer's GATT server.
* @param[in] endHandleIn The end handle of the discovered service in the
* peer's GATT server.
*/
void setup(
GattAttribute::Handle_t startHandleIn,
GattAttribute::Handle_t endHandleIn
) {
startHandle = startHandleIn;
endHandle = endHandleIn;
}
/**
* Set the long UUID of the discovered service.
*
* @important This API is not meant to be used publicly. It is meant to be
* used by internal APIs of Mbed BLE.
*
* @param[in] longUUID The bytes composing the long UUID of this discovered
* service.
* @param[in] order The byte ordering of @p longUUID.
*/
void setupLongUUID(
UUID::LongUUIDBytes_t longUUID,
UUID::ByteOrder_t order = UUID::MSB
) {
uuid.setupLong(longUUID, order);
}
private:
DiscoveredService(const DiscoveredService &);
private:
UUID uuid; /**< UUID of the service. */
GattAttribute::Handle_t startHandle; /**< Service Handle Range. */
GattAttribute::Handle_t endHandle; /**< Service Handle Range. */
/**
* UUID of the service.
*/
UUID uuid;
/**
* Begining of the Service Handle Range.
*/
GattAttribute::Handle_t startHandle;
/**
* Service Handle Range.
*/
GattAttribute::Handle_t endHandle;
};
#endif /*__DISCOVERED_SERVICE_H__*/
/**
* @}
* @}
* @}
*/
#endif /* MBED_DISCOVERED_SERVICE_H__ */

View File

@ -20,8 +20,37 @@
#include <string.h>
#include "SafeBool.h"
/** A class for storing and calling a pointer to a static or member void function
* that takes a context.
/**
* @file
* @addtogroup ble
* @{
* @addtogroup common
* @{
*/
/**
* Function like object adapter over freestanding and member functions.
*
* Freestanding and member functions are two distinct types in C++. One is
* not convertible into the other, and the call syntax between the two is
* different even if conceptually they are similar: Both primitives can be
* copied, called and produce a result.
*
* To solve incompatibilities, this class adapts freestanding and member functions
* to a common interface. The interface chosen is similar to the freestanding
* function pointers interface:
* - Copyable.
* - Nullable.
* - Callable.
*
* This class also offers a mechanism to chain other instances to it. When an
* instance is called, all the instances being part of the chain are called.
*
* @important freestanding or member function adapted must accept a single
* argument, and this argument is a pointer to ContextType. Adapted
* primitives do not return anything.
*
* @tparam ContextType Type of the argument pointee.
*/
template <typename ContextType>
class FunctionPointerWithContext : public SafeBool<FunctionPointerWithContext<ContextType> > {
@ -30,111 +59,201 @@ public:
typedef const FunctionPointerWithContext<ContextType> *cpFunctionPointerWithContext_t;
typedef void (*pvoidfcontext_t)(ContextType context);
/** Create a FunctionPointerWithContext, attaching a static function.
/**
* Create a FunctionPointerWithContext from a pointer to a freestanding
* function.
*
* @param function The void static function to attach (default is none).
* @param[in] function The freestanding function to attach.
*/
FunctionPointerWithContext(void (*function)(ContextType context) = NULL) :
_memberFunctionAndPointer(), _caller(NULL), _next(NULL) {
_memberFunctionAndPointer(), _caller(NULL), _next(NULL)
{
attach(function);
}
/** Create a FunctionPointerWithContext, attaching a member function.
/**
* Create a FunctionPointerWithContext from a pointer to a member function
* and the instance which is used to call it.
*
* @param object The object pointer to invoke the member function on (the "this" pointer).
* @param function The address of the void member function to attach.
* @param[in] object Pointer to the instance which is used to invoke @p
* member.
* @param[in] Pointer to the member function to adapt.
*/
template<typename T>
FunctionPointerWithContext(T *object, void (T::*member)(ContextType context)) :
_memberFunctionAndPointer(), _caller(NULL), _next(NULL) {
_memberFunctionAndPointer(), _caller(NULL), _next(NULL)
{
attach(object, member);
}
FunctionPointerWithContext(const FunctionPointerWithContext& that) :
_memberFunctionAndPointer(that._memberFunctionAndPointer), _caller(that._caller), _next(NULL) {
/**
* Copy construction.
*
* @param[in] that The FunctionPointerWithContext instance used to create
* this.
*/
FunctionPointerWithContext(const FunctionPointerWithContext &that) :
_memberFunctionAndPointer(that._memberFunctionAndPointer),
_caller(that._caller), _next(NULL) {
}
FunctionPointerWithContext& operator=(const FunctionPointerWithContext& that) {
/**
* Copy assignment.
*
* @param[in] that The FunctionPointerWithContext instance copied into this.
*/
FunctionPointerWithContext &operator=(const FunctionPointerWithContext &that)
{
_memberFunctionAndPointer = that._memberFunctionAndPointer;
_caller = that._caller;
_caller = that._caller;
_next = NULL;
return *this;
}
/** Attach a static function.
/**
* Adapt a freestanding function.
*
* @param function The void static function to attach (default is none).
* Previous content adapted is discarded while @p function replaces it.
*
* @note This function is equivalent to a call to the copy assignment
* operator.
*
* @param[in] function The freestanding function to attach.
*/
void attach(void (*function)(ContextType context) = NULL) {
void attach(void (*function)(ContextType context) = NULL)
{
_function = function;
_caller = functioncaller;
}
/** Attach a member function.
/**
* Adapt a pointer to member function and the instance to use to call it.
*
* @param object The object pointer to invoke the member function on (the "this" pointer).
* @param function The address of the void member function to attach.
* Previous content adapted is discarded while the adaptation
* of the pair @p object and @p member replaces it.
*
* @note This function is equivalent to a call to the copy assignment
* operator.
*
* @param[in] object Pointer to the instance is used to invoke @p member.
* @param[in] function Pointer to the member function to adapt.
*/
template<typename T>
void attach(T *object, void (T::*member)(ContextType context)) {
void attach(T *object, void (T::*member)(ContextType context))
{
_memberFunctionAndPointer._object = static_cast<void *>(object);
memcpy(_memberFunctionAndPointer._memberFunction, (char*) &member, sizeof(member));
memcpy(
_memberFunctionAndPointer._memberFunction,
(char*) &member,
sizeof(member)
);
_caller = &FunctionPointerWithContext::membercaller<T>;
}
/** Call the attached static or member function; if there are chained
* FunctionPointers their callbacks are invoked as well.
* @Note: All chained callbacks stack up, so hopefully there won't be too
* many FunctionPointers in a chain. */
void call(ContextType context) const {
/**
* Call the adapted function and functions chained to the instance.
*
* @param[in] context parameter to pass to chain of adapted functions.
*/
void call(ContextType context) const
{
_caller(this, context);
}
/**
* @brief Same as above
* Call the adapted function and functions chained to the instance.
*
* @param[in] context parameter to pass to chain of adapted functions.
*/
void operator()(ContextType context) const {
call(context);
void call(ContextType context)
{
((const FunctionPointerWithContext*) this)->call(context);
}
/** Same as above, workaround for mbed os FunctionPointer implementation. */
void call(ContextType context) {
((const FunctionPointerWithContext*) this)->call(context);
/**
* Call the adapted function and functions chained to the instance.
*
* @param[in] context parameter to pass to chain of adapted functions.
*/
void operator()(ContextType context) const
{
call(context);
}
typedef void (FunctionPointerWithContext::*bool_type)() const;
/**
* implementation of safe bool operator
/**
* Indicate if a callable object is being adapted.
*
* @note implementation of safe bool operator.
*
* @return true if the content of the instance can be invoked and false
* otherwise.
*/
bool toBool() const {
bool toBool() const
{
return (_function || _memberFunctionAndPointer._object);
}
/**
* Set up an external FunctionPointer as a next in the chain of related
* callbacks. Invoking call() on the head FunctionPointer will invoke all
* Set a FunctionPointer instance as the next element in the chain of
* callable objects.
*
* @note Invoking call() on the head FunctionPointer invokes all
* chained callbacks.
*
* Refer to 'CallChain' as an alternative.
* @note Refer to CallChainOfFunctionPointerWithContext as an alternative.
*
* @param next The instance to set as the next element in the chain of
* callable objects.
*/
void chainAsNext(pFunctionPointerWithContext_t next) {
void chainAsNext(pFunctionPointerWithContext_t next)
{
_next = next;
}
pFunctionPointerWithContext_t getNext(void) const {
/**
* Access the next element in the call chain.
*
* If there is no next element in the chain, this function returns NULL.
*
* @return A pointer to the next FunctionPointerWithContext instance in the
* chain.
*/
pFunctionPointerWithContext_t getNext(void) const
{
return _next;
}
pvoidfcontext_t get_function() const {
/**
* Access the next element in the call chain.
*
* If there is no next element in the chain, this function returns NULL.
*
* @return A pointer to the next FunctionPointerWithContext instance in the
* chain.
*/
pvoidfcontext_t get_function() const
{
return (pvoidfcontext_t)_function;
}
friend bool operator==(const FunctionPointerWithContext& lhs, const FunctionPointerWithContext& rhs) {
/**
* Equal to operator between two FunctionPointerWithContext instances.
*
* @param[in] lhs Left hand side of the expression.
* @param[in] rhs Right hand side of the expression.
*
* @return true if lhs and rhs adapt the same object and false otherwise.
*/
friend bool operator==(
const FunctionPointerWithContext &lhs,
const FunctionPointerWithContext &rhs
) {
return rhs._caller == lhs._caller &&
memcmp(
&rhs._memberFunctionAndPointer,
&lhs._memberFunctionAndPointer,
&rhs._memberFunctionAndPointer,
&lhs._memberFunctionAndPointer,
sizeof(rhs._memberFunctionAndPointer)
) == 0;
}
@ -160,7 +279,7 @@ private:
/*
* Forward declaration of a class and a member function to this class.
* Because the compiler doesn't know anything about the forwarded member
* function, it will always use the biggest size and the biggest alignment
* function, it always uses the biggest size and the biggest alignment
* that a member function can take for objects of type UndefinedMemberFunction.
*/
class UndefinedClass;
@ -191,22 +310,53 @@ private:
};
/**
* @brief Create a new FunctionPointerWithContext which bind an instance and a
* a member function together.
* @details This little helper is a just here to eliminate the need to write the
* FunctionPointerWithContext type each time you want to create one by kicking
* automatic type deduction of function templates. With this function, it is easy
* to write only one entry point for functions which expect a FunctionPointer
* in parameters.
*
* @param object to bound with member function
* @param member The member function called
* @return a new FunctionPointerWithContext
* Factory of adapted member function pointers.
*
* This factory eliminates the need to invoke the qualified constructor of
* FunctionPointerWithContext by using automatic type deduction of function
* templates.
*
* @code
*
* struct ReadHandler {
* void on_data_read(const GattReadCallbackParams*);
* };
*
* ReadHandler read_handler;
*
* GattClient& client;
*
* client.onDataRead(
* makeFunctionPointer(&read_handler, &ReadHandler::on_data_read)
* );
*
* // instead of
*
* client.onDataRead(
* FunctionPointerWithContext<const GattReadCallbackParams*>(
* &read_handler,
* &ReadHandler::on_data_read
* )
* );
* @endcode
*
*
* @param[in] object Instance to bound with @p member.
* @param member The member being adapted.
*
* @return Adaptation of the parameters in a FunctionPointerWithContext instance.
*/
template<typename T, typename ContextType>
FunctionPointerWithContext<ContextType> makeFunctionPointer(T *object, void (T::*member)(ContextType context))
{
FunctionPointerWithContext<ContextType> makeFunctionPointer(
T *object,
void (T::*member)(ContextType context)
) {
return FunctionPointerWithContext<ContextType>(object, member);
}
/**
* @}
* @}
*/
#endif // ifndef MBED_FUNCTIONPOINTER_WITH_CONTEXT_H

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -14,50 +14,101 @@
* limitations under the License.
*/
#ifndef __GAP_ADVERTISING_PARAMS_H__
#define __GAP_ADVERTISING_PARAMS_H__
#ifndef MBED_GAP_ADVERTISING_PARAMS_H__
#define MBED_GAP_ADVERTISING_PARAMS_H__
/**
* This class provides a wrapper for the core advertising parameters,
* including the advertising type (Connectable Undirected,
* Non Connectable Undirected and so on), as well as the advertising and
* timeout intervals.
* @addtogroup ble
* @{
* @addtogroup gap
* @{
*/
/**
* Parameters defining the advertising process.
*
* Advertising parameters are a triplet of three value:
* - The Advertising mode modeled after AdvertisingType_t. It defines
* if the device is connectable and scannable. This value can be set at
* construction time, updated with setAdvertisingType() and queried by
* getAdvertisingType().
* - Time interval between advertisement. It can be set at construction time,
* updated by setInterval() and obtained from getInterval().
* - Duration of the advertising process. As others, it can be set at
* construction time, modified by setTimeout() and retrieved by getTimeout().
*/
class GapAdvertisingParams {
public:
/**
* Minimum Advertising interval for connectable undirected and connectable
* directed events in 625us units - 20ms.
*/
static const unsigned GAP_ADV_PARAMS_INTERVAL_MIN = 0x0020;
/**
* Minimum Advertising interval for scannable and non-connectable
* undirected events in 625us units - 100ms.
*/
static const unsigned GAP_ADV_PARAMS_INTERVAL_MIN_NONCON = 0x00A0;
/**
* Maximum Advertising interval in 625us units - 10.24s.
*/
static const unsigned GAP_ADV_PARAMS_INTERVAL_MAX = 0x4000;
/**
* Maximum advertising timeout seconds.
*/
static const unsigned GAP_ADV_PARAMS_TIMEOUT_MAX = 0x3FFF;
/**
* Encapsulates the peripheral advertising modes, which determine how
* the device appears to other central devices in hearing range.
* Minimum Advertising interval for connectable undirected and connectable
* directed events in 625us units.
*
* @note Equal to 20 ms.
*/
static const unsigned GAP_ADV_PARAMS_INTERVAL_MIN = 0x0020;
/**
* Minimum Advertising interval for scannable and nonconnectable
* undirected events in 625us units.
*
* @note Equal to 100ms.
*/
static const unsigned GAP_ADV_PARAMS_INTERVAL_MIN_NONCON = 0x00A0;
/**
* Maximum Advertising interval in 625us units.
*
* @note Equal to 10.24s.
*/
static const unsigned GAP_ADV_PARAMS_INTERVAL_MAX = 0x4000;
/**
* Maximum advertising timeout allowed; in seconds.
*/
static const unsigned GAP_ADV_PARAMS_TIMEOUT_MAX = 0x3FFF;
/**
* Encapsulates the peripheral advertising modes.
*
* It determine how the device appears to other scanner and peripheral
* devices in the scanning range.
*/
enum AdvertisingType_t {
ADV_CONNECTABLE_UNDIRECTED, /**< Vol 3, Part C, Section 9.3.4 and Vol 6, Part B, Section 2.3.1.1. */
ADV_CONNECTABLE_DIRECTED, /**< Vol 3, Part C, Section 9.3.3 and Vol 6, Part B, Section 2.3.1.2. */
ADV_SCANNABLE_UNDIRECTED, /**< Include support for Scan Response payloads, see Vol 6, Part B, Section 2.3.1.4. */
ADV_NON_CONNECTABLE_UNDIRECTED /**< Vol 3, Part C, Section 9.3.2 and Vol 6, Part B, Section 2.3.1.3. */
/**
* Device is connectable, scannable and doesn't expect connection from a
* specific peer.
*
* @see Vol 3, Part C, Section 9.3.4 and Vol 6, Part B, Section 2.3.1.1.
*/
ADV_CONNECTABLE_UNDIRECTED,
/**
* Device is connectable and expects connection from a specific peer.
*
* @see Vol 3, Part C, Section 9.3.3 and Vol 6, Part B, Section 2.3.1.2.
*/
ADV_CONNECTABLE_DIRECTED,
/**
* Device is scannable but not connectable.
*
* @see Vol 6, Part B, Section 2.3.1.4.
*/
ADV_SCANNABLE_UNDIRECTED,
/**
* Device is not connectable and not scannable.
*
* @see Vol 3, Part C, Section 9.3.2 and Vol 6, Part B, Section 2.3.1.3.
*/
ADV_NON_CONNECTABLE_UNDIRECTED
};
/**
* Type alias for GapAdvertisingParams::AdvertisingType_t.
* Alias for GapAdvertisingParams::AdvertisingType_t.
*
* @deprecated This type alias will be dropped in future releases.
* @deprecated Future releases will drop this type alias.
*/
typedef enum AdvertisingType_t AdvertisingType;
@ -65,18 +116,23 @@ public:
/**
* Construct an instance of GapAdvertisingParams.
*
* @param[in] advType
* Type of advertising. Default is
* GapAdvertisingParams::ADV_CONNECTABLE_UNDIRECTED.
* @param[in] interval
* Advertising interval in units of 0.625ms. Default is
* GapAdvertisingParams::GAP_ADV_PARAMS_INTERVAL_MIN_NONCON.
* @param[in] timeout
* Advertising timeout. Default is 0.
* @param[in] advType Type of advertising.
* @param[in] interval Time interval between two advertisement in units of
* 0.625ms.
* @param[in] timeout Duration in seconds of the advertising process. A
* value of 0 indicate that there is no timeout of the advertising process.
*
* @note If value in input are out of range, they will be normalized.
*/
GapAdvertisingParams(AdvertisingType_t advType = ADV_CONNECTABLE_UNDIRECTED,
uint16_t interval = GAP_ADV_PARAMS_INTERVAL_MIN_NONCON,
uint16_t timeout = 0) : _advType(advType), _interval(interval), _timeout(timeout) {
GapAdvertisingParams(
AdvertisingType_t advType = ADV_CONNECTABLE_UNDIRECTED,
uint16_t interval = GAP_ADV_PARAMS_INTERVAL_MIN_NONCON,
uint16_t timeout = 0
) :
_advType(advType),
_interval(interval),
_timeout(timeout)
{
/* Interval checks. */
if (_advType == ADV_CONNECTABLE_DIRECTED) {
/* Interval must be 0 in directed connectable mode. */
@ -108,27 +164,32 @@ public:
}
}
static const uint16_t UNIT_0_625_MS = 625; /**< Number of microseconds in 0.625 milliseconds. */
/**
* Number of microseconds in 0.625 milliseconds.
*/
static const uint16_t UNIT_0_625_MS = 625;
/**
* Convert milliseconds to units of 0.625ms.
*
* @param[in] durationInMillis
* The number of milliseconds to convert.
* @param[in] durationInMillis Number of milliseconds to convert.
*
* @return The value of @p durationInMillis in units of 0.625ms.
*/
static uint16_t MSEC_TO_ADVERTISEMENT_DURATION_UNITS(uint32_t durationInMillis) {
static uint16_t MSEC_TO_ADVERTISEMENT_DURATION_UNITS(uint32_t durationInMillis)
{
return (durationInMillis * 1000) / UNIT_0_625_MS;
}
/**
* Convert units of 0.625ms to milliseconds.
*
* @param[in] gapUnits
* The number of units of 0.625ms to convert.
* @param[in] gapUnits The number of units of 0.625ms to convert.
*
* @return The value of @p gapUnits in milliseconds.
*/
static uint16_t ADVERTISEMENT_DURATION_UNITS_TO_MS(uint16_t gapUnits) {
static uint16_t ADVERTISEMENT_DURATION_UNITS_TO_MS(uint16_t gapUnits)
{
return (gapUnits * UNIT_0_625_MS) / 1000;
}
@ -137,7 +198,8 @@ public:
*
* @return The advertising type.
*/
AdvertisingType_t getAdvertisingType(void) const {
AdvertisingType_t getAdvertisingType(void) const
{
return _advType;
}
@ -146,16 +208,19 @@ public:
*
* @return The advertisement interval (in milliseconds).
*/
uint16_t getInterval(void) const {
uint16_t getInterval(void) const
{
return ADVERTISEMENT_DURATION_UNITS_TO_MS(_interval);
}
/**
* Get the advertisement interval in units of 0.625ms.
*
* @return The advertisement interval in advertisement duration units (0.625ms units).
* @return The advertisement interval in advertisement duration units
* (0.625ms units).
*/
uint16_t getIntervalInADVUnits(void) const {
uint16_t getIntervalInADVUnits(void) const
{
return _interval;
}
@ -164,44 +229,63 @@ public:
*
* @return The advertising timeout (in seconds).
*/
uint16_t getTimeout(void) const {
uint16_t getTimeout(void) const
{
return _timeout;
}
/**
* Set the advertising type.
* Update the advertising type.
*
* @param[in] newAdvType
* The new advertising type.
* @param[in] newAdvType The new advertising type.
*/
void setAdvertisingType(AdvertisingType_t newAdvType) {
void setAdvertisingType(AdvertisingType_t newAdvType)
{
_advType = newAdvType;
}
/**
* Set the advertising interval in milliseconds.
* Update the advertising interval in milliseconds.
*
* @param[in] newInterval
* The new advertising interval in milliseconds.
* @param[in] newInterval The new advertising interval in milliseconds.
*/
void setInterval(uint16_t newInterval) {
void setInterval(uint16_t newInterval)
{
_interval = MSEC_TO_ADVERTISEMENT_DURATION_UNITS(newInterval);
}
/**
* Set the advertising timeout.
* Update the advertising timeout.
*
* @param[in] newTimeout
* The new advertising timeout (in seconds).
* @param[in] newTimeout The new advertising timeout (in seconds).
*
* @note 0 is a special value meaning the advertising process never ends.
*/
void setTimeout(uint16_t newTimeout) {
void setTimeout(uint16_t newTimeout)
{
_timeout = newTimeout;
}
private:
AdvertisingType_t _advType; /**< The advertising type. */
uint16_t _interval; /**< The advertising interval in ADV duration units (i.e. 0.625ms). */
uint16_t _timeout; /**< The advertising timeout in seconds. */
/**
* The advertising type.
*/
AdvertisingType_t _advType;
/**
* The advertising interval in ADV duration units (in other words, 0.625ms).
*/
uint16_t _interval;
/**
* The advertising timeout in seconds.
*/
uint16_t _timeout;
};
#endif /* ifndef __GAP_ADVERTISING_PARAMS_H__ */
/**
* @}
* @}
*/
#endif /* ifndef MBED_GAP_ADVERTISING_PARAMS_H__ */

View File

@ -14,89 +14,154 @@
* limitations under the License.
*/
#ifndef __GAP_SCANNING_PARAMS_H__
#define __GAP_SCANNING_PARAMS_H__
#ifndef MBED_GAP_SCANNING_PARAMS_H__
#define MBED_GAP_SCANNING_PARAMS_H__
/**
* @addtogroup ble
* @{
* @addtogroup gap
* @{
*/
/**
* Parameters defining the scan process.
*
* Four distinct parameters define the scan procedure:
* - Scan window: Period during which the scanner listens to advertising
* channels. That value is in the range of 2.5ms to 10.24s. This value
* can be set at construction time, updated by calling setWindow() and
* retrieved by invoking getWindow().
*
* - Scan interval: Interval between the start of two consecutive scan windows.
* That value shall be greater or equal to the scan window value. The
* maximum allowed value is 10.24ms. The scan interval value can be set at
* construction time, updated with a call to setInterval() and queried by a
* call to getInterval().
*
* - Timeout: The duration of the scan procedure if any. It can be set at
* construction time, updated with setTimeout() and obtained from
* getTimeout().
*
* - Active scanning: If set, then the scanner sends scan requests to a scannable
* or connectable advertiser. Advertisers may respond to the scan request
* by a scan response containing the scan response payload. If not set, then
* the scanner does not send any request. This flag is set at construction
* time, may be updated with the help of setActiveScanning() and retrieved
* by getActiveScanning().
*
* @note If the scan window's duration is equal to the scan interval, then the
* device listens continuously during the scan procedure.
*/
class GapScanningParams {
public:
static const unsigned SCAN_INTERVAL_MIN = 0x0004; /**< Minimum Scan interval in 625us units - 2.5ms. */
static const unsigned SCAN_INTERVAL_MAX = 0x4000; /**< Maximum Scan interval in 625us units - 10.24s. */
static const unsigned SCAN_WINDOW_MIN = 0x0004; /**< Minimum Scan window in 625us units - 2.5ms. */
static const unsigned SCAN_WINDOW_MAX = 0x4000; /**< Maximum Scan window in 625us units - 10.24s. */
static const unsigned SCAN_TIMEOUT_MIN = 0x0001; /**< Minimum Scan timeout in seconds. */
static const unsigned SCAN_TIMEOUT_MAX = 0xFFFF; /**< Maximum Scan timeout in seconds. */
/**
* Minimum Scan interval in 625us units - 2.5ms.
*/
static const unsigned SCAN_INTERVAL_MIN = 0x0004;
/**
* Maximum Scan interval in 625us units - 10.24s.
*/
static const unsigned SCAN_INTERVAL_MAX = 0x4000;
/**
* Minimum Scan window in 625us units - 2.5ms.
*/
static const unsigned SCAN_WINDOW_MIN = 0x0004;
/**
* Maximum Scan window in 625us units - 10.24s.
*/
static const unsigned SCAN_WINDOW_MAX = 0x4000;
/**
* Minimum Scan duration in seconds.
*/
static const unsigned SCAN_TIMEOUT_MIN = 0x0001;
/**
* Maximum Scan duration in seconds.
*/
static const unsigned SCAN_TIMEOUT_MAX = 0xFFFF;
public:
/**
* Construct an instance of GapScanningParams.
*
* @param[in] interval
* The scan interval in milliseconds. Default is
* GapScanningParams::SCAN_INTERVAL_MIN.
* @param[in] window
* The scan window in milliseconds. Default is
* GapScanningParams::SCAN_WINDOW_MAX.
* @param[in] timeout
* The scan timeout in seconds. Default is 0.
* @param[in] activeScanning
* Set to True if active-scanning is required. This is used to
* fetch the scan response from a peer if possible. Default is
* false.
* @param[in] interval Milliseconds interval between the start of two
* consecutive scan windows. The value passed is between the scan
* window value and 10.24 seconds.
*
* @param[in] window Milliseconds period during which the device
* listens to advertising channels. The value of the scan window is in
* the range of 2.5ms to 10.24s.
*
* @param[in] timeout Duration in seconds of the scan procedure. The special
* value 0 may be used when the scan procedure is not time bounded.
*
* @param[in] activeScanning If true, then the scanner sends scan requests to
* to scannable or connectable advertiser. Advertisers may respond to the
* scan request by a scan response containing the scan response payload. If
* false, the scanner does not send any request.
*
* @note If interval is equal to window
*/
GapScanningParams(uint16_t interval = SCAN_INTERVAL_MAX,
uint16_t window = SCAN_WINDOW_MAX,
uint16_t timeout = 0,
bool activeScanning = false);
GapScanningParams(
uint16_t interval = SCAN_INTERVAL_MAX,
uint16_t window = SCAN_WINDOW_MAX,
uint16_t timeout = 0,
bool activeScanning = false
);
/**
* Number of microseconds in 0.625 milliseconds.
*/
static const uint16_t UNIT_0_625_MS = 625;
static const uint16_t UNIT_0_625_MS = 625; /**< Number of microseconds in 0.625 milliseconds. */
/**
* Convert milliseconds to units of 0.625ms.
*
* @param[in] durationInMillis
* The number of milliseconds to convert.
* @param[in] durationInMillis Milliseconds to convert.
*
* @return The value of @p durationInMillis in units of 0.625ms.
*/
static uint16_t MSEC_TO_SCAN_DURATION_UNITS(uint32_t durationInMillis) {
static uint16_t MSEC_TO_SCAN_DURATION_UNITS(uint32_t durationInMillis)
{
return (durationInMillis * 1000) / UNIT_0_625_MS;
}
/**
* Set the scan interval.
* Update the scan interval.
*
* @param[in] newIntervalInMS
* New scan interval in milliseconds.
* @param[in] newIntervalInMS New scan interval in milliseconds.
*
* @return BLE_ERROR_NONE if the new scan interval was set successfully.
*/
ble_error_t setInterval(uint16_t newIntervalInMS);
/**
* Set the scan window.
* Update the scan window.
*
* @param[in] newWindowInMS
* New scan window in milliseconds.
* @param[in] newWindowInMS New scan window in milliseconds.
*
* @return BLE_ERROR_NONE if the new scan window was set successfully.
*/
ble_error_t setWindow(uint16_t newWindowInMS);
/**
* Set the scan timeout.
* Update the scan timeout.
*
* @param[in] newTimeout
* New scan timeout in seconds.
* @param[in] newTimeout New scan timeout in seconds.
*
* @return BLE_ERROR_NONE if the new scan window was set successfully.
*/
ble_error_t setTimeout(uint16_t newTimeout);
/**
* Set active scanning. This is used to fetch the scan response from a peer
* if possible.
* Update the active scanning flag.
*
* @param[in] activeScanning
* The new boolean value of active scanning.
* @param[in] activeScanning New boolean value of active scanning.
*/
void setActiveScanning(bool activeScanning);
@ -106,7 +171,8 @@ public:
*
* @return the scan interval in units of 0.625ms.
*/
uint16_t getInterval(void) const {
uint16_t getInterval(void) const
{
return _interval;
}
@ -115,7 +181,8 @@ public:
*
* @return the scan window in units of 0.625ms.
*/
uint16_t getWindow(void) const {
uint16_t getWindow(void) const
{
return _window;
}
@ -124,7 +191,8 @@ public:
*
* @return The scan timeout in seconds.
*/
uint16_t getTimeout(void) const {
uint16_t getTimeout(void) const
{
return _timeout;
}
@ -133,15 +201,31 @@ public:
*
* @return True if active scanning is set, false otherwise.
*/
bool getActiveScanning(void) const {
bool getActiveScanning(void) const
{
return _activeScanning;
}
private:
uint16_t _interval; /**< Scan interval in units of 625us (between 2.5ms and 10.24s). */
uint16_t _window; /**< Scan window in units of 625us (between 2.5ms and 10.24s). */
uint16_t _timeout; /**< Scan timeout between 0x0001 and 0xFFFF in seconds; 0x0000 disables timeout. */
bool _activeScanning; /**< Obtain the peer device's advertising data and (if possible) scanResponse. */
/**
* Scan interval in units of 625us (between 2.5ms and 10.24s).
*/
uint16_t _interval;
/**
* Scan window in units of 625us (between 2.5ms and 10.24s).
*/
uint16_t _window;
/**
* Scan timeout between 0x0001 and 0xFFFF in seconds; 0x0000 disables timeout.
*/
uint16_t _timeout;
/**
* Obtain the peer device's advertising data and (if possible) scanResponse.
*/
bool _activeScanning;
private:
/* Disallow copy constructor. */
@ -149,4 +233,9 @@ private:
GapScanningParams& operator =(const GapScanningParams &in);
};
#endif /* ifndef __GAP_SCANNING_PARAMS_H__ */
/**
* @}
* @}
*/
#endif /* ifndef MBED_GAP_SCANNING_PARAMS_H__ */

View File

@ -20,6 +20,15 @@
#include "UUID.h"
#include "BLETypes.h"
/**
* @addtogroup ble
* @{
* @addtogroup gatt
* @{
* @addtogroup server
* @{
*/
/**
* Instances of this class encapsulate the data that belongs to a Bluetooth Low
* Energy attribute.
@ -28,7 +37,7 @@ class GattAttribute {
public:
/**
* Type for the handle or ID of the attribute in the ATT table. These are
* unique and are usually generated by the underlying BLE stack.
* unique, and the underlying BLE stack usually generates them.
*/
typedef ble::attribute_handle_t Handle_t;
/**
@ -50,7 +59,7 @@ public:
* @param[in] maxLen
* The max length in bytes of this attribute's value.
* @param[in] hasVariableLen
* Whether the attribute's value length changes overtime.
* Whether the attribute's value length changes over time.
*
* @section EXAMPLE
*
@ -172,4 +181,10 @@ private:
GattAttribute& operator=(const GattAttribute &);
};
/**
* @}
* @}
* @}
*/
#endif /* ifndef __GATT_ATTRIBUTE_H__ */

View File

@ -14,139 +14,377 @@
* limitations under the License.
*/
#ifndef __GATT_CALLBACK_PARAM_TYPES_H__
#define __GATT_CALLBACK_PARAM_TYPES_H__
#ifndef MBED_BLE_GATT_CALLBACK_PARAM_TYPES_H__
#define MBED_BLE_GATT_CALLBACK_PARAM_TYPES_H__
/**
* Parameter of the callback invoked on a write operation.
* This parameter is used whether a GattServer as received a write operation or
* if the GattClient has completed a write operation.
* @addtogroup ble
* @{
* @addtogroup gatt
* @{
*/
/**
* GATT Write event definition.
*
* @important The fields connHandle, handle and writeOp are used in both
* callbacks while:
* - offset, len and data are reserved for GattServer write callbacks.
* - status and error_code are reserved for GattClient write callbacks.
* Instances of this type are created and passed to user registered callbacks
* whether the GattServer has received a write request or a GattClient has
* received a write response.
*
* @important The GattServer only populates the fields offset, len and data
* when it has received a write request. Callbacks attached to the GattClient
* do not use those fields.
*
* @important The GattClient only populates the fields status and error_code
* when it has received a write response. Callbacks attached to the GattServer
* do not use those fields.
*/
struct GattWriteCallbackParams {
/**
* Enumeration for write operations.
* Enumeration of allowed write operations.
*/
enum WriteOp_t {
OP_INVALID = 0x00, /**< Invalid operation. */
OP_WRITE_REQ = 0x01, /**< Write request. */
OP_WRITE_CMD = 0x02, /**< Write command. */
OP_SIGN_WRITE_CMD = 0x03, /**< Signed write command. */
OP_PREP_WRITE_REQ = 0x04, /**< Prepare write request. */
OP_EXEC_WRITE_REQ_CANCEL = 0x05, /**< Execute write request: cancel all prepared writes. */
OP_EXEC_WRITE_REQ_NOW = 0x06, /**< Execute write request: immediately execute all prepared writes. */
/**
* Invalid operation.
*/
OP_INVALID = 0x00,
/**
* Write request.
*/
OP_WRITE_REQ = 0x01,
/**
* Write command.
*/
OP_WRITE_CMD = 0x02,
/**
* Signed write command.
*/
OP_SIGN_WRITE_CMD = 0x03,
/**
* Prepare write request.
*/
OP_PREP_WRITE_REQ = 0x04,
/**
* Execute write request: cancel all prepared writes.
*/
OP_EXEC_WRITE_REQ_CANCEL = 0x05,
/**
* Execute write request: immediately execute all prepared writes.
*/
OP_EXEC_WRITE_REQ_NOW = 0x06,
};
Gap::Handle_t connHandle; /**< The handle of the connection that triggered the event. */
GattAttribute::Handle_t handle; /**< Attribute Handle to which the write operation applies. */
WriteOp_t writeOp; /**< Type of write operation. */
/**
* Handle of the connection that triggered the event.
*/
Gap::Handle_t connHandle;
/**
* Handle of the attribute to which the write operation applies.
*/
GattAttribute::Handle_t handle;
/**
* Type of the write operation.
*/
WriteOp_t writeOp;
// Note: offset is used in GattServer while status is used in GattClient
union {
uint16_t offset; /**< Offset for the GattServer write operation. */
ble_error_t status; /**< Status of the GattClient Write operation */
/**
* Offset within the attribute value to be written.
*
* @important Reserved for GattServer registered callbacks.
*/
uint16_t offset;
/**
* Status of the GattClient Write operation.
*
* @important Reserved for GattClient registered callbacks.
*/
ble_error_t status;
};
// Note: len is used in GattServer while error_code is used in GattClient
union {
uint16_t len; /**< Length (in bytes) of the data to write (GattServer). */
uint8_t error_code; /**< Error code of the GattClient Write operation */
/**
* Length (in bytes) of the data to write.
*
* @important Reserved for GattServer registered callbacks.
*/
uint16_t len;
/**
* Error code of the GattClient Write operation.
*
* @important Reserved for GattClient registered callbacks.
*/
uint8_t error_code;
};
/**
* Pointer to the data to write.
*
* @note Data might not persist beyond the callback; make a local copy if
* needed.
* @note This field is not used by callbacks invoked by the GattClient module.
* @important Data may not persist beyond the callback scope.
*
* @important Reserved for GattServer registered callbacks.
*/
const uint8_t *data;
const uint8_t *data;
};
/**
* Parameter of the callback invoked on a read operation.
* This parameter is used whether a GattServer as received a read operation or
* if the GattClient has completed a read operation.
* GATT Read event definition.
*
* @important The fields connHandle, handle and offset are used in both
* callbacks while:
* - len and data are reserved for GattServer read callbacks.
* - status and error_code are reserved for GattClient read callbacks.
* Instances of this type are created and passed to user registered callbacks
* whether the GattServer has received a read request or a GattClient has
* received a read response.
*
* @important The GattClient only populates the fields status and error_code
* when it has received a read response. Callbacks attached to the GattServer
* do not use those fields.
*/
struct GattReadCallbackParams {
Gap::Handle_t connHandle; /**< The handle of the connection that triggered the event. */
GattAttribute::Handle_t handle; /**< Attribute Handle to which the read operation applies. */
uint16_t offset; /**< Offset for the read operation. */
/**
* Handle of the connection that triggered the event.
*/
Gap::Handle_t connHandle;
/**
* Attribute Handle to which the read operation applies.
*/
GattAttribute::Handle_t handle;
/**
* Offset within the attribute value read.
*/
uint16_t offset;
union {
uint16_t len; /**< Length (in bytes) of the data to read. */
uint8_t error_code; /**< Error code if any (GattClient) */
/**
* Length in bytes of the data read.
*/
uint16_t len;
/**
* Error code of the GattClient read operation.
*
* @important Reserved for GattClient registered callbacks.
*
* @important set if status is not equal to BLE_ERROR_NONE; otherwise,
* this field is interpreted as len.
*/
uint8_t error_code;
};
/**
* Pointer to the data read.
*
* @note Data might not persist beyond the callback; make a local copy if
* needed.
* @important Data may not persist beyond the callback scope.
*/
const uint8_t *data;
ble_error_t status; /**< Status of the operation BLE_ERROR_NONE in case of success or the error in case of error */
};
const uint8_t *data;
enum GattAuthCallbackReply_t {
AUTH_CALLBACK_REPLY_SUCCESS = 0x00, /**< Success. */
AUTH_CALLBACK_REPLY_ATTERR_INVALID_HANDLE = 0x0101, /**< ATT Error: Invalid attribute handle. */
AUTH_CALLBACK_REPLY_ATTERR_READ_NOT_PERMITTED = 0x0102, /**< ATT Error: Read not permitted. */
AUTH_CALLBACK_REPLY_ATTERR_WRITE_NOT_PERMITTED = 0x0103, /**< ATT Error: Write not permitted. */
AUTH_CALLBACK_REPLY_ATTERR_INSUF_AUTHENTICATION = 0x0105, /**< ATT Error: Authenticated link required. */
AUTH_CALLBACK_REPLY_ATTERR_INVALID_OFFSET = 0x0107, /**< ATT Error: The specified offset was past the end of the attribute. */
AUTH_CALLBACK_REPLY_ATTERR_INSUF_AUTHORIZATION = 0x0108, /**< ATT Error: Used in ATT as "insufficient authorization". */
AUTH_CALLBACK_REPLY_ATTERR_PREPARE_QUEUE_FULL = 0x0109, /**< ATT Error: Used in ATT as "prepare queue full". */
AUTH_CALLBACK_REPLY_ATTERR_ATTRIBUTE_NOT_FOUND = 0x010A, /**< ATT Error: Used in ATT as "attribute not found". */
AUTH_CALLBACK_REPLY_ATTERR_ATTRIBUTE_NOT_LONG = 0x010B, /**< ATT Error: Attribute cannot be read or written using read/write blob requests. */
AUTH_CALLBACK_REPLY_ATTERR_INVALID_ATT_VAL_LENGTH = 0x010D, /**< ATT Error: Invalid value size. */
AUTH_CALLBACK_REPLY_ATTERR_INSUF_RESOURCES = 0x0111, /**< ATT Error: Encrypted link required. */
};
struct GattWriteAuthCallbackParams {
Gap::Handle_t connHandle; /**< The handle of the connection that triggered the event. */
GattAttribute::Handle_t handle; /**< Attribute Handle to which the write operation applies. */
uint16_t offset; /**< Offset for the write operation. */
uint16_t len; /**< Length of the incoming data. */
const uint8_t *data; /**< Incoming data, variable length. */
/**
* This is the out parameter that the callback needs to set to
* AUTH_CALLBACK_REPLY_SUCCESS for the request to proceed.
* Status of the GattClient Read operation.
*
* @important Reserved for GattClient registered callbacks.
*/
GattAuthCallbackReply_t authorizationReply;
};
struct GattReadAuthCallbackParams {
Gap::Handle_t connHandle; /**< The handle of the connection that triggered the event. */
GattAttribute::Handle_t handle; /**< Attribute Handle to which the read operation applies. */
uint16_t offset; /**< Offset for the read operation. */
uint16_t len; /**< Optional: new length of the outgoing data. */
uint8_t *data; /**< Optional: new outgoing data. Leave at NULL if data is unchanged. */
/**
* This is the out parameter that the callback needs to set to
* AUTH_CALLBACK_REPLY_SUCCESS for the request to proceed.
*/
GattAuthCallbackReply_t authorizationReply;
ble_error_t status;
};
/**
* For encapsulating handle-value update events (notifications or indications)
* generated at the remote server.
* @addtogroup server
* @{
*/
struct GattHVXCallbackParams {
Gap::Handle_t connHandle; /**< The handle of the connection that triggered the event. */
GattAttribute::Handle_t handle; /**< Attribute Handle to which the HVx operation applies. */
HVXType_t type; /**< Indication or Notification, see HVXType_t. */
uint16_t len; /**< Attribute data length. */
const uint8_t *data; /**< Attribute data, variable length. */
/**
* Enumeration of allowed values returned by read or write authorization process.
*/
enum GattAuthCallbackReply_t {
/**
* Success.
*/
AUTH_CALLBACK_REPLY_SUCCESS = 0x00,
/**
* ATT Error: Invalid attribute handle.
*/
AUTH_CALLBACK_REPLY_ATTERR_INVALID_HANDLE = 0x0101,
/**
* ATT Error: Read not permitted.
*/
AUTH_CALLBACK_REPLY_ATTERR_READ_NOT_PERMITTED = 0x0102,
/**
* ATT Error: Write not permitted.
*/
AUTH_CALLBACK_REPLY_ATTERR_WRITE_NOT_PERMITTED = 0x0103,
/**
* ATT Error: Authenticated link required.
*/
AUTH_CALLBACK_REPLY_ATTERR_INSUF_AUTHENTICATION = 0x0105,
/**
* ATT Error: The specified offset was past the end of the attribute.
*/
AUTH_CALLBACK_REPLY_ATTERR_INVALID_OFFSET = 0x0107,
/**
* ATT Error: Used in ATT as "insufficient authorization".
*/
AUTH_CALLBACK_REPLY_ATTERR_INSUF_AUTHORIZATION = 0x0108,
/**
* ATT Error: Used in ATT as "prepare queue full".
*/
AUTH_CALLBACK_REPLY_ATTERR_PREPARE_QUEUE_FULL = 0x0109,
/**
* ATT Error: Used in ATT as "attribute not found".
*/
AUTH_CALLBACK_REPLY_ATTERR_ATTRIBUTE_NOT_FOUND = 0x010A,
/**
* ATT Error: Attribute cannot be read or written using read/write blob
* requests.
*/
AUTH_CALLBACK_REPLY_ATTERR_ATTRIBUTE_NOT_LONG = 0x010B,
/**
* ATT Error: Invalid value size.
*/
AUTH_CALLBACK_REPLY_ATTERR_INVALID_ATT_VAL_LENGTH = 0x010D,
/**
* ATT Error: Encrypted link required.
*/
AUTH_CALLBACK_REPLY_ATTERR_INSUF_RESOURCES = 0x0111,
};
#endif /*__GATT_CALLBACK_PARAM_TYPES_H__*/
/**
* GATT write authorization request event.
*/
struct GattWriteAuthCallbackParams {
/**
* Handle of the connection that triggered the event.
*/
Gap::Handle_t connHandle;
/**
* Attribute Handle to which the write operation applies.
*/
GattAttribute::Handle_t handle;
/**
* Offset for the write operation.
*/
uint16_t offset;
/**
* Length of the incoming data.
*/
uint16_t len;
/**
* Incoming data.
*/
const uint8_t *data;
/**
* Authorization result.
*
* The callback sets this parameter. If the value is set to
* AUTH_CALLBACK_REPLY_SUCCESS, then the write request is accepted;
* otherwise, an error code is returned to the peer client.
*/
GattAuthCallbackReply_t authorizationReply;
};
/**
* GATT read authorization request event.
*/
struct GattReadAuthCallbackParams {
/**
* The handle of the connection that triggered the event.
*/
Gap::Handle_t connHandle;
/**
* Attribute Handle to which the read operation applies.
*/
GattAttribute::Handle_t handle;
/**
* Offset for the read operation.
*/
uint16_t offset;
/**
* Optional: new length of the outgoing data.
*/
uint16_t len;
/**
* Optional: new outgoing data. Leave at NULL if data is unchanged.
*/
uint8_t *data;
/**
* Authorization result.
*
* The callback sets this parameter. If the value is set to
* AUTH_CALLBACK_REPLY_SUCCESS, then the read request is accepted;
* otherwise, an error code is returned to the peer client.
*/
GattAuthCallbackReply_t authorizationReply;
};
/**
* Handle Value Notification/Indication event.
*
* The GattClient generates this type of event upon the reception of a
* Handle Value Notification or Indication.
*
* The event is passed to callbacks registered by GattClient::onHVX().
*/
struct GattHVXCallbackParams {
/**
* The handle of the connection that triggered the event.
*/
Gap::Handle_t connHandle;
/**
* Attribute Handle to which the HVx operation applies.
*/
GattAttribute::Handle_t handle;
/**
* Indication or Notification, see HVXType_t.
*/
HVXType_t type;
/**
* Attribute value length.
*/
uint16_t len;
/**
* Attribute value.
*/
const uint8_t *data;
};
/**
* @}
* @}
* @}
*/
#endif /*MBED_BLE_GATT_CALLBACK_PARAM_TYPES_H__*/

View File

@ -23,6 +23,15 @@
#include "GattCallbackParamTypes.h"
#include "FunctionPointerWithContext.h"
/**
* @addtogroup ble
* @{
* @addtogroup gatt
* @{
* @addtogroup server
* @{
*/
class GattCharacteristic {
public:
enum {
@ -291,14 +300,14 @@ public:
/**
* @brief Creates a new GattCharacteristic using the specified 16-bit
* UUID, value length, and properties.
* UUID, value length and properties.
*
* @param[in] uuid
* The UUID to use for this characteristic.
* @param[in] valuePtr
* The memory holding the initial value. The value is copied
* into the stack when the enclosing service is added, and
* is thereafter maintained internally by the stack.
* the stack thereafter maintained it internally.
* @param[in] len
* The length in bytes of this characteristic's value.
* @param[in] maxLen
@ -307,8 +316,8 @@ public:
* The 8-bit field containing the characteristic's properties.
* @param[in] descriptors
* A pointer to an array of descriptors to be included within
* this characteristic. The memory for the descriptor array is
* owned by the caller, and should remain valid at least until
* this characteristic. The caller owns the memory for the descriptor
* array, which remains valid at least until
* the enclosing service is added to the GATT table.
* @param[in] numDescriptors
* The number of descriptors in the previous array.
@ -323,7 +332,7 @@ public:
* instantiating the service with the underlying BLE stack.
*
* @note A CCCD should not be allocated if either the notify or indicate
* flag is set, as it is handled by the underlying BLE stack. In such
* flag is set because the underlying BLE stack handles it. In such
* a case, the param descriptors could be empty and the param
* numDescriptors equal to zero.
*/
@ -363,7 +372,7 @@ public:
public:
/**
* Set up callback that will be triggered before the GATT Client is allowed
* to write this characteristic. The handler will determine the
* to write this characteristic. The handler determines the
* authorization reply for the write.
*
* @param[in] callback
@ -375,7 +384,7 @@ public:
}
/**
* Same as GattCharacrteristic::setWriteAuthorizationCallback(), but allows
* Same as GattCharacrteristic::setWriteAuthorizationCallback(), but it allows
* the possibility to add an object reference and member function as
* handler for connection event callbacks.
*
@ -394,7 +403,7 @@ public:
/**
* Set up callback that will be triggered before the GATT Client is allowed
* to read this characteristic. The handler will determine the
* to read this characteristic. The handler determines the
* authorization reply for the read.
*
* @param[in] callback
@ -406,7 +415,7 @@ public:
}
/**
* Same as GattCharacrteristic::setReadAuthorizationCallback(), but allows
* Same as GattCharacrteristic::setReadAuthorizationCallback(), but it allows
* the possibility to add an object reference and member function as
* handler for connection event callbacks.
*
@ -456,12 +465,12 @@ public:
* @return A GattAuthCallbackReply_t value indicating whether authorization
* is granted.
*
* @note To authorize or deny the read the params->authorizationReply field
* @note To authorize or deny the read, the params->authorizationReply field
* should be set to AUTH_CALLBACK_REPLY_SUCCESS (authorize) or any
* of the AUTH_CALLBACK_REPLY_ATTERR_* values (deny).
*
* @note If the read is approved and params->data is unchanged (NULL),
* the current characteristic value will be used.
* the current characteristic value is used.
*
* @note If the read is approved, a new value can be provided by setting
* the params->data pointer and params->len fields.
@ -500,8 +509,7 @@ public:
*
* @return The value attribute handle.
*
* @note The attribute handle is typically assigned by the underlying BLE
* stack.
* @note The underlying BLE stack typically assigns the attribute handle.
*/
GattAttribute::Handle_t getValueHandle(void) const {
return getValueAttribute().getHandle();
@ -536,7 +544,7 @@ public:
}
/**
* Check whether read authorization is enabled i.e. check whether a
* Check whether read authorization is enabled. In other words, check whether a
* read authorization callback was previously registered. Refer to
* GattCharacteristic::setReadAuthorizationCallback().
*
@ -547,7 +555,7 @@ public:
}
/**
* Check whether write authorization is enabled i.e. check whether a
* Check whether write authorization is enabled. In other words, check whether a
* write authorization callback was previously registered. Refer to
* GattCharacteristic::setWriteAuthorizationCallback().
*
@ -591,7 +599,7 @@ private:
/**
* The characteristic's descriptor attributes.
* This contains only CCCDs that has neither the notify nor the indicate
* flag set, as those are handled by the underlying BLE stack.
* flag set, as the underlying BLE stack handles those.
*/
GattAttribute **_descriptors;
/**
@ -600,12 +608,12 @@ private:
uint8_t _descriptorCount;
/**
* Whether read authorization is enabled i.e. whether there is a registered
* Whether read authorization is enabled - in other words, whether there is a registered
* callback to determine read authorization reply.
*/
bool enabledReadAuthorization;
/**
* Whether write authorization is enabled i.e. whether there is a registered
* Whether write authorization is enabled - in other words, whether there is a registered
* callback to determine write authorization reply.
*/
bool enabledWriteAuthorization;
@ -687,7 +695,7 @@ public:
*
* @note Instances of WriteOnlyGattCharacteristic have variable length
* attribute value with maximum size equal to sizeof(T). For a fixed length
* alternative use GattCharacteristic directly.
* alternative, use GattCharacteristic directly.
*/
WriteOnlyGattCharacteristic<T>(const UUID &uuid,
T *valuePtr,
@ -726,7 +734,7 @@ public:
*
* @note Instances of ReadWriteGattCharacteristic have variable length
* attribute value with maximum size equal to sizeof(T). For a fixed length
* alternative use GattCharacteristic directly.
* alternative, use GattCharacteristic directly.
*/
ReadWriteGattCharacteristic<T>(const UUID &uuid,
T *valuePtr,
@ -766,7 +774,7 @@ public:
*
* @note Instances of WriteOnlyGattCharacteristic have variable length
* attribute value with maximum size equal to sizeof(T) * NUM_ELEMENTS.
* For a fixed length alternative use GattCharacteristic directly.
* For a fixed length alternative, use GattCharacteristic directly.
*/
WriteOnlyArrayGattCharacteristic<T, NUM_ELEMENTS>(const UUID &uuid,
T valuePtr[NUM_ELEMENTS],
@ -806,7 +814,7 @@ public:
*
* @note Instances of ReadOnlyGattCharacteristic have fixed length
* attribute value that equals sizeof(T) * NUM_ELEMENTS.
* For a variable length alternative use GattCharacteristic directly.
* For a variable length alternative, use GattCharacteristic directly.
*/
ReadOnlyArrayGattCharacteristic<T, NUM_ELEMENTS>(const UUID &uuid,
T valuePtr[NUM_ELEMENTS],
@ -847,7 +855,7 @@ public:
*
* @note Instances of ReadWriteGattCharacteristic have variable length
* attribute value with maximum size equal to sizeof(T) * NUM_ELEMENTS.
* For a fixed length alternative use GattCharacteristic directly.
* For a fixed length alternative, use GattCharacteristic directly.
*/
ReadWriteArrayGattCharacteristic<T, NUM_ELEMENTS>(const UUID &uuid,
T valuePtr[NUM_ELEMENTS],
@ -860,4 +868,10 @@ public:
}
};
/**
* @}
* @}
* @}
*/
#endif /* ifndef __GATT_CHARACTERISTIC_H__ */

File diff suppressed because it is too large Load Diff

View File

@ -24,6 +24,15 @@
#include "GattCallbackParamTypes.h"
#include "CallChainOfFunctionPointersWithContext.h"
/**
* @addtogroup ble
* @{
* @addtogroup gatt
* @{
* @addtogroup server
* @{
*/
class GattServer {
public:
/**
@ -90,7 +99,7 @@ protected:
}
/*
* The following functions are meant to be overridden in the platform-specific sub-class.
* The following functions are meant to be overridden in the platform-specific subclass.
*/
public:
@ -120,7 +129,7 @@ public:
* @param[in,out] lengthP
* Length of the buffer being supplied. If the attribute
* value is longer than the size of the supplied buffer,
* this variable will hold upon return the total attribute value length
* this variable holds upon return the total attribute value length
* (excluding offset). The application may use this
* information to allocate a suitable buffer size.
*
@ -147,7 +156,7 @@ public:
* @param[in,out] lengthP
* Length of the buffer being supplied. If the attribute
* value is longer than the size of the supplied buffer,
* this variable will hold upon return the total attribute value length
* this variable holds upon return the total attribute value length
* (excluding offset). The application may use this
* information to allocate a suitable buffer size.
*
@ -278,12 +287,12 @@ public:
}
/*
* APIs with non-virtual implementations.
* APIs with nonvirtual implementations.
*/
public:
/**
* Add a callback for the GATT event DATA_SENT (which is triggered when
* updates are sent out by GATT in the form of notifications).
* GATT sends updates in the form of notifications).
*
* @param[in] callback
* Event handler being registered.
@ -300,7 +309,7 @@ public:
}
/**
* Same as GattServer::onDataSent(), but allows the possibility to add an object
* Same as GattServer::onDataSent() but it allows the possibility to add an object
* reference and member function as handler for DATA_SENT event
* callbacks.
*
@ -350,8 +359,8 @@ public:
}
/**
* Same as GattServer::onDataWritten(), but allows the possibility to add an object
* reference and member function as handler for data written event
* Same as GattServer::onDataWritten() but it allows the possibility to add an object
* reference and member function as a handler for data written event
* callbacks.
*
* @param[in] objPtr
@ -380,8 +389,8 @@ public:
}
/**
* Setup a callback to be invoked on the peripheral when an attribute is
* being read by a remote client.
* Set up a callback to be invoked on the peripheral when a remote client is
* reading an attribute.
*
* @param[in] callback
* Event handler being registered.
@ -413,7 +422,7 @@ public:
}
/**
* Same as GattServer::onDataRead(), but allows the possibility to add an object
* Same as GattServer::onDataRead() but it allows the possibility to add an object
* reference and member function as handler for data read event
* callbacks.
*
@ -448,8 +457,8 @@ public:
}
/**
* Setup a callback to be invoked to notify the user application that the
* GattServer instance is about to shutdown (possibly as a result of a call
* Set up a callback to be invoked to notify the user application that the
* GattServer instance is about to shut down (possibly as a result of a call
* to BLE::shutdown()).
*
* @param[in] callback
@ -457,7 +466,7 @@ public:
*
* @note It is possible to chain together multiple onShutdown callbacks
* (potentially from different modules of an application) to be notified
* before the GattServer is shutdown.
* before the GattServer is shut down.
*
* @note It is also possible to set up a callback into a member function of
* some object.
@ -469,7 +478,7 @@ public:
}
/**
* Same as GattServer::onShutdown(), but allows the possibility to add an object
* Same as GattServer::onShutdown() but it allows the possibility to add an object
* reference and member function as handler for shutdown event
* callbacks.
*
@ -607,13 +616,13 @@ protected:
public:
/**
* Notify all registered onShutdown callbacks that the GattServer is
* about to be shutdown and clear all GattServer state of the
* about to be shut down and clear all GattServer state of the
* associated object.
*
* This function is meant to be overridden in the platform-specific
* sub-class. Nevertheless, the sub-class is only expected to reset its
* state and not the data held in GattServer members. This shall be achieved
* by a call to GattServer::reset() from the sub-class' reset()
* subclass. Nevertheless, the subclass only resets its
* state and not the data held in GattServer members. This is achieved
* by a call to GattServer::reset() from the subclass' reset()
* implementation.
*
* @return BLE_ERROR_NONE on success.
@ -686,4 +695,10 @@ private:
GattServer& operator=(const GattServer &);
};
/**
* @}
* @}
* @}
*/
#endif /* ifndef __GATT_SERVER_H__ */

View File

@ -14,28 +14,73 @@
* limitations under the License.
*/
#ifndef __GATT_SERVER_EVENTS_H__
#define __GATT_SERVER_EVENTS_H__
#ifndef MBED_BLE_GATT_SERVER_EVENTS_H__
#define MBED_BLE_GATT_SERVER_EVENTS_H__
/**
* @brief The base class used to abstract away the callback events that can be
* triggered with the GATT Server.
* @addtogroup ble
* @{
* @addtogroup gatt
* @{
* @addtogroup server
* @{
*/
/**
* Abstract events generated by a GattServer vendor port.
*
* @important This class is not part of the public API.
*/
class GattServerEvents
{
public:
/**
* Enumeration for GattServer events.
* Enumeration of events, which a GattServer
* implementation can generate.
*/
typedef enum gattEvent_e {
GATT_EVENT_DATA_SENT = 1, /**< Fired when a message was successfully sent out (notify only?) */
GATT_EVENT_DATA_WRITTEN = 2, /**< Client wrote data to the server (separate into char and descriptor writes?) */
GATT_EVENT_UPDATES_ENABLED = 3, /**< Notify/Indicate enabled in CCCD. */
GATT_EVENT_UPDATES_DISABLED = 4, /**< Notify/Indicate disabled in CCCD. */
GATT_EVENT_CONFIRMATION_RECEIVED = 5, /**< Response received from Indicate message. */
GATT_EVENT_READ_AUTHORIZATION_REQ = 6, /**< Request application to authorize read. */
GATT_EVENT_WRITE_AUTHORIZATION_REQ = 7, /**< Request application to authorize write. */
/**
* Fired when a server event was successfully sent.
*/
GATT_EVENT_DATA_SENT = 1,
/**
* Client has written a server attribute.
*/
GATT_EVENT_DATA_WRITTEN = 2,
/**
* Notification or indication enabled in CCCD.
*/
GATT_EVENT_UPDATES_ENABLED = 3,
/**
* Notification or Indication disabled in CCCD.
*/
GATT_EVENT_UPDATES_DISABLED = 4,
/**
* Response received from Characteristic Value Indication message.
*/
GATT_EVENT_CONFIRMATION_RECEIVED = 5,
/**
* Request application to authorize read.
*/
GATT_EVENT_READ_AUTHORIZATION_REQ = 6,
/**
* Request application to authorize write.
*/
GATT_EVENT_WRITE_AUTHORIZATION_REQ = 7,
} gattEvent_t;
};
#endif /* ifndef __GATT_SERVER_EVENTS_H__ */
/**
* @}
* @}
* @}
*/
#endif /* ifndef MBED_BLE_GATT_SERVER_EVENTS_H__ */

View File

@ -20,6 +20,15 @@
#include "UUID.h"
#include "GattCharacteristic.h"
/**
* @addtogroup ble
* @{
* @addtogroup gatt
* @{
* @addtogroup server
* @{
*/
class GattService {
public:
enum {
@ -134,10 +143,17 @@ private:
/**
* Handle of the service declaration attribute in the ATT table.
*
* @note This handle is generally assigned by the underlying BLE stack when the
* @note The underlying BLE stack generally assigns this handle when the
* service is added to the ATT table.
*/
uint16_t _handle;
};
/**
* @}
* @}
* @}
*/
#endif /* ifndef __GATT_SERVICE_H__ */

View File

@ -17,12 +17,25 @@
#ifndef BLE_API_SAFE_BOOL_H_
#define BLE_API_SAFE_BOOL_H_
/* Safe bool idiom, see : http://www.artima.com/cppsource/safebool.html */
/* Safe bool idiom, see: http://www.artima.com/cppsource/safebool.html */
/**
* @file
* @addtogroup ble
* @{
* @addtogroup common
* @{
*/
/**
* Private namespace used to host details of the SafeBool implementation.
*/
namespace SafeBool_ {
/**
* @brief Base class for all intances of SafeBool.
* This base class reduces instantiation of trueTag function.
* Base class of all SafeBool instances.
*
* This nontemplate base class exists to reduce the number of instantiation of
* the trueTag function.
*/
class base {
template<typename>
@ -30,17 +43,17 @@ class base {
protected:
/**
* The bool type is a pointer to method which can be used in boolean context.
* The bool type is a pointer to method that can be used in boolean context.
*/
typedef void (base::*BoolType_t)() const;
/**
* Non implemented call, use to disallow conversion between unrelated types.
* Nonimplemented call, use to disallow conversion between unrelated types.
*/
void invalidTag() const;
/**
* Member function which indicate true value.
* Special member function that indicates a true value.
*/
void trueTag() const {}
};
@ -49,9 +62,14 @@ protected:
}
/**
* @brief template class SafeBool use CRTP to made boolean conversion easy and correct.
* Derived class should implement the function bool toBool() const to make this work. Inheritance
* should be public.
* Safe conversion of objects in boolean context.
*
* Classes wanting evaluation of their instances in boolean context must derive
* publicly from this class rather than implementing the easy to misuse
* operator bool().
*
* Descendant classes must implement the function bool toBool() const to enable
* the safe conversion in boolean context.
*
* @tparam T Type of the derived class
*
@ -61,7 +79,7 @@ protected:
* public:
*
* // boolean conversion
* bool toBool() {
* bool toBool() const {
*
* }
* };
@ -87,17 +105,17 @@ protected:
* if(a == b) {
*
* }
*
*
* @endcode
*/
template <typename T>
class SafeBool : public SafeBool_::base {
public:
/**
* Bool operator implementation, derived class has to provide bool toBool() const function.
* Bool operator implementation, derived class must provide a bool
* toBool() const function.
*/
operator BoolType_t() const {
operator BoolType_t() const
{
return (static_cast<const T*>(this))->toBool()
? &SafeBool<T>::trueTag : 0;
}
@ -105,20 +123,32 @@ public:
/**
* Avoid conversion to bool between different classes.
*
* @important Will generate a compile time error if instantiated.
*/
template <typename T, typename U>
void operator==(const SafeBool<T>& lhs,const SafeBool<U>& rhs) {
void operator==(const SafeBool<T>& lhs,const SafeBool<U>& rhs)
{
lhs.invalidTag();
// return false;
}
/**
* Avoid conversion to bool between different classes.
*
* @important Will generate a compile time error if instantiated.
*/
template <typename T,typename U>
void operator!=(const SafeBool<T>& lhs,const SafeBool<U>& rhs) {
void operator!=(const SafeBool<T>& lhs,const SafeBool<U>& rhs)
{
lhs.invalidTag();
// return false;
}
/**
* @}
* @}
*/
#endif /* BLE_API_SAFE_BOOL_H_ */

View File

@ -14,8 +14,8 @@
* limitations under the License.
*/
#ifndef __SERVICE_DISOVERY_H__
#define __SERVICE_DISOVERY_H__
#ifndef MBED_BLE_SERVICE_DISOVERY_H__
#define MBED_BLE_SERVICE_DISOVERY_H__
#include "UUID.h"
#include "Gap.h"
@ -24,43 +24,68 @@
class DiscoveredService;
class DiscoveredCharacteristic;
/**
* @addtogroup ble
* @{
* @addtogroup gatt
* @{
* @addtogroup client
* @{
*/
/**
* Host callback types needed by the service discovery procedure.
*
* This class is also an interface that may be used in vendor port to model
* the service discovery process. This interface is not used in user code.
*
* @important Implementing this interface is not a requirement for the
* implementation of the service discover process.
*/
class ServiceDiscovery {
public:
/*
* Exposed application callback types.
/**
* Service discovered event handler.
*
* The callback accepts a pointer to a DiscoveredService as parameter.
*
* @important The argument passed to the callback may not persist after the
* callback invocation; therefore, the callbacks must make a shallow copy
* of the DiscoveredService passed as parameter to access its value beyond
* the callback scope.
*/
typedef FunctionPointerWithContext<const DiscoveredService *>
ServiceCallback_t;
/**
* Callback type for when a matching service is found during service-
* discovery. The receiving function is passed in a pointer to a
* DiscoveredService object, which will remain valid for the lifetime of the
* callback. Memory for this object is owned by the BLE_API eventing
* framework. The application can safely make a persistent shallow-copy of
* this object to work with the service beyond the callback.
* Characteristic discovered event handler.
*
* The callback accepts a pointer to a DiscoveredCharacteristic as
* parameter.
*
* @important The argument passed to the callback may not persist after the
* callback invocation; therefore, the callbacks must make a shallow copy
* of the DiscoveredCharacteristic passed as parameter to access its value
* beyond the callback scope.
*/
typedef FunctionPointerWithContext<const DiscoveredService *> ServiceCallback_t;
typedef FunctionPointerWithContext<const DiscoveredCharacteristic *>
CharacteristicCallback_t;
/**
* Callback type for when a matching characteristic is found during service-
* discovery. The receiving function is passed in a pointer to a
* DiscoveredCharacteristic object, which will remain valid for the lifetime
* of the callback. Memory for this object is owned by the BLE_API eventing
* framework. The application can safely make a persistent shallow-copy of
* this object to work with the characteristic beyond the callback.
*/
typedef FunctionPointerWithContext<const DiscoveredCharacteristic *> CharacteristicCallback_t;
/**
* Callback type for when serviceDiscovery terminates.
* Service discovery ended event.
*
* The callback accepts a connection handle as parameter. This
* parameter is used to identify on which connection the service discovery
* process ended.
*/
typedef FunctionPointerWithContext<Gap::Handle_t> TerminationCallback_t;
public:
/**
* Launch service discovery. Once launched, service discovery will remain
* Launch service discovery. Once launched, service discovery remains
* active with callbacks being issued back into the application for matching
* services or characteristics. isActive() can be used to determine status, and
* a termination callback (if set up) will be invoked at the end. Service
* a termination callback (if set up) is invoked at the end. Service
* discovery can be terminated prematurely, if needed, using terminate().
*
* @param connectionHandle
@ -85,24 +110,24 @@ public:
* characteristic.
* @param matchingServiceUUID
* UUID-based filter for specifying a service in which the application is
* interested. By default it is set as the wildcard UUID_UNKNOWN,
* interested. By default, it is set as the wildcard UUID_UNKNOWN,
* in which case it matches all services. If characteristic-UUID
* filter (below) is set to the wildcard value, then a service
* callback will be invoked for the matching service (or for every
* callback is invoked for the matching service (or for every
* service if the service filter is a wildcard).
* @param matchingCharacteristicUUIDIn
* UUID-based filter for specifying a characteristic in which the application
* is interested. By default it is set as the wildcard UUID_UKNOWN
* is interested. By default, it is set as the wildcard UUID_UKNOWN
* to match against any characteristic. If both service-UUID
* filter and characteristic-UUID filter are used with non-wildcard
* filter and characteristic-UUID filter are used with nonwildcard
* values, then only a single characteristic callback is
* invoked for the matching characteristic.
*
* @note Using wildcard values for both service-UUID and characteristic-
* UUID will result in complete service discovery: callbacks being
* UUID result in complete service discovery: callbacks being
* called for every service and characteristic.
*
* @note Providing NULL for the characteristic callback will result in
* @note Providing NULL for the characteristic callback results in
* characteristic discovery being skipped for each matching
* service. This allows for an inexpensive method to discover only
* services.
@ -136,9 +161,9 @@ public:
* Clear all ServiceDiscovery state of the associated object.
*
* This function is meant to be overridden in the platform-specific
* sub-class. Nevertheless, the sub-class is only expected to reset its
* state and not the data held in ServiceDiscovery members. This shall be
* achieved by a call to ServiceDiscovery::reset() from the sub-class'
* subclass. Nevertheless, the subclass is only expected to reset its
* state and not the data held in ServiceDiscovery members. This is
* achieved by a call to ServiceDiscovery::reset() from the subclass'
* reset() implementation.
*
* @return BLE_ERROR_NONE on success.
@ -180,4 +205,10 @@ protected:
CharacteristicCallback_t characteristicCallback;
};
#endif /* ifndef __SERVICE_DISOVERY_H__ */
/**
* @}
* @}
* @}
*/
#endif /* ifndef MBED_BLE_SERVICE_DISOVERY_H__ */

View File

@ -14,8 +14,8 @@
* limitations under the License.
*/
#ifndef __UUID_H__
#define __UUID_H__
#ifndef MBED_UUID_H__
#define MBED_UUID_H__
#include <stdint.h>
#include <string.h>
@ -24,14 +24,22 @@
#include "blecommon.h"
/**
* A trivial converter for single hexadecimal character to an unsigned integer.
* @file
* @addtogroup ble
* @{
* @addtogroup common
* @{
*/
/**
* Convert a character containing an hexadecimal digit into an unsigned integer.
*
* @param c
* Hexadecimal character.
* @param[in] c Hexadecimal digit in a character representation.
*
* @return The corresponding value as unsigned integer.
*/
static uint8_t char2int(char c) {
static uint8_t char2int(char c)
{
if ((c >= '0') && (c <= '9')) {
return c - '0';
} else if ((c >= 'a') && (c <= 'f')) {
@ -44,72 +52,110 @@ static uint8_t char2int(char c) {
}
/**
* An instance of this class represents a Universally Unique Identifier (UUID)
* in the BLE API.
* Representation of a Universally Unique Identifier (UUID).
*
* UUIDs are 128-bit wide numbers used to identify data type and elements in
* many layers of the Bluetooth specification.
*
* Two representations of UUIDS exist:
* - 16-bit UUIDs: Shortened representation of the 128 bit UUID
* 0000xxxx-0000-1000-8000-00805F9B34FB where xxxx is the 16 bit UUID.
* Values of those UUIDs are defined by the Bluetooth body. The short
* representation saves bandwidth during protocol transactions.
* - 128-bit UUIDs: Complete representation of a UUID. They are commonly
* used for user defined UUID.
*
* This class acts as an adapter over these two kinds of UUIDs to allow
* indiscriminate use of both forms in Mbed BLE APIs.
*
* @note 32-bit UUID representation is not supported currently.
*/
class UUID {
public:
/**
* Enumeration of the possible types of UUIDs in BLE with regards to length.
* Enumeration of the types of UUIDs.
*/
enum UUID_Type_t {
UUID_TYPE_SHORT = 0, /**< Short 16-bit UUID. */
UUID_TYPE_LONG = 1 /**< Full 128-bit UUID. */
/**
* 16-bit wide UUID representation.
*/
UUID_TYPE_SHORT = 0,
/**
* 128-bit wide UUID representation.
*/
UUID_TYPE_LONG = 1
};
/**
* Enumeration to specify byte ordering of the long version of the UUID.
* Enumeration of byte ordering.
*
* It is used to construct 128-byte UUIDs.
*/
typedef enum {
MSB, /**< Most-significant byte first (at the smallest address) */
LSB /**< least-significant byte first (at the smallest address) */
/**
* Most significant byte first (at the smallest address).
*/
MSB,
/**
* Least significant byte first (at the smallest address).
*/
LSB
} ByteOrder_t;
/**
* Type for a 16-bit UUID.
*/
typedef uint16_t ShortUUIDBytes_t;
typedef uint16_t ShortUUIDBytes_t;
/**
* Length of a long UUID in bytes.
* Length in bytes of a long UUID.
*/
static const unsigned LENGTH_OF_LONG_UUID = 16;
/**
* Type for a 128-bit UUID.
*/
typedef uint8_t LongUUIDBytes_t[LENGTH_OF_LONG_UUID];
typedef uint8_t LongUUIDBytes_t[LENGTH_OF_LONG_UUID];
/**
* Maximum length of a string representation of a UUID not including the
* null termination ('\0'): two characters per
* byte plus four '-' characters.
* Maximum length for the string representation of a UUID excluding the null
* terminator.
*
* The string is composed of two characters per byte plus four '-'
* characters.
*/
static const unsigned MAX_UUID_STRING_LENGTH = LENGTH_OF_LONG_UUID * 2 + 4;
public:
/**
* Creates a new 128-bit UUID.
* Construct a 128-bit UUID from a string.
*
* @note The UUID is a unique 128-bit (16 byte) ID used to identify
* different service or characteristics on the BLE device.
* @param[in] stringUUID Human readable representation of the UUID following
* the format XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX.
*
* @param stringUUID
* The 128-bit (16-byte) UUID as a human readable const-string.
* Format: XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX
* Upper and lower case supported. Hyphens are optional, but only
* upto four of them. The UUID is stored internally as a 16 byte
* array, LSB (little endian), which is opposite from the string.
* @note Upper and lower case are supported.
* @note Hyphens are optional. The string must include at most four hyphens.
*
* @note Internally, the UUID is stored in the little endian order as a
* 16-byte array.
*/
UUID(const char* stringUUID) : type(UUID_TYPE_LONG), baseUUID(), shortUUID(0) {
UUID(const char* stringUUID) :
type(UUID_TYPE_LONG),
baseUUID(),
shortUUID(0)
{
bool nibble = false;
uint8_t byte = 0;
size_t baseIndex = 0;
uint8_t tempUUID[LENGTH_OF_LONG_UUID];
/*
* Iterate through string, abort if NULL is encountered prematurely.
* Ignore upto four hyphens.
* Iterate through string; abort if NULL is encountered prematurely.
* Ignore up to four hyphens.
*/
for (size_t index = 0; (index < MAX_UUID_STRING_LENGTH) && (baseIndex < LENGTH_OF_LONG_UUID); index++) {
if (stringUUID[index] == '\0') {
@ -143,15 +189,10 @@ public:
}
/**
* Creates a new 128-bit UUID.
* Construct a new UUID from a 128-bit representation.
*
* @param[in] longUUID
* The 128-bit (16-byte) UUID value.
* @param[in] order
* The bit order of the UUID, MSB by default.
*
* @note The UUID is a unique 128-bit (16 byte) ID used to identify
* different service or characteristics on the BLE device.
* @param[in] longUUID The 128-bit (16-byte) of the UUID value.
* @param[in] order Bytes order of @p longUUID.
*/
UUID(const LongUUIDBytes_t longUUID, ByteOrder_t order = UUID::MSB) : type(UUID_TYPE_LONG), baseUUID(), shortUUID(0) {
setupLong(longUUID, order);
@ -160,69 +201,59 @@ public:
/**
* Creates a new 16-bit UUID.
*
* For efficiency, and because 16 bytes would take a large chunk of the
* 27-byte data payload length of the Link Layer, the BLE specification adds
* two additional UUID formats: 16-bit and 32-bit UUIDs. These shortened
* formats can be used only with UUIDs that are defined in the Bluetooth
* specification (listed by the Bluetooth SIG as standard
* Bluetooth UUIDs).
* The Bluetooth standard body defines 16-bit wide UUIDs. They are the
* shortened version of the UUID 0000xxxx-0000-1000-8000-00805F9B34FB, where
* xxxx is the value of the 16-bit UUID.
*
* To reconstruct the full 128-bit UUID from the shortened version, insert
* the 16-bit short value (indicated by xxxx, including leading zeros) into
* the Bluetooth Base UUID:
* @important 16-bit UUIDs are not used in user defined data type or
* user defined element ID.
*
* 0000xxxx-0000-1000-8000-00805F9B34FB
*
* @param[in] _shortUUID
* @param[in] _shortUUID 16-bit part of the standard UUID.
* The short UUID value.
*
* @note Shortening is not available for UUIDs that are not derived from the
* Bluetooth Base UUID. Such non-standard UUIDs are commonly called
* vendor-specific UUIDs. In these cases, youll need to use the full
* 128-bit UUID value at all times.
*
* @note The UUID is a unique 16-bit (2 byte) ID used to identify
* different service or characteristics on the BLE device.
*
* @note We do not yet support 32-bit shortened UUIDs.
* @note User defined UUIDs are commonly named vendor-specific UUIDs across
* the Bluetooth literature.
*/
UUID(ShortUUIDBytes_t _shortUUID) : type(UUID_TYPE_SHORT), baseUUID(), shortUUID(_shortUUID) {
/* Empty */
UUID(ShortUUIDBytes_t _shortUUID) :
type(UUID_TYPE_SHORT),
baseUUID(),
shortUUID(_shortUUID) {
}
/**
* Copy constructor.
* UUID copy constructor.
*
* @param[in] source
* The UUID to copy.
* @param[in] source The UUID to copy.
*/
UUID(const UUID &source) {
UUID(const UUID &source)
{
type = source.type;
shortUUID = source.shortUUID;
memcpy(baseUUID, source.baseUUID, LENGTH_OF_LONG_UUID);
}
/**
* The empty constructor.
* Default constructor.
*
* @note The type of the resulting UUID instance is UUID_TYPE_SHORT and the
* value BLE_UUID_UNKNOWN.
* Construct an invalid UUID.
*
* @post shortOrLong() returns the value UUID_TYPE_SHORT.
* @post getShortUUID() returns the value BLE_UUID_UNKNOWN.
*/
UUID(void) : type(UUID_TYPE_SHORT), shortUUID(BLE_UUID_UNKNOWN) {
/* empty */
UUID(void) :
type(UUID_TYPE_SHORT),
shortUUID(BLE_UUID_UNKNOWN) {
}
/**
* Fill in a 128-bit UUID; this is useful when the UUID is not known at the
* time of the object construction.
* Replace existing value with a 128-bit UUID.
*
* @param[in] longUUID
* The UUID value to copy.
* @param[in] order
* The byte ordering of the UUID at @p longUUID.
* @param[in] longUUID New 16-byte wide UUID value.
* @param[in] order Byte ordering of @p longUUID.
*/
void setupLong(const LongUUIDBytes_t longUUID, ByteOrder_t order = UUID::MSB) {
type = UUID_TYPE_LONG;
void setupLong(const LongUUIDBytes_t longUUID, ByteOrder_t order = UUID::MSB)
{
type = UUID_TYPE_LONG;
if (order == UUID::MSB) {
/*
* Switch endian. Input is big-endian, internal representation
@ -237,22 +268,24 @@ public:
public:
/**
* Check whether this UUID is short or long.
* Return the internal type of the UUID.
*
* @return UUID_TYPE_SHORT if the UUID is short, UUID_TYPE_LONG otherwise.
* @return UUID_TYPE_SHORT if the UUID is 16-bit wide.
* @return UUID_TYPE_LONG if the UUID is 128-bit wide.
*/
UUID_Type_t shortOrLong(void) const {
UUID_Type_t shortOrLong(void) const
{
return type;
}
/**
* Get a pointer to the UUID value based on the current UUID type.
*
* @return A pointer to the short UUID if the type is set to
* UUID_TYPE_SHORT. Otherwise, a pointer to the long UUID if the
* type is set to UUID_TYPE_LONG.
* @return A pointer to an uint16_t object if the UUID is 16 bits long.
* @return A pointer to an array of 16 bytes if the UUID is 128 bits long.
*/
const uint8_t *getBaseUUID(void) const {
const uint8_t *getBaseUUID(void) const
{
if (type == UUID_TYPE_SHORT) {
return (const uint8_t*)&shortUUID;
} else {
@ -261,33 +294,39 @@ public:
}
/**
* Get the short UUID.
* Get the uint16_t value of the UUID.
*
* @return The short UUID.
* @important This function is not used on long UUIDs.
*
* @return The value of the shortened UUID.
*/
ShortUUIDBytes_t getShortUUID(void) const {
ShortUUIDBytes_t getShortUUID(void) const
{
return shortUUID;
}
/**
* Get the length (in bytes) of the UUID based on its type.
* Get the length (in bytes) of the internal UUID representation.
*
* @retval sizeof(ShortUUIDBytes_t) if the UUID type is UUID_TYPE_SHORT.
* @retval LENGTH_OF_LONG_UUID if the UUID type is UUID_TYPE_LONG.
* @return sizeof(ShortUUIDBytes_t) if the UUID type is UUID_TYPE_SHORT.
* @return LENGTH_OF_LONG_UUID if the UUID type is UUID_TYPE_LONG.
*/
uint8_t getLen(void) const {
return ((type == UUID_TYPE_SHORT) ? sizeof(ShortUUIDBytes_t) : LENGTH_OF_LONG_UUID);
uint8_t getLen(void) const
{
return ((type == UUID_TYPE_SHORT) ?
sizeof(ShortUUIDBytes_t) :
LENGTH_OF_LONG_UUID);
}
/**
* Overload == operator to enable UUID comparisons.
* Equal to operator between UUIDs.
*
* @param[in] other
* The other UUID in the comparison.
* @param[in] other The UUID to compare to this.
*
* @return true if this == @p other, false otherwise.
* @return true if both UUIDs are equal and false otherwise.
*/
bool operator== (const UUID &other) const {
bool operator== (const UUID &other) const
{
if ((this->type == UUID_TYPE_SHORT) && (other.type == UUID_TYPE_SHORT) &&
(this->shortUUID == other.shortUUID)) {
return true;
@ -302,30 +341,37 @@ public:
}
/**
* Overload != operator to enable UUID comparisons.
* Not equal to operator.
*
* @param[in] other
* The other UUID in the comparison.
* @param[in] other The UUID compared to this.
*
* @return true if this != @p other, false otherwise.
* @return true if both UUIDs are not equal and false otherwise.
*/
bool operator!= (const UUID &other) const {
bool operator!= (const UUID &other) const
{
return !(*this == other);
}
private:
/**
* The UUID type. Refer to UUID_Type_t.
* Representation type of the UUID.
*/
UUID_Type_t type;
UUID_Type_t type;
/**
* The long UUID value.
* Container of UUID value if the UUID type is equal to UUID_TYPE_LONG.
*/
LongUUIDBytes_t baseUUID;
/**
* The short UUID value.
* Container of UUID value if the UUID type is equal to UUID_TYPE_SHORT.
*/
ShortUUIDBytes_t shortUUID;
};
#endif // ifndef __UUID_H__
/**
* @}
* @}
*/
#endif // ifndef MBED_UUID_H__

View File

@ -14,68 +14,234 @@
* limitations under the License.
*/
#ifndef __BLE_COMMON_H__
#define __BLE_COMMON_H__
#ifndef MBED_BLE_COMMON_H__
#define MBED_BLE_COMMON_H__
#ifdef __cplusplus
extern "C" {
#endif
/**
* @addtogroup ble
* @{
* @addtogroup common
* @{
*/
/*! @brief Assigned values for BLE UUIDs. */
/**
* Assigned values for BLE UUIDs.
*/
enum {
BLE_UUID_UNKNOWN = 0x0000, /**< Reserved UUID. */
BLE_UUID_SERVICE_PRIMARY = 0x2800, /**< Primary Service. */
BLE_UUID_SERVICE_SECONDARY = 0x2801, /**< Secondary Service. */
BLE_UUID_SERVICE_INCLUDE = 0x2802, /**< Include. */
BLE_UUID_CHARACTERISTIC = 0x2803, /**< Characteristic. */
BLE_UUID_DESCRIPTOR_CHAR_EXT_PROP = 0x2900, /**< Characteristic Extended Properties Descriptor. */
BLE_UUID_DESCRIPTOR_CHAR_USER_DESC = 0x2901, /**< Characteristic User Description Descriptor. */
BLE_UUID_DESCRIPTOR_CLIENT_CHAR_CONFIG = 0x2902, /**< Client Characteristic Configuration Descriptor. */
BLE_UUID_DESCRIPTOR_SERVER_CHAR_CONFIG = 0x2903, /**< Server Characteristic Configuration Descriptor. */
BLE_UUID_DESCRIPTOR_CHAR_PRESENTATION_FORMAT = 0x2904, /**< Characteristic Presentation Format Descriptor. */
BLE_UUID_DESCRIPTOR_CHAR_AGGREGATE_FORMAT = 0x2905, /**< Characteristic Aggregate Format Descriptor. */
/**
* Reserved UUID.
*/
BLE_UUID_UNKNOWN = 0x0000,
/**
* Primary Service.
*/
BLE_UUID_SERVICE_PRIMARY = 0x2800,
/**
* Secondary Service.
*/
BLE_UUID_SERVICE_SECONDARY = 0x2801,
/**
* Included service.
*/
BLE_UUID_SERVICE_INCLUDE = 0x2802,
/**
* Characteristic.
*/
BLE_UUID_CHARACTERISTIC = 0x2803,
/**
* Characteristic Extended Properties Descriptor.
*/
BLE_UUID_DESCRIPTOR_CHAR_EXT_PROP = 0x2900,
/**
* Characteristic User Description Descriptor.
*/
BLE_UUID_DESCRIPTOR_CHAR_USER_DESC = 0x2901,
/**
* Client Characteristic Configuration Descriptor.
*/
BLE_UUID_DESCRIPTOR_CLIENT_CHAR_CONFIG = 0x2902,
/**
* Server Characteristic Configuration Descriptor.
*/
BLE_UUID_DESCRIPTOR_SERVER_CHAR_CONFIG = 0x2903,
/**
* Characteristic Presentation Format Descriptor.
*/
BLE_UUID_DESCRIPTOR_CHAR_PRESENTATION_FORMAT = 0x2904,
/**
* Characteristic Aggregate Format Descriptor.
*/
BLE_UUID_DESCRIPTOR_CHAR_AGGREGATE_FORMAT = 0x2905,
/* GATT specific UUIDs */
BLE_UUID_GATT = 0x1801, /**< Generic Attribute Profile. */
BLE_UUID_GATT_CHARACTERISTIC_SERVICE_CHANGED = 0x2A05, /**< Service Changed Characteristic. */
/**
* Generic Attribute Profile.
*/
BLE_UUID_GATT = 0x1801,
/**
* Service Changed Characteristic.
*/
BLE_UUID_GATT_CHARACTERISTIC_SERVICE_CHANGED = 0x2A05,
/* GAP specific UUIDs */
BLE_UUID_GAP = 0x1800, /**< Generic Access Profile. */
BLE_UUID_GAP_CHARACTERISTIC_DEVICE_NAME = 0x2A00, /**< Device Name Characteristic. */
BLE_UUID_GAP_CHARACTERISTIC_APPEARANCE = 0x2A01, /**< Appearance Characteristic. */
BLE_UUID_GAP_CHARACTERISTIC_PPF = 0x2A02, /**< Peripheral Privacy Flag Characteristic. */
BLE_UUID_GAP_CHARACTERISTIC_RECONN_ADDR = 0x2A03, /**< Reconnection Address Characteristic. */
BLE_UUID_GAP_CHARACTERISTIC_PPCP = 0x2A04, /**< Peripheral Preferred Connection Parameters Characteristic. */
/**
* Generic Access Profile.
*/
BLE_UUID_GAP = 0x1800,
/**
* Device Name Characteristic.
*/
BLE_UUID_GAP_CHARACTERISTIC_DEVICE_NAME = 0x2A00,
/**
* Appearance Characteristic.
*/
BLE_UUID_GAP_CHARACTERISTIC_APPEARANCE = 0x2A01,
/**
* Peripheral Privacy Flag Characteristic.
*/
BLE_UUID_GAP_CHARACTERISTIC_PPF = 0x2A02,
/**
* Reconnection Address Characteristic.
*/
BLE_UUID_GAP_CHARACTERISTIC_RECONN_ADDR = 0x2A03,
/**
* Peripheral Preferred Connection Parameters Characteristic.
*/
BLE_UUID_GAP_CHARACTERISTIC_PPCP = 0x2A04,
};
/*! @brief Error codes for the BLE API. */
/**
* Error codes for the BLE API.
*
* The value 0 means that no error was reported; therefore, it allows an API
* user to cleanly test for errors.
*
* @code
* ble_error_t error = some_ble_api_function();
* if (error) {
* // handle the error
* }
* @endcode
*/
enum ble_error_t {
BLE_ERROR_NONE = 0, /**< No error. */
BLE_ERROR_BUFFER_OVERFLOW = 1, /**< The requested action would cause a buffer overflow and has been aborted. */
BLE_ERROR_NOT_IMPLEMENTED = 2, /**< Requested a feature that isn't yet implemented or isn't supported by the target HW. */
BLE_ERROR_PARAM_OUT_OF_RANGE = 3, /**< One of the supplied parameters is outside the valid range. */
BLE_ERROR_INVALID_PARAM = 4, /**< One of the supplied parameters is invalid. */
BLE_STACK_BUSY = 5, /**< The stack is busy. */
BLE_ERROR_INVALID_STATE = 6, /**< Invalid state. */
BLE_ERROR_NO_MEM = 7, /**< Out of memory */
BLE_ERROR_OPERATION_NOT_PERMITTED = 8,
/**
* No error.
*/
BLE_ERROR_NONE = 0,
/**
* The requested action would cause a buffer overflow and has been aborted.
*/
BLE_ERROR_BUFFER_OVERFLOW = 1,
/**
* Requested a feature that isn't yet implemented or isn't supported by the
* target HW.
*/
BLE_ERROR_NOT_IMPLEMENTED = 2,
/**
* One of the supplied parameters is outside the valid range.
*/
BLE_ERROR_PARAM_OUT_OF_RANGE = 3,
/**
* One of the supplied parameters is invalid.
*/
BLE_ERROR_INVALID_PARAM = 4,
/**
* The stack is busy.
*/
BLE_STACK_BUSY = 5,
/**
* Invalid state.
*/
BLE_ERROR_INVALID_STATE = 6,
/**
* Out of memory.
*/
BLE_ERROR_NO_MEM = 7,
/**
* The operation requested is not permitted.
*/
BLE_ERROR_OPERATION_NOT_PERMITTED = 8,
/**
* The BLE subsystem has not completed its initialization.
*/
BLE_ERROR_INITIALIZATION_INCOMPLETE = 9,
BLE_ERROR_ALREADY_INITIALIZED = 10,
BLE_ERROR_UNSPECIFIED = 11, /**< Unknown error. */
BLE_ERROR_INTERNAL_STACK_FAILURE = 12, /**< The platform-specific stack failed */
/**
* The BLE system has already been initialized.
*/
BLE_ERROR_ALREADY_INITIALIZED = 10,
/**
* Unknown error.
*/
BLE_ERROR_UNSPECIFIED = 11,
/**
* The platform-specific stack failed.
*/
BLE_ERROR_INTERNAL_STACK_FAILURE = 12,
};
/** @brief Default MTU size. */
/**
* Default MTU size.
*/
static const unsigned BLE_GATT_MTU_SIZE_DEFAULT = 23;
/**
* Handle Value Notification/Indication event.
*
* Emmitted when a notification or indication has been received from a GATT
* server.
*/
enum HVXType_t {
BLE_HVX_NOTIFICATION = 0x01, /**< Handle Value Notification. */
BLE_HVX_INDICATION = 0x02, /**< Handle Value Indication. */
/**
* Handle Value Notification.
*/
BLE_HVX_NOTIFICATION = 0x01,
/**
* Handle Value Indication.
*/
BLE_HVX_INDICATION = 0x02,
};
/**
* @}
* @}
*/
#ifdef __cplusplus
}
#endif
#endif // ifndef __BLE_COMMON_H__
#endif // ifndef MBED_BLE_COMMON_H__

View File

@ -14,12 +14,15 @@
* limitations under the License.
*/
#ifndef __DEPRECATE_H__
#define __DEPRECATE_H__
#ifndef MBED_BLE_DEPRECATE_H__
#define MBED_BLE_DEPRECATE_H__
#ifdef YOTTA_CFG_MBED_OS
#include "compiler-polyfill/attributes.h"
#else
/**
* Deprecated, use MBED_DEPRECATED instead.
*/
#define __deprecated_message(msg)
#endif