Release 0.3.6
============= Enhancements ~~~~~~~~~~~~ * Add APIs for scanning of advertisements. BLEDevice::setScanParams(uint16_t interval, uint16_t window, uint16_t timeout, bool activeScanning); BLEDevice::startScan(Gap::AdvertisementReportCallback_t callback); BLEDevice::stopScan(void); Also introduced a type to encapsulate scanning-parameters. There's a new demo on mbed.org for a trivial observer. Bugfixes ~~~~~~~~ * fix #40: fix value of Gap::UNIT_0_625_MS
This commit is contained in:
commit
dcc18e3d18
4 changed files with 245 additions and 9 deletions
|
@ -20,6 +20,7 @@
|
|||
#include "blecommon.h"
|
||||
#include "Gap.h"
|
||||
#include "GattServer.h"
|
||||
#include "GapScanningParams.h"
|
||||
#include "BLEDeviceInstanceBase.h"
|
||||
|
||||
/**
|
||||
|
@ -231,6 +232,52 @@ public:
|
|||
*/
|
||||
ble_error_t stopAdvertising(void);
|
||||
|
||||
/**
|
||||
* Setup parameters for GAP scanning--i.e. observer mode.
|
||||
* @param interval Scan interval (in milliseconds) [valid values lie between 2.5ms and 10.24s].
|
||||
* @param window Scan Window (in milliseconds) [valid values lie between 2.5ms and 10.24s].
|
||||
* @param timeout Scan timeout (in seconds) between 0x0001 and 0xFFFF, 0x0000 disables timeout.
|
||||
* @param activeScanning Set to True if active-scanning is required. This is used to fetch the
|
||||
* scan response from a peer if possible.
|
||||
*
|
||||
* The scanning window divided by the interval determines the duty cycle for
|
||||
* scanning. For example, if the interval is 100ms and the window is 10ms,
|
||||
* then the controller will scan for 10 percent of the time. It is possible
|
||||
* to have the interval and window set to the same value. In this case,
|
||||
* scanning is continuous, with a change of scanning frequency once every
|
||||
* interval.
|
||||
*
|
||||
* Once the scanning parameters have been configured, scanning can be
|
||||
* enabled by using startScan().
|
||||
*
|
||||
* @Note: The scan interval and window are recommendations to the BLE stack.
|
||||
*/
|
||||
ble_error_t setScanParams(uint16_t interval = GapScanningParams::SCAN_INTERVAL_MAX,
|
||||
uint16_t window = GapScanningParams::SCAN_WINDOW_MAX,
|
||||
uint16_t timeout = 0,
|
||||
bool activeScanning = false);
|
||||
ble_error_t setScanInterval(uint16_t interval);
|
||||
ble_error_t setScanWindow (uint16_t window);
|
||||
ble_error_t setScanTimeout (uint16_t timeout);
|
||||
void setActiveScan (bool activeScanning);
|
||||
|
||||
/**
|
||||
* Start scanning (Observer Procedure) based on the scan-params currently
|
||||
* in effect.
|
||||
*
|
||||
* @param callback The application callback to be invoked upon receiving
|
||||
* every advertisement report. Can be passed in as NULL, in which case
|
||||
* scanning may not be enabled at all.
|
||||
*/
|
||||
ble_error_t startScan(Gap::AdvertisementReportCallback_t callback);
|
||||
|
||||
/**
|
||||
* Stop scanning. The current scanning parameters remain in effect.
|
||||
*
|
||||
* @retval BLE_ERROR_NONE if successfully stopped scanning procedure.
|
||||
*/
|
||||
ble_error_t stopScan(void);
|
||||
|
||||
/**
|
||||
* This call initiates the disconnection procedure, and its completion will
|
||||
* be communicated to the application with an invocation of the
|
||||
|
@ -528,7 +575,7 @@ public:
|
|||
ble_error_t purgeAllBondingState(void);
|
||||
|
||||
public:
|
||||
BLEDevice() : transport(createBLEDeviceInstance()), advParams(), advPayload(), scanResponse(), needToSetAdvPayload(true) {
|
||||
BLEDevice() : transport(createBLEDeviceInstance()), advParams(), advPayload(), scanResponse(), needToSetAdvPayload(true), scanningParams() {
|
||||
advPayload.clear();
|
||||
scanResponse.clear();
|
||||
}
|
||||
|
@ -544,6 +591,8 @@ private:
|
|||
* eventually result in a call to the target's setAdvertisingData() before
|
||||
* the server begins advertising. This flag marks the status of the pending update.*/
|
||||
bool needToSetAdvPayload;
|
||||
|
||||
GapScanningParams scanningParams;
|
||||
};
|
||||
|
||||
/* BLEDevice methods. Most of these simply forward the calls to the underlying
|
||||
|
@ -699,6 +748,51 @@ BLEDevice::stopAdvertising(void)
|
|||
return transport->getGap().stopAdvertising();
|
||||
}
|
||||
|
||||
inline ble_error_t
|
||||
BLEDevice::setScanParams(uint16_t interval, uint16_t window, uint16_t timeout, bool activeScanning) {
|
||||
ble_error_t rc;
|
||||
if (((rc = scanningParams.setInterval(interval)) == BLE_ERROR_NONE) &&
|
||||
((rc = scanningParams.setWindow(window)) == BLE_ERROR_NONE) &&
|
||||
((rc = scanningParams.setTimeout(timeout)) == BLE_ERROR_NONE)) {
|
||||
scanningParams.setActiveScanning(activeScanning);
|
||||
return BLE_ERROR_NONE;
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
inline ble_error_t
|
||||
BLEDevice::setScanInterval(uint16_t interval) {
|
||||
return scanningParams.setInterval(interval);
|
||||
}
|
||||
|
||||
inline ble_error_t
|
||||
BLEDevice::setScanWindow(uint16_t window) {
|
||||
|
||||
return scanningParams.setWindow(window);
|
||||
}
|
||||
|
||||
inline ble_error_t
|
||||
BLEDevice::setScanTimeout(uint16_t timeout) {
|
||||
return scanningParams.setTimeout(timeout);
|
||||
}
|
||||
|
||||
inline void
|
||||
BLEDevice::setActiveScan(bool activeScanning) {
|
||||
return scanningParams.setActiveScanning(activeScanning);
|
||||
}
|
||||
|
||||
inline ble_error_t
|
||||
BLEDevice::startScan(Gap::AdvertisementReportCallback_t callback) {
|
||||
return transport->getGap().startScan(scanningParams, callback);
|
||||
}
|
||||
|
||||
inline ble_error_t
|
||||
BLEDevice::stopScan(void) {
|
||||
return transport->getGap().stopScan();
|
||||
}
|
||||
|
||||
|
||||
inline ble_error_t
|
||||
BLEDevice::disconnect(Gap::DisconnectionReason_t reason)
|
||||
{
|
||||
|
|
40
public/Gap.h
40
public/Gap.h
|
@ -24,6 +24,8 @@
|
|||
|
||||
using namespace mbed;
|
||||
|
||||
class GapScanningParams; /* forward declaration */
|
||||
|
||||
class Gap {
|
||||
public:
|
||||
enum AddressType_t {
|
||||
|
@ -32,11 +34,18 @@ public:
|
|||
ADDR_TYPE_RANDOM_PRIVATE_RESOLVABLE,
|
||||
ADDR_TYPE_RANDOM_PRIVATE_NON_RESOLVABLE
|
||||
};
|
||||
typedef enum AddressType_t addr_type_t; /* @Note: decprecated. */
|
||||
typedef enum AddressType_t addr_type_t; /* @Note: deprecated. Use AddressType_t instead. */
|
||||
|
||||
static const unsigned ADDR_LEN = 6;
|
||||
typedef uint8_t Address_t[ADDR_LEN]; /* 48-bit address, LSB format. */
|
||||
typedef Address_t address_t; /* @Note: deprecated. */
|
||||
typedef Address_t address_t; /* @Note: deprecated. Use Address_t instead. */
|
||||
|
||||
enum AdvertisementType_t {
|
||||
ADV_IND = 0x00, /**< Connectable undirected. */
|
||||
ADV_DIRECT_IND = 0x01, /**< Connectable directed. */
|
||||
ADV_SCAN_IND = 0x02, /**< Scannable undirected. */
|
||||
ADV_NONCONN_IND = 0x03, /**< Non connectable undirected. */
|
||||
};
|
||||
|
||||
/**
|
||||
* Enumeration for disconnection reasons. The values for these reasons are
|
||||
|
@ -119,14 +128,14 @@ public:
|
|||
typedef uint8_t Passkey_t[PASSKEY_LEN]; /**< 6-digit passkey in ASCII ('0'-'9' digits only). */
|
||||
|
||||
static const uint16_t UNIT_1_25_MS = 1250; /**< Number of microseconds in 1.25 milliseconds. */
|
||||
static const uint16_t UNIT_0_625_MS = 650; /**< Number of microseconds in 0.625 milliseconds. */
|
||||
static const uint16_t UNIT_0_625_MS = 625; /**< Number of microseconds in 0.625 milliseconds. */
|
||||
static uint16_t MSEC_TO_GAP_DURATION_UNITS(uint32_t durationInMillis) {
|
||||
return (durationInMillis * 1000) / UNIT_1_25_MS;
|
||||
}
|
||||
static uint16_t MSEC_TO_ADVERTISEMENT_DURATION_UNITS(uint32_t durationInMillis) {
|
||||
return (durationInMillis * 1000) / UNIT_0_625_MS;
|
||||
}
|
||||
static uint16_t GAP_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;
|
||||
}
|
||||
|
||||
|
@ -143,7 +152,15 @@ public:
|
|||
typedef void (*LinkSecuredCallback_t)(Handle_t handle, SecurityMode_t securityMode);
|
||||
typedef void (*PasskeyDisplayCallback_t)(Handle_t handle, const Passkey_t passkey);
|
||||
|
||||
typedef void (*AdvertisementReportCallback_t)(const address_t peerAddr,
|
||||
int8_t rssi,
|
||||
bool isScanResponse,
|
||||
AdvertisementType_t type,
|
||||
uint8_t advertisingDataLen,
|
||||
const uint8_t *advertisingData);
|
||||
|
||||
friend class BLEDevice;
|
||||
|
||||
private:
|
||||
/* These functions must be defined in the sub-class */
|
||||
virtual ble_error_t setAddress(addr_type_t type, const address_t address) = 0;
|
||||
|
@ -151,6 +168,8 @@ private:
|
|||
virtual ble_error_t setAdvertisingData(const GapAdvertisingData &, const GapAdvertisingData &) = 0;
|
||||
virtual ble_error_t startAdvertising(const GapAdvertisingParams &) = 0;
|
||||
virtual ble_error_t stopAdvertising(void) = 0;
|
||||
virtual ble_error_t startScan(const GapScanningParams &scanningParams, AdvertisementReportCallback_t callback) = 0;
|
||||
virtual ble_error_t stopScan() = 0;
|
||||
virtual uint16_t getMinAdvertisingInterval(void) const = 0;
|
||||
virtual uint16_t getMinNonConnectableAdvertisingInterval(void) const = 0;
|
||||
virtual uint16_t getMaxAdvertisingInterval(void) const = 0;
|
||||
|
@ -246,6 +265,7 @@ protected:
|
|||
onLinkSecured(),
|
||||
onSecurityContextStored(),
|
||||
onPasskeyDisplay(),
|
||||
onAdvertisementReport(),
|
||||
disconnectionCallChain() {
|
||||
/* empty */
|
||||
}
|
||||
|
@ -296,6 +316,17 @@ public:
|
|||
}
|
||||
}
|
||||
|
||||
void processAdvertisementReport(const address_t peerAddr,
|
||||
int8_t rssi,
|
||||
bool isScanResponse,
|
||||
AdvertisementType_t type,
|
||||
uint8_t advertisingDataLen,
|
||||
const uint8_t *advertisingData) {
|
||||
if (onAdvertisementReport) {
|
||||
onAdvertisementReport(peerAddr, rssi, isScanResponse, type, advertisingDataLen, advertisingData);
|
||||
}
|
||||
}
|
||||
|
||||
void processEvent(GapEvents::gapEvent_e type) {
|
||||
switch (type) {
|
||||
case GapEvents::GAP_EVENT_TIMEOUT:
|
||||
|
@ -322,6 +353,7 @@ protected:
|
|||
LinkSecuredCallback_t onLinkSecured;
|
||||
HandleSpecificEvent_t onSecurityContextStored;
|
||||
PasskeyDisplayCallback_t onPasskeyDisplay;
|
||||
AdvertisementReportCallback_t onAdvertisementReport;
|
||||
CallChain disconnectionCallChain;
|
||||
|
||||
private:
|
||||
|
|
110
public/GapScanningParams.h
Normal file
110
public/GapScanningParams.h
Normal file
|
@ -0,0 +1,110 @@
|
|||
/* 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 __GAP_SCANNING_PARAMS_H__
|
||||
#define __GAP_SCANNING_PARAMS_H__
|
||||
|
||||
#include "Gap.h"
|
||||
|
||||
class GapScanningParams {
|
||||
public:
|
||||
static const unsigned SCAN_INTERVAL_MIN = 0x0004; /**< Minimum Scan interval in 625 us units, i.e. 2.5 ms. */
|
||||
static const unsigned SCAN_INTERVAL_MAX = 0x4000; /**< Maximum Scan interval in 625 us units, i.e. 10.24 s. */
|
||||
static const unsigned SCAN_WINDOW_MIN = 0x0004; /**< Minimum Scan window in 625 us units, i.e. 2.5 ms. */
|
||||
static const unsigned SCAN_WINDOW_MAX = 0x4000; /**< Maximum Scan window in 625 us units, i.e. 10.24 s. */
|
||||
static const unsigned SCAN_TIMEOUT_MIN = 0x0001; /**< Minimum Scan timeout in seconds. */
|
||||
static const unsigned SCAN_TIMEOUT_MAX = 0xFFFF; /**< Maximum Scan timeout in seconds. */
|
||||
|
||||
public:
|
||||
GapScanningParams(uint16_t interval = SCAN_INTERVAL_MAX,
|
||||
uint16_t window = SCAN_WINDOW_MAX,
|
||||
uint16_t timeout = 0,
|
||||
bool activeScanning = false) : _interval(Gap::MSEC_TO_ADVERTISEMENT_DURATION_UNITS(interval)),
|
||||
_window(Gap::MSEC_TO_ADVERTISEMENT_DURATION_UNITS(window)),
|
||||
_timeout(timeout),
|
||||
_activeScanning(activeScanning) {
|
||||
/* stay within limits */
|
||||
if (_interval < SCAN_INTERVAL_MIN) {
|
||||
_interval = SCAN_INTERVAL_MIN;
|
||||
}
|
||||
if (_interval > SCAN_INTERVAL_MAX) {
|
||||
_interval = SCAN_INTERVAL_MAX;
|
||||
}
|
||||
if (_window < SCAN_WINDOW_MIN) {
|
||||
_window = SCAN_WINDOW_MIN;
|
||||
}
|
||||
if (_window > SCAN_WINDOW_MAX) {
|
||||
_window = SCAN_WINDOW_MAX;
|
||||
}
|
||||
if (_timeout > SCAN_TIMEOUT_MAX) {
|
||||
_timeout = SCAN_TIMEOUT_MAX;
|
||||
}
|
||||
}
|
||||
|
||||
ble_error_t setInterval(uint16_t newIntervalInMS) {
|
||||
uint16_t newInterval = Gap::MSEC_TO_ADVERTISEMENT_DURATION_UNITS(newIntervalInMS);
|
||||
if ((newInterval >= SCAN_INTERVAL_MIN) && (newInterval < SCAN_INTERVAL_MAX)) {
|
||||
_interval = newInterval;
|
||||
return BLE_ERROR_NONE;
|
||||
}
|
||||
|
||||
return BLE_ERROR_PARAM_OUT_OF_RANGE;
|
||||
}
|
||||
|
||||
ble_error_t setWindow(uint16_t newWindowInMS) {
|
||||
uint16_t newWindow = Gap::MSEC_TO_ADVERTISEMENT_DURATION_UNITS(newWindowInMS);
|
||||
if ((newWindow >= SCAN_WINDOW_MIN) && (newWindow < SCAN_WINDOW_MAX)) {
|
||||
_window = newWindow;
|
||||
return BLE_ERROR_NONE;
|
||||
}
|
||||
|
||||
return BLE_ERROR_PARAM_OUT_OF_RANGE;
|
||||
}
|
||||
|
||||
ble_error_t setTimeout(uint16_t newTimeout) {
|
||||
if (newTimeout <= SCAN_TIMEOUT_MAX) {
|
||||
_timeout = newTimeout;
|
||||
return BLE_ERROR_NONE;
|
||||
}
|
||||
|
||||
return BLE_ERROR_PARAM_OUT_OF_RANGE;
|
||||
}
|
||||
|
||||
void setActiveScanning(bool activeScanning) {
|
||||
_activeScanning = activeScanning;
|
||||
}
|
||||
|
||||
|
||||
/* @Note: The following return durations in units of 0.625 ms */
|
||||
uint16_t getInterval(void) const {return _interval;}
|
||||
uint16_t getWindow(void) const {return _window; }
|
||||
|
||||
uint16_t getTimeout(void) const {return _timeout; }
|
||||
bool getActiveScanning(void) const {return _activeScanning;}
|
||||
|
||||
private:
|
||||
uint16_t _interval; /**< Scan interval in units of 625us (between 2.5ms to 10.24s). */
|
||||
uint16_t _window; /**< Scan window in units of 625us (between 2.5ms to 10.24s). */
|
||||
uint16_t _timeout; /**< Scan timeout between 0x0001 and 0xFFFF in seconds, 0x0000 disables timeout. */
|
||||
bool _activeScanning; /**< obtain not only the advertising data from the peer device, but also their scanResponse if possible. */
|
||||
|
||||
private:
|
||||
/* disallow copy constructor */
|
||||
GapScanningParams(const GapScanningParams &);
|
||||
GapScanningParams& operator =(const GapScanningParams &in);
|
||||
};
|
||||
|
||||
#endif // ifndef __GAP_SCANNING_PARAMS_H__
|
|
@ -104,7 +104,7 @@ public:
|
|||
\note See https://developer.bluetooth.org/gatt/units/Pages/default.aspx
|
||||
*/
|
||||
/**************************************************************************/
|
||||
typedef enum ble_gatt_unit_e {
|
||||
enum {
|
||||
BLE_GATT_UNIT_NONE = 0x2700, /**< No specified unit type */
|
||||
BLE_GATT_UNIT_LENGTH_METRE = 0x2701, /**< Length, Metre */
|
||||
BLE_GATT_UNIT_MASS_KILOGRAM = 0x2702, /**< Mass, Kilogram */
|
||||
|
@ -214,7 +214,7 @@ public:
|
|||
BLE_GATT_UNIT_TIME_MONTH = 0x27B4, /**< Time, Month */
|
||||
BLE_GATT_UNIT_CONCENTRATION_COUNT_PER_CUBIC_METRE = 0x27B5, /**< */
|
||||
BLE_GATT_UNIT_IRRADIANCE_WATT_PER_SQUARE_METRE = 0x27B6 /**< */
|
||||
} ble_gatt_unit_t;
|
||||
};
|
||||
|
||||
/**************************************************************************/
|
||||
/*!
|
||||
|
@ -224,7 +224,7 @@ public:
|
|||
\note See http://developer.bluetooth.org/gatt/descriptors/Pages/DescriptorViewer.aspx?u=org.bluetooth.descriptor.gatt.characteristic_presentation_format.xml
|
||||
*/
|
||||
/**************************************************************************/
|
||||
typedef enum ble_gatt_format_e {
|
||||
enum {
|
||||
BLE_GATT_FORMAT_RFU = 0x00, /**< Reserved For Future Use. */
|
||||
BLE_GATT_FORMAT_BOOLEAN = 0x01, /**< Boolean. */
|
||||
BLE_GATT_FORMAT_2BIT = 0x02, /**< Unsigned 2-bit integer. */
|
||||
|
@ -253,7 +253,7 @@ public:
|
|||
BLE_GATT_FORMAT_UTF8S = 0x19, /**< UTF-8 string. */
|
||||
BLE_GATT_FORMAT_UTF16S = 0x1A, /**< UTF-16 string. */
|
||||
BLE_GATT_FORMAT_STRUCT = 0x1B /**< Opaque Structure. */
|
||||
} ble_gatt_format_t;
|
||||
};
|
||||
|
||||
/**************************************************************************/
|
||||
/*!
|
||||
|
|
Loading…
Reference in a new issue