how to get 3g modem signal strength in c++ linux? - c++

without using AT commands how can we get signal strength of 3g modem? The gdbus object for NetworkManager don't have any method like getSignalStrength.
Network manager is locking device file preventing to use AT commands.
nm-applet was able to display signal strength in system tray. so there should be a way to get signal strength form network manager!
nmcli is command line counter part of nm-applet. Can i get signal strength using nmcli? nothing about signal strength is mentioned in its man pages.

Finally got the answer!
In c++ use libnm-glib to act on dbus proxy. From command line use..
gdbus call --system --dest org.freedesktop.ModemManager --object-path /org/freedesktop/ModemManager/Modems/0 --method org.freedesktop.ModemManager.Modem.Gsm.Network.GetSignalQuality
gives u the signal strength of gsm modem.
If MM says it cannot get signal quality while connected, it's because
there is only one AT port for all command and data. So when the AT port
is connected, no AT commands can be sent to gather signal quality.
You'll need to either get a better modem with more AT ports, or switch
to a non-AT modem, like a QMI or MBIM powered one. -- Aleksander Morgado
One can listen to org.freedesktop.ModemManager.Modem.Gsm.Network.GetSignalQuality signal using
gdbus monitor --system --dest org.freedesktop.NetworkManager --object-path /org/freedesktop/NetworkManager/Modems/0
Q. Does the proxy signals everytime there is a change in signal strength asynchonously or ModemManager polls modem periodically to get signal quality?
A. That depends on the modem being used; if the modem supports unsolicited
quality change indications, we'll use them; otherwise MM will poll every
30s for signal quality values. The property values in the interface will
be updated once we get the new values (more or less). -- Aleksander Morgado

NetworkManager uses ModemManager for mobile broadband modem control. Instead of looking at the NetworkManager DBus APIs, you can look at the ModemManager ones, which will actually expose the connection/registration details, including signal quality.
If targeting to develop an application using C++ to gather information from the modem, I'd suggest to use libmm-glib (GLib-based library) to access the ModemManager DBus API transparently (i.e. without needing to know DBus).

I was working on a homework, in which I had to determine the indoor location by means of signal strengths of access points in a building. I was using
iwlist wlan0 scanning
command in order to see get the signal strength of the access points nearby. Then I was processing the output of it in Bash and redirecting it to C++ executable file, which is easy in Bash. I hope it will help you.

Related

Qt modbus serial port flow control handling

I'm writing a small program using QModbusDevice over the serial port (using the QModbusRtuSerialMaster class) and have some problems.
One of the problems seems to be that the flow control of the serial port is incorrect. Checking in a serial port sniffer I see that a working client sets RTS on when it sends requests, and then RTS off to receive replies. When I use QModbusRtuSerialMaster to send messages that doesn't happen.
The message is sent correctly (sometimes, subject for another question) compared to the working client. It's just the control flow that doesn't work and which causes the servers to be unable to reply.
I have set the Windows port settings for the COM-port in question to hardware flow control but it doesn't matter, the sniffer still reports no flow control.
Is there a way to get QModbusRtuSerialMaster to set the flow control as I would like? Or is there a way to manually handle the flow control (which is what the working client does)? Or is the only solution to skip the Qt modbus classes and make up my own using the serial port directly?
A short summary of what I'm doing...
First the initialization of the QModbusRtuSerialMaster object:
QModbusDevice* modbusDevice = new QModbusRtuSerialMaster(myMainWindow);
modbusDevice->setConnectionParameter(QModbusDevice::SerialPortNameParameter, "COM3");
modbusDevice->setConnectionParameter(QModbusDevice::SerialParityParameter, QSerialPort::NoParity);
modbusDevice->setConnectionParameter(QModbusDevice::SerialBaudRateParameter, QSerialPort::Baud115200);
modbusDevice->setConnectionParameter(QModbusDevice::SerialDataBitsParameter, QSerialPort::Data8);
modbusDevice->setConnectionParameter(QModbusDevice::SerialStopBitsParameter, QSerialPort::OneStop);
modbusDevice->setTimeout(100);
modbusDevice->setNumberOfRetries(3);
modbusDevice->connectDevice();
Then how I send a request:
auto response = modbusDevice->sendReadRequest(QModbusDataUnit(QModbusDataUnit::Coils, 0, 1), 1);
QtModbus does not implement an automatic toggling for the RTS line because it expects your hardware to do it on its own (with a dedicated line instead).
This should be the case for most RS485 converters (even cheap ones). You would only need the RTS line if you have a separate transceiver like this one with a DE/~RE input.
If you were on Linux and had some specific hardware you could try to use the RS485 mode to toggle the RTS line for you automatically. But you don't seem to be on Linux and the supported hardware is certainly very limited.
You can also toggle the line manually with port.setRequestToSend(true), see here. But note that depending on the timing needs of the device you are talking too, this software solution might not be very reliable. This particular problem has been discussed at length here. Take a look at the links on my answer too, I made some benchmarks with libmodbus that show good results.
Enabling or disabling flow control on the driver won't have any effect on this issue because this is not actually a flow control problem but a direction control one. Modbus runs on two-wire half-duplex links very often, and that means you need a way to indicate which device is allowed to talk on the bus at all times. The RTS (flow control) from an RS232 port can be used for this purpose as a software workaround.
In the end, it would be much less of a headache if you just replace your transceiver with one that supports hardware direction control. If you have a serial port with an FTDI engine you should be able to use the TXEN line for this purpose. Sometimes this hardware line is not directly routed and available on a pin but you can reroute it with MProg.
I would like to highlight that you did not mention if you are running your Modbus on RS485. I guess it's fair to assume you are, but if you have only a couple of devices next to each other you might use RS232 (even on TTL levels) and forget about direction control (you would be running full-duplex with three wires: TX, RX and GND).

