Reputation: 6201
Referencing this post I have successfully managed to get a Linux Device (A Raspberry Pi Model A+) to switch my Bluetooth 4.0 USB dongle into the 'advertising' state:
sudo hciconfig hci0 leadv 3
or
sudo hciconfig hci0 leadv 0
I verified this using an Ipod running the 'LightBlue Explorer' App.
All good so far.
From another Linux box (another Pi) which also has a Bluetooth 4.0 dongle; I can also see the device, using this command:
sudo hcitool lescan --passive
Which returns something like this:
LE Scan ...
xx:xx:xx:xx:xx:xx (unknown)
yy:yy:yy:yy:yy:yy (unknown)
xx:xx:xx;xx:xx:xx (unknown)
But the command loops around constantly refreshing the list of devices.
So my main question is: is there a variation of the command that can be run, listen for (say) 5 seconds; return the list of devices that it found to be advertising and exit ?
I want to build a simple script (or Python program ideally) that will periodically wake up, listen (passively) for advertising traffic for a few seconds, and then return the list of source devices.
Additionally: I'm not sure why the the command shows 'unknown' for the devices it finds. (Whereas the LightBlue does identify the name).
Upvotes: 0
Views: 14400
Reputation: 1891
There is no argument in hcitool for that, however here are some options
timeout 15s hcitool lescan
This will run the scan for 15s hcitool lescan
This will report each device only onceAbout (unknown)
: I assume your peripheral does not include the Bluetooth name in the advertising or even not at all.
--passive
tells your HCI Device to not request the ScanResponse (which probably contains the name), thus the name remains unknown, whereas the iOS APIs do an active scan and receive the name.
Upvotes: 6
Reputation: 120
I ran into this same problem running on a Raspberry Pi 3. But, if I ran the command more than once I got the error
Set scan parameters failed: Input/output error
To avoid this error, I had to send hcitool the INT signal like this:
timeout -s INT 10s hcitool lescan
Upvotes: 5
Reputation: 35
I know this question is already answered and not recent, but I used bluepy for a similar purpose. It comes with a class Scanner
with method scan([timeout = 10])
and example script (in the online documentation: http://ianharvey.github.io/bluepy-doc/scanner.html
Here is the code:
from bluepy.btle import Scanner, DefaultDelegate
class ScanDelegate(DefaultDelegate):
def __init__(self):
DefaultDelegate.__init__(self)
def handleDiscovery(self, dev, isNewDev, isNewData):
if isNewDev:
print "Discovered device", dev.addr
elif isNewData:
print "Received new data from", dev.addr
scanner = Scanner().withDelegate(ScanDelegate())
devices = scanner.scan(10.0)
for dev in devices:
print "Device %s (%s), RSSI=%d dB" % (dev.addr, dev.addrType, dev.rssi)
for (adtype, desc, value) in dev.getScanData():
print " %s = %s" % (desc, value)
This way you can scan when you want, for a given amount of time. I think this is exactly what you asked for and for me it works great in a scenario where a Raspberry Pi 3 should periodically (once every week) poll for devices.
Upvotes: 3