diff HardwareOperations.cpp @ 12:ac837fe1d590 default tip

Switch implementation for reqex class and added RFCOMM as label for Bluetooth based connection by Linux
author Ideenmodellierer
date Mon, 12 Jan 2026 13:58:41 +0000
parents e30f00f760d3
children
line wrap: on
line diff
--- a/HardwareOperations.cpp	Mon Jan 12 13:57:24 2026 +0000
+++ b/HardwareOperations.cpp	Mon Jan 12 13:58:41 2026 +0000
@@ -36,38 +36,36 @@
 //////////////////////////////////////////////////////////////////////////////
 
 #include "HardwareOperations.h"
+#include <QSerialPortInfo>
 #include "MainWindow.h"
 #include "Utils/Log.h"
-#include <QSerialPortInfo>
+
+#include <QRegularExpression>
 
 #ifdef WIN32
-#   include <winreg.h>
+#include <winreg.h>
 #endif
 
 #include <QDir>
 
 //////////////////////////////////////////////////////////////////////////////
 
-unsigned char HardwareOperations::retryCommand(Serial& serial,
-                                               unsigned char cmd,
-                                               int retries)
+unsigned char HardwareOperations::retryCommand(Serial &serial, unsigned char cmd, int retries)
 {
-    for(int retry=0; retry<retries; ++retry)
-    {
-        serial.writeByte( cmd );    // Send command
-        serial.sleep(25);           // Allow 25msec lag.
+    for (int retry = 0; retry < retries; ++retry) {
+        serial.writeByte(cmd); // Send command
+        serial.sleep(25);      // Allow 25msec lag.
 
         try {
             unsigned char echo = serial.readByte();
-            if( echo == cmd || echo == 'M' || echo == 'L' )
-                return echo;            // Got it, or unknown command...
-        }
-        catch(const ReadTimeout&) {
+            if (echo == cmd || echo == 'M' || echo == 'L')
+                return echo; // Got it, or unknown command...
+        } catch (const ReadTimeout &) {
             continue;
         }
 
-        serial.sleep(100);         // Cleanup any pending stuff,
-        serial.purge();            // and retry...
+        serial.sleep(100); // Cleanup any pending stuff,
+        serial.purge();    // and retry...
     }
 
     return 0xFF;
@@ -75,87 +73,100 @@
 
 //////////////////////////////////////////////////////////////////////////////
 
-HardwareOperations::HardwareDescriptor
-HardwareOperations::hardwareDescriptor()
+HardwareOperations::HardwareDescriptor HardwareOperations::hardwareDescriptor()
 {
-    unsigned char echo  = 0;
-    unsigned int  hardFeatures = 0xFF; // timeout response...
-    unsigned int  softFeatures = 0;
-    unsigned int  model        = 0;
-    unsigned char ok    = 0;
+    unsigned char echo = 0;
+    unsigned int hardFeatures = 0xFF; // timeout response...
+    unsigned int softFeatures = 0;
+    unsigned int model = 0;
+    unsigned char ok = 0;
 
     try {
         //---- First: try the new extended hardware query --------------------
         echo = retryCommand(_serial, 0x60, 1); // BACKQUOTE char
-        if( echo == 0x60 ) {
+        if (echo == 0x60) {
             uchar extendedDescriptor[6];
             _serial.readBlock(extendedDescriptor, sizeof extendedDescriptor);
 
-
             hardFeatures = extendedDescriptor[0] * 256 + extendedDescriptor[1];
             softFeatures = extendedDescriptor[2] * 256 + extendedDescriptor[3];
-            model        = extendedDescriptor[4];
-            ok           = extendedDescriptor[5];
-        }
-        else
-        {
+            model = extendedDescriptor[4];
+            ok = extendedDescriptor[5];
+        } else {
             // Did we have a timeout ?
             // In that case, some hwOS versions fails and need a reset of
             // the connection mode...
-            if( echo == 0xFF )
-            {
-                echo = retryCommand(_serial, 0xBB);     // Try to reconnect
-                if( echo == 0xBB )
-                    echo = _serial.readByte();          // Eat 4d prompt
+            if (echo == 0xFF) {
+                echo = retryCommand(_serial, 0xBB); // Try to reconnect
+                if (echo == 0xBB)
+                    echo = _serial.readByte(); // Eat 4d prompt
             }
 
             // Then try the OLD hardware descriptor command...
-            echo = retryCommand(_serial, 'j');  // 0x6A
-            if( echo == 'j' ) {
+            echo = retryCommand(_serial, 'j'); // 0x6A
+            if (echo == 'j') {
                 hardFeatures = _serial.readByte();
-                ok    = _serial.readByte();
+                ok = _serial.readByte();
             }
         }
+    } catch (const ReadTimeout &) {
     }
-    catch(const ReadTimeout&) {}
 
-    if( (echo != 0x60 && echo != 'j')
-     || (ok != 'M' && ok != 'L')
-    ) {
+    if ((echo != 0x60 && echo != 'j') || (ok != 'M' && ok != 'L')) {
         LOG_TRACE("Old OSTC not responding...");
         return HW_UNKNOWN_OSTC;
     }
 
-    switch(hardFeatures) {
-    case HW_Frog        : LOG_TRACE("Frog found"); break;
-    case HW_OSTCSport_a : LOG_TRACE("OSTC Sport found"); break;
-    case HW_OSTC2c      : LOG_TRACE("OSTC 2c found"); break;
+    switch (hardFeatures) {
+    case HW_Frog:
+        LOG_TRACE("Frog found");
+        break;
+    case HW_OSTCSport_a:
+        LOG_TRACE("OSTC Sport found");
+        break;
+    case HW_OSTC2c:
+        LOG_TRACE("OSTC 2c found");
+        break;
     case HW_OSTC2_a:
-    case HW_OSTC2_c     : LOG_TRACE("OSTC 2 found"); break;
+    case HW_OSTC2_c:
+        LOG_TRACE("OSTC 2 found");
+        break;
     case HW_OSTCcR_a:
-    case HW_OSTCcR_b    : LOG_TRACE("OSTC cR found"); break;
-    case HW_OSTC3       : LOG_TRACE("OSTC 3 found"); break;
-    case HW_OSTC3p_a    : LOG_TRACE("OSTC 3+ found"); break;
-    case HW_OSTC4       : LOG_TRACE("OSTC 4/5 found"); break;
+    case HW_OSTCcR_b:
+        LOG_TRACE("OSTC cR found");
+        break;
+    case HW_OSTC3:
+        LOG_TRACE("OSTC 3 found");
+        break;
+    case HW_OSTC3p_a:
+        LOG_TRACE("OSTC 3+ found");
+        break;
+    case HW_OSTC4:
+        LOG_TRACE("OSTC 4/5 found");
+        break;
 
-    case HW_OSTCSport_b : LOG_TRACE("OSTC Sport, OSTC 2 or OSTC 3 found."); break;
+    case HW_OSTCSport_b:
+        LOG_TRACE("OSTC Sport, OSTC 2 or OSTC 3 found.");
+        break;
 
-    case 0xFF: case 0x4C: case 0x4D:
+    case 0xFF:
+    case 0x4C:
+    case 0x4D:
         LOG_TRACE("old OSTC not responding...");
         return HW_UNKNOWN_OSTC;
 
     default:
-     //   LOG_TRACE("Unknown hardware feature =" << QString().sprintf("0x%04x", hardFeatures));
+        //   LOG_TRACE("Unknown hardware feature =" << QString().sprintf("0x%04x", hardFeatures));
         LOG_TRACE("Unknown hardware feature =" << QString::asprintf("0x%04x", hardFeatures));
         break;
     }
 
-    if( echo == 0x60 ) {
-        LOG_TRACE("    software feature = "  <<  QString::asprintf("0x%04x", softFeatures));
-        LOG_TRACE("    model = "  <<  QString::asprintf("0x%02x", model));
+    if (echo == 0x60) {
+        LOG_TRACE("    software feature = " << QString::asprintf("0x%04x", softFeatures));
+        LOG_TRACE("    model = " << QString::asprintf("0x%02x", model));
     }
 
-    return (HardwareDescriptor)hardFeatures;
+    return (HardwareDescriptor) hardFeatures;
 }
 
 //////////////////////////////////////////////////////////////////////////////
@@ -169,43 +180,44 @@
 
 #if defined(Q_OS_MAC) || defined(Q_OS_LINUX)
     // TODO: Linux USB search...
-    QRegExp pTemplate = portTemplate();
+    QRegularExpression pTemplate = portTemplate();
     QDir dev("/dev");
-    QStringList all = dev.entryList(QStringList() << "tty.*",
-                                    QDir::NoDotAndDotDot|QDir::System|QDir::Writable,
+    QStringList all = dev.entryList(QStringList() << "rfcomm*" << "tty.*",
+                                    QDir::NoDotAndDotDot | QDir::Files | QDir::System | QDir::Writable,
                                     QDir::Name);
 
-    for(int i=0; i<(int)all.count(); ++i) {
-        if( pTemplate.indexIn(all[i]) >= 0 ) {
+    for (int i = 0; i < all.count(); ++i) {
+        QRegularExpressionMatch match = pTemplate.match(all[i]);
+
+        if (match.hasMatch()) {
             LOG_TRACE("Port " << all[i]);
             list += all[i];
+        } else {
+            LOG_DEBUG("...  " << all[i]);
         }
-        else
-            LOG_DEBUG("...  " << all[i]);
     }
 #else
     /* Check the descriptors of the available COMs for Bluetooth tag */
     for (const QSerialPortInfo &serialPortInfo : serialPortInfos) {
-         PortDesc = serialPortInfo.description();
-         if( PortDesc.contains("Bluetooth"))
-             list += serialPortInfo.portName();
+        PortDesc = serialPortInfo.description();
+        if (PortDesc.contains("Bluetooth"))
+            list += serialPortInfo.portName();
     }
 
-    if( list.isEmpty() ) /* no port identified => fallback to old detection function */
+    if (list.isEmpty()) /* no port identified => fallback to old detection function */
     {
-        for(int i=1; i<300; ++i)
-        {
+        for (int i = 1; i < 300; ++i) {
             QString port = QString("COM%1").arg(i);
 
             // First: try to read default configuration...
             COMMCONFIG config = {0};
-            config.dwSize   = sizeof config;
+            config.dwSize = sizeof config;
             config.wVersion = 1;
             DWORD len = sizeof config;
 
             QByteArray fixed = "\\\\.\\" + port.toLocal8Bit();
-            if( GetDefaultCommConfigA(fixed.constData(), &config, &len) ) {
-                if( config.dwProviderSubType == PST_RS232 )
+            if (GetDefaultCommConfigA(fixed.constData(), &config, &len)) {
+                if (config.dwProviderSubType == PST_RS232)
                     list += port;
             }
         }
@@ -216,33 +228,36 @@
         {
             HKEY key;
             const char registryPath[] = "HARDWARE\\DEVICEMAP\\SERIALCOMM";
-            if( RegOpenKeyExA(HKEY_LOCAL_MACHINE,           // PWD
-                             registryPath,                  // "SOFTWARE\Intel\PSIB"
-                             0,                             // Options
-                             KEY_READ,                      // Desired SAM: See 32bits view.
-                             &key) == ERROR_SUCCESS
-            ) {
-                for(DWORD i = 0; ++i;) {
+            if (RegOpenKeyExA(HKEY_LOCAL_MACHINE, // PWD
+                              registryPath,       // "SOFTWARE\Intel\PSIB"
+                              0,                  // Options
+                              KEY_READ,           // Desired SAM: See 32bits view.
+                              &key)
+                == ERROR_SUCCESS) {
+                for (DWORD i = 0; ++i;) {
                     char nameBuffer[128] = {0};
                     DWORD nameLen = sizeof nameBuffer;
                     unsigned char dataBuffer[128] = {0};
                     DWORD dataLen = sizeof dataBuffer;
-                    long rc = RegEnumValueA(key, i,
-                                  nameBuffer, &nameLen,
-                                  nullptr,
-                                  nullptr,
-                                  dataBuffer, &dataLen);
-                    if( rc != ERROR_SUCCESS )
+                    long rc = RegEnumValueA(key,
+                                            i,
+                                            nameBuffer,
+                                            &nameLen,
+                                            nullptr,
+                                            nullptr,
+                                            dataBuffer,
+                                            &dataLen);
+                    if (rc != ERROR_SUCCESS)
                         break;
 
                     QString name = QString(nameBuffer);
-                    QString port = QString((char*)dataBuffer);
+                    QString port = QString((char *) dataBuffer);
                     LOG_TRACE("Resource " << i << ": " << name << ", " << port);
-                    if( name.contains("\\BtModem") || name.contains("\\BthModem") || name.contains("\\BtPort") ) {
+                    if (name.contains("\\BtModem") || name.contains("\\BthModem")
+                        || name.contains("\\BtPort")) {
                         list += port + " (Bluetooth)";
                         LOG_TRACE("Port " << name);
-                    }
-                    else
+                    } else
                         LOG_DEBUG("...  " << name);
                 }
                 RegCloseKey(key);
@@ -258,48 +273,50 @@
 
 QStringList HardwareOperations::listUSBPorts() const
 {
-    assert( !(supported() & BLUETOOTH) );
+    assert(!(supported() & BLUETOOTH));
     QStringList list;
 
 #if defined(Q_OS_MAC) || defined(Q_OS_LINUX)
     // TODO: Linux USB search...
     QDir dev("/dev");
-    QRegExp pTemplate = portTemplate();
+    QRegularExpression pTemplate = portTemplate();  // Hier bleibt alles gleich
     QStringList all = dev.entryList(QStringList() << "tty.*",
-                                    QDir::System|QDir::Writable|QDir::NoDotAndDotDot,
+                                    QDir::System | QDir::Writable | QDir::NoDotAndDotDot,
                                     QDir::Name);
-    for(int i=0; i<(int)all.count(); ++i) {
-        if( pTemplate.indexIn(all[i]) >= 0 ) {
+
+    for (int i = 0; i < all.count(); ++i) {
+        // Verwende QRegularExpression::match anstelle von indexIn
+        QRegularExpressionMatch match = pTemplate.match(all[i]);
+
+        if (match.hasMatch()) {  // Überprüfe, ob eine Übereinstimmung gefunden wurde
             LOG_TRACE("Port " << all[i]);
             list += all[i];
+        } else {
+            LOG_TRACE("... " << all[i]);
         }
-        else
-            LOG_TRACE("... " << all[i]);
     }
 #else
     //---- First chance: Try the normal port list:
-    for(int i=1; i<300; ++i)
-    {
+    for (int i = 1; i < 300; ++i) {
         QString port = QString("COM%1").arg(i);
 
         // First: try to read default configuration...
         COMMCONFIG config;
         memset(&config, 0, sizeof config);
-        config.dwSize   = sizeof config;
+        config.dwSize = sizeof config;
         config.wVersion = 1;
         DWORD len = sizeof config;
 
         QByteArray fixed = "\\\\.\\" + port.toLocal8Bit();
-        if( GetDefaultCommConfigA(fixed.constData(), &config, &len) ) {
-            LOG_TRACE("Port " << port << " subtype=" << int(config.dwProviderSubType) );
-            if( config.dwProviderSubType == PST_RS232 )
+        if (GetDefaultCommConfigA(fixed.constData(), &config, &len)) {
+            LOG_TRACE("Port " << port << " subtype=" << int(config.dwProviderSubType));
+            if (config.dwProviderSubType == PST_RS232)
                 list += port;
-        } else if( len != sizeof config )
+        } else if (len != sizeof config)
             LOG_THROW("Required " << len << " bytes.");
-        else if( HRESULT rc = GetLastError() )
-            if( rc != 87 )
-                LOG_TRACE("Port " << port << "  error=" << rc );
-
+        else if (HRESULT rc = GetLastError())
+            if (rc != 87)
+                LOG_TRACE("Port " << port << "  error=" << rc);
     }
     //---- Second chance
     //     overide usual MS bug, by looking into the registry for more
@@ -307,34 +324,37 @@
     {
         HKEY key;
         const char registryPath[] = "HARDWARE\\DEVICEMAP\\SERIALCOMM";
-        if( RegOpenKeyExA(HKEY_LOCAL_MACHINE,           // PWD
-                         registryPath,                  // path
-                         0,                             // Options
-                         KEY_READ,                      // Desired SAM: See 32bits view.
-                         &key) == ERROR_SUCCESS
-        ) {
-            for(DWORD i = 0;; ++i) {
+        if (RegOpenKeyExA(HKEY_LOCAL_MACHINE, // PWD
+                          registryPath,       // path
+                          0,                  // Options
+                          KEY_READ,           // Desired SAM: See 32bits view.
+                          &key)
+            == ERROR_SUCCESS) {
+            for (DWORD i = 0;; ++i) {
                 char nameBuffer[128] = {0};
                 DWORD nameLen = sizeof nameBuffer;
                 unsigned char dataBuffer[128] = {0};
                 DWORD dataLen = sizeof dataBuffer;
-                long rc = RegEnumValueA(key, i,
-                              nameBuffer, &nameLen,
-                              nullptr,
-                              nullptr,
-                              dataBuffer, &dataLen);
+                long rc = RegEnumValueA(key,
+                                        i,
+                                        nameBuffer,
+                                        &nameLen,
+                                        nullptr,
+                                        nullptr,
+                                        dataBuffer,
+                                        &dataLen);
 
-                if( rc == ERROR_NO_MORE_ITEMS )
+                if (rc == ERROR_NO_MORE_ITEMS)
                     break;
 
-                if( rc != ERROR_SUCCESS )
-                    LOG_THROW( "Enumeration error" );
+                if (rc != ERROR_SUCCESS)
+                    LOG_THROW("Enumeration error");
 
                 QString name = QString(nameBuffer);
-                QString port = QString((char*)dataBuffer);
+                QString port = QString((char *) dataBuffer);
                 LOG_TRACE("Resource " << i << ": " << name << ", " << port);
 
-                if( name.contains("\\VCP") )
+                if (name.contains("\\VCP"))
                     list += port + " (USB)";
             }
             RegCloseKey(key);