How to make interaction kext os x network filter with application?

I am writing network filter kernel extension for os x.
I want to call something like callbacks in kext.
For example in data_in function when I get a tcp packet I want to call this callback from user application. Application changes this packet and I inject it.
How to make this interaction between kext and user application?
First of all, you don't want to block the data_in callback - you should "swallow" the packet, send it to userspace, and when it comes back, re-inject it into the connection.
There are a few ways of exchanging data with userspace processes. The most convenient way for exchanging network packets is probably the kernel control mechanism, which essentially allows you to open a socket connection between a user program and your kext.
Apple used to offer sample source code, "tcplognke" that did something extremely similar, but it seems to have disappeared from their own site. Someone kindly appears to have saved it and is offering it for download - looks OK to me right now, but obviously be cautious about downloading stuff from random websites.

Create virtual serial port in Qt/C++

I would like to create a linux app which appears as a serial port (eg /dev/ttyTEST). This app will listen for commands sent to the port, and respond back.
Is this possible using Qt/C++ ? I haven't done kernel programming so I'm hoping this is possible in user space.
Everything depends on what the application using such device expects.
If /dev/ttyTEST is to behave like a real serial device and respond properly to all ioctl's that set its speed etc., then this can't be done from userspace. It wouldn't be too hard to implement in the kernel space, though.
If /dev/ttyTEST only needs to be a tty, then provide a pseudo tty.
If /dev/ttyTEST is merely to be something another application can write to and read from then socketpair() does it.
If you have control over the application's code, then you can have it check whether the device is a socket pair or a real character device, and ignore the failures of the serial-port-specific APIs on a socket.

Detect wakeup computer using C++ on linux

I don't know how can i detect that the computer has been waken up, or even I would prefer to detect wake-up on lan. I have no idea what is the common way, I found that in /etc/pm/sleep.d I can add a custom script, but i need to get invoked inside my C++ application. Now i know I could also add a custom executable written in C++ and send a socket and listen for it somewhere else but that sounds too complicated.
Your C++ application is a daemon? You may add a shell script to /etc/pm/sleep.d which should send a signal to your C++ application (SIGUSR1, for example). Inside C++ application you need to catch this signal.
see
man kill
man 7 signal
man signal
This is similar to solution with sockets but easier.

Making the application passive, which triggered by events?

I'm studying some codes about RS232 with Borland C++. The implementation of reading data from the port is polling the status of the port by timer. There are some events checking whether the status of the port changed. If the status changed, events trigger the data-reading subroutine.
However, I think that polling is so bad that much resource is spent on the action. Could the program be passive in monitoring the port without any aggressive polling or something else? In other words,
the program hibernates unless some events which triggered by incoming
data in the port activate it.
Is the idea is possible?
Thank you for reading
Best regards
I think for your requirements the design pattern named Reactor is appropriate. Reactor is based on the system call 'select' (which is available in both Unix and Windows environments). From the referenced document,
Blocks awaiting events to occur on a set of Handles. It returns when it is possible to
initiate an operation on a Handle without blocking. A common demultiplexer for I/O
events is select [1], which is an event demultiplexing system call provided by the UNIX
and Win32 OS platforms. The select call indicates which Handles can have operations
invoked on them synchronously without blocking the application process.
You can see that this pattern is encoded as a library in several frameworks such as ACE, Boost.
If you are working with the Win32 API functions for reading the serial port you can call ReadFile. It will suspend until it has the number of bytes you requested or until a timeout that you can set. If your program is a GUI then the serial read should be in a secondary thread so the GUI thread can react to any received Windows messages.