Skip to content

Commit

Permalink
openmv: Pick the exact drive for cameras on windows.
Browse files Browse the repository at this point in the history
  • Loading branch information
kwagyeman committed Nov 21, 2024
1 parent 2fb7f9f commit ef28da1
Show file tree
Hide file tree
Showing 6 changed files with 136 additions and 2 deletions.
1 change: 1 addition & 0 deletions src/plugins/openmv/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ add_qtc_plugin(OpenMV
histogram/rgb2rgb_tab.c
histogram/lab_tab.c
histogram/yuv_tab.c
tools/driveserialnumber.cpp tools/driveserialnumber.h
tools/myqserialportinfo.cpp tools/myqserialportinfo.h
tools/loaderdialog.cpp tools/loaderdialog.h
tools/alif.cpp tools/alif.h
Expand Down
40 changes: 38 additions & 2 deletions src/plugins/openmv/openmvplugin.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ OpenMVPlugin::OpenMVPlugin() : IPlugin()
m_reconnects = int();
m_portName = QString();
m_portPath = QString();
m_portDriveSerialNumber = QString();
m_formKey = QString();

m_serialNumberFilter = QString();
Expand Down Expand Up @@ -2431,6 +2432,37 @@ bool OpenMVPlugin::delayedInitialize()
QTimer::singleShot(0, scanSerialPortsThread, &ScanSerialPortsThread::scanSerialPortsSlot);
}

// Scan Drives
{
QThread *thread = new QThread;
ScanDriveThread *scanDrivesThread = new ScanDriveThread();
scanDrivesThread->moveToThread(thread);
QTimer *timer = new QTimer(this);

connect(timer, &QTimer::timeout, scanDrivesThread, [this, scanDrivesThread] () {
if (!m_connected) {
scanDrivesThread->scanDrivesSlot();
}
});

connect(scanDrivesThread, &ScanDriveThread::driveScanned, this, [this] (const QList<QPair<QStorageInfo, QString> > &output) {
m_availableDrives = output;
});

connect(this, &OpenMVPlugin::destroyed,
scanDrivesThread, &ScanDriveThread::deleteLater);

connect(scanDrivesThread, &ScanDriveThread::destroyed,
thread, &QThread::quit);

connect(thread, &QThread::finished,
thread, &QThread::deleteLater);

thread->start();
timer->start(1000);
QTimer::singleShot(0, scanDrivesThread, &ScanDriveThread::scanDrivesSlot);
}

