Get node name given to a USB by ACM Driver - c

I have two usb devices that are recognized by the ACM driver and I’m developing a program in C to communicate with them. As the command for each one are different, I need to know the name given for each one (usb/acm/X).
How can I get this name given the vendorId and productId? I have tried parsing dmesg text but in some cases I may have the two lines “ttyACMX: USB ACM device” one after the other.
I could parse the order each device shows its name in dmesg and take the same number in the “ttyACMX” but this force me to parse also the disconnections messages and all becomes a bit dirty.
I’ve seen that the information I need is in the structure tty_driver created for each device and I’m sure I can have this information easier than parsing dmesg.
Can someone point me out int the right direction?

libudev (C) might be a solution, also have a look at the source of ModemManager daemon (C, glib based)

Use libudev or some higher-level library like gudev (GLib-based libudev). Don't use ModemManager unless your devices are really mobile broadband (2G/3G/4G) modems.

I found this thread to be helpful: http://forum.pololu.com/viewtopic.php?f=16&t=6741
You can make a udev rule file in /etc/udev/rules.d that has a rule like this:
KERNEL=="ttyACM0", SUBSYSTEM=="tty", SUBSYSTEMS=="usb",
ATTRS{idVendor}=="1ffb", ATTRS{idProduct}=="008c",
ATTRS{serial}=="00053419", MODE="0666", SYMLINK+="TTYS_002"
I think this will make a device named /dev/TTYS_002 when you plug in a CDC ACM device that has the specified vendor ID, product ID, and serial number.

Related

How do I get PID from socket port on Windows?

Given a socket port how do you find the process ID (process name) of the process on Windows 10 that uses this port? I am aware of netstat command but I would like to do it with C code only.
How about there, it appears there's a way: the IP Helper library.
Ref: https://learn.microsoft.com/en-us/windows/win32/iphlp/ip-helper-start-page
I haven't used it for this, but it's clearly going down the right road by providing everything you need to basically roll your own netstat.exe.
The low-level object that contains all the info is MIB_TCPROW2, which has the local and remote address + port, plus dwOwningPid. So we know there's a way.
Drilling down we ultimately need the GetTcpTable2() call, and Microsoft's web page helpfully has what appears to be fully-functional C code to do all this yourself.
https://learn.microsoft.com/en-us/windows/win32/api/iphlpapi/nf-iphlpapi-gettcptable2
Finding this was the best surprise of my day!

Implementation of linux char driver with multiple parameters to access

I am writing a simple char driver which accesses a PCI card. It is registered to sysfs with the help of a new class and accessible under /dev/foodev. Using standard file operations I can perform simple read and write operations to the device.
My problem: I have multiple parameters stored at different addresses on the card (version, status, control, ...) which I would like access independently. Currently having only one read and one write function I therefore have to change the address every time again in the driver code.
Obviously there is a more convenient way to implement this. I stumbled about the two following approaches and was wondering which is the better one in terms of sustainability and user accessibility:
Using ioctl commands setting the address/parameter before an
access.
Having the device already nicely set up in udev using multiple attributes
(device_create_file()) of which the user than just can write/read from
different "files":
/dev/foodev
../version
../status
../control
I think you should take a look at the PCI framework to implement your driver.
Don't (mis)use ioctls; you'll have race conditions. Use the attributes as files. That scheme is already used in sysfs. E.G. look at GPIO LEDs and keys. – sawdust

libudev monitor, filtering on KERNEL

in real-time I want to print out hot-plugging events on Harddisks only. My code does print out all events for the correct "devtype"("disk") and "subsystem"("block"). However this includes devices I don`t care about such as loop devices, cdrom devices etc I only care about raw disks (e.g /dev/sda and not partitions like /dev/sda1). Is there a ways to filter from within libudev on something like that? in udev rule speak this is called "KERNEL". In essence I want to show all new devices that would match a udev rule like this:
KERNEL=="sd*", ENV{DEVTYPE}=="disk"
this would only match raw disks. like /dev/sda.
Now my program can match against devtype and and subsystem by using the
udev_monitor_filter_add_match_subsystem_devtype(mon, "block", "disk");
libudev call.
now this however still prints out changes to devices such as /dev/loop* or /dev/sr* which I don`t want.
is there a way to filter on KERNEL?
edit:

