23 #include <QAbstractSocket>
25 #include <QDomElement>
31 #include <QXmlStreamWriter>
47 , qsHost(
"127.0.0.1" )
50 , bCallsignLookup( true )
51 , bGroundTraffic( false )
55 , fdCallsignCleanupTimestamp( 0 )
59 QObject::connect(
pqTcpSocket, SIGNAL( error( QAbstractSocket::SocketError ) ),
this, SLOT(
slotTcpError( QAbstractSocket::SocketError ) ) );
76 switch( _eOperatingMode )
95 qCritical(
"ERROR[%s]: Failed to switch operating mode; host=%s, port=%d", Q_FUNC_INFO, qPrintable(
qsHost ),
iPort );
111 if( __poDeviceTcpSbs1EditView->exec() == QDialog::Accepted )
showDetail();
112 delete __poDeviceTcpSbs1EditView;
117 QDomElement __qDomElement = _rqDomElement.firstChildElement(
"Configuration" );
118 if( __qDomElement.isNull() )
return;
119 qsHost = __qDomElement.attribute(
"host",
"127.0.0.1" );
120 iPort = __qDomElement.attribute(
"port",
"30003" ).toInt();
122 bCallsignLookup = (bool)__qDomElement.attribute(
"callsign_lookup",
"1" ).toInt();
123 bGroundTraffic = (bool)__qDomElement.attribute(
"ground_traffic",
"0" ).toInt();
129 _rqXmlStreamWriter.writeStartElement(
"Device" );
131 _rqXmlStreamWriter.writeAttribute(
"name",
qsName );
132 _rqXmlStreamWriter.writeAttribute(
"driver",
"tcp_sbs1" );
134 _rqXmlStreamWriter.writeStartElement(
"Configuration" );
135 _rqXmlStreamWriter.writeAttribute(
"host",
qsHost );
136 _rqXmlStreamWriter.writeAttribute(
"port", QString::number(
iPort ) );
138 _rqXmlStreamWriter.writeAttribute(
"callsign_lookup", QString::number( (
int)
bCallsignLookup ) );
139 _rqXmlStreamWriter.writeAttribute(
"ground_traffic", QString::number( (
int)
bGroundTraffic ) );
140 _rqXmlStreamWriter.writeEndElement();
142 _rqXmlStreamWriter.writeEndElement();
156 qDebug(
"DEBUG[%s]: Device successfully started", Q_FUNC_INFO );
165 qCritical(
"ERROR[%s]: Connection error; %s", Q_FUNC_INFO, qPrintable( __qsError ) );
166 emit
signalError( QString( tr(
"Connection error")+
"; %1" ).arg( __qsError ) );
175 static const QRegExp __qRegExpYMD(
"^(197\\d|19[89]\\d|[2-9]\\d\\d\\d)/(0?[1-9]|1[12])/(0?[1-9]|[12]\\d|3[01])$" );
176 static const QRegExp __qRegExpHMS(
"^(0?\\d|1\\d|2[0-3]):(0?\\d|[1-5]\\d):(0?\\d|[1-5]\\d(\\.\\d+)?)$" );
180 __pqMutexDataChange->lock();
190 QString __qsDataLine = QString::fromLatin1(
pqTcpSocket->readLine().trimmed() );
197 if( __qsDataLine.isEmpty() )
continue;
202 QStringList __qDataFields = __qsDataLine.split(
"," );
203 if( __qDataFields.at( 0 ) !=
"MSG" )
continue;
204 if( __qDataFields.size() != 22 )
continue;
205 if( ( __iMSG = __qDataFields.at( 1 ).toInt() ) > 4 )
continue;
206 if( __qDataFields.at( 21 ).toInt() < 0 && !
bGroundTraffic )
continue;
207 if( __qDataFields.at( 4 ).isEmpty() )
continue;
208 QString __qsSource = __qDataFields.at( 4 );
214 QString __qsCallsign;
222 for( QList<QString>::const_iterator __iqsSource = __qListSource.begin();
223 __iqsSource != __qListSource.end();
226 if( __fdTimestamp -
qHashCallsign[ *__iqsSource ].fdTimestamp > (
double)900.0 )
231 if( !__qDataFields.at( 10 ).isEmpty() )
233 __qsCallsign = __qDataFields.at( 10 ).trimmed();
235 qHashCallsign[ __qsSource ].update( __qsCallsign, __fdTimestamp );
242 __qsCallsign =
qHashCallsign[ __qsSource ].get( __fdTimestamp );
246 __qsSource = __qsCallsign;
248 if( __iMSG == 1 )
continue;
254 bool __bDataAvailable =
false;
257 if( !__qDataFields.at( 6 ).isEmpty() && !__qDataFields.at( 7 ).isEmpty()
258 && __qRegExpYMD.exactMatch( __qDataFields.at( 6 ) ) && __qRegExpHMS.exactMatch( __qDataFields.at( 7 ) ) )
260 QDateTime __qDateTime;
262 __qDateTime.setDate( QDate( __qRegExpYMD.cap(1).toInt(), __qRegExpYMD.cap(2).toInt(), __qRegExpYMD.cap(3).toInt() ) );
263 __qDateTime.setTime( QTime( __qRegExpHMS.cap(1).toInt(), __qRegExpHMS.cap(2).toInt(), __qRegExpHMS.cap(3).toInt(), !__qRegExpHMS.cap(4).isEmpty() ? 1000*__qRegExpHMS.cap(4).toDouble() : 0 ) );
264 __oDeviceDataFix.
setTime( (
double)__qDateTime.toTime_t() );
269 __oDeviceDataFix.
setTime( (
double)QDateTime::currentDateTime().toTime_t() );
274 if( !__qDataFields.at( 14 ).isEmpty() && !__qDataFields.at( 15 ).isEmpty() )
276 if( !__qDataFields.at( 11 ).isEmpty() )
278 __oDeviceDataFix.
setPosition( __qDataFields.at( 15 ).toDouble(), __qDataFields.at( 14 ).toDouble(), __qDataFields.at( 11 ).toDouble() * 0.3048 );
283 __oDeviceDataFix.
setPosition( __qDataFields.at( 15 ).toDouble(), __qDataFields.at( 14 ).toDouble() );
286 __bDataAvailable =
true;
290 if( !__qDataFields.at( 13 ).isEmpty() )
292 __oDeviceDataFix.
setBearing( __qDataFields.at( 13 ).toDouble() );
293 __bDataAvailable =
true;
299 if( !__qDataFields.at( 12 ).isEmpty() )
301 if( !__qDataFields.at( 16 ).isEmpty() )
303 __oDeviceDataFix.
setSpeed( __qDataFields.at( 12 ).toDouble() / 1.94384449244, __qDataFields.at( 16 ).toDouble() / 196.8503937 );
307 __oDeviceDataFix.
setSpeed( __qDataFields.at( 12 ).toDouble() / 1.94384449244 );
309 __bDataAvailable =
true;
315 __oDeviceDataFix.
setText(
bCallsignLookup ?
"HEX:"+__qDataFields.at( 4 ) :
"C/S:"+__qDataFields.at( 10 ) );
316 __bDataAvailable =
true;
320 if( __bDataAvailable )
328 __pqMutexDataChange->unlock();
345 qDebug(
"DEBUG[%s]: Device successfully stopped", Q_FUNC_INFO );
356 qDebug(
"DEBUG[%s]: Device successfully paused", Q_FUNC_INFO );
void setBearing(double _fdBearing)
Sets this course's bearing, in degrees.
void setSpeed(double _fdSpeed, double _fdSpeedVertical=UNDEFINED_SPEED)
Sets this course's horizontal speed, in meters per second.
void setPosition(double _fdLongitude, double _fdLatitude, double _fdElevation=UNDEFINED_ELEVATION)
Sets new coordinates.
void setTime(double _fdTime)
Sets the time, in seconds from Unix epoch.
Fix data [source,time,position,course,DOPs,...].
void setText(const QString &_rqsText)
Sets the additional textual data string.
void setType(int _eType)
Sets the fix type.
void setCourseFromPosition(bool _bCourseFromPosition)
Sets whether to use position to compute course.
void setSourceType(EType _eType)
Sets the source type.
virtual void refreshContent()
Refreshes the content of the underlying widget.
[UI] Route container's edit view
Callsign dictionary entry.
QTcpSocket * pqTcpSocket
TCP socket.
virtual void showDetail()
Displays the device's details (in the appropriate widget/view)
void parseQVCT(const QDomElement &_rqDomElement)
Retrieves the device's configuration from the given QVCT source (file)
double fdCallsignCleanupTimestamp
Callsign dictionary cleanup timestamp.
CUnitTimeZone::EUnit eTimeZone
Time zone.
bool bPaused
Pause status.
bool bStarted
Start status.
virtual void showEdit()
Displays the device's edit (configuration) widget/view.
QString qsHost
Network host.
QVCT::EStatus pause()
Pause the device.
void slotProcessData()
Slots to process device data.
virtual ~CDeviceTcpSbs1()
CDeviceTcpSbs1(const QString &_rqsName)
void slotTcpConnected()
Slots to report TCP connection.
void slotTcpError(QAbstractSocket::SocketError _qSocketError)
Slots to report TCP error.
QHash< QString, CCallsign > qHashCallsign
Callsign dictionary.
bool bGroundTraffic
Ground traffic (inclusion/track)
QVCT::EStatus start()
Stop the device.
bool bCallsignLookup
Callsign lookup.
QVCT::EStatus setOperatingMode(CDevice::EOperatingMode _eOperatingMode)
Sets the device's operating mode.
QVCT::EStatus stop()
Start the device.
void dumpQVCT(QXmlStreamWriter &_rqXmlStreamWriter) const
Stores the device's configuration to the given QVCT destination (file)
CDevice::EOperatingMode status()
Returns the device's status (operating mode)
Generic navigation device (GPS, speedometer, compass, etc.)
void signalDataFix(const CDeviceDataFix &_roDeviceDataFix)
Signal emitted by the device when an updated fix is available.
void signalActivity()
Signal emitted by the device when activity occures.
EOperatingMode
Device operating mode (stop, start, pause)
void signalError(const QString &_rqsErrorMessage)
Signal emitted by the device when an error occured.
void signalOperatingMode(CDevice::EOperatingMode _eOperatingMode)
Signal emitted by the device when its operating mode changed.
void switchView(EView eView)
Displays the requested container/item details (switching to the appropriate widget)
void switchView(EView eView)
Displays the requested overlay (switching to the appropriate tab)
void setOverlayObject(COverlayObject *_poOverlayObject)
Sets the overlay object to be displayed (and refreshes the underlying widget)
QString qsName
Object name.
Time zone (UTC, local) selection class.
static QString toCode(EUnit _eUnit)
Returns the machine-friendly code corresponding to the given format/unit ID.
static EUnit fromCode(const QString &_rqsCode)
Returns the format/unit ID corresponding to the given machine-friendly code.
@ UTC
Universal Time Coordinates.
static COverlayDetailView * useOverlayDetailView()
static CDeviceDetailView * useDeviceDetailView()
static QMutex * useMutexDataChange()
static COverlayListView * useOverlayListView()
double microtime()
Returns the system time with microseconds resolution, in seconds.