if(!socket->bind(OPENMVCAM_BROADCAST_PORT))
{
delete socket;
Expand Down Expand Up @@ -3925,8 +3957,11 @@ void OpenMVPlugin::setPortPath(bool silent)
{
QStringList drives;

for(const QStorageInfo &info : QStorageInfo::mountedVolumes())
for(const QPair<QStorageInfo, QString> &pair : m_availableDrives)
{
const QStorageInfo info = pair.first;
const QString serialNumber = pair.second;

if(info.isValid()
&& info.isReady()
&& (!info.isRoot())
Expand All @@ -3935,10 +3970,11 @@ void OpenMVPlugin::setPortPath(bool silent)
&& ((!Utils::HostOsInfo::isMacHost()) || info.rootPath().startsWith(QStringLiteral("/volumes/"), Qt::CaseInsensitive))
&& ((!Utils::HostOsInfo::isLinuxHost()) || info.rootPath().startsWith(QStringLiteral("/media/"), Qt::CaseInsensitive) || info.rootPath().startsWith(QStringLiteral("/mnt/"), Qt::CaseInsensitive) || info.rootPath().startsWith(QStringLiteral("/run/"), Qt::CaseInsensitive)))
{
if(((m_major < OPENMV_DISK_ADDED_MAJOR)
if((((m_major < OPENMV_DISK_ADDED_MAJOR)
|| ((m_major == OPENMV_DISK_ADDED_MAJOR) && (m_minor < OPENMV_DISK_ADDED_MINOR))
|| ((m_major == OPENMV_DISK_ADDED_MAJOR) && (m_minor == OPENMV_DISK_ADDED_MINOR) && (m_patch < OPENMV_DISK_ADDED_PATCH)))
|| QFile::exists(info.rootPath() + QStringLiteral(OPENMV_DISK_ADDED_NAME)))
&& (serialNumber == m_portDriveSerialNumber))
{
drives.append(info.rootPath());
}
Expand Down
19 changes: 19 additions & 0 deletions src/plugins/openmv/openmvplugin.h
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@
#include "tools/alif.h"
#include "tools/bossac.h"
#include "tools/dfu-util.h"
#include "tools/driveserialnumber.h"
#include "tools/edgeimpulse.h"
#include "tools/imx.h"
#include "tools/keypointseditor.h"
Expand Down Expand Up @@ -327,6 +328,22 @@ class ScanSerialPortsThread: public QObject
private: QJsonDocument m_firmwareSettings; QString m_serialNumberFilter;
};

class ScanDriveThread: public QObject
{
Q_OBJECT

public: explicit ScanDriveThread() {
}
public slots: void scanDrivesSlot() {
QList<QPair<QStorageInfo, QString> > drives;
for(const QStorageInfo &drive : QStorageInfo::mountedVolumes()) {
drives.append(QPair<QStorageInfo, QString>(drive, driveSerialNumber(drive.rootPath())));
}
emit driveScanned(drives);
}
signals: void driveScanned(const QList<QPair<QStorageInfo, QString> > &output);
};

class OpenMVPlugin : public ExtensionSystem::IPlugin
{
Q_OBJECT
Expand Down Expand Up @@ -484,6 +501,7 @@ public slots: // private
int m_reconnects;
QString m_portName;
QString m_portPath;
QString m_portDriveSerialNumber;
QString m_formKey;

QString m_serialNumberFilter;
Expand Down Expand Up @@ -546,6 +564,7 @@ public slots: // private
QMap<QStringList, QStringList> m_argumentsByHierarchy;
QMap<QStringList, QString> m_returnTypesByHierarchy;
QList<wifiPort_t> m_availableWifiPorts;
QList<QPair<QStorageInfo, QString> > m_availableDrives;

typedef struct openTerminalMenuData
{
Expand Down
2 changes: 2 additions & 0 deletions src/plugins/openmv/openmvpluginconnect.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2387,6 +2387,7 @@ void OpenMVPlugin::connectClicked(bool forceBootloader, QString forceFirmwarePat
m_running = false;
m_portName = selectedPort;
m_portPath = QString();
m_portDriveSerialNumber = serialPortDriveSerialNumber(selectedPort);
m_major = major2;
m_minor = minor2;
m_patch = patch2;
Expand Down Expand Up @@ -2666,6 +2667,7 @@ void OpenMVPlugin::disconnectClicked(bool reset)
m_sensorType = QString();
m_portName = QString();
m_portPath = QString();
m_portDriveSerialNumber = QString();
m_errorFilterString = QString();

m_openDriveFolderAction->setEnabled(false);
Expand Down
61 changes: 61 additions & 0 deletions src/plugins/openmv/tools/driveserialnumber.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
#include <QtCore>
#include <QSerialPortInfo>

#include <utils/hostosinfo.h>
#include <utils/qtcprocess.h>

namespace OpenMV {
namespace Internal {

QString serialPortDriveSerialNumber(const QString &portName)
{
#if defined(Q_OS_WIN)
Utils::Process process;
std::chrono::seconds timeout(10);
process.setTextChannelMode(Utils::Channel::Output, Utils::TextChannelMode::MultiLine);
process.setTextChannelMode(Utils::Channel::Error, Utils::TextChannelMode::MultiLine);
process.setCommand(Utils::CommandLine(Utils::FilePath::fromString(QStringLiteral("powershell")),
QStringList()
<< QStringLiteral("-Command")
<< QString(QStringLiteral("(Get-PnpDeviceProperty -InstanceId (Get-WmiObject Win32_SerialPort | Where-Object { $_.DeviceID -eq '%1' }).PNPDeviceId | Where-Object { $_.KeyName -eq 'DEVPKEY_Device_Parent' }).Data")).arg(QString(portName))));
process.runBlocking(timeout, Utils::EventLoopMode::Off);

if(process.result() == Utils::ProcessResult::FinishedWithSuccess)
{
QRegularExpressionMatch match = QRegularExpression("\\\\(\\w+)$").match(process.stdOut().trimmed());
if (match.hasMatch()) return match.captured(1);
}
#elif defined(Q_OS_LINUX)
#elif defined(Q_OS_MAC)
#endif

return QString();
}

QString driveSerialNumber(const QString &drivePath)
{
#if defined(Q_OS_WIN)
Utils::Process process;
std::chrono::seconds timeout(10);
process.setTextChannelMode(Utils::Channel::Output, Utils::TextChannelMode::MultiLine);
process.setTextChannelMode(Utils::Channel::Error, Utils::TextChannelMode::MultiLine);
process.setCommand(Utils::CommandLine(Utils::FilePath::fromString(QStringLiteral("powershell")),
QStringList()
<< QStringLiteral("-Command")
<< QString(QStringLiteral("(Get-Disk -Number (Get-Partition -DriveLetter '%1').DiskNumber).SerialNumber")).arg(QString(drivePath).remove(QStringLiteral(":")).remove(QStringLiteral("/")))));
process.runBlocking(timeout, Utils::EventLoopMode::Off);

if(process.result() == Utils::ProcessResult::FinishedWithSuccess)
{
QString serialNumber = process.stdOut().trimmed();
return serialNumber;
}
#elif defined(Q_OS_LINUX)
#elif defined(Q_OS_MAC)
#endif

return QString();
}

} // namespace Internal
} // namespace OpenMV
15 changes: 15 additions & 0 deletions src/plugins/openmv/tools/driveserialnumber.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
#ifndef DRIVE_SERIAL_NUMBER_H
#define DRIVE_SERIAL_NUMBER_H

#include <QString>

namespace OpenMV {
namespace Internal {

QString serialPortDriveSerialNumber(const QString &portName);
QString driveSerialNumber(const QString &drivePath);

} // namespace Internal
} // namespace OpenMV

#endif // DRIVE_SERIAL_NUMBER_H

0 comments on commit ef28da1

Please sign in to comment.