QSerialPort::UnsupportedOperationError ("Invalid argument") error in opening /dev/diag port in Android device using QSerialPort in Qt Android
-
I want to build an android application with Qt which just opens the /dev/diag port in my Android device. At first, I have written a simple codes as follows:
main.cpp
#include <QCoreApplication> #include <QDebug> #include "serialporthandler.h" int main(int argc, char *argv[]) { QCoreApplication a(argc, argv); SerialPortHandler* serialPortHandler = new SerialPortHandler("/dev/diag"); serialPortHandler->openSerialPort(); return a.exec(); }
serialporthandler.h
#ifndef MYSERIALPORT_H #define MYSERIALPORT_H #include <QDebug> #include <QFile> #include <QObject> #include <QtSerialPort/QSerialPort> #include <QtSerialPort/QSerialPortInfo> class SerialPortHandler : public QObject { Q_OBJECT public: SerialPortHandler(QString serialPort, QObject *parent = nullptr); ~SerialPortHandler(); bool openSerialPort(); private: QSerialPort* serial_; QString serialPort_; }; #endif // MYSERIALPORT_H
serialporthandler.cpp
#include "serialporthandler.h" SerialPortHandler::SerialPortHandler(QString serialPort, QObject *parent) { serial_ = new QSerialPort(parent); serial_->close(); serialPort_=serialPort; } SerialPortHandler::~SerialPortHandler() { serial_->reset(); serial_->close(); delete serial_; } bool SerialPortHandler::openSerialPort() { serial_->setPortName(serialPort_); serial_->setBaudRate(QSerialPort::Baud19200); serial_->setDataBits(QSerialPort::Data8); serial_->setParity(QSerialPort::NoParity); serial_->setStopBits(QSerialPort::OneStop); serial_->setFlowControl(QSerialPort::NoFlowControl); if (!serial_->open(QIODevice::ReadWrite)) { qDebug()<<"ERROR: "<<serial_->error()<<serial_->errorString(); return 0; } return 1; }
After building and running this app on my Android device, the following error appeared:
ERROR: QSerialPort::PermissionError "Permission denied"
It means that my application has no permission to open /dev/diag port. So, in Ubuntu I opened adb shell and executed the following commands to change the permission:
adb shell su setenforce 0 chmod 777 /dev/diag
Now, After executing the above commands and building my application again, I see this error and I don't know how can I solve that:
ERROR: QSerialPort::UnsupportedOperationError "Invalid argument"
(I am using java-8-openjdk-amd64, SDK Version: 25.2.5, NDK Version: 20.0.5594570, Clang Qt 5.12.7 (android_armv7))
Update:
This C language code, can simply open /dev/diag port of Android device:
//serialPort_=/dev/diag open(serialPort_.toStdString().c_str(), O_RDWR | O_LARGEFILE | O_NONBLOCK);
But
QSerialPort::open
function can not! -
- QSP does not supported on Android (nobody even checked it, AFAIK) and even removed from the build.
- Does your open() work without of O_LARGEFILE flag?
- I suspect that QSerialPort::UnsupportedOperationError "Invalid argument" error related to the QSP configuring, but not to open(). Because by default QSP::open() opens and then configures the QSP (set baud rate, stop bits and etc). So, maybe '/dev/diag ' just does not support serial port specifig ioctl() flags.
-
Thanks,
- I can open the other ports on Android using QSerialPort like ttyHSL0 and ttyHSUSB0.
- QSerialPort::open() just get the open mode (i.e. ReadOnly, WriteOnly, ReadWrite) as input argument and I don't know how can I set O_LARGEFILE flag.
- Is there a way to set ioctl() flags in QSerialPort?
-
-
I can open the other ports on Android using QSerialPort like ttyHSL0 and ttyHSUSB0.
Because /dev/ttyHSL0 and /dev/ttyHSUSB0 is a 'true' serial ports... But, seems that /dev/diag is not a serial port.
-
QSerialPort::open() just get the open mode (i.e. ReadOnly, WriteOnly, ReadWrite) as input argument and I don't know how can I set O_LARGEFILE flag.
No, just test your native ::open() function (not QSP) just without of O_LARGEFILE flag and report us about results. If a problem is in O_LARGEFILE then it is not a problem to add it to QSP.
-
Is there a way to set ioctl() flags in QSerialPort?
What are flags? QSP already use ioctl's() calls (e.g. inside of QSP::open()), wrapped e.g. by tcsetattr() to change the termius structure, or some ioctl's() directly to change the speed and etc.
You should re-build QSP for Android himself and debug it (or, at least to add qDebug() console outputs) to see, where it fails.
UPD: I have found some info about /dev/diag. Seems, it is a special Qualcomm modem interface. So, most likelly, for this device don't inplemented some 'standard' serial port features (e.g. baud rate, stop bits and etc). You can look on a Kernel sources too to see where is the EINVAL errno returned.
-
-
I can open this port by:
int fd=open("/dev/diag", O_RDWR); qDebug()<<"Open port with C function: "<<fd
and the fd=33.
There are just a few codes in QSP sources in github linkVtable for std::invalid_argument std::invalid_argument::_ZTVSt16invalid_argument: 5u entries 0 (int (*)(...))0 8 (int (*)(...))(& _ZTISt16invalid_argument) 16 (int (*)(...))std::invalid_argument::~invalid_argument 24 (int (*)(...))std::invalid_argument::~invalid_argument 32 (int (*)(...))std::logic_error::what Class std::invalid_argument size=16 align=8 base size=16 base align=8 std::invalid_argument (0x0x7f3911e1a8f0) 0 vptr=((& std::invalid_argument::_ZTVSt16invalid_argument) + 16u) std::logic_error (0x0x7f3911e1a958) 0 primary-for std::invalid_argument (0x0x7f3911e1a8f0) std::exception (0x0x7f3911f4a2a0) 0 nearly-empty primary-for std::logic_error (0x0x7f3911e1a958)
But I think the above source does not help!
Yes, /dev/diag port is a special Qualcomm mobile and modem interface. I prefer to not to use C functions. Before building the QSP sources to debug, is there another way to open this special interface using Qt? (C can simply open it but Qt?!)