From 8cbc53617f78d08e08dbcfad3d8e6e4fe044b62b Mon Sep 17 00:00:00 2001 From: Vincent Coubard Date: Sun, 25 Nov 2018 17:29:48 +0000 Subject: [PATCH] BLE: Add a simple builder for AdvertisingData. --- .../ble/gap/AdvertisingDataSimpleBuilder.h | 315 ++++++++++++++++++ features/FEATURE_BLE/ble/gap/Gap.h | 1 + 2 files changed, 316 insertions(+) create mode 100644 features/FEATURE_BLE/ble/gap/AdvertisingDataSimpleBuilder.h diff --git a/features/FEATURE_BLE/ble/gap/AdvertisingDataSimpleBuilder.h b/features/FEATURE_BLE/ble/gap/AdvertisingDataSimpleBuilder.h new file mode 100644 index 00000000000..a7204371784 --- /dev/null +++ b/features/FEATURE_BLE/ble/gap/AdvertisingDataSimpleBuilder.h @@ -0,0 +1,315 @@ +/* mbed Microcontroller Library + * Copyright (c) 2006-2013 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_GAP_SIMPLEADVERTISINGDATABUILDER_H +#define BLE_GAP_SIMPLEADVERTISINGDATABUILDER_H + +#include "ble/gap/AdvertisingDataBuilder.h" + +namespace ble { + +/** + * @addtogroup ble + * @{ + * @addtogroup gap + * @{ + */ + +/** + * Build advertising data. + * + * It is a simplified version of AdvertisingDataBuilder that can generate + * advertising data "inline". + * + * It differs on different points with AdvertisingDataBuilder: + * - The buffer used to build the advertising data is embedded in the object. + * - If insertion fail, an assertion is raised. In non debug mode, if an + * insertion fail, the buffer is not modified. + * - The API is fluent. + * - It hides advanced functions. + * + * @code + void setupAdvertisingData(ble::Gap& gap) + { + using namespace ble; + gap.setAdvertisingPayload( + LEGACY_ADVERTISING_HANDLE, + AdvertisingDataSimpleBuilder() + .setFlags() + .setName("My device", true) + .setAppearance(adv_data_appearance_t::GENERIC_HEART_RATE_SENSOR) + .setLocalService(ATT_UUID_HEART_RATE_SERVICE) + .getAdvertisingData() + ); + } + * @endcode + */ +template +class AdvertisingDataSimpleBuilder { +public: + /** + * Construct a AdvertisingDataSimpleBuilder + */ + AdvertisingDataSimpleBuilder() : _builder(_buffer) + { + } + + /** + * Add device appearance in the advertising payload. + * + * @param[in] appearance The appearance to advertise. + * + * @return A reference to this object. + * + * @note If the field is already present in the payload, it is replaced. + */ + AdvertisingDataSimpleBuilder &setAppearance(adv_data_appearance_t appearance) + { + MBED_ASSERT(_builder.setAppearance(appearance) == BLE_ERROR_NONE); + return *this; + } + + /** + * Add BLE flags in the advertising payload. + * + * @param[in] flags Bitfield describing the capability of the device. See + * allowed flags in Flags_t. + * + * @return A reference to this object. + * + * @note If the field is already present in the payload, it is replaced. + */ + AdvertisingDataSimpleBuilder &setFlags( + adv_data_flags_t flags = adv_data_flags_t::default_flags + ) + { + MBED_ASSERT(_builder.setFlags(flags) == BLE_ERROR_NONE); + return *this; + } + + /** + * Add the advertising TX in the advertising payload. + * + * @param[in] txPower Transmission power level in dB. + * + * @return A reference to this object. + * + * @note If the field is already present in the payload, it is replaced. + */ + AdvertisingDataSimpleBuilder &setTxPowerAdvertised(advertising_power_t txPower) + { + MBED_ASSERT(_builder.setTxPowerAdvertised(txPower) == BLE_ERROR_NONE); + return *this; + } + + /** + * Add device name to the advertising payload. + * + * @note Data size for individual types cannot exceed 255 bytes. + * + * @param[in] name Null terminated string containing the name. + * @param[in] complete Complete local name if true, otherwise + * + * @return A reference to this object. + * + * @note If the field is already present in the payload, it is replaced. + */ + AdvertisingDataSimpleBuilder &setName(const char *name, bool complete = true) + { + MBED_ASSERT(_builder.setName(name, complete) == BLE_ERROR_NONE); + return *this; + } + + /** + * Add manufacturer specific data to the advertising payload. + * + * @note Data size for individual types cannot exceed 255 bytes. + * + * @param[in] data New data to be added. + * + * @return a reference to this object. + */ + AdvertisingDataSimpleBuilder &setManufacturerSpecificData(mbed::Span data) + { + MBED_ASSERT(_builder.setManufacturerSpecificData(data) == BLE_ERROR_NONE); + return *this; + } + + /** + * Add advertising interval to the payload. This field can only carry 2 bytes. + * + * @param interval Interval to advertise. Cannot be larger than 0xFFFF. + * + * @return a reference to this object. + */ + AdvertisingDataSimpleBuilder &setAdvertisingInterval(adv_interval_t interval) + { + MBED_ASSERT(_builder.setAdvertisingInterval(interval) == BLE_ERROR_NONE); + } + + /** + * Add connection interval preferences to the payload + * + * @param min Minimum connection interval to advertise. + * @param max Maximum connection interval to advertise. + * + * @return a reference to this object. + */ + AdvertisingDataSimpleBuilder &setConnectionIntervalPreference( + conn_interval_t min, + conn_interval_t max + ) + { + MBED_ASSERT(_builder.setConnectionIntervalPreference(min, max) == BLE_ERROR_NONE); + return *this; + } + + /** + * Add service data data to the advertising payload. + * + * @note Data size for individual types cannot exceed 255 bytes. + * + * @param[in] service UUID of the service. + * @param[in] data New data to be added. + * + * @return A reference to this object. + */ + AdvertisingDataSimpleBuilder &setServiceData(UUID service, mbed::Span data) + { + MBED_ASSERT(_builder.setServiceData(service, data) == BLE_ERROR_NONE); + return *this; + } + + /** + * Add local service ID to the advertising payload. If they data can't fit + * no modification will take place. + * + * @note Data size for individual types cannot exceed 255 bytes. + * + * @param[in] data New data to be added. + * @param[in] complete True if this is a complete list. + * + * @return A reference to this object. + */ + AdvertisingDataSimpleBuilder &setLocalService( + const UUID& data, + bool complete = true + ) + { + MBED_ASSERT( + _builder.setLocalServiceList( + mbed::make_Span(&data, 1), complete + ) == BLE_ERROR_NONE + ); + return *this; + } + + + /** + * Add local service IDs to the advertising payload. If they data can't fit + * no modification will take place. + * + * @note Data size for individual types cannot exceed 255 bytes. + * + * @param[in] data New data to be added. + * @param[in] complete True if this is a complete list. + * + * @return A reference to this object. + */ + AdvertisingDataSimpleBuilder &setLocalServiceList( + mbed::Span data, + bool complete = true + ) + { + MBED_ASSERT(_builder.setLocalServiceList(data, complete) == BLE_ERROR_NONE); + return *this; + } + + /** + * Add a UUID of a solicited service. + * + * @note Data size for individual types cannot exceed 255 bytes. + * + * @param[in] data List of 128 or 16 bit service UUIDs. + * + * @return A reference to this object. + */ + AdvertisingDataSimpleBuilder &setRequestedService(const UUID& data) + { + MBED_ASSERT( + _builder.setRequestedServiceList(mbed::make_Span(&data, 1)) == BLE_ERROR_NONE + ); + return *this; + } + + /** + * Add a list of UUIDs of solicited services. + * + * @note Data size for individual types cannot exceed 255 bytes. + * + * @param[in] data List of 128 or 16 bit service UUIDs. + * + * @return A reference to this object. + */ + AdvertisingDataSimpleBuilder &setRequestedServiceList(mbed::Span data) + { + MBED_ASSERT(_builder.setRequestedServiceList(data) == BLE_ERROR_NONE); + return *this; + } + + /** + * Add a new field into the payload. The operation fail if type is already present. + * + * @note Data size for individual types cannot exceed 255 bytes. + * + * @param[in] advDataType The type of the field to add. + * @param[in] fieldData Span of data to add. + * + * @return A reference to this object. + */ + AdvertisingDataSimpleBuilder& addData( + adv_data_type_t advDataType, + mbed::Span fieldData + ) + { + MBED_ASSERT(_builder.addData(advDataType, fieldData) == BLE_ERROR_NONE); + return *this; + } + + /** + * Get the subspan of the buffer containing valid data. + * + * @return A Span containing the payload. + */ + mbed::Span getAdvertisingData() const + { + return _builder.getAdvertisingData(); + } + +private: + uint8_t _buffer[DataSize]; + AdvertisingDataBuilder _builder; +}; + +/** + * @} + * @} + */ + +} // namespace ble + + +#endif //BLE_GAP_SIMPLEADVERTISINGDATABUILDER_H diff --git a/features/FEATURE_BLE/ble/gap/Gap.h b/features/FEATURE_BLE/ble/gap/Gap.h index b2d0023aee8..7c79e624936 100644 --- a/features/FEATURE_BLE/ble/gap/Gap.h +++ b/features/FEATURE_BLE/ble/gap/Gap.h @@ -21,6 +21,7 @@ #include "ble/BLETypes.h" #include "ble/BLEProtocol.h" #include "ble/gap/AdvertisingDataBuilder.h" +#include "ble/gap/AdvertisingDataSimpleBuilder.h" #include "ble/gap/ConnectionParameters.h" #include "ble/gap/ScanParameters.h" #include "ble/gap/AdvertisingParameters.h"