feat(ble): replace blocking scan with advertisement observation
The one-shot scan kept only the top six devices by RSSI and dropped the advertisement payload, so a distant beacon lost its slot to nearby phones and its data was unreachable -- wrong on every axis for reading sensors that broadcast in their adverts. Replace it with a continuous observer: observe(filter)/observed()/ unobserve()/isObserving(). BleObservation carries the raw advertisement bytes for Lua to parse, and BleFilter keeps only adverts matching a service-data UUID or manufacturer id.
This commit is contained in:
@@ -276,9 +276,10 @@ struct Wifi : WifiProvider {
|
||||
};
|
||||
|
||||
struct Ble : BleProvider {
|
||||
int32_t duration = 0;
|
||||
std::string value;
|
||||
bool initialized = false;
|
||||
bool observing = false;
|
||||
BleFilter filter;
|
||||
|
||||
Status init(const std::string*) override {
|
||||
initialized = true;
|
||||
@@ -286,12 +287,17 @@ struct Ble : BleProvider {
|
||||
}
|
||||
void deinit() override { initialized = false; }
|
||||
bool isInitialized() const override { return initialized; }
|
||||
Status scan(int32_t durationMs, std::vector<BleDevice>& devices) override {
|
||||
duration = durationMs;
|
||||
const BleDevice device = {"tag", "aa:bb", -60};
|
||||
devices.push_back(device);
|
||||
Status observe(const BleFilter& next) override {
|
||||
filter = next;
|
||||
observing = true;
|
||||
return Status::success();
|
||||
}
|
||||
void unobserve() override { observing = false; }
|
||||
bool isObserving() const override { return observing; }
|
||||
void observed(std::vector<BleObservation>& out) override {
|
||||
const BleObservation device = {"aa:bb", "tag", -60, "payload", 1234};
|
||||
out.push_back(device);
|
||||
}
|
||||
Status connect(const std::string&) override { return Status::success(); }
|
||||
void disconnect() override {}
|
||||
bool isConnected() const override { return true; }
|
||||
|
||||
@@ -121,10 +121,14 @@ int main() {
|
||||
run(state, "assert(not ble.isInitialized())\n"
|
||||
"assert(ble.init())\n"
|
||||
"assert(ble.isInitialized())\n"
|
||||
"assert(ble.scan()[1].address == 'aa:bb')\n"
|
||||
"assert(ble.observe({ services = { '181A' } }))\n"
|
||||
"assert(ble.isObserving())\n"
|
||||
"assert(ble.observed()[1].address == 'aa:bb')\n"
|
||||
"assert(ble.observed()[1].payload == 'payload')\n"
|
||||
"assert(#ble.read('svc', 'chr') == 3)\n"
|
||||
"assert(ble.write('svc', 'chr', 'x\\0y'))");
|
||||
assert(bench.ble.duration == 3000);
|
||||
assert(bench.ble.filter.services.size() == 1);
|
||||
assert(bench.ble.filter.services[0] == "181A");
|
||||
assert(bench.ble.value.size() == 3);
|
||||
|
||||
run(state, "fired = 0\n"
|
||||
|
||||
Reference in New Issue
Block a user