Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Q
qgroundcontrol
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Valentin Platzgummer
qgroundcontrol
Commits
70124a1e
Commit
70124a1e
authored
Mar 26, 2016
by
Don Gagne
Browse files
Options
Browse Files
Download
Plain Diff
Merge pull request #3079 from NaterGator/linkthreadfix
[WIP] Link thread safety enforcement
parents
e0efcb20
fe8ff69e
Changes
26
Hide whitespace changes
Inline
Side-by-side
Showing
26 changed files
with
113 additions
and
158 deletions
+113
-158
Vehicle.cc
src/Vehicle/Vehicle.cc
+1
-1
BluetoothLink.cc
src/comm/BluetoothLink.cc
+3
-8
BluetoothLink.h
src/comm/BluetoothLink.h
+5
-3
LinkInterface.h
src/comm/LinkInterface.h
+11
-2
LinkManager.cc
src/comm/LinkManager.cc
+1
-1
LogReplayLink.cc
src/comm/LogReplayLink.cc
+1
-2
LogReplayLink.h
src/comm/LogReplayLink.h
+2
-2
MAVLinkProtocol.cc
src/comm/MAVLinkProtocol.cc
+2
-2
MockLink.cc
src/comm/MockLink.cc
+1
-11
MockLink.h
src/comm/MockLink.h
+2
-7
QGCFlightGearLink.cc
src/comm/QGCFlightGearLink.cc
+4
-4
QGCFlightGearLink.h
src/comm/QGCFlightGearLink.h
+5
-1
QGCHilLink.h
src/comm/QGCHilLink.h
+17
-1
QGCJSBSimLink.cc
src/comm/QGCJSBSimLink.cc
+4
-4
QGCJSBSimLink.h
src/comm/QGCJSBSimLink.h
+5
-1
QGCXPlaneLink.cc
src/comm/QGCXPlaneLink.cc
+10
-10
QGCXPlaneLink.h
src/comm/QGCXPlaneLink.h
+5
-1
SerialLink.cc
src/comm/SerialLink.cc
+3
-3
SerialLink.h
src/comm/SerialLink.h
+3
-2
TCPLink.cc
src/comm/TCPLink.cc
+9
-6
TCPLink.h
src/comm/TCPLink.h
+5
-4
UDPLink.cc
src/comm/UDPLink.cc
+6
-63
UDPLink.h
src/comm/UDPLink.h
+2
-7
XbeeLink.cpp
src/comm/XbeeLink.cpp
+3
-9
XbeeLink.h
src/comm/XbeeLink.h
+2
-2
TCPLinkTest.cc
src/qgcunittest/TCPLinkTest.cc
+1
-1
No files found.
src/Vehicle/Vehicle.cc
View file @
70124a1e
...
@@ -735,7 +735,7 @@ void Vehicle::_sendMessageOnLink(LinkInterface* link, mavlink_message_t message)
...
@@ -735,7 +735,7 @@ void Vehicle::_sendMessageOnLink(LinkInterface* link, mavlink_message_t message)
uint8_t
buffer
[
MAVLINK_MAX_PACKET_LEN
];
uint8_t
buffer
[
MAVLINK_MAX_PACKET_LEN
];
int
len
=
mavlink_msg_to_send_buffer
(
buffer
,
&
message
);
int
len
=
mavlink_msg_to_send_buffer
(
buffer
,
&
message
);
link
->
writeBytes
((
const
char
*
)
buffer
,
len
);
link
->
writeBytes
Safe
((
const
char
*
)
buffer
,
len
);
_messagesSent
++
;
_messagesSent
++
;
emit
messagesSentChanged
();
emit
messagesSentChanged
();
}
}
...
...
src/comm/BluetoothLink.cc
View file @
70124a1e
...
@@ -89,19 +89,14 @@ QString BluetoothLink::getName() const
...
@@ -89,19 +89,14 @@ QString BluetoothLink::getName() const
return
_config
->
name
();
return
_config
->
name
();
}
}
void
BluetoothLink
::
writeBytes
(
const
char
*
data
,
qint64
size
)
void
BluetoothLink
::
_writeBytes
(
const
QByteArray
bytes
)
{
_sendBytes
(
data
,
size
);
}
void
BluetoothLink
::
_sendBytes
(
const
char
*
data
,
qint64
size
)
{
{
if
(
_targetSocket
)
if
(
_targetSocket
)
{
{
if
(
_targetSocket
->
isWritable
())
if
(
_targetSocket
->
isWritable
())
{
{
if
(
_targetSocket
->
write
(
data
,
size
)
>
0
)
{
if
(
_targetSocket
->
write
(
bytes
)
>
0
)
{
_logOutputDataRate
(
size
,
QDateTime
::
currentMSecsSinceEpoch
());
_logOutputDataRate
(
bytes
.
size
()
,
QDateTime
::
currentMSecsSinceEpoch
());
}
}
else
else
qWarning
()
<<
"Bluetooth write error"
;
qWarning
()
<<
"Bluetooth write error"
;
...
...
src/comm/BluetoothLink.h
View file @
70124a1e
...
@@ -165,9 +165,7 @@ public:
...
@@ -165,9 +165,7 @@ public:
LinkConfiguration
*
getLinkConfiguration
()
{
return
_config
;
}
LinkConfiguration
*
getLinkConfiguration
()
{
return
_config
;
}
public
slots
:
public
slots
:
void
readBytes
();
void
readBytes
();
void
writeBytes
(
const
char
*
data
,
qint64
length
);
void
deviceConnected
();
void
deviceConnected
();
void
deviceDisconnected
();
void
deviceDisconnected
();
void
deviceError
(
QBluetoothSocket
::
SocketError
error
);
void
deviceError
(
QBluetoothSocket
::
SocketError
error
);
...
@@ -193,7 +191,11 @@ private:
...
@@ -193,7 +191,11 @@ private:
bool
_hardwareConnect
();
bool
_hardwareConnect
();
void
_restartConnection
();
void
_restartConnection
();
void
_sendBytes
(
const
char
*
data
,
qint64
size
);
private
slots
:
void
_writeBytes
(
const
QByteArray
bytes
);
private:
void
_createSocket
();
void
_createSocket
();
private:
private:
...
...
src/comm/LinkInterface.h
View file @
70124a1e
...
@@ -151,16 +151,24 @@ public slots:
...
@@ -151,16 +151,24 @@ public slots:
*
*
* If the underlying communication is packet oriented,
* If the underlying communication is packet oriented,
* one write command equals a datagram. In case of serial
* one write command equals a datagram. In case of serial
* communication arbitrary byte lengths can be written
* communication arbitrary byte lengths can be written. The method ensures
* thread safety regardless of the underlying LinkInterface implementation.
*
*
* @param bytes The pointer to the byte array containing the data
* @param bytes The pointer to the byte array containing the data
* @param length The length of the data array
* @param length The length of the data array
**/
**/
virtual
void
writeBytes
(
const
char
*
bytes
,
qint64
length
)
=
0
;
void
writeBytesSafe
(
const
char
*
bytes
,
int
length
)
{
emit
_invokeWriteBytes
(
QByteArray
(
bytes
,
length
));
}
private
slots
:
virtual
void
_writeBytes
(
const
QByteArray
)
=
0
;
signals:
signals:
void
autoconnectChanged
(
bool
autoconnect
);
void
autoconnectChanged
(
bool
autoconnect
);
void
activeChanged
(
bool
active
);
void
activeChanged
(
bool
active
);
void
_invokeWriteBytes
(
QByteArray
);
/**
/**
* @brief New data arrived
* @brief New data arrived
...
@@ -212,6 +220,7 @@ protected:
...
@@ -212,6 +220,7 @@ protected:
memset
(
_outDataWriteAmounts
,
0
,
sizeof
(
_outDataWriteAmounts
));
memset
(
_outDataWriteAmounts
,
0
,
sizeof
(
_outDataWriteAmounts
));
memset
(
_outDataWriteTimes
,
0
,
sizeof
(
_outDataWriteTimes
));
memset
(
_outDataWriteTimes
,
0
,
sizeof
(
_outDataWriteTimes
));
QObject
::
connect
(
this
,
&
LinkInterface
::
_invokeWriteBytes
,
this
,
&
LinkInterface
::
_writeBytes
);
qRegisterMetaType
<
LinkInterface
*>
(
"LinkInterface*"
);
qRegisterMetaType
<
LinkInterface
*>
(
"LinkInterface*"
);
}
}
...
...
src/comm/LinkManager.cc
View file @
70124a1e
...
@@ -881,7 +881,7 @@ void LinkManager::_activeLinkCheck(void)
...
@@ -881,7 +881,7 @@ void LinkManager::_activeLinkCheck(void)
if
(
!
found
&&
link
)
{
if
(
!
found
&&
link
)
{
// See if we can get an NSH prompt on this link
// See if we can get an NSH prompt on this link
bool
foundNSHPrompt
=
false
;
bool
foundNSHPrompt
=
false
;
link
->
writeBytes
(
"
\r
"
,
1
);
link
->
writeBytes
Safe
(
"
\r
"
,
1
);
QSignalSpy
spy
(
link
,
SIGNAL
(
bytesReceived
(
LinkInterface
*
,
QByteArray
)));
QSignalSpy
spy
(
link
,
SIGNAL
(
bytesReceived
(
LinkInterface
*
,
QByteArray
)));
if
(
spy
.
wait
(
100
))
{
if
(
spy
.
wait
(
100
))
{
QList
<
QVariant
>
arguments
=
spy
.
takeFirst
();
QList
<
QVariant
>
arguments
=
spy
.
takeFirst
();
...
...
src/comm/LogReplayLink.cc
View file @
70124a1e
...
@@ -151,10 +151,9 @@ void LogReplayLink::_replayError(const QString& errorMsg)
...
@@ -151,10 +151,9 @@ void LogReplayLink::_replayError(const QString& errorMsg)
}
}
/// Since this is log replay, we just drops writes on the floor
/// Since this is log replay, we just drops writes on the floor
void
LogReplayLink
::
writeBytes
(
const
char
*
bytes
,
qint64
cB
ytes
)
void
LogReplayLink
::
_writeBytes
(
const
QByteArray
b
ytes
)
{
{
Q_UNUSED
(
bytes
);
Q_UNUSED
(
bytes
);
Q_UNUSED
(
cBytes
);
}
}
/// Parses a BigEndian quint64 timestamp
/// Parses a BigEndian quint64 timestamp
...
...
src/comm/LogReplayLink.h
View file @
70124a1e
...
@@ -98,8 +98,8 @@ public:
...
@@ -98,8 +98,8 @@ public:
bool
connect
(
void
);
bool
connect
(
void
);
bool
disconnect
(
void
);
bool
disconnect
(
void
);
p
ublic
slots
:
p
rivate
slots
:
virtual
void
writeBytes
(
const
char
*
bytes
,
qint64
cB
ytes
);
virtual
void
_writeBytes
(
const
QByteArray
b
ytes
);
signals:
signals:
void
logFileStats
(
bool
logTimestamped
,
int
logDurationSecs
,
int
binaryBaudRate
);
void
logFileStats
(
bool
logTimestamped
,
int
logDurationSecs
,
int
binaryBaudRate
);
...
...
src/comm/MAVLinkProtocol.cc
View file @
70124a1e
...
@@ -438,7 +438,7 @@ void MAVLinkProtocol::_sendMessage(LinkInterface* link, mavlink_message_t messag
...
@@ -438,7 +438,7 @@ void MAVLinkProtocol::_sendMessage(LinkInterface* link, mavlink_message_t messag
if
(
link
->
isConnected
())
if
(
link
->
isConnected
())
{
{
// Send the portion of the buffer now occupied by the message
// Send the portion of the buffer now occupied by the message
link
->
writeBytes
((
const
char
*
)
buffer
,
len
);
link
->
writeBytes
Safe
((
const
char
*
)
buffer
,
len
);
}
}
}
}
...
@@ -461,7 +461,7 @@ void MAVLinkProtocol::_sendMessage(LinkInterface* link, mavlink_message_t messag
...
@@ -461,7 +461,7 @@ void MAVLinkProtocol::_sendMessage(LinkInterface* link, mavlink_message_t messag
if
(
link
->
isConnected
())
if
(
link
->
isConnected
())
{
{
// Send the portion of the buffer now occupied by the message
// Send the portion of the buffer now occupied by the message
link
->
writeBytes
((
const
char
*
)
buffer
,
len
);
link
->
writeBytes
Safe
((
const
char
*
)
buffer
,
len
);
}
}
}
}
...
...
src/comm/MockLink.cc
View file @
70124a1e
...
@@ -115,7 +115,6 @@ MockLink::MockLink(MockConfiguration* config)
...
@@ -115,7 +115,6 @@ MockLink::MockLink(MockConfiguration* config)
moveToThread
(
this
);
moveToThread
(
this
);
_loadParams
();
_loadParams
();
QObject
::
connect
(
this
,
&
MockLink
::
_incomingBytes
,
this
,
&
MockLink
::
_handleIncomingBytes
);
}
}
MockLink
::~
MockLink
(
void
)
MockLink
::~
MockLink
(
void
)
...
@@ -314,16 +313,7 @@ void MockLink::respondWithMavlinkMessage(const mavlink_message_t& msg)
...
@@ -314,16 +313,7 @@ void MockLink::respondWithMavlinkMessage(const mavlink_message_t& msg)
}
}
/// @brief Called when QGC wants to write bytes to the MAV
/// @brief Called when QGC wants to write bytes to the MAV
void
MockLink
::
writeBytes
(
const
char
*
bytes
,
qint64
cBytes
)
void
MockLink
::
_writeBytes
(
const
QByteArray
bytes
)
{
// Package up the data so we can signal it over to the right thread
QByteArray
byteArray
(
bytes
,
cBytes
);
emit
_incomingBytes
(
byteArray
);
}
/// @brief Handles bytes from QGC on the thread
void
MockLink
::
_handleIncomingBytes
(
const
QByteArray
bytes
)
{
{
if
(
_inNSH
)
{
if
(
_inNSH
)
{
_handleIncomingNSHBytes
(
bytes
.
constData
(),
bytes
.
count
());
_handleIncomingNSHBytes
(
bytes
.
constData
(),
bytes
.
count
());
...
...
src/comm/MockLink.h
View file @
70124a1e
...
@@ -150,12 +150,8 @@ public:
...
@@ -150,12 +150,8 @@ public:
static
MockLink
*
startAPMArduCopterMockLink
(
bool
sendStatusText
);
static
MockLink
*
startAPMArduCopterMockLink
(
bool
sendStatusText
);
static
MockLink
*
startAPMArduPlaneMockLink
(
bool
sendStatusText
);
static
MockLink
*
startAPMArduPlaneMockLink
(
bool
sendStatusText
);
signals:
private
slots
:
/// @brief Used internally to move data to the thread.
virtual
void
_writeBytes
(
const
QByteArray
bytes
);
void
_incomingBytes
(
const
QByteArray
bytes
);
public
slots
:
virtual
void
writeBytes
(
const
char
*
bytes
,
qint64
cBytes
);
private
slots
:
private
slots
:
void
_run1HzTasks
(
void
);
void
_run1HzTasks
(
void
);
...
@@ -172,7 +168,6 @@ private:
...
@@ -172,7 +168,6 @@ private:
// MockLink methods
// MockLink methods
void
_sendHeartBeat
(
void
);
void
_sendHeartBeat
(
void
);
void
_handleIncomingBytes
(
const
QByteArray
bytes
);
void
_handleIncomingNSHBytes
(
const
char
*
bytes
,
int
cBytes
);
void
_handleIncomingNSHBytes
(
const
char
*
bytes
,
int
cBytes
);
void
_handleIncomingMavlinkBytes
(
const
uint8_t
*
bytes
,
int
cBytes
);
void
_handleIncomingMavlinkBytes
(
const
uint8_t
*
bytes
,
int
cBytes
);
void
_loadParams
(
void
);
void
_loadParams
(
void
);
...
...
src/comm/QGCFlightGearLink.cc
View file @
70124a1e
...
@@ -234,7 +234,7 @@ void QGCFlightGearLink::updateControls(quint64 time, float rollAilerons, float p
...
@@ -234,7 +234,7 @@ void QGCFlightGearLink::updateControls(quint64 time, float rollAilerons, float p
{
{
QString
state
(
"%1
\t
%2
\t
%3
\t
%4
\t
%5
\n
"
);
QString
state
(
"%1
\t
%2
\t
%3
\t
%4
\t
%5
\n
"
);
state
=
state
.
arg
(
rollAilerons
).
arg
(
pitchElevator
).
arg
(
yawRudder
).
arg
(
true
).
arg
(
throttle
);
state
=
state
.
arg
(
rollAilerons
).
arg
(
pitchElevator
).
arg
(
yawRudder
).
arg
(
true
).
arg
(
throttle
);
writeBytes
(
state
.
toLatin1
().
constData
(),
state
.
length
());
emit
_invokeWriteBytes
(
state
.
toLatin1
());
//qDebug() << "Updated controls" << rollAilerons << pitchElevator << yawRudder << throttle;
//qDebug() << "Updated controls" << rollAilerons << pitchElevator << yawRudder << throttle;
//qDebug() << "Updated controls" << state;
//qDebug() << "Updated controls" << state;
}
}
...
@@ -244,13 +244,13 @@ void QGCFlightGearLink::updateControls(quint64 time, float rollAilerons, float p
...
@@ -244,13 +244,13 @@ void QGCFlightGearLink::updateControls(quint64 time, float rollAilerons, float p
}
}
}
}
void
QGCFlightGearLink
::
writeBytes
(
const
char
*
data
,
qint64
size
)
void
QGCFlightGearLink
::
_writeBytes
(
const
QByteArray
data
)
{
{
//#define QGCFlightGearLink_DEBUG
//#define QGCFlightGearLink_DEBUG
#ifdef QGCFlightGearLink_DEBUG
#ifdef QGCFlightGearLink_DEBUG
QString
bytes
;
QString
bytes
;
QString
ascii
;
QString
ascii
;
for
(
int
i
=
0
;
i
<
size
;
i
++
)
for
(
int
i
=
0
,
size
=
data
.
size
()
;
i
<
size
;
i
++
)
{
{
unsigned
char
v
=
data
[
i
];
unsigned
char
v
=
data
[
i
];
bytes
.
append
(
QString
().
sprintf
(
"%02x "
,
v
));
bytes
.
append
(
QString
().
sprintf
(
"%02x "
,
v
));
...
@@ -267,7 +267,7 @@ void QGCFlightGearLink::writeBytes(const char* data, qint64 size)
...
@@ -267,7 +267,7 @@ void QGCFlightGearLink::writeBytes(const char* data, qint64 size)
qDebug
()
<<
bytes
;
qDebug
()
<<
bytes
;
qDebug
()
<<
"ASCII:"
<<
ascii
;
qDebug
()
<<
"ASCII:"
<<
ascii
;
#endif
#endif
if
(
connectState
&&
_udpCommSocket
)
_udpCommSocket
->
writeDatagram
(
data
,
size
,
currentHost
,
currentPort
);
if
(
connectState
&&
_udpCommSocket
)
_udpCommSocket
->
writeDatagram
(
data
,
currentHost
,
currentPort
);
}
}
/**
/**
...
...
src/comm/QGCFlightGearLink.h
View file @
70124a1e
...
@@ -121,13 +121,17 @@ public slots:
...
@@ -121,13 +121,17 @@ public slots:
}
}
void
readBytes
();
void
readBytes
();
private
slots
:
/**
/**
* @brief Write a number of bytes to the interface.
* @brief Write a number of bytes to the interface.
*
*
* @param data Pointer to the data byte array
* @param data Pointer to the data byte array
* @param size The size of the bytes array
* @param size The size of the bytes array
**/
**/
void
writeBytes
(
const
char
*
data
,
qint64
length
);
void
_writeBytes
(
const
QByteArray
data
);
public
slots
:
bool
connectSimulation
();
bool
connectSimulation
();
bool
disconnectSimulation
();
bool
disconnectSimulation
();
...
...
src/comm/QGCHilLink.h
View file @
70124a1e
...
@@ -64,13 +64,26 @@ public slots:
...
@@ -64,13 +64,26 @@ public slots:
* @param data Pointer to the data byte array
* @param data Pointer to the data byte array
* @param size The size of the bytes array
* @param size The size of the bytes array
**/
**/
virtual
void
writeBytes
(
const
char
*
data
,
qint64
length
)
=
0
;
void
writeBytesSafe
(
const
char
*
data
,
int
length
)
{
emit
_invokeWriteBytes
(
QByteArray
(
data
,
length
));
}
virtual
bool
connectSimulation
()
=
0
;
virtual
bool
connectSimulation
()
=
0
;
virtual
bool
disconnectSimulation
()
=
0
;
virtual
bool
disconnectSimulation
()
=
0
;
private
slots
:
virtual
void
_writeBytes
(
const
QByteArray
)
=
0
;
protected:
protected:
virtual
void
setName
(
QString
name
)
=
0
;
virtual
void
setName
(
QString
name
)
=
0
;
QGCHilLink
()
:
QThread
()
{
connect
(
this
,
&
QGCHilLink
::
_invokeWriteBytes
,
this
,
&
QGCHilLink
::
_writeBytes
);
}
signals:
signals:
/**
/**
* @brief This signal is emitted instantly when the link is connected
* @brief This signal is emitted instantly when the link is connected
...
@@ -130,6 +143,9 @@ signals:
...
@@ -130,6 +143,9 @@ signals:
/** @brief Sensor leve HIL state changed */
/** @brief Sensor leve HIL state changed */
void
sensorHilChanged
(
bool
enabled
);
void
sensorHilChanged
(
bool
enabled
);
/** @brief Helper signal to force execution on the correct thread */
void
_invokeWriteBytes
(
QByteArray
);
};
};
#endif // QGCHILLINK_H
#endif // QGCHILLINK_H
src/comm/QGCJSBSimLink.cc
View file @
70124a1e
...
@@ -246,7 +246,7 @@ void QGCJSBSimLink::updateControls(quint64 time, float rollAilerons, float pitch
...
@@ -246,7 +246,7 @@ void QGCJSBSimLink::updateControls(quint64 time, float rollAilerons, float pitch
{
{
QString
state
(
"%1
\t
%2
\t
%3
\t
%4
\t
%5
\n
"
);
QString
state
(
"%1
\t
%2
\t
%3
\t
%4
\t
%5
\n
"
);
state
=
state
.
arg
(
rollAilerons
).
arg
(
pitchElevator
).
arg
(
yawRudder
).
arg
(
true
).
arg
(
throttle
);
state
=
state
.
arg
(
rollAilerons
).
arg
(
pitchElevator
).
arg
(
yawRudder
).
arg
(
true
).
arg
(
throttle
);
writeBytes
(
state
.
toLatin1
().
constData
(),
state
.
length
());
emit
_invokeWriteBytes
(
state
.
toLatin1
());
}
}
else
else
{
{
...
@@ -255,13 +255,13 @@ void QGCJSBSimLink::updateControls(quint64 time, float rollAilerons, float pitch
...
@@ -255,13 +255,13 @@ void QGCJSBSimLink::updateControls(quint64 time, float rollAilerons, float pitch
//qDebug() << "Updated controls" << state;
//qDebug() << "Updated controls" << state;
}
}
void
QGCJSBSimLink
::
writeBytes
(
const
char
*
data
,
qint64
size
)
void
QGCJSBSimLink
::
_writeBytes
(
const
QByteArray
data
)
{
{
//#define QGCJSBSimLink_DEBUG
//#define QGCJSBSimLink_DEBUG
#ifdef QGCJSBSimLink_DEBUG
#ifdef QGCJSBSimLink_DEBUG
QString
bytes
;
QString
bytes
;
QString
ascii
;
QString
ascii
;
for
(
int
i
=
0
;
i
<
size
;
i
++
)
for
(
int
i
=
0
,
size
=
data
.
size
()
;
i
<
size
;
i
++
)
{
{
unsigned
char
v
=
data
[
i
];
unsigned
char
v
=
data
[
i
];
bytes
.
append
(
QString
().
sprintf
(
"%02x "
,
v
));
bytes
.
append
(
QString
().
sprintf
(
"%02x "
,
v
));
...
@@ -278,7 +278,7 @@ void QGCJSBSimLink::writeBytes(const char* data, qint64 size)
...
@@ -278,7 +278,7 @@ void QGCJSBSimLink::writeBytes(const char* data, qint64 size)
qDebug
()
<<
bytes
;
qDebug
()
<<
bytes
;
qDebug
()
<<
"ASCII:"
<<
ascii
;
qDebug
()
<<
"ASCII:"
<<
ascii
;
#endif
#endif
if
(
connectState
&&
socket
)
socket
->
writeDatagram
(
data
,
size
,
currentHost
,
currentPort
);
if
(
connectState
&&
socket
)
socket
->
writeDatagram
(
data
,
currentHost
,
currentPort
);
}
}
/**
/**
...
...
src/comm/QGCJSBSimLink.h
View file @
70124a1e
...
@@ -114,13 +114,17 @@ public slots:
...
@@ -114,13 +114,17 @@ public slots:
}
}
void
readBytes
();
void
readBytes
();
private
slots
:
/**
/**
* @brief Write a number of bytes to the interface.
* @brief Write a number of bytes to the interface.
*
*
* @param data Pointer to the data byte array
* @param data Pointer to the data byte array
* @param size The size of the bytes array
* @param size The size of the bytes array
**/
**/
void
writeBytes
(
const
char
*
data
,
qint64
length
);
void
_writeBytes
(
const
QByteArray
data
);
public
slots
:
bool
connectSimulation
();
bool
connectSimulation
();
bool
disconnectSimulation
();
bool
disconnectSimulation
();
...
...
src/comm/QGCXPlaneLink.cc
View file @
70124a1e
...
@@ -229,7 +229,7 @@ void QGCXPlaneLink::run()
...
@@ -229,7 +229,7 @@ void QGCXPlaneLink::run()
strncpy
(
ip
.
str_port_them
,
localPortStr
.
toLatin1
(),
qMin
((
int
)
sizeof
(
ip
.
str_port_them
),
6
));
strncpy
(
ip
.
str_port_them
,
localPortStr
.
toLatin1
(),
qMin
((
int
)
sizeof
(
ip
.
str_port_them
),
6
));
ip
.
use_ip
=
1
;
ip
.
use_ip
=
1
;
writeBytes
((
const
char
*
)
&
ip
,
sizeof
(
ip
));
writeBytes
Safe
((
const
char
*
)
&
ip
,
sizeof
(
ip
));
_should_exit
=
false
;
_should_exit
=
false
;
...
@@ -395,10 +395,10 @@ void QGCXPlaneLink::updateControls(quint64 time, float rollAilerons, float pitch
...
@@ -395,10 +395,10 @@ void QGCXPlaneLink::updateControls(quint64 time, float rollAilerons, float pitch
{
{
// Ail / Elevon / Rudder
// Ail / Elevon / Rudder
p
.
index
=
12
;
// XPlane, wing sweep
p
.
index
=
12
;
// XPlane, wing sweep
writeBytes
((
const
char
*
)
&
p
,
sizeof
(
p
));
writeBytes
Safe
((
const
char
*
)
&
p
,
sizeof
(
p
));
p
.
index
=
8
;
// XPlane, joystick? why?
p
.
index
=
8
;
// XPlane, joystick? why?
writeBytes
((
const
char
*
)
&
p
,
sizeof
(
p
));
writeBytes
Safe
((
const
char
*
)
&
p
,
sizeof
(
p
));
p
.
index
=
25
;
// Thrust
p
.
index
=
25
;
// Thrust
memset
(
p
.
f
,
0
,
sizeof
(
p
.
f
));
memset
(
p
.
f
,
0
,
sizeof
(
p
.
f
));
...
@@ -408,13 +408,13 @@ void QGCXPlaneLink::updateControls(quint64 time, float rollAilerons, float pitch
...
@@ -408,13 +408,13 @@ void QGCXPlaneLink::updateControls(quint64 time, float rollAilerons, float pitch
p
.
f
[
3
]
=
throttle
;
p
.
f
[
3
]
=
throttle
;
// Throttle
// Throttle
writeBytes
((
const
char
*
)
&
p
,
sizeof
(
p
));
writeBytes
Safe
((
const
char
*
)
&
p
,
sizeof
(
p
));
}
}
else
else
{
{
qDebug
()
<<
"Transmitting p.index = 25"
;
qDebug
()
<<
"Transmitting p.index = 25"
;
p
.
index
=
25
;
// XPlane, throttle command.
p
.
index
=
25
;
// XPlane, throttle command.
writeBytes
((
const
char
*
)
&
p
,
sizeof
(
p
));
writeBytes
Safe
((
const
char
*
)
&
p
,
sizeof
(
p
));
}
}
}
}
...
@@ -448,14 +448,14 @@ Eigen::Matrix3f euler_to_wRo(double yaw, double pitch, double roll) {
...
@@ -448,14 +448,14 @@ Eigen::Matrix3f euler_to_wRo(double yaw, double pitch, double roll) {
return
wRo
;
return
wRo
;
}
}
void
QGCXPlaneLink
::
writeBytes
(
const
char
*
data
,
qint64
size
)
void
QGCXPlaneLink
::
_writeBytes
(
const
QByteArray
data
)
{
{
if
(
!
data
)
return
;
if
(
data
.
isEmpty
()
)
return
;
// If socket exists and is connected, transmit the data
// If socket exists and is connected, transmit the data
if
(
socket
&&
connectState
)
if
(
socket
&&
connectState
)
{
{
socket
->
writeDatagram
(
data
,
size
,
remoteHost
,
remotePort
);
socket
->
writeDatagram
(
data
,
remoteHost
,
remotePort
);
}
}
}
}
...
@@ -899,7 +899,7 @@ void QGCXPlaneLink::setPositionAttitude(double lat, double lon, double alt, doub
...
@@ -899,7 +899,7 @@ void QGCXPlaneLink::setPositionAttitude(double lat, double lon, double alt, doub
pos
.
gear_flap_vect
[
1
]
=
0.0
f
;
pos
.
gear_flap_vect
[
1
]
=
0.0
f
;
pos
.
gear_flap_vect
[
2
]
=
0.0
f
;
pos
.
gear_flap_vect
[
2
]
=
0.0
f
;
writeBytes
((
const
char
*
)
&
pos
,
sizeof
(
pos
));
writeBytes
Safe
((
const
char
*
)
&
pos
,
sizeof
(
pos
));
// pos.header[0] = 'V';
// pos.header[0] = 'V';
// pos.header[1] = 'E';
// pos.header[1] = 'E';
...
@@ -917,7 +917,7 @@ void QGCXPlaneLink::setPositionAttitude(double lat, double lon, double alt, doub
...
@@ -917,7 +917,7 @@ void QGCXPlaneLink::setPositionAttitude(double lat, double lon, double alt, doub
// pos.gear_flap_vect[1] = -999;
// pos.gear_flap_vect[1] = -999;
// pos.gear_flap_vect[2] = -999;
// pos.gear_flap_vect[2] = -999;
// writeBytes((const char*)&pos, sizeof(pos));
// writeBytes
Safe
((const char*)&pos, sizeof(pos));
}
}
/**
/**
...
...
src/comm/QGCXPlaneLink.h
View file @
70124a1e
...
@@ -126,13 +126,17 @@ public slots:
...
@@ -126,13 +126,17 @@ public slots:
void
processError
(
QProcess
::
ProcessError
err
);
void
processError
(
QProcess
::
ProcessError
err
);
void
readBytes
();
void
readBytes
();
private
slots
:
/**
/**
* @brief Write a number of bytes to the interface.
* @brief Write a number of bytes to the interface.
*
*
* @param data Pointer to the data byte array
* @param data Pointer to the data byte array
* @param size The size of the bytes array
* @param size The size of the bytes array
**/
**/
void
writeBytes
(
const
char
*
data
,
qint64
length
);
void
_writeBytes
(
const
QByteArray
data
);
public
slots
:
bool
connectSimulation
();
bool
connectSimulation
();
bool
disconnectSimulation
();
bool
disconnectSimulation
();
/**
/**
...
...
src/comm/SerialLink.cc
View file @
70124a1e
...
@@ -82,11 +82,11 @@ bool SerialLink::_isBootloader()
...
@@ -82,11 +82,11 @@ bool SerialLink::_isBootloader()
return
false
;
return
false
;
}
}
void
SerialLink
::
writeBytes
(
const
char
*
data
,
qint64
size
)
void
SerialLink
::
_writeBytes
(
const
QByteArray
data
)
{
{
if
(
_port
&&
_port
->
isOpen
())
{
if
(
_port
&&
_port
->
isOpen
())
{
_logOutputDataRate
(
size
,
QDateTime
::
currentMSecsSinceEpoch
());
_logOutputDataRate
(
data
.
size
()
,
QDateTime
::
currentMSecsSinceEpoch
());
_port
->
write
(
data
,
size
);
_port
->
write
(
data
);
}
else
{
}
else
{
// Error occured
// Error occured
_emitLinkError
(
tr
(
"Could not send data - link %1 is disconnected!"
).
arg
(
getName
()));
_emitLinkError
(
tr
(
"Could not send data - link %1 is disconnected!"
).
arg
(
getName
()));
...
...
src/comm/SerialLink.h
View file @
70124a1e
...
@@ -157,15 +157,16 @@ public:
...
@@ -157,15 +157,16 @@ public:
bool
connect
(
void
);
bool
connect
(
void
);
bool
disconnect
(
void
);
bool
disconnect
(
void
);
p
ublic
slots
:
p
rivate
slots
:
/**
/**
* @brief Write a number of bytes to the interface.
* @brief Write a number of bytes to the interface.
*
*
* @param data Pointer to the data byte array
* @param data Pointer to the data byte array
* @param size The size of the bytes array
* @param size The size of the bytes array
**/
**/
void
writeBytes
(
const
char
*
data
,
qint64
length
);
void
_writeBytes
(
const
QByteArray
data
);
public
slots
:
void
linkError
(
QSerialPort
::
SerialPortError
error
);
void
linkError
(
QSerialPort
::
SerialPortError
error
);
protected:
protected:
...
...
src/comm/TCPLink.cc
View file @
70124a1e
...
@@ -65,11 +65,11 @@ void TCPLink::run()
...
@@ -65,11 +65,11 @@ void TCPLink::run()
}
}
#ifdef TCPLINK_READWRITE_DEBUG
#ifdef TCPLINK_READWRITE_DEBUG
void
TCPLink
::
_writeDebugBytes
(
const
char
*
data
,
qint16
size
)
void
TCPLink
::
_writeDebugBytes
(
const
QByteArray
data
)
{
{
QString
bytes
;
QString
bytes
;
QString
ascii
;
QString
ascii
;
for
(
int
i
=
0
;
i
<
size
;
i
++
)
for
(
int
i
=
0
,
size
=
data
.
size
()
;
i
<
size
;
i
++
)
{
{
unsigned
char
v
=
data
[
i
];
unsigned
char
v
=
data
[
i
];
bytes
.
append
(
QString
().
sprintf
(
"%02x "
,
v
));
bytes
.
append
(
QString
().
sprintf
(
"%02x "
,
v
));
...
@@ -88,13 +88,16 @@ void TCPLink::_writeDebugBytes(const char *data, qint16 size)
...
@@ -88,13 +88,16 @@ void TCPLink::_writeDebugBytes(const char *data, qint16 size)
}
}
#endif
#endif
void
TCPLink
::
writeBytes
(
const
char
*
data
,
qint64
size
)
void
TCPLink
::
_writeBytes
(
const
QByteArray
data
)
{
{
#ifdef TCPLINK_READWRITE_DEBUG
#ifdef TCPLINK_READWRITE_DEBUG
_writeDebugBytes
(
data
,
size
);
_writeDebugBytes
(
data
);
#endif
#endif
_socket
->
write
(
data
,
size
);
if
(
!
_socket
)
_logOutputDataRate
(
size
,
QDateTime
::
currentMSecsSinceEpoch
());
return
;
_socket
->
write
(
data
);
_logOutputDataRate
(
data
.
size
(),
QDateTime
::
currentMSecsSinceEpoch
());
}
}
/**
/**
...
...
src/comm/TCPLink.h
View file @
70124a1e
...
@@ -152,10 +152,11 @@ public:
...
@@ -152,10 +152,11 @@ public:
bool
connect
(
void
);
bool
connect
(
void
);
bool
disconnect
(
void
);
bool
disconnect
(
void
);
public
slots
:
private
slots
:
// From LinkInterface
// From LinkInterface
void
writeBytes
(
const
char
*
data
,
qint64
length
);
void
_writeBytes
(
const
QByteArray
data
);
public
slots
:
void
waitForBytesWritten
(
int
msecs
);
void
waitForBytesWritten
(
int
msecs
);
void
waitForReadyRead
(
int
msecs
);
void
waitForReadyRead
(
int
msecs
);
...
@@ -182,7 +183,7 @@ private:
...
@@ -182,7 +183,7 @@ private:
void
_restartConnection
();
void
_restartConnection
();
#ifdef TCPLINK_READWRITE_DEBUG
#ifdef TCPLINK_READWRITE_DEBUG
void
_writeDebugBytes
(
const
char
*
data
,
qint16
size
);
void
_writeDebugBytes
(
const
QByteArray
data
);
#endif
#endif
TCPConfiguration
*
_config
;
TCPConfiguration
*
_config
;
...
...
src/comm/UDPLink.cc
View file @
70124a1e
...
@@ -29,12 +29,6 @@ This file is part of the QGROUNDCONTROL project
...
@@ -29,12 +29,6 @@ This file is part of the QGROUNDCONTROL project
*/
*/
#include <QtGlobal>
#include <QtGlobal>
#if QT_VERSION > 0x050401
#define UDP_BROKEN_SIGNAL 1
#else
#define UDP_BROKEN_SIGNAL 0
#endif
#include <QTimer>
#include <QTimer>
#include <QList>
#include <QList>
#include <QDebug>
#include <QDebug>
...
@@ -111,9 +105,6 @@ UDPLink::~UDPLink()
...
@@ -111,9 +105,6 @@ UDPLink::~UDPLink()
quit
();
quit
();
// Wait for it to exit
// Wait for it to exit
wait
();
wait
();
while
(
_outQueue
.
count
()
>
0
)
{
delete
_outQueue
.
dequeue
();
}
this
->
deleteLater
();
this
->
deleteLater
();
}
}
...
@@ -124,25 +115,7 @@ UDPLink::~UDPLink()
...
@@ -124,25 +115,7 @@ UDPLink::~UDPLink()
void
UDPLink
::
run
()
void
UDPLink
::
run
()
{
{
if
(
_hardwareConnect
())
{
if
(
_hardwareConnect
())
{
if
(
UDP_BROKEN_SIGNAL
)
{
exec
();
bool
loop
=
false
;
while
(
true
)
{
//-- Anything to read?
loop
=
_socket
->
hasPendingDatagrams
();
if
(
loop
)
{
readBytes
();
}
//-- Loop right away if busy
if
((
_dequeBytes
()
||
loop
)
&&
_running
)
continue
;
if
(
!
_running
)
break
;
//-- Settle down (it gets here if there is nothing to read or write)
_socket
->
waitForReadyRead
(
5
);
}
}
else
{
exec
();
}
}
}
if
(
_socket
)
{
if
(
_socket
)
{
_deregisterZeroconf
();
_deregisterZeroconf
();
...
@@ -174,36 +147,11 @@ void UDPLink::removeHost(const QString& host)
...
@@ -174,36 +147,11 @@ void UDPLink::removeHost(const QString& host)
_config
->
removeHost
(
host
);
_config
->
removeHost
(
host
);
}
}
void
UDPLink
::
writeBytes
(
const
char
*
data
,
qint64
size
)
void
UDPLink
::
_writeBytes
(
const
QByteArray
data
)
{
{
if
(
!
_socket
)
{
if
(
!
_socket
)
return
;
return
;
}
if
(
UDP_BROKEN_SIGNAL
)
{
QByteArray
*
qdata
=
new
QByteArray
(
data
,
size
);
QMutexLocker
lock
(
&
_mutex
);
_outQueue
.
enqueue
(
qdata
);
}
else
{
_sendBytes
(
data
,
size
);
}
}
bool
UDPLink
::
_dequeBytes
()
{
QMutexLocker
lock
(
&
_mutex
);
if
(
_outQueue
.
count
()
>
0
)
{
QByteArray
*
qdata
=
_outQueue
.
dequeue
();
lock
.
unlock
();
_sendBytes
(
qdata
->
data
(),
qdata
->
size
());
delete
qdata
;
lock
.
relock
();
}
return
(
_outQueue
.
count
()
>
0
);
}
void
UDPLink
::
_sendBytes
(
const
char
*
data
,
qint64
size
)
{
QStringList
goneHosts
;
QStringList
goneHosts
;
// Send to all connected systems
// Send to all connected systems
QString
host
;
QString
host
;
...
@@ -211,7 +159,7 @@ void UDPLink::_sendBytes(const char* data, qint64 size)
...
@@ -211,7 +159,7 @@ void UDPLink::_sendBytes(const char* data, qint64 size)
if
(
_config
->
firstHost
(
host
,
port
))
{
if
(
_config
->
firstHost
(
host
,
port
))
{
do
{
do
{
QHostAddress
currentHost
(
host
);
QHostAddress
currentHost
(
host
);
if
(
_socket
->
writeDatagram
(
data
,
size
,
currentHost
,
(
quint16
)
port
)
<
0
)
{
if
(
_socket
->
writeDatagram
(
data
,
currentHost
,
(
quint16
)
port
)
<
0
)
{
// This host is gone. Add to list to be removed
// This host is gone. Add to list to be removed
// We should keep track of hosts that were manually added (static) and
// We should keep track of hosts that were manually added (static) and
// hosts that were added because we heard from them (dynamic). Only
// hosts that were added because we heard from them (dynamic). Only
...
@@ -225,7 +173,7 @@ void UDPLink::_sendBytes(const char* data, qint64 size)
...
@@ -225,7 +173,7 @@ void UDPLink::_sendBytes(const char* data, qint64 size)
// "host not there" takes time too regardless of size of data. In fact,
// "host not there" takes time too regardless of size of data. In fact,
// 1 byte or "UDP frame size" bytes are the same as that's the data
// 1 byte or "UDP frame size" bytes are the same as that's the data
// unit sent by UDP.
// unit sent by UDP.
_logOutputDataRate
(
size
,
QDateTime
::
currentMSecsSinceEpoch
());
_logOutputDataRate
(
data
.
size
()
,
QDateTime
::
currentMSecsSinceEpoch
());
}
}
}
while
(
_config
->
nextHost
(
host
,
port
));
}
while
(
_config
->
nextHost
(
host
,
port
));
//-- Remove hosts that are no longer there
//-- Remove hosts that are no longer there
...
@@ -260,8 +208,6 @@ void UDPLink::readBytes()
...
@@ -260,8 +208,6 @@ void UDPLink::readBytes()
// would trigger this.
// would trigger this.
// Add host to broadcast list if not yet present, or update its port
// Add host to broadcast list if not yet present, or update its port
_config
->
addHost
(
sender
.
toString
(),
(
int
)
senderPort
);
_config
->
addHost
(
sender
.
toString
(),
(
int
)
senderPort
);
if
(
UDP_BROKEN_SIGNAL
&&
!
_running
)
break
;
}
}
//-- Send whatever is left
//-- Send whatever is left
if
(
databuffer
.
size
())
{
if
(
databuffer
.
size
())
{
...
@@ -326,10 +272,7 @@ bool UDPLink::_hardwareConnect()
...
@@ -326,10 +272,7 @@ bool UDPLink::_hardwareConnect()
_socket
->
setSocketOption
(
QAbstractSocket
::
ReceiveBufferSizeSocketOption
,
512
*
1024
);
_socket
->
setSocketOption
(
QAbstractSocket
::
ReceiveBufferSizeSocketOption
,
512
*
1024
);
#endif
#endif
_registerZeroconf
(
_config
->
localPort
(),
kZeroconfRegistration
);
_registerZeroconf
(
_config
->
localPort
(),
kZeroconfRegistration
);
//-- Connect signal if this version of Qt is not broken
QObject
::
connect
(
_socket
,
&
QUdpSocket
::
readyRead
,
this
,
&
UDPLink
::
readBytes
);
if
(
!
UDP_BROKEN_SIGNAL
)
{
QObject
::
connect
(
_socket
,
&
QUdpSocket
::
readyRead
,
this
,
&
UDPLink
::
readBytes
);
}
emit
connected
();
emit
connected
();
}
else
{
}
else
{
emit
communicationError
(
"UDP Link Error"
,
"Error binding UDP port"
);
emit
communicationError
(
"UDP Link Error"
,
"Error binding UDP port"
);
...
...
src/comm/UDPLink.h
View file @
70124a1e
...
@@ -201,13 +201,14 @@ public slots:
...
@@ -201,13 +201,14 @@ public slots:
void
readBytes
();
void
readBytes
();
private
slots
:
/*!
/*!
* @brief Write a number of bytes to the interface.
* @brief Write a number of bytes to the interface.
*
*
* @param data Pointer to the data byte array
* @param data Pointer to the data byte array
* @param size The size of the bytes array
* @param size The size of the bytes array
**/
**/
void
writeBytes
(
const
char
*
data
,
qint64
length
);
void
_writeBytes
(
const
QByteArray
data
);
protected:
protected:
...
@@ -235,12 +236,6 @@ private:
...
@@ -235,12 +236,6 @@ private:
#endif
#endif
bool
_running
;
bool
_running
;
QMutex
_mutex
;
QQueue
<
QByteArray
*>
_outQueue
;
bool
_dequeBytes
();
void
_sendBytes
(
const
char
*
data
,
qint64
size
);
};
};
#endif // UDPLINK_H
#endif // UDPLINK_H
src/comm/XbeeLink.cpp
View file @
70124a1e
...
@@ -172,17 +172,11 @@ void XbeeLink::_disconnect(void)
...
@@ -172,17 +172,11 @@ void XbeeLink::_disconnect(void)
emit
disconnected
();
emit
disconnected
();
}
}
void
XbeeLink
::
writeBytes
(
const
char
*
bytes
,
qint64
length
)
// TO DO: delete the data array
void
XbeeLink
::
_writeBytes
(
const
QByteArray
bytes
)
{
{
char
*
data
;
if
(
!
xbee_nsenddata
(
this
->
m_xbeeCon
,
const_cast
<
char
*>
(
bytes
.
data
()),
bytes
.
size
()))
// return value of 0 is successful written
data
=
new
char
[
length
];
for
(
long
i
=
0
;
i
<
length
;
i
++
)
{
{
data
[
i
]
=
bytes
[
i
];
_logOutputDataRate
(
bytes
.
size
(),
QDateTime
::
currentMSecsSinceEpoch
());
}
if
(
!
xbee_nsenddata
(
this
->
m_xbeeCon
,
data
,
length
))
// return value of 0 is successful written
{
_logOutputDataRate
(
length
,
QDateTime
::
currentMSecsSinceEpoch
());
}
}
else
else
{
{
...
...
src/comm/XbeeLink.h
View file @
70124a1e
...
@@ -45,8 +45,8 @@ public:
...
@@ -45,8 +45,8 @@ public:
qint64
getCurrentOutDataRate
()
const
;
qint64
getCurrentOutDataRate
()
const
;
qint64
getCurrentInDataRate
()
const
;
qint64
getCurrentInDataRate
()
const
;
p
ublic
slots
:
// virtual functions from LinkInterface
p
rivate
slots
:
// virtual functions from LinkInterface
void
writeBytes
(
const
char
*
bytes
,
qint64
length
);
void
_writeBytes
(
const
QByteArray
bytes
);
protected
slots
:
// virtual functions from LinkInterface
protected
slots
:
// virtual functions from LinkInterface
void
readBytes
();
void
readBytes
();
...
...
src/qgcunittest/TCPLinkTest.cc
View file @
70124a1e
...
@@ -154,7 +154,7 @@ void TCPLinkUnitTest::_connectSucceed_test(void)
...
@@ -154,7 +154,7 @@ void TCPLinkUnitTest::_connectSucceed_test(void)
const
char
*
bytesWrittenSignal
=
SIGNAL
(
bytesWritten
(
qint64
));
const
char
*
bytesWrittenSignal
=
SIGNAL
(
bytesWritten
(
qint64
));
MultiSignalSpy
bytesWrittenSpy
;
MultiSignalSpy
bytesWrittenSpy
;
QCOMPARE
(
bytesWrittenSpy
.
init
(
_link
->
getSocket
(),
&
bytesWrittenSignal
,
1
),
true
);
QCOMPARE
(
bytesWrittenSpy
.
init
(
_link
->
getSocket
(),
&
bytesWrittenSignal
,
1
),
true
);
_link
->
writeBytes
(
bytesOut
.
data
(),
bytesOut
.
size
());
_link
->
writeBytes
Safe
(
bytesOut
.
data
(),
bytesOut
.
size
());
_multiSpy
->
clearAllSignals
();
_multiSpy
->
clearAllSignals
();
// We emit this signal such that it will be queued and run on the TCPLink thread. This in turn
// We emit this signal such that it will be queued and run on the TCPLink thread. This in turn
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment