Skip to content
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

Ble5 long range wiring API #2298

Merged
merged 9 commits into from
Mar 24, 2021
Merged
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
4 changes: 2 additions & 2 deletions hal/inc/ble_hal.h
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ extern "C" {
* @{
*/

#define BLE_API_VERSION 2
#define BLE_API_VERSION 3

// Particle's company ID
#define PARTICLE_COMPANY_ID 0x0662
Expand Down Expand Up @@ -190,7 +190,6 @@ typedef struct hal_ble_adv_params_t {
hal_ble_adv_fp_t filter_policy;
uint8_t inc_tx_power;
uint8_t primary_phy; /**< Supports BLE_PHYS_1MBPS (standard) or BLE_PHYS_CODED (long range) */
uint8_t reserved;
} hal_ble_adv_params_t;

/* BLE scanning parameters */
Expand All @@ -203,6 +202,7 @@ typedef struct hal_ble_scan_params_t {
uint8_t active;
hal_ble_scan_fp_t filter_policy;
uint8_t scan_phys; /**< Supports BLE_PHYS_1MBPS, BLE_PHYS_CODED, or (BLE_PHYS_1MBPS | BLE_PHYS_CODED) */
uint8_t reserved[3];
} hal_ble_scan_params_t;

/* BLE connection parameters */
Expand Down
16 changes: 13 additions & 3 deletions hal/src/nRF52840/ble_hal.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,7 @@ using namespace particle::ble;

#define BLE_API_VERSION_1 1
#define BLE_API_VERSION_2 2
#define BLE_API_VERSION_3 3

//anonymous namespace
namespace {
Expand Down Expand Up @@ -1032,8 +1033,13 @@ int BleObject::Broadcaster::setAdvertisingParams(const hal_ble_adv_params_t* par
tempParams.interval = BLE_DEFAULT_ADVERTISING_INTERVAL;
tempParams.timeout = BLE_DEFAULT_ADVERTISING_TIMEOUT;
tempParams.inc_tx_power = false;
tempParams.primary_phy = BLE_PHYS_AUTO;
} else {
memcpy(&tempParams, params, std::min(tempParams.size, params->size));
if (tempParams.primary_phy != BLE_PHYS_AUTO && tempParams.primary_phy != BLE_PHYS_1MBPS && tempParams.primary_phy != BLE_PHYS_CODED) {
LOG(ERROR, "primary_phy value not supported");
return SYSTEM_ERROR_NOT_SUPPORTED;
}
}
CHECK(suspend());
if (connHandle_ != BLE_INVALID_CONN_HANDLE) {
Expand Down Expand Up @@ -1214,8 +1220,12 @@ int BleObject::Broadcaster::resume() {
ble_gap_adv_params_t BleObject::Broadcaster::toPlatformAdvParams(const hal_ble_adv_params_t* halParams) {
ble_gap_adv_params_t params = {};
if (halParams->primary_phy == BLE_PHYS_CODED) {
// For Coded Phy advertising, type must be extended, nonscannable
params.properties.type = BLE_GAP_ADV_TYPE_EXTENDED_CONNECTABLE_NONSCANNABLE_UNDIRECTED;
if (halParams->type == BLE_ADV_SCANABLE_UNDIRECTED_EVT) {
params.properties.type = BLE_GAP_ADV_TYPE_EXTENDED_NONCONNECTABLE_NONSCANNABLE_UNDIRECTED;
} else {
// For Coded Phy advertising, type must be extended, nonscannable
params.properties.type = BLE_GAP_ADV_TYPE_EXTENDED_CONNECTABLE_NONSCANNABLE_UNDIRECTED;
}
params.primary_phy = BLE_GAP_PHY_CODED;
} else {
// For 1 MBPS advertising, use whatever type is specified
Expand Down Expand Up @@ -1458,7 +1468,7 @@ int BleObject::Observer::stopScanning() {

ble_gap_scan_params_t BleObject::Observer::toPlatformScanParams() const {
ble_gap_scan_params_t params = {};
params.extended = (scanParams_.scan_phys == BLE_PHYS_1MBPS) ? 0x00 : 0x01; /**< Extended required if other than PHYS_1MBPS */
params.extended = ( (scanParams_.scan_phys & BLE_PHYS_CODED) != 0) ? 0x01 : 0x00; /**< Extended must be 1 if using Coded PHY */
XuGuohui marked this conversation as resolved.
Show resolved Hide resolved
params.active = scanParams_.active;
params.interval = scanParams_.interval;
params.window = scanParams_.window;
Expand Down
10 changes: 10 additions & 0 deletions user/tests/wiring/api/ble.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -198,6 +198,14 @@ test(ble_pairing_event_type) {
(void)type;
}

test(ble_phys_type) {
BlePhy phy;
API_COMPILE({ phy = BlePhy::BLE_PHYS_AUTO; });
API_COMPILE({ phy = BlePhy::BLE_PHYS_1MBPS; });
API_COMPILE({ phy = BlePhy::BLE_PHYS_CODED; });
(void)phy;
}

test(ble_address_class) {
hal_ble_addr_t halAddr;
uint8_t addrArray[BLE_SIG_ADDR_LEN];
Expand Down Expand Up @@ -690,6 +698,7 @@ test(ble_local_device_class) {
API_COMPILE({ int ret = BLE.setAdvertisingInterval(0); (void)ret; });
API_COMPILE({ int ret = BLE.setAdvertisingTimeout(0); (void)ret; });
API_COMPILE({ int ret = BLE.setAdvertisingType(BleAdvertisingEventType::CONNECTABLE_SCANNABLE_UNDIRECRED); (void)ret; });
API_COMPILE({ int ret = BLE.setAdvertisingPhy(BlePhy::BLE_PHYS_AUTO); (void)ret; });
API_COMPILE({ int ret = BLE.setAdvertisingParameters(&params); (void)ret; });
API_COMPILE({ int ret = BLE.setAdvertisingParameters(params); (void)ret; });
API_COMPILE({ int ret = BLE.setAdvertisingParameters(0, 0, BleAdvertisingEventType::CONNECTABLE_SCANNABLE_UNDIRECRED); (void)ret; });
Expand All @@ -715,6 +724,7 @@ test(ble_local_device_class) {
API_COMPILE({ bool ret = BLE.advertising(); (void)ret; });

API_COMPILE({ int ret = BLE.setScanTimeout(0); (void)ret; });
API_COMPILE({ int ret = BLE.setScanPhy(BlePhy::BLE_PHYS_AUTO | BlePhy::BLE_PHYS_CODED); (void)ret; });
API_COMPILE({ int ret = BLE.setScanParameters(&scanParams); (void)ret; });
API_COMPILE({ int ret = BLE.setScanParameters(scanParams); (void)ret; });
API_COMPILE({ int ret = BLE.getScanParameters(&scanParams); (void)ret; });
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,8 @@ typedef enum {
CMD_RESTART_ADV,
CMD_ADV_DEVICE_NAME,
CMD_ADV_APPEARANCE,
CMD_ADV_CUSTOM_DATA
CMD_ADV_CUSTOM_DATA,
CMD_ADV_CODED_PHY
} TestCommand;
TestCommand cmd = CMD_UNKNOWN;

Expand Down Expand Up @@ -89,4 +90,18 @@ test(BLE_Broadcaster_05_Advertise_Custom_Data) {
assertTrue(BLE.advertising());
}

test(BLE_Broadcaster_06_Advertise_On_Coded_Phy) {
assertTrue(BLE.connected());
assertTrue(waitFor([&]{ return cmd == CMD_ADV_CODED_PHY; }, 60000));

assertEqual(BLE.setAdvertisingPhy(BlePhy::BLE_PHYS_CODED), 0);

BleAdvertisingData data;
data.appendLocalName("CODED_PHY");
assertEqual(data.deviceName(), String("CODED_PHY"));
int ret = BLE.advertise(&data);
assertEqual(ret, 0);
assertTrue(BLE.advertising());
}

#endif // #if Wiring_BLE == 1
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,8 @@ typedef enum {
CMD_RESTART_ADV,
CMD_ADV_DEVICE_NAME,
CMD_ADV_APPEARANCE,
CMD_ADV_CUSTOM_DATA
CMD_ADV_CUSTOM_DATA,
CMD_ADV_CODED_PHY
} TestCommand;

const char* peerServiceUuid = "6E400000-B5A3-F393-E0A9-E50E24DCCA9E";
Expand Down Expand Up @@ -217,4 +218,24 @@ test(BLE_Scanner_09_Scan_With_Custom_Data) {
assertEqual(results.size(), 0);
}

test(BLE_Scanner_10_Scan_On_Coded_Phy) {
assertTrue(BLE.connected());

int ret;
TestCommand cmd = CMD_ADV_CODED_PHY;
ret = peerCharWriteWoRsp.setValue((const uint8_t*)&cmd, 1);
assertEqual(ret, 1);

delay(1s);

assertEqual(BLE.setScanPhy(BlePhy::BLE_PHYS_CODED), 0);
Vector<BleScanResult> results = BLE.scanWithFilter(BleScanFilter().deviceName("CODED_PHY"));
assertEqual(results.size(), 1);

// Scan on 1MBPS PHY
assertEqual(BLE.setScanPhy(BlePhy::BLE_PHYS_1MBPS), 0);
results = BLE.scanWithFilter(BleScanFilter().deviceName("CODED_PHY"));
assertEqual(results.size(), 0);
}

#endif // #if Wiring_BLE == 1
10 changes: 10 additions & 0 deletions wiring/inc/spark_wiring_ble.h
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,14 @@ enum class BleAdvertisingEventType : uint8_t {
SCANABLE_DIRECTED = BLE_ADV_SCANABLE_DIRECTED_EVT
};

enum class BlePhy : uint8_t {
BLE_PHYS_AUTO = hal_ble_phys_t::BLE_PHYS_AUTO,
BLE_PHYS_1MBPS = hal_ble_phys_t::BLE_PHYS_1MBPS,
BLE_PHYS_CODED = hal_ble_phys_t::BLE_PHYS_CODED
};

ENABLE_ENUM_CLASS_BITWISE(BlePhy);

enum class BleAntennaType : uint8_t {
DEFAULT = BLE_ANT_DEFAULT,
INTERNAL = BLE_ANT_INTERNAL,
Expand Down Expand Up @@ -921,6 +929,7 @@ class BleLocalDevice {
int setAdvertisingInterval(uint16_t interval) const;
int setAdvertisingTimeout(uint16_t timeout) const;
int setAdvertisingType(BleAdvertisingEventType type) const;
int setAdvertisingPhy(BlePhy phy) const; // Only one of the enum values can be specified as the argument.
int setAdvertisingParameters(const BleAdvertisingParams* params) const;
int setAdvertisingParameters(const BleAdvertisingParams& params) const;
int setAdvertisingParameters(uint16_t interval, uint16_t timeout, BleAdvertisingEventType type) const;
Expand Down Expand Up @@ -948,6 +957,7 @@ class BleLocalDevice {

// Access scanning parameters
int setScanTimeout(uint16_t timeout) const;
int setScanPhy(EnumFlags<BlePhy> phy) const;
int setScanParameters(const BleScanParams* params) const;
int setScanParameters(const BleScanParams& params) const;
int getScanParameters(BleScanParams* params) const;
Expand Down
23 changes: 23 additions & 0 deletions wiring/src/spark_wiring_ble.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2088,6 +2088,7 @@ int BleLocalDevice::selectAntenna(BleAntennaType antenna) const {
int BleLocalDevice::setAdvertisingInterval(uint16_t interval) const {
hal_ble_adv_params_t advParams = {};
advParams.size = sizeof(hal_ble_adv_params_t);
advParams.version = BLE_API_VERSION;
XuGuohui marked this conversation as resolved.
Show resolved Hide resolved
CHECK(hal_ble_gap_get_advertising_parameters(&advParams, nullptr));
advParams.interval = interval;
return hal_ble_gap_set_advertising_parameters(&advParams, nullptr);
Expand All @@ -2096,6 +2097,7 @@ int BleLocalDevice::setAdvertisingInterval(uint16_t interval) const {
int BleLocalDevice::setAdvertisingTimeout(uint16_t timeout) const {
hal_ble_adv_params_t advParams = {};
advParams.size = sizeof(hal_ble_adv_params_t);
advParams.version = BLE_API_VERSION;
CHECK(hal_ble_gap_get_advertising_parameters(&advParams, nullptr));
advParams.timeout = timeout;
return hal_ble_gap_set_advertising_parameters(&advParams, nullptr);
Expand All @@ -2104,11 +2106,21 @@ int BleLocalDevice::setAdvertisingTimeout(uint16_t timeout) const {
int BleLocalDevice::setAdvertisingType(BleAdvertisingEventType type) const {
hal_ble_adv_params_t advParams = {};
advParams.size = sizeof(hal_ble_adv_params_t);
advParams.version = BLE_API_VERSION;
CHECK(hal_ble_gap_get_advertising_parameters(&advParams, nullptr));
advParams.type = static_cast<hal_ble_adv_evt_type_t>(type);
return hal_ble_gap_set_advertising_parameters(&advParams, nullptr);
}

int BleLocalDevice::setAdvertisingPhy(BlePhy phy) const {
hal_ble_adv_params_t advParams = {};
advParams.size = sizeof(hal_ble_adv_params_t);
XuGuohui marked this conversation as resolved.
Show resolved Hide resolved
advParams.version = BLE_API_VERSION;
CHECK(hal_ble_gap_get_advertising_parameters(&advParams, nullptr));
advParams.primary_phy = static_cast<uint8_t>(phy);
return hal_ble_gap_set_advertising_parameters(&advParams, nullptr);
}

int BleLocalDevice::setAdvertisingParameters(const BleAdvertisingParams* params) const {
return hal_ble_gap_set_advertising_parameters(params, nullptr);
}
Expand All @@ -2120,6 +2132,7 @@ int BleLocalDevice::setAdvertisingParameters(const BleAdvertisingParams& params)
int BleLocalDevice::setAdvertisingParameters(uint16_t interval, uint16_t timeout, BleAdvertisingEventType type) const {
hal_ble_adv_params_t advParams = {};
advParams.size = sizeof(hal_ble_adv_params_t);
advParams.version = BLE_API_VERSION;
CHECK(hal_ble_gap_get_advertising_parameters(&advParams, nullptr));
advParams.interval = interval;
advParams.timeout = timeout;
Expand Down Expand Up @@ -2469,11 +2482,21 @@ class BleScanDelegator {
int BleLocalDevice::setScanTimeout(uint16_t timeout) const {
hal_ble_scan_params_t scanParams = {};
scanParams.size = sizeof(hal_ble_scan_params_t);
scanParams.version = BLE_API_VERSION;
hal_ble_gap_get_scan_parameters(&scanParams, nullptr);
scanParams.timeout = timeout;
return hal_ble_gap_set_scan_parameters(&scanParams, nullptr);
}

int BleLocalDevice::setScanPhy(EnumFlags<BlePhy> phy) const {
hal_ble_scan_params_t scanParams = {};
scanParams.size = sizeof(hal_ble_scan_params_t);
XuGuohui marked this conversation as resolved.
Show resolved Hide resolved
scanParams.version = BLE_API_VERSION;
hal_ble_gap_get_scan_parameters(&scanParams, nullptr);
scanParams.scan_phys = static_cast<uint8_t>(phy.value());
return hal_ble_gap_set_scan_parameters(&scanParams, nullptr);
}

int BleLocalDevice::setScanParameters(const BleScanParams* params) const {
return hal_ble_gap_set_scan_parameters(params, nullptr);
}
Expand Down