How to configure libnfc to use a specific device? - raspberry-pi

I have a Raspberry PI with two NFC readers attached. Problem is that the readers get different device numbers each time the system reboots or a reader is detached and attached again.
I therefore created udev rules that create a fixed device name depending on the physical port a device is attached to. E.g. plug in NFC reader in the upper left port leads always to /dev/nfc_a and plugged into the upper right port leads always to /dev/nfc_b.
How can I now configure libnfc to use these devices and report the device names such as /dev/nfc_a as a part of the reading? I am using Node-RED with node-red-contrib-nfc (https://github.com/hardillb/node-red-contrib-nfc) on top of libnfc. My ultimate goal is to safely distinguish the two readers within my Node-RED flow to act differently upon the readings.
I already found the "connstring" configuration but I don't know how to correctly set it for using /dev/nfc_a.

It's been a LONG time since I wrote this node, but looking back at the nodejs library it's based on (nfc) the output message should contain a field called deviceID which should indicate which NFC reader triggered the input.
When I run on my machine I get:
deviceID: 'pn53x_usb:001:005'
Where 001 is the USB bus id and 005 is the device ID, which matches up with the output from lsusb. These should stay static as long as the readers are always plugged into the same USB sockets.

Related

Flutter and Iot devices

I am currently building an app that controls a single actuator and a LED strip. The controller for the actuator and LED strip is based on an ESP32.
On the ESP32 I have used the <ESPAsyncWebServer.h>, <ESPAsyncWiFiManager.h> to set up and connect the ESP to the local wireless network. In the app I would like to send some commands to the ESP like http://<ESP32_IP>/led_set?level=<level> and
http://<ESP32_IP>/act_open and so on, this shouldn't be an issue.
Normally I would set up mDNS on the ESP and in the Flutter app, however several of the ESP controllers are already shipped to the customers. So I am looking for another way to identify the ESP.
At the moment I have used the ping_discover_network library and the ESP shows up fine on port 80. I am however not able to separate the ESP from the other devices that shows up on port 80.
Do any of you have any suggestions?
Thank you in advance
You don't have many good options. If you only want to identify a few devices which have slipped through your fingers without mDNS, you can use their MAC address as a filter. If you happen to know their individual MAC addresses, then that should be quite painless. Otherwise you'd have to look for devices with MAC OUI (first 3 bytes, usually) ranges allocated to Espressif. Espressif has several OUI ranges, but if your devices were from a single batch of ESP32 module of the same type, they'll be using the same OUI so it should be quite easy to figure out.
E.g. a batch of modules I have all start with 40:F5:20:...
Of course, if a third party installs their (unrelated) ESP32 module into the same network, you'll have a chance of identifying those as well, but such is life.
This is obviously a stop-gap measure. Make sure further devices go out of door with some identification (mDNS or otherwise).

Why does the driver request the USB device to send the USB descriptors?

As far as I understand the USB devices introduce themselves by sending a device descriptor to the host which uses the information embedded in the descriptor to find and load the right driver/drivers. What I don't understand is why the drivers need the configuration, interface, endpoint and string descriptors from the device. I know the descriptors describe the device as a whole e.g. number of configurations, interfaces, endpoints, types, the size of the packets, the purpose of each byte in the packet etc. Why can't the drivers include this information from the start? Why does the USB device hold this information?
I guess the main reason is because it was designed that way. The designers could just as easily have gone the other way as you say.
Possibly more helpfully, I can think of a few reasons why they did decide on it this way:
Consider the context in which USB came about. PC peripheral connectivity was a mess. You had serial (UART) ports, PS/2 keyboard & mouse, parallel ports in various modes (e.g. ECP and EPP), game port & MIDI, the various SCSI variants, etc. Most of these did not allow for self-describing devices in a standardised way, demanding custom drivers for each type of device, and mostly manual driver loading. Device descriptors alone would mostly solve the problem of selecting the correct driver, but not necessarily the issue of needing a custom driver for each device.
Various standard device class specifications (e.g. HID, audio) define their own class-specific descriptors for communicating device variations to the standard driver. For this reason alone the generalised descriptor mechanism is useful.
Composite devices in their present form would effectively not be possible without standardised interface descriptors. You'd presumably have to make each composite device act as a hub with multiple devices attached.
Many (most?) standard device class specifications mandate a certain minimum number of endpoints where the standardised protocol is implemented, (e.g. bulk-only USB mass storage defines 1 bulk input and 1 bulk output endpoint) while devices are free to add more for vendor-specific extensions, or…
…future expansion of the standard device class or USB standard itself while maintaining backwards compatibility both ways (old driver/new device, new driver/old device). Think of UASP devices that fall back to regular bulk-only mass storage transport.
While not strictly necessary for making all those things happen, making devices self-describing in this way does seem to have been a success overall.

How to test the actual presence of platform i2c device in driver's probe() function

I am writing an I2C bus driver. I have tested it on one external module I have plugged in my system (video card module) and it works. I have specified the i2c device (frequency, registers etc.) in device tree.
I would like to specify the rest of devices which will be using the driver in device tree as well. However, if I do that and the device is currently not present in the system, kernel fails to initialize. I guess this happens because in my probe function, I am setting up the frequency (which gets set up by writing to I2C register of that device - FPGA) and since the device isn't there - it just fails.
How should I solve this issue. Is there a way to check the actual physical presence in probe function without kernel failing? Or should I move the code that sets up frequency in another function that happens after ".master_xfer" when I'm reading/writing. The second option just seems like waste of resources. Another thing I had in mind was after I use open() to access the device in user-space, I should set the frequency in user-space as well. But I would really like all of this to happen inside the driver if possible. I'd like the frequency to be set after open() happens in userspace but for the code to execute in device driver code because there I access the register range specified in device tree. Maybe I could find where open() happens, check the ID of I2C device, than get the registers and do it there?

Extending Wifi/WLAN Range with one NIC on a Laptop

I plan to extend the range of my Wifi with my Notebook. - My question to this, is it possible to build a wireless repeater with only one NIC? or do I really need at least two NICs, one for being logged in and receiving the packets and the other for extending the WiFi/Signal. - Actually, what I wanna do is, using my laptop as a WiFi-Repeater, but only with the built-in NIC, no second one.
I've searched the net already but found nothing about the functionality of a WiFi-Repeater and if they have two NICs integrated.
Hope you guys can enlight me ;)
EDIT(added schemes):
Possibility A
Possibility B
What can be achieved with an AP capable Chip/Firmware, for instance, the Ath9k.
You can't turn laptop's WiFi into range extender, since I believe it requires a special WiFi chip firmware and a special configuration of antenna(s).
However, you might try to look on the internet if WiFi chip you have supports AP mode in firmware (not all manufacturers provides that), and if yes, you can set up the access point with the same SSID. In this case your WiFi clients will roam from one AP to another. Of course, this kind of setup requires Ethernet cable attached to your laptop.

