Linux - Limit USB Device Bandwidth - linux

I am trying to connect multiple (10-20) USB Wi-Fi Dongles to a single USB port (using an external powered USB HUB), however I am not able to get more than 5-6 devices connected at the same time.
It seems that each dongle is allocating "500-800" Mbps from the total available 5000 Mbps (1x USB3 port), which does not make sense.
My question however would be if there is some way to have the USB port/hub behave as a "Best-Effort" and ignore the allocated bandwidths or simply be able to limit each device to a lower bandwidth such as 20-50 Mbps. I don't need them to perform at full speed.

I do not think it will be possible and the reasons are below.
Before going to the reason, lets discuss "Bus Instance".
As per the XHCI spec, "Each Bus Instance (BI) represents a “unit” bandwidth at the speed that the BI supports"
So each of your USB 3.0 port in the hub will have two Bus Instance. Super speed and High speed.
Bandwidth depends on the device attached. If its a USB 2.0 device, it will get at most 480 Mbps bandwidth and for SS device 5 Gbps at most. If multiple device is connected, then it will be completely dependent on the USB controller hardware to divide the bandwidth between the Bus instances.
So basically, I do not think we can do it via software. XHCI specification does not have any command to change bandwidth. We have only command to get bandwidth. Also we do not have any hub requests for bandwidth management of hub ports.

Related

BLE packet drops when Bluetooth and BLE are simultaneously in use

I am using BLE v4.1 for my application where I am able to transfer 200 packets of length 20 bytes each from peripheral to central side.
I want to transfer data via BLE and play some music while the data is being transferred. The music file is available locally and will be played on earphones(can be wired or wireless BlueTooth earphones)
I am facing an issue of packet drops around 15-20% when I am playing audio through wireless earphones while data is being transferred via BLE and audio is played on phone Bluetooth earphones(tried on Android and iOS, both) simultaneously.
With wired earphones connected; there is no issue, I can transfer data via BLE and play audio smoothly without any issue but things are different with wireless Bluetooth earphones case. I tried it with different Android phones(Android 11, different manufacturers) and different BlueTooth earphones, the issue still exists.
What could be a cause for the same and how can I debug it?
Bluetooth and Bluetooth Low Energy has only one radio that can only do one thing at a time. The connection events are scheduled and cannot overlap. This means the throughput is shared among all connected devices. You will get a higher throughput per device with only one connection than with two connections.
You will have to experiment with connection interval and connection event length to find parameters that seems to work, and test with multiple Bluetooth controllers (phones), since all have different scheduling algorithms.

Is there a way to restrict gadgetfs to Full Speed?

I have two USB devices (host and device) that both support high speed. I am trying to emulate a legacy device on gadgetfs which is full speed. The host device unfortunately complains that there is something odd when it connects to the high speed device. I cannot change anything on the host. my device is a Raspberry Pi zero W.
I can not find any way to restrict the gadgetfs device to connect (negotiate?) as a full speed device. Short term I am using a usb 1.1 hub to sovle the problem. Long term this is not a viable solution.
The only reference I have found for this is in Limit USB gadget driver speed, and I would prefer not to have go into the kernel and modify the drivers.
Does anyone have any suggestion on how I could achieve this?

Maximum number of BLE sensors that could be connected to a BLE gateway at a given instant?

