QGroundControl
Ground Control Station for MAVLink Drones
Loading...
Searching...
No Matches
SerialAutoConnect.cc
Go to the documentation of this file.
1#include "SerialAutoConnect.h"
2
3#include <algorithm>
4#include <utility>
5
6#include <QtCore/QCoreApplication>
7#include <QtCore/QSet>
8
9#include "MonotonicClock.h"
10#include "QGCLoggingCategory.h"
11#include "SerialLink.h"
12
13QGC_LOGGING_CATEGORY(SerialAutoConnectLog, "Comms.Serial.SerialAutoConnect")
14
16 : _ports(ports), _connect(std::move(connect))
17{
18 qCDebug(SerialAutoConnectLog) << this;
19}
20
22{
23 qCDebug(SerialAutoConnectLog) << this;
24}
25
26void SerialAutoConnect::update(const QList<SerialPortManager::Port>& ports, const Options& options)
27{
28 const auto isAbsentLocation = [&ports](const QString& location) {
29 return std::none_of(ports.cbegin(), ports.cend(),
30 [&location](const auto& port) { return port.systemLocation == location; });
31 };
32 const auto isAbsent = [&isAbsentLocation](const auto& entry) { return isAbsentLocation(entry.key()); };
33 _identities.removeIf(isAbsent);
34 for (const auto& port : ports) {
35 const Identity identity{port.physicalDeviceId, port.boardType, port.bootloader};
36 const auto previous = _identities.constFind(port.systemLocation);
37 if (previous != _identities.cend() && previous.value() != identity) {
38 _configs.remove(port.systemLocation);
39 _waitingPorts.remove(port.systemLocation);
40 }
41 _identities.insert(port.systemLocation, identity);
42 }
43 _configs.removeIf(isAbsent);
44 _waitingPorts.removeIf(isAbsentLocation);
45
46 QSet<QString> seenDevices;
47 for (const SerialPortManager::Port& port : ports) {
48 if (!_allowed(port.boardType, options) || port.bootloader ||
49 _ports.isAutoConnectExcluded(port.systemLocation)) {
50 continue;
51 }
52 // Select one MAVLink interface per physical device, even while its port is reserved or retrying.
53 if (!SerialPortManager::isPrimaryInterface(port, seenDevices) ||
54 !_ports.canAutoConnectPort(port.systemLocation)) {
55 continue;
56 }
57 auto config = _configs.value(port.systemLocation);
58 if (config) {
59 if (!config->link() && !config->suppressAutoReconnect() && config->reconnectReady()) {
60 config->noteReconnectAttempt();
61 _connect(config);
62 }
63 continue;
64 }
65 if (!_waitingPorts.settled(port.systemLocation, MonotonicClock::nowUs())) {
66 continue;
67 }
68 _waitingPorts.remove(port.systemLocation);
69 auto* serialConfig = new SerialConfiguration(
70 QCoreApplication::translate("LinkManager", "%1 on %2 (AutoConnect)").arg(port.boardName, port.portName));
71 serialConfig->setUsbDirect(port.boardType == QGCSerialPortInfo::BoardTypePixhawk);
72 serialConfig->setSikRadio(port.boardType == QGCSerialPortInfo::BoardTypeSiKRadio);
73 serialConfig->setBaud(port.boardType == QGCSerialPortInfo::BoardTypeSiKRadio ? 57600 : 115200);
74 serialConfig->setDynamic(true);
75 serialConfig->setPortName(port.systemLocation);
76 serialConfig->setAutoConnect(true);
77 config.reset(serialConfig);
78 _configs.insert(port.systemLocation, config);
79 config->noteReconnectAttempt();
80 _connect(config);
81 }
82}
83
84bool SerialAutoConnect::_allowed(QGCSerialPortInfo::BoardType_t boardType, const Options& options)
85{
86 switch (boardType) {
88 return options.pixhawk;
90 return options.sikRadio;
92 return options.openPilot;
93 default:
94 return false;
95 }
96}
Config config
#define QGC_LOGGING_CATEGORY(name, categoryStr)
Application-thread MAVLink serial discovery. LinkManager owns creation and live links.
std::function< void(SharedLinkConfigurationPtr &)> Connect
void update(const QList< SerialPortManager::Port > &ports, const Options &options)
Shared serial inventory and exclusive claims. Called on the application thread.
bool isAutoConnectExcluded(const QString &systemLocation) const
bool canAutoConnectPort(const QString &systemLocation) const
static bool isPrimaryInterface(const Port &port, QSet< QString > &seenDevices)
void removeIf(Predicate forget)
Forgets the ports forget returns true for.
bool settled(const QString &port, quint64 nowUs)
Records port as listed at nowUs; true once it has been listed for the settle delay.
void remove(const QString &port)
uint64_t nowUs()