Does any interrupt occur when a usb device is connected?

I am working on USB HIDs on linux platform. Keyboards, mouse etc., are examples of Human Interface Devices. Whenever a HID is inserted to a system, at first device enumeration occurs. Then an entry in the form of hidraw appears in the /dev directory.
In linux, "usbhid and hid" are the modules which are called when an HID device is inserted. When I disabled these modules (using rmmod and system restart), the devices were not enumerated and no hidraw entry appeared on /dev(as expected).
Now my question is there any way to know if any USB HID device is connected to a system with the above two modules being disabled i.e does any interrupt or signal generate upon hardware insertion.
I am planning to execute some code when such signal or interrupt occurs(in C). Any kind of help is appreciated.
Thanks,
Insertion of the device is detected through the voltage level changes occuring on the D+ and the D- lines. I do not think that insertion of USB device generates any interrupt. The voltage level changes are read by the hub(root or any hub further down on the line) and according reported to the core.
The USB core driver would be notified about the same. So may be you can write a user-space driver which targets a specific device (using Vendor and Product ID) and through this you can carry out your functionality.
If you are doing this in user mode, you get get a notification using udev (which use netlink internally).
You can match a device using the vendorId and productId field in the rulefile.
SUBSYSTEMS=="usb", ATTRS{idVendor}=="abcd", ATTRS{idProduct}=="1234"