I have this doubt. For example, I have a Smart Wrist Band (measures pulse, body temp), a Smart Gear/Watch (to display text alerts, control calls) and a Bluetooth headset. I need all the three to communicate with my mobile phone at the same given instant.
Is it possible to achieve the same ?
What are the challenges involved if I need to develop an application on my own if I had to achieve the above possibilities ?
Your help is highly appreciated.
Note:
- BLE has star-based network topology and maximum devices per Piconet is 8 including the Master
- Please help me in understanding/visualizing the above theory that I learnt.
Thanks.
The Bluetooth Classic has a limitation of 7 slave devices in a piconet and they are time and hop synchronized to the master ( ie master and slaves share a common physical channel and it is not possible to address more than seven slaves for a master when in Active mode).
In BLE each connection from a master to a slave operates in an independent physical channel( ie LE slaves does not share a common physical channel with the master), hence there is no limitation imposed by the Specification except as specified by the Connection interval and slave latency rules ( Note that individual bluetooth controller manufacturers may decide to limit the number of connections depending on the practical bandwidth limitation).
please see the Bluetooth Classic vs Bluetooth Low energy Topology below.
Is it possible to achieve the multiple sensors ( BLE) and Headset (BT classic) connected to mobile?
Yes it is very much possible, except that there are some BT4.0 controllers which doesn't allow LE advertisement while connected to another BLE device. please check the known limitations in a particular bluetooth controller.
It's the Bluetooth controller that has the limitation. Different Bluetooth controllers have different maximum number of concurrent connections. It's usually between 5 and 14. However Android has an additional hardcoded limit of 10 for some strange reason.
Other than this, there shouldn't be any particular challenges.

i/o Bus Standards & Device Controllers

I'm really confused about bus standards like ide,ata,sata,pci etc.
I have just read this article : 1https://superuser.com/questions/350582/when-a-disk-read-or-disk-write-occurs-where-does-the-data-go/350592#350592
So if we talk about hard disk drive; hdd logic board contains a microcontroller,buffer-ram,motor driver etc.This microcontroller communicates with the motor driver for reading and writing sectors to hdd platers.As i know a microcontroller is combination of cpu,registers,io ports,ram etc.Also there must be firmware inside the microcontroller.
My first question is how hdd microcontroller clock frequency is determined?
And according to above article why there is a word like "sata drive"? I mean if "ata" or "sata" etc. are just bus interfaces between the cpu and device controllers why "ata","sata" or "pci" words become a prefix for peripheral devices?
I really want to understand deeply about communication with peripheral devices.Above article i understood that two seperate communications occur when we want to read sectors from hdd,
first is between "cpu - device controller" and second is "device controller - hdd".So how these seperate communications work each other?
Finally if "ata" or "sata" are interfaces that just stand for "cpu&memory(dma)-device controller" communication gateway, why this interface is slower than the front side bus(fsb)?i mean if i speak for dma transfer, after disk controller reads one sector from hdd it must transfer this sector to memory right?So why these slow bus interfaces are used for communication between the memory and device controllers?

Linux writing raw bytes on USB

I've got usb cable plugged to my computer, which D+ and D- pins are connected to multimeter. I want to send some raw bytes to get some voltage.. is it possible at all?
I'm 99% sure that usb port I've plugged cable in is something like /dev/bus/usb/002
I know that there was possibility to do the same with LPT or RS232 ports.
RS232 and LPT are not bus ! USB devices need to be addressed in order to become reachable.
Maybe unloading and reloading usb driver that drive your usb host... or trying to make a reset on usb hub host...
For doing this kind of operation on usb port, you have to break usb kernel driver and whipe all addressing operation to address directly the chipset...
At all, due to USB concept, I'm not sure you may successfully hold some power state on outlet.
For playing with that kind of physical IO, two solution:
Install a low-cost RS-232 <-> USB adapter
or better
Buy an Arduino micro-controller for prototyping and development.
I'm nearly 100% sure that you can't send anything down your USB lead unless you actually have a device at the other end. If you still want to play with this, get a cheap memory stick, break the casing off it [not too roughly], and measure whilst doing a large file-transfer to the memory stick, or some such.
But I'm not sure your multimeter will show much, as they tend to be a bit slow, compared to USB rates.
USB uses pull-up / pull-down resistors on the data lines to detect whether or not a port is connected (1.5k pull-up to 3.3v on the device side, 15k pull-down on the host side IIRC). The exact connection depends on the device speed.
So if you connect an appropriate resistor, the host should attempt to start signalling. Because of the data-rate, you might not be able to see that on a multimeter; an oscilloscope would be more appropriate.
If you want to by-pass the normal USB protocol and just blindly send data, I think you'll need to get your hands dirty and write code to bypass the usual device drivers and access the USB hardware directly. Even then I'm not sure what's possible - the USB hardware is a lot smarter than good ol' LPT and RS232 ports, which might get in the way of doing this sort of low level stuff.

Resources