Verifying CRC using airpcap and pcap

I'm writing an application in C using airpcap and pcap libraries. I want to ask if there is a ready function to check the CRC (FCS) of received packets or whether it must be calculated manually. In airpcap's Control Panel you can setup the FCS filter.
One of the functions of the application will be something similar to site survey. I want to ask how to list discovered networks in order not to duplicate them. Compare the ssid or maybe there is a simpler way; is there some parameter which is unique to a network?
First I would check whether the driver is providing the OS with the invalid frames. If your driver is capable of providing these invalid frames - then the rest is up to you. Checking the code of aircrack-ng (or a different tool) should give you an idea.
Side note for site survey: I would focus on identifying different BSSIDs which should give you idea about the radios in the neighbourhood. Same SSID can be used for many overlapping BSSes (of course at some point you'd be needing it as well). Have a look at the different 802.11 frames (start with something easy - like Beacon Frame).
Wireshark has a CRC-32 function that it uses to check Ethernet and 802.11 FCSes when available; check out its Ethernet and 802.11 dissectors. It's licensed under the GNU Public License, Version 2.

Linux device model: Same device but different drivers

I'm customising Linux for an ARM9 Atmel AT91SAM960 board.
In the device file Atmel named all the USART the same atmel_usart. Of course with id enumeration:
static struct platform_device at91sam9260_uart0_device = {
.name = "atmel_usart",
.id = 1,
.dev = { ...}
}
According to the Linux Device model, all these devices (5 UARTS on a SAM9260) would be bind to the driver named atmel_usart.
I don't want to set a TTYS driver on all UARTS which will be registerd. I have several own drivers which serve for different specialised purposes (LON, RS-485 etc.) I want the control which driver does serve a certain USART. So what could I do:
The Atmel device files are unsatisfiable and I can do it better. So I rename (patch) the devices in the device file. However, in case I want a TTYS driver on UART4 I would be in trouble.
I manipulate (patch) the device file,
so that I'm able the access the
structures platform_device. I could
change their names before I would
register them. But as far as I
understood the idea of the Linux Driver Model,
devices should be
registered early during boot-up but the binding to a driver follows .... later.
I could write a driver, which has an
alias name and which would be binded
to a specific bus_Id ->
atmel_usart.4. Can I really?
What solutions else exist. I want to touch a minimal set of Kernel files but I want all the freedom possible?
Addendum what freedom means to me: I can specify at runtime how the UARTS can be used
with the Atmel-Serial driver (ttyS)
with my own drivers
It means also, that changes to the kernel source are minimal.
I built my own line discipline drivers. You can build them as kernel modules and attach them to the UARTs at runtime. No changes to the Linux source are necessary.
Any funny timing or control stuff can be done through ioctl(). Specifically, I implemented a timing-sensitive RS-485 protocol in this way.
When I did this (Linux 2.6.17) there was no dynamic registration mechanism, so I overwrote the existing line disciplines. The Linux code is (was) pretty straightforward, and I was satisfied that this would be a safe thing to do.
Your problem is quite easily solved. The 5 UART devices are presently registered at kernel startup and their function is locked. This is now how it normally works for PCI or USB devices, right? So what you need to do is pull the device registration out of the startup code and register it dynamically. You can even register/unregister as needed.
at91_register_uart() is being called from your board file for every UART that needs registered. at91_add_device_serial() will then platform_device_register all those you what setup. One solution is to let at91_register_uart() be called for all 5 UARTS, but then remove the call to at91_add_device_serial() from your board. You can then make it an exported function that can be called by your loadable drivers. You can even add an argument to it (int) so that instead of looping on all UARTS, you can select which ones to register individually. You can also mirror this function by making one that unregisters the devices.
NOTE: I think you'll need to always leave one UART dedicated as your console, if you are using one that way. You could probably hide that in the exported function by only allowing index 0->3 as in input and then mapping 0->3 to 0-4, skipping the UART that you want to use for console.

Resources