controller won't stay in sniff mode - bluetooth

I'm using the bluez stack on linux and need to put a slave controller into sniff mode. I am able to initiate sniff mode by issuing the command with hcitool: hcitool -i hci0 cmd 0x02 0x0003 0x00 0x01 0x12 0x00 0x12 0x00 0x01 0x00 0x01 0x00. The problem is that the slave always issues an exit sniff mode command immediately after I send any data on this socket. Can anyone tell me why this is happening and how I can stop the controller from exiting sniff mode arbitrarily?

This ended up being an issue with the default params for the linux bluetooth driver.

Either device is allowed to exit sniff mode at any time. This is part of how classic Bluetooth is defined. I'm guessing that your target device's controller has a policy to automatically resume active mode at a certain data size payload.
If you want a persistent connection with sniff characteristics, I suggest implementing a low energy ACL.

Related

Which BluetoothLE handle do I need to write on to enable notifications?

This is my first shot working with bluetooth and I'm confused about which channel I should be sending my write packet to enable notifications. I'm working with the Fitness Machine 0x1826 service and I'm trying to get the data from the 0x2AD2 characteristic, specifically the 0x0030 handle.
When I run "sudo gatttool -t random -b [MAC ADDRESS] -I --char-write-req -a 0x0030 - 0300 --listen" I get no response so I'm led to believe that I'm sending the packet to the wrong handle, as the device should be sending notifications with my actions.
Thanks for any help!
You should send your write packet to Client Characteristic Configuration Descriptor (CCCD), which has a UUID 0x2902. You first need to find the handle of that CCCD within the fitness machine service. You can find more information here:-
Reading Thermometer Data with BlueZ
Bluetooth Low Energy: listening for notifications/indications in linux
However, as ukBaz mentioned, gatttool is deprecated so you should look into using bluetoothctl instead. More information on using bluetoothctl as a gatt client is found here:-
bluetoothctl write on descriptor to enable notification
Using acquire-write and acquire-notify in bluetoothctl

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 )

Packet "0x71" transmitted by iPad over control channel in HIDP Bluetooth connection

iPad is transmitting a 0x71 packet immediately after connecting over the control L2CAP channel in a Bluetooth HIDP connection.
Unless I respond with 0x00 byte immediately, over the same channel, iPad disconnects.
What does 0x71 mean? I cannot find this byte in HID specification nor in Bluetooth HIDP specification, although I might just be searching poorly. I have some indication it might be the set_protocol packet, probably setting to REQUEST protocol as opposed the BOOT protocol, but I can't confirm that.
I don't think it matters much that I'm connecting OS X machine with the iPad, with OS X machine serving as the server, but I'm noting it here in case it does.
0x71 means "SET_PROTOCOL for Input reports". One can choose between Boot mode (0x70) and regular mode (0x71). See 7.4.6 of the HID_SPEC_V10 from Bluetooth.org for more details.

Coding for Ethernet PHY Loopback Test

I have to write a Ethernet PHY loopback test in Linux. I've never done it before and had no clue where to start. After some researching, I came up with the plan for the test, and I wonder if anyone can help me to verify it and give me some pointers to my questions.
This is a external loopback setup. It connects the TX+/- to RX+/- pins for each internal PHY's on the Ethernet switch chip.
So the loopback high level packet path is as follow:
CPU->PHY0(chip)->Ethernet switch(chip)'s internal PHY->PHY0(chip)->CPU
For this test, I plan to
configure the internal PHYs on the Ethernet switch with specific MAC addresses,
pack the Ethernet test packet using CPU's MAC address as the source address and the
MAC address configured in step 1. as the destination address,
send and wait to receive the test packet,
compare sent and received data pattern.
Any suggestions? Also, I wonder if there are functions in Linux that I can use to generate the packets for step 2, and send the packets for step 3.
Thank you very much.
Most Phys can be switched to a test mode. We used the bootloader to write directly to the
Phy and switch to testing mode.
There is also an ioctl taken from documentation/networking/phy.txt
Ethtool convenience functions.
int phy_mii_ioctl(struct phy_device *phydev,
struct mii_ioctl_data *mii_data, int cmd);
The MII ioctl. Note that this function will completely screw up the state
machine if you write registers like BMCR, BMSR, ADVERTISE, etc. Best to
use this only to write registers which are not standard, and don't set off
a renegotiation.

USB Keyboard Protocol

I am trying to build an HID keyboard. I got my STM32 MCU to recognize as a keyboard, but for some reason when I try to send the HID report (8 bytes) using Endpoint 1 in Interrupt mode. The host side doesn't get the data(key pressed) . Do I need to use the standard method Get_Report ?
I have also tried another implementation on a AT90USB1287. It works well but for some odd reason I must set the endpoint to 3 in order to get it working.
i am wondering if the USB HID keyboard protocol only looks at end point 3 when getting data?
The USB HID (keyboard) protocol uses the endpoint you specify in your USB descriptor. Look at the Endpoint address in the Endpoint descriptor.

Resources