Skip to content

Commit

Permalink
Improve BLE interface
Browse files Browse the repository at this point in the history
Use uint64_t as interface between NimBLE client and SensiScan
as we only convert it into a invalid string and back into an
uint64_t.

Add constructor and destructure to NimBLE client to better
represent the life-cycle of this class.

Remove squash method from SensiScan as it is not required anymore.
  • Loading branch information
psachs committed Oct 24, 2024
1 parent 099fb9b commit ecfe84a
Show file tree
Hide file tree
Showing 5 changed files with 29 additions and 40 deletions.
2 changes: 1 addition & 1 deletion src/BleClientCallback.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ class BleClientCallback {
public:
virtual ~BleClientCallback() = default;

virtual void onAdvertisementReceived(std::string address, std::string name,
virtual void onAdvertisementReceived(uint64_t address, std::string name,
std::string data) = 0;
};

Expand Down
37 changes: 21 additions & 16 deletions src/NimBleClient.cpp
Original file line number Diff line number Diff line change
@@ -1,8 +1,23 @@
#include "NimBleClient.h"

NimBleClient::NimBleClient() : _callback(nullptr) {
// CONFIG_BTDM_SCAN_DUPL_TYPE_DATA_DEVICE (2)
// Filter by address and data, advertisements from the same address will be
// reported only once, except if the data in the advertisement has changed,
// then it will be reported again.
NimBLEDevice::setScanFilterMode(CONFIG_BTDM_SCAN_DUPL_TYPE_DATA_DEVICE);
NimBLEDevice::setScanDuplicateCacheSize(200);
NimBLEDevice::init("");
_bleScan = NimBLEDevice::getScan();
setupBleScans();
}

NimBleClient::~NimBleClient() {
_bleScan->stop();
}

void NimBleClient::begin(BleClientCallback* callback) {
_callback = callback;
setupBleScans();
startBleScans();
}

Expand All @@ -15,18 +30,18 @@ void NimBleClient::keepAlive() {
}
}


void NimBleClient::onResult(NimBLEAdvertisedDevice* advertisedDevice) {
if (!advertisedDevice->haveManufacturerData()) {
return;
}

// MAC address contains 6 bytes of MAC address (in reversed order)
// (Note: advertisedDevice->getAddress().toString() seems broken)
const uint8_t* bleMACAddress = advertisedDevice->getAddress().getNative();
std::string address;
for (int i = 5; i >= 0; i--) {
address.push_back(static_cast<char>(bleMACAddress[i]));
uint64_t address = 0;
size_t address_size = 6;
// reverse MAC address and store it as 64-bit unsigned int
for (int ix = 0; ix < address_size; ix++) {
address = (address << 8) | bleMACAddress[address_size - 1 - ix];
}

std::string name = advertisedDevice->haveName()
Expand All @@ -38,16 +53,6 @@ void NimBleClient::onResult(NimBLEAdvertisedDevice* advertisedDevice) {
}

void NimBleClient::setupBleScans() {
// CONFIG_BTDM_SCAN_DUPL_TYPE_DATA_DEVICE (2)
// Filter by address and data, advertisements from the same address will be
// reported only once, except if the data in the advertisement has changed,
// then it will be reported again.
NimBLEDevice::setScanFilterMode(CONFIG_BTDM_SCAN_DUPL_TYPE_DATA_DEVICE);
NimBLEDevice::setScanDuplicateCacheSize(200);
NimBLEDevice::init("");

// create new scan
_bleScan = NimBLEDevice::getScan();
// Activate callback on advertisement update
_bleScan->setAdvertisedDeviceCallbacks(this, true);
// Set active scanning, this will get more data from the advertiser.
Expand Down
3 changes: 2 additions & 1 deletion src/NimBleClient.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,8 @@ class __attribute__((unused)) NimBleClient
: public BleClient,
public NimBLEAdvertisedDeviceCallbacks {
public:
NimBleClient() : _bleScan(nullptr), _callback(nullptr) {};
NimBleClient();
~NimBleClient();
void begin(BleClientCallback* callback) override;
void keepAlive() override;

Expand Down
24 changes: 4 additions & 20 deletions src/Sensirion_upt_ble_auto_detection.cpp
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
#include "Sensirion_upt_ble_auto_detection.h"
#include "Arduino.h"
#include "NimBleClient.h"

const int COMPANY_ID_FILTER = 54534;
Expand All @@ -20,19 +21,16 @@ __attribute__((unused)) void SensiScan::keepAlive() {
_bleClient->keepAlive();
}

void SensiScan::onAdvertisementReceived(const std::string address,
std::string name, std::string data) {
void SensiScan::onAdvertisementReceived(uint64_t address, std::string name,
std::string data) {
uint16_t companyId = (uint16_t)data[0] << 8 | (uint8_t)data[1];
if (companyId != COMPANY_ID_FILTER) {
return;
}

// Get MAC address as uint64_t
uint64_t deviceID = squashMACAddress(address);

// Build MetaData
MetaData metaData;
metaData.deviceID = deviceID;
metaData.deviceID = address;
metaData.deviceType.bleGadgetType =
bleGadgetTypeFromCompleteLocalName(name.c_str());
metaData.platform = DevicePlatform::BLE;
Expand All @@ -48,20 +46,6 @@ void SensiScan::onAdvertisementReceived(const std::string address,
_sampleCache[getDeviceId(data)] = samples;
}

/**
* @brief squash std::string address to a uint64_t
* @note MAC address is comprised of 6 bytes
*/
uint64_t SensiScan::squashMACAddress(const std::string& macAddressString) {

uint64_t deviceID = static_cast<unsigned char>(macAddressString[0]);
for (size_t i = 1; i < 6; i++) {
deviceID = (deviceID << 8) | macAddressString[i];
}

return deviceID;
}

/**
* @brief last two digits of MAC address uniquely define a device
*/
Expand Down
3 changes: 1 addition & 2 deletions src/Sensirion_upt_ble_auto_detection.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,8 @@ class __attribute__((unused)) SensiScan: public BleClientCallback {
private:
BleClient* _bleClient;
std::map<uint16_t, std::vector<Measurement>> _sampleCache;
void onAdvertisementReceived(std::string address, std::string name,
void onAdvertisementReceived(uint64_t address, std::string name,
std::string data) override;
static uint64_t squashMACAddress(const std::string& macAddressString);
static uint16_t getDeviceId(const std::string& data);
static uint8_t decodeData(const MetaData& metaData, const std::string& data,
std::vector<Measurement>& samples);
Expand Down

0 comments on commit ecfe84a

Please sign in to comment.