Skip to content

BLE: feature gatt client - Generic GattClient implementation #4781

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
162 changes: 162 additions & 0 deletions features/FEATURE_BLE/ble/ArrayView.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,162 @@
/* mbed Microcontroller Library
* Copyright (c) 2017-2017 ARM Limited
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

#ifndef BLE_ARRAY_VIEW_H_
#define BLE_ARRAY_VIEW_H_

#include <stddef.h>
#include <stdint.h>

namespace ble {

/**
* Immutable view to an array.
*/
template<typename T>
struct ArrayView {

/**
* construct an array view to an empty array
*/
ArrayView() : _array(0), _size(0) { }

/**
* construct an array view from a pointer.
* and its size.
*/
ArrayView(T* array_ptr, size_t array_size) :
_array(array_ptr), _size(array_size) { }

/**
* Construct an array view from the reference to an array.
*/
template<size_t Size>
ArrayView(T (&elements)[Size]):
_array(elements), _size(Size) { }

/**
* Return the size of the array viewed.
*/
size_t size() const {
return _size;
}

/**
* Access to a mutable element of the array.
*/
T& operator[](size_t index) {
return _array[index];
}

/**
* Access to an immutable element of the array.
*/
const T& operator[](size_t index) const {
return _array[index];
}

/**
* Get the pointer to the array
*/
T* data() {
return _array;
}

/**
* Get the pointer to the const array
*/
const T* data() const {
return _array;
}

friend bool operator==(const ArrayView& lhs, const ArrayView& rhs) {
if (lhs.size() != rhs.size()) {
return false;
}

if (lhs.data() == rhs.data()) {
return true;
}

return memcmp(lhs.data(), rhs.data(), lhs.size()) == 0;
}

friend bool operator!=(const ArrayView& lhs, const ArrayView& rhs) {
return !(lhs == rhs);
}

private:
T* const _array;
const size_t _size;
};


/**
* Generate an array view from a C/C++ array.
* This helper avoid the typing of template parameter when ArrayView are
* 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]) {
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
* 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) {
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'.
* @param elements The array viewed.
* @return The ArrayView to elements.
*/
template<typename T, size_t 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.
* @return The ArrayView to array_ptr with a size of array_size.
*/
template<typename T>
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_ */
78 changes: 78 additions & 0 deletions features/FEATURE_BLE/ble/BLETypes.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
/* mbed Microcontroller Library
* Copyright (c) 2017-2017 ARM Limited
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

#ifndef BLE_TYPES_H_
#define BLE_TYPES_H_

#include <stddef.h>
#include <stdint.h>

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.
*/
typedef uintptr_t connection_handle_t;


/**
* Model an attribute handle in a GATT database.
*/
typedef uint16_t attribute_handle_t;


/**
* Model an inclusive range of GATT attributes handles.
*/
struct attribute_handle_range_t {
attribute_handle_t begin;
attribute_handle_t end;

friend bool operator==(
const attribute_handle_range_t& lhs, const attribute_handle_range_t& rhs
) {
return (lhs.begin == rhs.begin) && (lhs.end == rhs.end);
}

friend bool operator!=(
const attribute_handle_range_t& lhs, const attribute_handle_range_t& rhs
) {
return !(lhs == rhs);
}
};


/**
* Construct an attribute_handle_range_t from its start and end handle.
* @note This function is defined instead of a constructor to keep "POD-ness"
* of attribute_handle_range_t.
*/
static inline attribute_handle_range_t attribute_handle_range(
attribute_handle_t begin,
attribute_handle_t end
) {
attribute_handle_range_t result = {
begin,
end
};
return result;
}

} // namespace ble

#endif /* BLE_TYPES_H_ */
5 changes: 5 additions & 0 deletions features/FEATURE_BLE/ble/CharacteristicDescriptorDiscovery.h
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,11 @@ class CharacteristicDescriptorDiscovery {
* status of the discovery operation
*/
ble_error_t status;

/**
* error code associated with the status if any.
*/
uint8_t error_code;
};

/**
Expand Down
2 changes: 1 addition & 1 deletion features/FEATURE_BLE/ble/DiscoveredCharacteristic.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
#include "GattAttribute.h"
#include "GattClient.h"
#include "CharacteristicDescriptorDiscovery.h"
#include "ble/DiscoveredCharacteristicDescriptor.h"
#include "DiscoveredCharacteristicDescriptor.h"

/**
* @brief Representation of a characteristic discovered during a GattClient
Expand Down
3 changes: 2 additions & 1 deletion features/FEATURE_BLE/ble/Gap.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
#ifndef __GAP_H__
#define __GAP_H__

#include "BLETypes.h"
#include "ble/BLEProtocol.h"
#include "GapAdvertisingData.h"
#include "GapAdvertisingParams.h"
Expand Down Expand Up @@ -171,7 +172,7 @@ class Gap {
/**
* Type for connection handle.
*/
typedef uint16_t Handle_t;
typedef ble::connection_handle_t Handle_t;

/**
* Structure containing GAP connection parameters. When in peripheral role
Expand Down
3 changes: 2 additions & 1 deletion features/FEATURE_BLE/ble/GattAttribute.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
#define __GATT_ATTRIBUTE_H__

#include "UUID.h"
#include "BLETypes.h"

/**
* Instances of this class encapsulate the data that belongs to a Bluetooth Low
Expand All @@ -29,7 +30,7 @@ class GattAttribute {
* 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.
*/
typedef uint16_t Handle_t;
typedef ble::attribute_handle_t Handle_t;
/**
* Define the value of an invalid attribute handle.
*/
Expand Down
43 changes: 40 additions & 3 deletions features/FEATURE_BLE/ble/GattCallbackParamTypes.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,16 @@
#ifndef __GATT_CALLBACK_PARAM_TYPES_H__
#define __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.
*
* @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.
*/
struct GattWriteCallbackParams {
/**
* Enumeration for write operations.
Expand All @@ -34,22 +44,49 @@ struct GattWriteCallbackParams {
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. */
uint16_t offset; /**< Offset for the write operation. */
uint16_t len; /**< Length (in bytes) of the data to write. */

// 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 */
};

// 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 */
};

/**
* 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.
*/
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.
*
* @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.
*/
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. */
uint16_t len; /**< Length (in bytes) of the data to read. */
ble_error_t status; /**< Status of the operation BLE_ERROR_NONE in case of success or the error in case of error */
union {
uint16_t len; /**< Length (in bytes) of the data to read. */
uint8_t error_code; /**< Error code if any (GattClient) */
};

/**
* Pointer to the data read.
*
Expand Down
3 changes: 3 additions & 0 deletions features/FEATURE_BLE/ble/GattClient.h
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,9 @@ class GattClient {
* The following functions are meant to be overridden in the platform-specific sub-class.
*/
public:

virtual ~GattClient() { }

/**
* Launch service discovery. Once launched, application callbacks will be
* invoked for matching services or characteristics. isServiceDiscoveryActive()
Expand Down
Loading