Always assign the same bluetooth dongle the same linux identifier hci0 - linux

we have a Raspberry Pi that is always listening for Bluetooth devices and if some conditions for the peripheral apply, it opens a Bluetooth connection to write some data to the peripheral.
For performance optimizations, there is one Bluetooth Dongle only for listening and another one that does the connections/writing. In our scripts, we hardwired hci0 to be the listening device and hci1 to connect.
Now we have the problem, that if somebody unplugs the dongle during runtime and plugs it back in, the device will receive the name hci2. This of course breaks our scripts.
So, my question is: Can I configure my Raspberry Pi OS to always assign the same name to the dongle? I would imagine, as they are using the MAC of the Dongle as an identifier, this should be possible.
Thanks for your help!

Rather than hardcode hci0 and hci1 in your code, I would look up the value for the mac address.
I'll assume you are using the D-Bus API and so could use GetManagedObjects.
For example:
import pydbus
bus = pydbus.SystemBus()
mngr = bus.get('org.bluez', '/')
def get_hci(address):
mngd_objs = mngr.GetManagedObjects()
for path in mngd_objs:
device_info = mngd_objs[path].get('org.bluez.Adapter1', {}).get('Address', 'none')
if device_info == address:
return path
print(get_hci('B8:27:EB:22:33:44'))
# /org/bluez/hci0

Related

What is bluez "bluetoothctl scan on" (StartDiscovery) doing that "hcitool lescan" is not

I see its adding a file to /var/lib/bluetooth/hci MAC/cache/ for each discovered device with its name as the address. Documentation says its creating device objects. Where and what are they, virtual dbus objects? ( ex: /dev_F8:41:1B:6B:95:2A). I know the device is removed after 3 minutes if not connected. And what else is it doing to make a device available for connecting with the bluez dbus interface. Thanks.
Bluetoothctl uses the Bluez DBus apis to do everything it does. When you do 'scan on' in bluetoothctl, it will call the StartDiscovery method of the Adapter object. Internally the Dbus will use the HCI interface to start a lescan. Once advertisement come in, Bluez will create objects for them on the Dbus and will send an InterfaceAdded or PropertiesChanged signals on the Dbus. Your application can listen to those signals which contain the address of the objects they are about.

Can webusb connect a website to a Kmtronic Usb one relay device in a ChromeOs chromebox?

