How to scan available WiFi access points while in master mode in Linux - linux

In Linux, when the wifi interface (wlan0) is in "Managed" mode, we can run the following command to scan available WiFi access points:
$iwlist wlan0 scan
But this command stops to work when the interface is in "Master" mode:
$iwlist wlan0 scan
wlan0 No scan results
Is this a hard constraint of WiFi chip, or a limit in Linux software?
Is there a way to scan for available WiFi access points while the current interface itself is in "Master" mode, i.e. itself is an Access Point.

Very good question. Results of some minor research on the matter are as follows.
https://elixir.bootlin.com/linux/latest/source/net/mac80211/cfg.c#L2439
In ieee80211_scan() one can notice that the function tests NL80211_FEATURE_AP_SCAN flag in the set of features advertised by the underlying wireless device driver. That effectively means that, indeed, it's a constraint, but it's likely imposed by the specific vendor / driver / device rather than by Linux generic code.
https://elixir.bootlin.com/linux/latest/C/ident/NL80211_FEATURE_AP_SCAN
One may try to search for the said feature flag among the available wireless drivers. For example, my Wi-Fi card needs ath9k driver, and I don't see the latter in the list of drivers that advertise the said feature. Hence, my Wi-Fi card can't scan while in AP/master mode. Indeed, when I run (as root) iwlist dev_name scan or iw dev dev_name scan, I observe very similar output (Interface doesn't support scanning : Operation not supported and command failed: Operation not supported (-95) respectively).

Related

How can I check if the FPGA device is connected to the server?

For some reason, I can only remotely control a server containing FPGA (Intel Arria 10 GX FPGA). But when I use the command in Intel OpenCL for FPGA to find the driver, I cannot find the FPGA device that can be used.
The command is as follows:
aocl diagnose
Output result:
enter image description here
Later, I used hardinfo to check whether FPGA is included, but unfortunately there is no useful information.
The only thing related to FPGA is that I found two files about fpga under my server (Ubuntu16.04). Since I am using FPGA for the first time, I don't know what this file represents.
enter image description here
In addition, due to network problems, I have not yet been able to install OPAE for testing. I would like to ask if there is an easy way to verify whether the FPGA is successfully inserted into the server.
You can check with lspci | grep "FPGA". The lspci command lists all devices connected to a PCIe slot, whether a driver is installed or not. If you find the FPGA in the list of devices, it is installed in the PCIe slot on the mainboard.

Can a USB 3 Host machine be programmed as a USB 3 Peripheral (or a HID keyboard)?

What I want to do:
An AI program on a host machine, reading inputs from a camera sensing the screen of the target machine and outputting controls to the target machine via USB connection--programming the host machine's USB host as a USB peripheral connected to the target machine.
What I want to do step by step: (is it possible to implement the steps below?)
Have a host machine A and a target machine B.
Connect A and B with a USB 3.0 Type-A male-male cable.
The USB connection shows up as an HID keyboard device on B.
Write code to simulate key presses on A that sends to B.
(Eg. calling press('F') on a program running on A would type F to B's input)
It shouldn't require any program installed on B.
What I already searched:
USB 3.0 Host to host connection is possible:
https://superuser.com/questions/795053/how-do-i-connect-two-computers-using-usb-3-0
USB 2.0 Host to host connection is impossible:
https://superuser.com/questions/99274/how-to-connect-two-computers-with-usb
Similar questions asked without the assumption that USB 3.0 Host to Host connection is possible:
https://superuser.com/questions/1128365/simulate-usb-keyboard-from-machine
Setting up a computer to act as an HID device connected to another computer via ps/2,usb or another wired connection
https://superuser.com/questions/507921/computer-to-act-as-keyboard?rq=1
Suggestions in ascending order of feasibility:
USB Gadgets
You are using linux, so the default way would be to create/configure/load a gadget driver. Have a look at this tutorial, though for a raspberry, should work on your PC too. However, I could not find any information regarding the use of USB3 - the tutorial assumes your host is using one of it's OTG ports, which your PC most likely does not have. So whether this works with your USB3.1 Type-A-to-Type-A connection you'll need to test.
USBIP
The idea of sharing USB devices (not just keyboards) is not really new. With USBIP you can "export" any local USB device to the network, and your client will need the client-side USBIP driver to access the keyboard.
Dont bother with USB at all, just use Ethernet
I'd simply write two userland scripts/programs that send/receive+execute the keystrokes. Very easy to implement, you're probably familiar with python anyway.
If you absolutely cant have software installed on the client-PC and your Type-C-to-Type-C connection doesnt support USB Gadgets, there's another way. It basically involves the use of two USB-to-serial adapters (~15$) and a serial cable. While this wont be enumerated as a keyboard, but rather as serial port, it's the lowest-effort solution to transfer data without additional software on the client. Both computers will just do file I/O. If your computers still have COM-ports, you can even omit the serial converters!

How to detect when a usb cable is connected/disconnected on the device side in Linux 2.6.37?

I have a embedded device that runs linux 2.6.37.
I want my application to know when the USB is connected.
Currently I can achieve this by pooling
/sys/devices/platform/musb/musb-hdrc.0/vbus.
However this approach does not distinguish between a USB charger or a USB host.
I found this udev approach but I don't think it's available in my version of the kernel. because I did not find any USB related nodes in my /dev. This discussing also shows that it might not be feasible, ether.
I also found linux hotplug and tried the netlink example, but I didn't see any output running the example when I connect/disconnect the USB cable.
What I want to do is to detect connection type on the device, when USB is connected, and prepare (unmount file system) and switch to g_file_storage if device is connected to a host, and do nothing if device is connect to a charger.
How shall I achieve this?
To achieve that, you can use the inotify(7) feature, available in all linux kernels to be awaken as soon as some device node gets created in /sys.
To know what type of device you have, you have to read the usb info from proper usb ioctl call (or if you are not a kernel interface expert, using the libusb interface) to get the device vendor, device id and device class fields coming from the device. Normally, the hotplug software gets informed on these clase of events (via a special socket). The most probably reason you don't get the device properly initialized is some misconfiguration in the config files for udev system, which normally has one entry for each possible device vendor/device id pair and allows it to load the appropiate device driver to control it. The process continues with the device driver module creating dynamically the actual devices, and they'll appear in the /dev/ filesystem as a consequence of some other kernel event to udevd.
Read apropiate documents in <linux_src>/Documentation (this directory directory belongs to the linux kernel source code, so you'll probably need to install it), and udevd(8) man pages to be able to add a new usb.
On 2.6.37 kernel, this could be done by polling
/sys/devices/platform/musb-omap2430.0/musb-hdrc.0/mode
If handshake with host is successful then it will read as "peripheral", if fail it'll be "idle".

Use a Linux Computer as a USB Coupler

I am on debian and:
I have a USB controller hooked up to a USB port on my PC (Device 1).
I have a male to male USB cord hooked up to another port on the PC that connects to Device 2. (it is a "bridging" usb cord, and has the chip for it)
I want to make them connect to each other as if they were one cord, so neither device knows that there is a computer in the middle.
This would be called a 'Coupler', except that I am using a PC as a coupler.
Here is a (really bad) diagram I made:
What I have done:
I have been able to connect the two devices independently of each other and sniff the results for when they fail to connect. The devices don't send a large volume of data back and forth.
Maybe there is some kind of command tool that I could use, for example (psudocode):
$ couple-usb-ports PORT1 PORT2
You're trying to reinvent the wheel here.
You might consider looking at this link instead.
http://dan3lmi.blogspot.com/2012/10/sniffing-usb-traffic-different.html
Specifically this.
Windows: You cannot directly capture raw USB traffic on Windows with Wireshark/WinPcap, but it is possible to capture and debug USB traffic on a virtual Windows machine under Oracle Virtual Box.
You cannot use a simple PC as transparent USB sniffer without extra (expensive) hardware. An USB bus has always one host (and one or more devices), and the PC can only be the host. This is a hardware limitation.
But you can capture USB data in a Windows machine using Wireshark and USBPcap, eliminating the need for the middle box in most cases.
As this post is tagged Linux, I suppose the controller PC is a Linux machine. Instead of connecting USB ports with a male-male connector, which is all kinds of bad (you are connecting the 5V lines of both machine with each other!), just run Wireshark in the controller PC.
There might be a little work to be done previously, as you have to enable Wireshark for USB monitoring (Particularly in Debian, this is disabled by default), and you might have to install a small driver to enable the monitoring. Have a look at this page for more information.
Once you get it working, Wireshark is an excellent tool for this!

Getting WIFI signal strength- seeking the best way (IOCTL, iwlist (iw) etc.)

I want to scan the signal strength received from 3 AP.
I would be happy if that could happen every 300ms (max.500ms). I flashed OpenWRT on the routers.
I was seeking for a good tool to do that.
First I found iwconfig which worked, but only with networks that I was connected to. So I used iwlist (iw didn't work- maybe I need to update it?). Do you know how accurate is the output of it? Can I trust it?
After that, I came across the IOCTL. It looks really powerful* and professional. But is the output from getting the signal stregnth from a WIFI more reliable than the simple method like iwlist/iw?
*even too much powerful as I failed to compile any program I wrote using it
If you want to determine the signal strength of WLAN access points to which you are not connected, scanning is the right way.
The scanning is performed by the wireless network card with much or little "help" from the driver, depending on the design of the wireless card. There are cards (chipsets, to be more specific) that have their own processor and run their own firmware code independently from the host computer. On the other end, there are "stupid" cards where the driver on the host computer does most of the work.
Between the driver and the rest of the operating system, there is an interface (API) for sending commands to the driver and reading back information in a standardized way. With Linux, there are at least two different APIs. The older one is named Wireless Extensions, and the newer one is named cfg80211. Normally, a driver supports only one of the APIs. Most current drivers use cfg80211, but there may be older drivers that still use Wireless Extensions.
For each of the two APIs, there's a user-space tool (or family of tools) to use it. For Wireless Extensions, there is iwconfig (and iwlist, iwpriv etc.) For cfg80211, there is just iw.
So, the questions about the right tool depends on what API the wireless driver uses. To add confusion ;-), cfg80211 does some emulation which allows you to perform some Wireless Extension calls to drivers that use the newer cfg80211 API.
Regarding your questions about ioctl(): This is a generic method for communication between user-space and kernel-space in Unix operating systems. The old Wireless Extensions API uses ioctl(). The newer cfg80211 API does not use an ioctl()-based interface, but uses nl80211 instead.
To sum it up: whether to use iw/cfg80211/nl80211 or iwconfig/Wireless Extensions/ioctl depends on the driver or your wireless card.
Regarding your desired scanning interval, I would say that 300ms is rather short. This is because for a useful scan, the client needs to leave its current channel for a short time, switch to another channel and listen to signals from other access points on this channel. Since leaving its channel interrupts communication, these off-channel times are usually kept short and are carried out infrequently.
Calling iw <dev> scan or iwlist <dev> scan, respectively, will not necessarily cause a new scan, but may return an old (cached) list of access points. Depending on your wireless card/driver it may be (im)possible to enforce a new scan.

Resources