For test purposes, I want to connect a USB device and want to check what is the speed (HS/FS/LS).
I am able to access to Device Descriptor, Endpoint descriptor, interface descriptor but I would like to know the device address which has been allocated by the OS (windows 7)
My code so far :
import usb
busses = usb.busses()
for bus in busses:
for dev in bus.devices:
if dev.idVendor == vendor_id and dev.idProduct == product_id:
print ("Test vehicle %s device FOUND!" %protocol)
print ("iManufacturer : %s" %usb.util.get_string(dev.dev, 256, 1))
print ("iProduct : %s" %usb.util.get_string(dev.dev, 256, 2))
print ("iSerialNumber : %s" %usb.util.get_string(dev.dev, 256, 3))
return dev
print ("Test vehicle %s device NOT FOUND!" %protocol)
Returns :
C:\Python27\Lib\site-packages>python example.py
Test vehicle HS device FOUND!
iManufacturer : Kingston
iProduct : DataTraveler 2.0
iSerialNumber : 5B720A82364A
In the very useful USBview software, there is a section :
ConnectionStatus: DeviceConnected
Current Config Value: 0x01
Device Bus Speed: High
Device Address: 0x09
Open Pipes: 2
How do I get these informations ? is it a query to the USB device using pyUSB ? or is it a query to sys ?
Thanks for any help.
There are several more fields available in the device objects (in your code these are named dev).
A quick and dirty way to look at them
def print_internals(dev):
for attrib in dir(dev):
if not attrib.startswith('_') and not attrib == 'configurations':
x=getattr(dev, attrib)
print " ", attrib, x
for config in dev.configurations:
for attrib in dir(config):
if not attrib.startswith('_'):
x=getattr(config, attrib)
print " ", attrib, x
And call it within your "for dev in bus.devices" loop. It looks like the filename might correspond to 'device address', though bus speed is a bit deeper in (dev.configurations[i].interfaces[j][k].interfaceProtocol), and this only has an integer. usb.util might be able to provide you more information based on those integers, but I don't have that module available to me.
Documentation for pyUSB doesn't seem to be very extensive, but this SO question points at the libusb docs which it wraps up.
You can get usb device speed information by pyUSB with this patch https://github.com/DeliangFan/pyusb/commit/a882829859cd6ef3c91ca11870937dfff93fea9d.
Because libusb1.0 has already support to get usb speed information.
These attributes are (nowadays) easily accessible. At least it works for me. https://github.com/pyusb/pyusb/blob/master/usb/core.py
import usb.core
devices = usb.core.find(find_all=True)
dev = next(devices)
print("device bus:", dev.bus)
print("device address:", dev.address)
print("device port:", dev.port_number)
print("device speed:", dev.speed)
Related
For example, I have connected to a LAN using the ethernet cable and to the internet using the WiFi. My computer has got 2 more interfaces that are currently not used.
The script should check for only active interfaces and return their IPs, router IPs, and the device names.
I would use netifaces. Like this:
import netifaces as ni
for iface in ni.interfaces():
print('interface : {0}'.format(iface))
try:
addrs = ni.ifaddresses(iface)
for k, v in addrs[ni.AF_INET][0].items():
print(' {0} : {1}'.format(k, v))
except:
pass
gways = ni.gateways()
print('gateway: {0}'.format(gways['default'][ni.AF_INET][0]))
I've been trying to get a simple python bluetooth example running on my lenovo y50-70 laptop running ubuntu 18. But while doing this i noticed that the Pybluez library is unable to find any devices, while using the bluetoothctl tool can.
import bluetooth
print("performing inquiry...")
nearby_devices = bluetooth.discover_devices(duration=8,
lookup_names=True, flush_cache=True, lookup_class=False)
print("found %d devices" % len(nearby_devices))
for addr, name in nearby_devices:
try:
print(" %s - %s" % (addr, name))
except UnicodeEncodeError:
print(" %s - %s" % (addr, name.encode('utf-8', 'replace')))
Running the code above gives as an output: found 0 devices. While running bluetoothctl gives me the following output:
[NEW] Controller 40:B8:9A:44:E0:46 daan-Lenovo-Y50-70 [default]
Agent registered
[bluetooth]# scan on
Discovery started
[CHG] Controller 40:B8:9A:44:E0:46 Discovering: yes
[NEW] Device 30:AE:A4:37:A2:4A 30-AE-A4-37-A2-4A
[NEW] Device D0:D2:B0:91:1C:C5 D0-D2-B0-91-1C-C5
[NEW] Device 70:73:CB:DF:1B:08 70-73-CB-DF-1B-08
[NEW] Device 51:80:89:6F:6E:B6 51-80-89-6F-6E-B6
[bluetooth]#
I have tried running my python script as root, and my current pybluez version is 0.22. I hope anyone knows how to resolve this issue.
How to get the USB information like Manufacture Name, Size etc?
I am using Ubuntu 16.
and Python 2.7.12
Have you tried something like this :
busses = usb.busses()
for bus in busses:
devices = bus.devices
for dev in devices:
print (repr(dev))
print("manufacturer", dev.iManufacturer)
print("Size", dev.iSize)
NOTE : I think it will work only when you are connected one usb at a time
with this you can print all USB String Descriptors in pyusb : Manufacturer String Descriptor, Product String Descriptor, Serial Number String Descriptor ( for all USB devices, including the host controllers ) cf https://www-user.tu-chemnitz.de/~heha/viewchm.php/hs/usb.chm/usb5.htm
import usb
busses = usb.busses()
for bus in busses:
devices = bus.devices
for dev in devices:
manufacturer = usb.util.get_string(dev.dev, dev.dev.iManufacturer)
print str(manufacturer)
product = usb.util.get_string(dev.dev, dev.dev.iProduct)
print str(product)
serialnumber = usb.util.get_string(dev.dev, dev.dev.iSerialNumber)
print str(serialnumber)
print('\n')
you have to call this as root / with sudo else you get ValueError: The device has no langid error
other USB attributes you can print with their names :
import usb
busses = usb.busses()
for bus in busses:
devices = bus.devices
for dev in devices:
print " Device class:",dev.dev.bDeviceClass
print " Device sub class:",dev.dev.bDeviceSubClass
print " Device protocol:",dev.dev.bDeviceProtocol
First off if anybody knows of a good tutorial for coding bluetooth on my raspberry pi zero w with python to turn on discovery, listen for a pair request, connect and save the paired device, and more, that would be awesome. My code for testing bluetooth discovery is below.
import bluetooth
print("performing inquiry...")
nearby_devices = bluetooth.discover_devices(
duration=8, lookup_names=True, flush_cache=True)
print("found %d devices" % len(nearby_devices))
for addr, name in nearby_devices:
try:
print(" %s - %s" % (addr, name))
except UnicodeEncodeError:
print(" %s - %s" % (addr, name.encode('utf-8', 'replace')))
The TraceBack is below
Traceback (most recent call last):
File "bluetoothConnect.py", line 6, in <module>
duration=8, lookup_names=True, flush_cache=True)
File "/usr/lib/python2.7/dist-packages/bluetooth/bluez.py", line 17, in discover_devices
sock = _gethcisock ()
File "/usr/lib/python2.7/dist-packages/bluetooth/bluez.py", line 226, in _gethcisock
raise BluetoothError ("error accessing bluetooth device")
bluetooth.btcommon.BluetoothError: error accessing bluetooth device
("error accessing bluetooth device") is the clue.
Yes - as earlier mentioned you need elevated privileges.
Simply run the script with sudo...
eg - sudo python myscript.py
enter your password
It should now work..for testing purposes.
Though going forward I would create a privileged user and add that user to the root group with the setting /bin/false.
Then use that user to run all your scripts..
Had the same issue and then I wrote this simple script to wrap Bluetoothctl using python3. Tested on Raspberry pi 4.
import subprocess
import time
def scan(scan_timeout=20):
""" scan
Scan for devices
Parameters
----------
scan_timeout : int
Timeout to run the scan
Returns
----------
devices : dict
set of discovered devices as MAC:Name pairs
"""
p = subprocess.Popen(["bluetoothctl", "scan", "on"])
time.sleep(scan_timeout)
p.terminate()
return __devices()
def __devices():
""" devices
List discovered devices
Returns
----------
devices : dict
set of discovered devices as MAC:Name pairs
"""
devices_s = subprocess.check_output("bluetoothctl devices", shell=True).decode().split("\n")[:-1]
devices = {}
for each in devices_s:
devices[each[7:24]] = each[25:]
return devices
def info():
""" Info
Returns
----------
info : str
information about the device connected currently if any
"""
return subprocess.check_output("bluetoothctl info", shell=True).decode()
def pair(mac_address):
""" pair
Pair with a device
Parameters
----------
mac_address : str
mac address of the device tha you need to pair
"""
subprocess.check_output("bluetoothctl pair {}".format(mac_address), shell=True)
def remove(mac_address):
""" remove
Remove a connected(paired) device
Parameters
----------
mac_address : str
mac address of the device tha you need to remove
"""
subprocess.check_output("bluetoothctl remove {}".format(mac_address), shell=True)
def connect(mac_address):
""" connect
Connect to a device
Parameters
----------
mac_address : str
mac address of the device tha you need to connect
"""
subprocess.check_output("bluetoothctl connect {}".format(mac_address), shell=True)
def disconnect():
""" disconnect
Disconnects for currently connected device
"""
subprocess.check_output("bluetoothctl disconnect", shell=True)
def paired_devices():
""" paired_devices
Return a list of paired devices
"""
return subprocess.check_output("bluetoothctl paired-devices", shell=True).decode()
Im trying to make a algorithm in python to detect if my phone is in the area. Im using this to find my device:
bluetooth.discover_devices()
But it only detects my phone if I set my Bluetooth on my phone to "visible".
Is there a function or command to detect my phone when it's set to hidden?
Im fairly new to python so any form of help is very welcome!
Thanks in advance!
You could attempt to connect to your phone. If it's nearby, the connection will succeed. Devices can be connectable when they are not discoverable. You would have to already know the device address of your phone (via discovery when your phone was visible) in order to initiate the connection.
Not sure if a solution is still needed (I think this is right, just haven't been succesful with it). A book entitled "Violent Python" gives a solution for this in chapter 5, but I haven't been successful in implementing it. Supposedly you just need to increment the MAC address of the devices wifi adapter by one to calculate the Bluetooth MAC.
def retBtAddr(addr):
btAddr=str(hex(int(addr.replace(':', ''), 16) + 1))[2:]
btAddr=btAddr[0:2]+":"+btAddr[2:4]+":"+btAddr[4:6]+":"+\
btAddr[6:8]+":"+btAddr[8:10]+":"+btAddr[10:12]
return btAddr
and then something like the following (where OUI is the first 24 bytes of BT MAC)
def checkBluetooth(btAddr):
btName = lookup_name(btAddr)
if btName:
print '[+] Detected Bluetooth Device: ' + btName
else:
print '[-] Failed to Detect Bluetooth Device.'
def wifiPrint(pkt):
iPhone_OUI = 'd0:23:db'
if pkt.haslayer(Dot11):
wifiMAC = pkt.getlayer(Dot11).addr2
if wifiMAC != None and iPhone_OUI == wifiMAC[:8]:
print '[*] Detected iPhone MAC: ' + wifiMAC
btAddr = retBtAddr(wifiMAC)
print '[+] Testing Bluetooth MAC: ' + btAddr
checkBluetooth(btAddr)