Closed ferologics closed 6 years ago
I can't recreate it. What version of bluepy/bleah do you use? I see the version numbers, but bleah version number hasn't been touched for 9 months. bluepy tag for version 1.1.4 has been set in Nov 2017. By "it" you mean the device? If so, do you know what's the UUID of the device?
I'm able to recreate this with bluepy 1.1.4 and bleah-1.0.0 as well. My device is returning a value of 0xFF00 for Generic Access Profile data type 0x3 (Complete List of 16-bit Service Class UUIDs):
sudo bleah -b "30:AE:A4:89:A8:86" -e
Trace Log:
Traceback (most recent call last):
File "/bin/bleah", line 5, in <module>
pkg_resources.run_script('bleah==1.0.0', 'bleah')
File "/usr/lib/python2.7/site-packages/pkg_resources.py", line 540, in run_script
self.require(requires)[0].run_script(script_name, ns)
File "/usr/lib/python2.7/site-packages/pkg_resources.py", line 1455, in run_script
execfile(script_filename, namespace, namespace)
File "/usr/lib/python2.7/site-packages/bleah-1.0.0-py2.7.egg/EGG-INFO/scripts/bleah", line 148, in <module>
main()
File "/usr/lib/python2.7/site-packages/bleah-1.0.0-py2.7.egg/EGG-INFO/scripts/bleah", line 108, in main
devices = start_scan(args)
File "/usr/lib/python2.7/site-packages/bleah-1.0.0-py2.7.egg/bleah/scan.py", line 163, in start_scan
return scanner.scan(args.timeout)
File "/usr/lib/python2.7/site-packages/bluepy-1.1.4-py2.7.egg/bluepy/btle.py", line 734, in scan
self.process(timeout)
File "/usr/lib/python2.7/site-packages/bleah-1.0.0-py2.7.egg/bleah/scan.py", line 78, in process
self.delegate.handleDiscovery(dev, (dev.updateCount <= 1), isNewData)
File "/usr/lib/python2.7/site-packages/bleah-1.0.0-py2.7.egg/bleah/scan.py", line 135, in handleDiscovery
for ( tag, desc, val ) in dev.getScanData():
File "/usr/lib/python2.7/site-packages/bluepy-1.1.4-py2.7.egg/bluepy/btle.py", line 655, in getScanData
for sdid in self.scanData.keys() ]
File "/usr/lib/python2.7/site-packages/bluepy-1.1.4-py2.7.egg/bluepy/btle.py", line 650, in getValueText
return str(self.getValue(sdid))
File "/usr/lib/python2.7/site-packages/bluepy-1.1.4-py2.7.egg/bluepy/btle.py", line 641, in getValue
return self._decodeUUID(val,2)
File "/usr/lib/python2.7/site-packages/bluepy-1.1.4-py2.7.egg/bluepy/btle.py", line 622, in _decodeUUID
rs = ("%02X" % val[i]) + rs
TypeError: %X format: a number is required, not str
Poking around with PDB, I can see that one of the Generic Access Profiles (0x3) is returning a byte-string of '\xff\x00', which _decodeUUID is choking on:
/usr/lib/python2.7/site-packages/bluepy-1.1.4-py2.7.egg/bluepy/btle.py(656)getScanData()
-> return [ (sdid, self.getDescription(sdid), self.getValueText(sdid))
(Pdb) self.scanData.keys()
[1, 10, 3, 9]
(Pdb) self.getDescription(1)
'Flags'
(Pdb) self.getValueText(1)
'06'
(Pdb) self.getDescription(10)
'Tx Power'
(Pdb) self.getValueText(10)
'eb'
(Pdb) self.getDescription(9)
'Complete Local Name'
(Pdb) self.getValueText(9)
'BLECTF'
(Pdb) self.getDescription(3)
'Complete 16b Services'
(Pdb) self.getValueText(3)
*** TypeError: %X format: a number is required, not str
(Pdb) self.getValue(3)
*** TypeError: %X format: a number is required, not str
(Pdb) self.scanData.get(3, None)
'\xff\x00'
(Pdb) val = self.scanData.get(3, None)
(Pdb) type(val)
<type 'str'>
(Pdb) val[0]
'\xff'
(Pdb) val[1]
'\x00'
(Pdb) type(val[0])
<type 'str'>
(Pdb) type(val[1])
<type 'str'>
(Pdb) ("%02X" % val[0])
*** TypeError: %X format: a number is required, not str
I ran a BLE scan and dumped the advertisement packets. My device has address 30:AE:A4:89:A8:86, which corresponds to this advertisement:
sudo hcitool lescan --duplicates &
sudo hcidump --raw
...
> 04 3E 1E 02 01 00 00 86 A8 89 A4 AE 30 12 02 01 06 02 0A EB
03 03 FF 00 07 09 42 4C 45 43 54 46 CA
...
Scanning with bleah causes the same failure as attempting to connect to the device with bleah. hcitool can scan for the device successfully, and gatttool can connect to it and dump characteristics/etc.
I concur with the above, experiencing identical behavior.
As per the findings @mdeverhart, patching the _decodeUUID
function fixes the error.
def _decodeUUID(self, val, nbytes):
if len(val) < nbytes:
return None
rs=""
# Bytes are little-endian; convert to big-endian string
for i in range(nbytes):
if type(val[i]) == int:
rs = ("%02X" % val[i]) + rs
else:
rs = ("%02X" % ord(val[i])) + rs
return UUID(rs)
This is a Python 2 vs Python 3 problem; when I wrote it it worked for me on Python 3, but I couldn't have tested it on 2.
I'm slightly puzzled that this is being reported against version 1.1.4, or things installed from PyPI. The code in question was added in 927e37c38 - the 1.1.4 release was way back in 2017.
I've justed pushed e27f9c7 which should fix it on Python 2.7.
Let me know if this fixes it. You'll have to install from source.
Yes, cloning the latest from GitHub resolves the issue while running Python 2.7. Thanks!
I believe that the confusion around the version number (1.1.4) is that the version number doesn't appear to have been changed since its release in 2017, but I didn't realize it. I can confirm that I was running the latest source from GitHub as of 7/10 when I reported my findings.
I've now made a 1.2.0 release with this code in, so hopefully you can pip install
Bluepy and get the fixed version.
I used
bleah
and got failed to scan for my device. If I turn it off the scan goes through just fine because it won't try to parse the mac UUID.Full trace log 👉