Hi I am trying to give a website direct on/off control of a usb relay on a chrome os device. In the past I just used some terminal scripts to run on start-up on a ubuntu device but chrome os is giving me a hard time making this work.
Based on the sample Linux code it looks like these devices are using an FTDI USB serial chip and support a very simple set of commands to turn the relays on and off. The FTDI chips are supported by ChromeOS and so you can use the Web Serial API to control the device like this:
let port = navigator.serial.requestPort();
await port.open({ baudRate: 9600 });
let writer = port.writable.getWriter();
writer.write(new Uint8Array([0xff, 0x01, 0x01]); // Turn relay on command.
await writer.close();
await port.close();
This is a very minimal example. You can improve this by passing a filter to requestPort() to select only the USB devices you want. You also don't need to request permission every time. You can call navigator.serial.getPorts() to get a list of ports that your site already has permission to access.
See https://web.dev/serial and https://wicg.github.io/serial for more information about how to use this API.

Imitating specific USB device

I recently got hands on an workout device which has a USB to PC interface and logs workouts on a lousy Windows Application. My intention is to read out the USB and build a custom application for presenting that data.
When connected to a linux machine the device registers in /dev/ttyUSB0, can be seen with lsusb and stty reports the baudrate among other information. I fire up minicom with the stty settings and as soon as the workout is initiated the device sends a series of 41 bytes
I assume that those bytes represent an announcement to the the PC interface.
What I would like to do is to imitate the workout device and send those 41 bytes to the PC interface myself in order to see what the PC side does upon initiation. Is there a way to imitate the device so that the PC software will recognize it?
if the device is /dev/ttyUSB0 it is very likel implementing a virtual COM port, this is USB Communication Device class CDC (ACM).
the operating system knows what driver / kernel module it has to load because when you plug in the device in USB protocol descriptors are exchanged ( the device sends its device descriptor to the host, according to this the host loads the driver / kernel module ), you can see this information with lsusb -v. Specifically the device sends the following descriptors to the host : device descriptor, configuration descriptor, interface descriptor, endpoint descriptor : http://www.beyondlogic.org/usbnutshell/usb1.shtml
for imitating a device you have to write a firmware on a MCU with exaclty these descriptors and additionally with identic VID ( vendor id ) and PID ( product id )
the 41 bytes you receive flow over the virtual COM port and so in RS-232 protocol ( you are able to receive them with minicom ) and so they are above USB level, however they are part of the payload in USB packets. if you have a proprietary driver in windows of your device in windows these 41 bytes are very likely addressed to the driver ( whichs source code you very likely do not have ...). this is very common there are multimeters with RS-232 interface and one has to send a D = 44 (hex) = 01000100 (bin) to receive any data
so you can try to sniff the virtual COM port ( RS-232 protocol ) directly using a RS-232 sniffer, i.e. https://www.eltima.com/rs232-sniffer.html
alternatively you can try is to sniff the underlying USB traffic with wireshark ( or usbmon in linux ) and extract the payload from the USB packets to record the communication between the windows driver and ther device
https://ask.wireshark.org/question/36/how-to-capture-usb-packets-please/
https://www.youtube.com/watch?v=EfkC7kmIMt8 ( USB in Wireshark )
https://www.kernel.org/doc/Documentation/usb/usbmon.txt
( https://www.kernel.org/doc/html/v4.13/driver-api/usb/URB.html )

What's the difference between Jackdaw and KillerBee on RZ Raven USB Stick

What is the difference between Jackdaw and KillerBee on ZigBee USB Stick, both seem to be sniffing packet, but Jackdaw can act as a network interface, and KillerBee is only used for pentest? As far as I understand it, you can't use either to connect to like a hub or Wireless router, but only to ZigBee based devices, which would be the IoT devices such as sensors or smart socket etc.
Thank you

In PiTooth.py program after pairing from a second terminal, the program in the other terminal is still "waiting for connection"

I followed this tutorial for emulating my Raspberry pi model B as a bluetooth Keyboard. I am able to identify the pi as a keyboard when searching for connection.
The pairing part is working fine also, I am using the following command for pairing:
sudo blue-simple-agent hci0 <mac address>
The tutorial asks to run the PiTooth code in one terminal and it will initialise the required ports (control and interrupt ports), read the SDP record, advertise the sdp record and it will listen for connection in the control and interrupt port. Then open another terminal and use the above command to pair with the client.
It is getting paired but it not reflected in the other terminal, which is still like "waiting for connection. The following is the part of the python code where it is listening for connection and connecting:
class Bluetooth:
HOST = 0 # BT Mac address
PORT = 1 # Bluetooth Port Number...
def listen(self):
# Advertise our service record
self.service_handle = self. service.AddRecord(self.service_record)
print “Service record added”
# Start listening on the server sockets
self.scontrol.listen(1) # Limit of 1 connection
self.sinterrupt.listen(1)
print “Waiting for a connection”
self.ccontrol, self.cinfo = self.scontrol.accept()
print “Got a connection on the control channel from “ + self.cinfo[Bluetooth.HOST]
self.cinterrupt, self.cinfo = self.sinterrupt.accept()
print “Got a connection on the interrupt channel from “ + self.cinfo[Bluetooth.HOST]
The whole code is really big and I don't like to enlarge the question. Please view this google doc for the code:
https://docs.google.com/document/d/1hEyprvN1MyFqyczL9Qh07_-pJjRvBIEkomiJhLHcXiQ/edit?usp=sharing
Can anyone help me solve this issue. Or is there any problem with the code. Is there any alternative ways to listen for connection.
The issue is resolved. It was an out-of-box solution actually. The problem was with the operating power of the pi. The pi was powered from my laptop's USB port and it's voltage was about 4.4V. USB ports usually provide only 500 mA, 5 V. Raspberry pi need a voltage source of about 4.75 to 5.25V and current in range of 700 to 1000 mA for optimum performance. Exactly how much current (mA) the Raspberry Pi requires is dependent on what you connect to it. For reference about power supply. I just changed the source, I fetched power via a 1000 mA 5v adapter and checked the voltage in the pi, it was about 4.64V and it worked fine.

Resources