noble / bleno

A Node.js module for implementing BLE (Bluetooth Low Energy) peripherals
MIT License
2.12k stars 447 forks source link

It stopped advertising shortly after startAdvertising(). #387

Closed vicary closed 6 years ago

vicary commented 6 years ago

This is a follow up of #382, opening a new issue since it is closed prematurely and I am not getting replies. I am copying the context here.

The Issue

I am testing Bleno with Noble in a Raspberry Pi with Raspbian Lite.

After I called bleno.startAdvertising(...); I can scan the device with an iPhone and an Android, but when I refresh the device list after initial discovery the Pi never appeared again until I reboot.

Update 1 https://github.com/noble/bleno/issues/382#issuecomment-388281714

I added the DEBUG=* env var, could use some help in making sense out of it.

At the very least, assuming the default advertisement interval is 100ms, shall I be seeing logs starting with the following lines every 100ms?

hci set advertise enable - writing: 010a200100 +6ms
hci set advertisement parameters - writing: 0106200fa000a0000000000000000000000700 +5ms

If that's the case, the log is not generating at that interval. It only happened 4 times in 5 mins.

EDIT: Further narrowing it down, when using NOBLE_MULTI_ROLE both noble and bleno will emit an addressChange event with an identical MAC address at about 1 minute mark. There it follows some onSocketData things, and that's where it stops advertising.

Update 2 https://github.com/noble/bleno/issues/382#issuecomment-388296035

This gist shows a full log along with my test script, at line 189-190 is where it stops advertising.

In the test script I tried tapping into the internal bindings' bleno._bindings.on("addressChange", ...) event, but, interestingly, it generated exactly one more tick of advertisement in response just to fail again.

There is a roughly 60s interval between each addressChange event.

vicary commented 6 years ago

Solution

Do not require bleno twice, even from another process. In my case crond and a daemonized process.

tl;dr

This package initiates hardware upon reuqire("bleno") where I use lockfile and daemonized processes to keep it running. Whenever another process starts by crond and checks for lockfile, by best practise we require everything at the top of the script it kind of "takes over" the hardware handle, or more accurately, the HCI binding and re-initiates it with defaults and stops the advertisement.

The behavior of this package, and I've seen others alike, conflicts with an established common-practise in the community, aka hoisting require.