C program stalls when the serial device's path changes - c

In Linux I am running in the background a program written in C, which periodically communicates with a device connected to one of the USB ports. Although the device is always plugged into the same port, over time it switches from /dev/ttyACM0 to /dev/ttyACM1 and back, even when no other devices are connected. Consequently every time a switch occurs, I have to restart the program.
To cope with the problem I have tried setting up a UDEV rule for a new symlink and the the symlink works regardless of the changes in the connected device's path. However, when the switch occurs, the program still stalls and needs to be restarted.
Is there a system rule I can implement for the device to keep the same path at all times, or is there another more general approach?

First approach (easier):
If you have access to the other's device code, I would implement a ping message from it.
Then, I would listen for that ping message, on both tty devices, to see on which port it is received (/dev/ttyACM0 or /dev/ttyACM1).
Second approach:
On a separate thread implement an UDEV monitor.
The monitor checks which TTY port is used by your device.
In case of a port change, just reinit the communication thread...
See udev_monitor_usb.c for a udev monitor usb code.

Related

C UART not working all the time

I'm having an issue connecting a serial device to an embedded device I'm writing code for.
The device I am writing has two serial ports, an incoming from my laptop, and an outgoing to an external device.
When I connect both terminals to my laptop and view the data, I get exactly the data I am expecting.
When I connect my laptop to the external device directly, I am getting exactly what I expect, and a response.
When I connect the laptop and the external device to the embedded device I am working on, the laptop sends data to it, it receives it, it passes it on to the external device. This works as expected.
However, the external device doesn't send back the response.
If I send data to the external device from the embedded device, each new message I send allows it to send the original reply.
I know the first message got through correctly because the external device whirrs to live, and I know when it is sending the response by running and logic analyser on the tx/rx comms and viewing the traffic.
I considered that the embedded device is holding the rx line and preventing its transmission, but I don't see how that possible in the code. Also if that is the case it shouldn't work when I plug both lines into my laptop.
I also considered the DTR was not set high, but checked this and it appears to be set high.
Does anyone know a reason which would prevent a device from responding?
Note: When I say Serial Ports I am referring to the UART when referring to the embedded device. All device use a DB9 connector running RS232.
Edit: Operating System on laptop is Windows 10. Embedded device is a Atmega324p.
Edit 2: Did some more testing. It appears that it sometimes work and sometimes doesn't.
I have added an image which show a almost perfect signal of the response.
The blue section is a gap in the signal that shouldn't be there.
Ended up finding a solution.
The RTS line was held via the embedded device at 1.2v, while the Pc was holding it at 5.2v.
Pulling the RTS line up to 5v fixed the issue.

Does USB mass-storage class requires re-enumeration after timeout?

this might be a stupid question,
I was debugging a USB storage device on an ARM-CortexM4 platform (STM32F4 series) which runs embedded Linux. The ARM is working as USB host, and tries to communicate with a thumb drive in USB full speed (12Mb/s).
Now here is the problem. After successful enumeration and several SCSI commands thru BULK transfers, the capacity and everything can be read correctly. However, after about 15 seconds when I try to send these SCSI commands again (under same condition), the USB host controller just returns 'Transaction Error', which looks like the device is not responding to BULK transfers anymore (not ACKing) and the host controller times out. The question is, is there any timeout mechanism for USB mass-storage class or SCSI system such that, after a timeout the system must be re-enumerated or re-probed, otherwise it won't respond anymore?
I understand this might be due to a stupid error in my program, or due to some limitations on the specific hardware. However when I used usbmon module in Linux on a PC to capture the transfers on the very same thumb drive, I can see the operating system actually sends a sequence probing command (Read-max-Lun followed by Test-unit-ready) every 5 sec, which could be the reason why the thumb drive doesn't fail on my PC.
Thanks! I'm looking forward to any replies.
I think you're on the right track with the Test Unit Ready commands.. I am in the middle of writing a mass storage device driver for an embedded device and When testing on OS X, after the initial SCSI queries, my device receives Test Unit Ready command about once every second when no other activity is occurring. Since your post is quite old, I recommend you post your own solution if you've since solved your problem.
Otherwise try adding periodic test unit ready commands from the host side when there is no other activity.. You could set and activate a timer whenever USB activity is occurring. If the timer fires, u can send a Test unit ready command.. Rinse repeat.

Way to watch network activity of another linux process in C

I'm need to start some helper processes when web interface of mine router is being used, and shut them down after some time, if activity in webface was stopped (to save RAM when webface isn't used).
Is there any way (except prace() ) to know, when another process (server) accepted any network connection?
I'm tried to parse /proc/net/tcp for socket inodes placed in /proc/pidof httpd/fd but it is very unrelaible, and catch only full webface reloading, but not navigating over it.
Here is source I written this way:
https://dl.dropboxusercontent.com/u/100376233/zyxel/nethelperd.tar.bz2
OR: is there any way to catch only accept() syscall using ptrace() and not disturb traced process if it's called another syscall?
I would recommend that you use libpcap with a filter such as tcp port X, where X is the port hosting the web interface. Whenever you receive a packet, you can reset your timer. If the timer fires before you receive a packet, you can shut down the services. You can also reduce the overhead of this by not capturing the whole packet. libpcap allows you to specify the maximum number of bytes to capture per packet.

listening to communication between a local application and a device

I have a windows application on my PC which connects to a device over telnet. It sends a series of commands to the device, and the device responds to it.
Is there any way I can listen to what that program is writing to the device?
I tried using win32 socket programming to create a client that connects to the application. But, I get an error saying connection refused. When I analyze the traffic between the application and device on wireshark, I can see that the application uses different ports each time it reads from or writes to the telnet port(23) of the device.
Is there any way I can read the commands sent by the program to the device?
If you want to capture program's output to the device
programmatically, the right way is not to connect to the program (you
can't tap into an existing connection), but instead provide a server
that will stand for target device from the program's point of view.
It's going to work if the program can be configured to connect to the
device at different address and port. Write a "proxy" that listens on
some fixed port, and for any accepted connection, opens a client
connection to the real device. Then it should forward data in both
directions between the accepted connection from the program and the
client connection to the device. During this, you can also parse data
or do whatever you want with them, e.g. forward them to yet another
connection to another real device.

Hayes AT Commands: Detect Remote Hangup?

How are you supposed to programatically detect when the remote modem on your call hangs up? I am writing a C program which interfaces with a SoftModem device /dev/ttySL0 in Ubuntu linux. I am able to configure the modem using Hayes AT commands and communicate with the remote modem. However, I haven't been able to determine how I'm supposed to detect that the other end has hung up the line.
I have the modem configured so that when the other end hangs up, the device prints NO CARRIER and switches to command mode. However, I can't use the NO CARRIER string because I can't guarantee that the modem won't receive that string while in data mode.
How do you "listen" for remote hang up?
This is a hardware signal on modems, the Carrier Detect (CD) line. You'll need to monitor it to know that the connection was lost. Basics in linux are described in this how-to, you obtain the signal state with ioctl() using the TIOCM_CAR command.
Testing for NO CARRIER as text will not suffice. This text frequently occurs on sites in the net, even on Q&A sites.
Coming from the modem, it should be enclosed in line breaks.
Besides, after you detect that text, you can try to switch to command mode with +++. If that works, your connection persists and you can reattach it and continue using it. If it doesn't (because you are already there and +++ is an invalid command), the connection has gone.

Resources