22#if defined( Q_OS_ANDROID ) || defined( Q_OS_LINUX ) 
   23#include <sys/socket.h> 
   32  mIODevice.reset( device );
 
 
   42  return mIODevice.get();
 
 
   57  , mTcpSocket( new QTcpSocket() )
 
   59  connect( mTcpSocket, &QAbstractSocket::stateChanged, 
this, &QgsTcpSocketSensor::socketStateChanged );
 
   60  connect( mTcpSocket, qOverload<QAbstractSocket::SocketError>( &QAbstractSocket::errorOccurred ), 
this, &QgsTcpSocketSensor::handleError );
 
 
   72  return QLatin1String( 
"tcp_socket" );
 
 
  103  if ( mHostName.isEmpty() || mPort == 0 )
 
  109  mTcpSocket->connectToHost( mHostName, mPort, QTcpSocket::ReadOnly );
 
 
  117void QgsTcpSocketSensor::handleError( QAbstractSocket::SocketError error )
 
  121    case QAbstractSocket::HostNotFoundError:
 
  124    case QAbstractSocket::NetworkError:
 
  125      mErrorString = tr( 
"Attempt to read or write from socket returned an error" );
 
  127    case QAbstractSocket::ConnectionRefusedError:
 
  128      mErrorString = tr( 
"The connection was refused by the remote host" );
 
  131      mErrorString = tr( 
"%1" ).arg( QMetaEnum::fromType<QAbstractSocket::SocketError>().valueToKey( error ) );
 
  138void QgsTcpSocketSensor::socketStateChanged( 
const QAbstractSocket::SocketState socketState )
 
  140  switch ( socketState )
 
  142    case QAbstractSocket::ConnectedState:
 
  147    case QAbstractSocket::UnconnectedState:
 
  159  element.setAttribute( QStringLiteral( 
"hostName" ), mHostName );
 
  160  element.setAttribute( QStringLiteral( 
"port" ), QString::number( mPort ) );
 
 
  167  mHostName = element.attribute( QStringLiteral( 
"hostName" ) );
 
  168  mPort = element.attribute( QStringLiteral( 
"port" ) ).toInt();
 
 
  177  , mUdpSocket( std::make_unique<QUdpSocket>() )
 
  178  , mBuffer( new QBuffer() )
 
  180#if defined( Q_OS_ANDROID ) || defined( Q_OS_LINUX ) 
  181  int sockfd = socket( AF_INET, SOCK_DGRAM, 0 );
 
  183  setsockopt( sockfd, SOL_SOCKET, SO_REUSEADDR,
 
  184              ( 
void * ) &optval, 
sizeof( optval ) );
 
  185  mUdpSocket->setSocketDescriptor( sockfd, QUdpSocket::UnconnectedState );
 
  188  connect( mUdpSocket.get(), &QAbstractSocket::stateChanged, 
this, &QgsUdpSocketSensor::socketStateChanged );
 
  189  connect( mUdpSocket.get(), &QUdpSocket::readyRead, 
this, [
this]()
 
  192    while ( mUdpSocket->hasPendingDatagrams() )
 
  194      datagram.resize( int( mUdpSocket->pendingDatagramSize() ) );
 
  195      mUdpSocket->readDatagram( datagram.data(), datagram.size() );
 
  197      mBuffer->buffer().clear();
 
  199      mBuffer->write( datagram );
 
  204  connect( mUdpSocket.get(), qOverload<QAbstractSocket::SocketError>( &QAbstractSocket::errorOccurred ), 
this, &QgsUdpSocketSensor::handleError );
 
  206  initIODevice( mBuffer );
 
 
  216  return QLatin1String( 
"udp_socket" );
 
 
  247  if ( mHostName.isEmpty() || mPort == 0 )
 
  253  mBuffer->open( QIODevice::ReadWrite );
 
  254  mUdpSocket->bind( QHostAddress( mHostName ), mPort, QAbstractSocket::ShareAddress | QAbstractSocket::ReuseAddressHint );
 
  255  mUdpSocket->joinMulticastGroup( QHostAddress( mHostName ) );
 
 
  264void QgsUdpSocketSensor::handleError( QAbstractSocket::SocketError error )
 
  268    case QAbstractSocket::HostNotFoundError:
 
  271    case QAbstractSocket::NetworkError:
 
  272      mErrorString = tr( 
"Attempt to read or write from socket returned an error" );
 
  274    case QAbstractSocket::ConnectionRefusedError:
 
  275      mErrorString = tr( 
"The connection was refused by the remote host" );
 
  278      mErrorString = tr( 
"%1" ).arg( QMetaEnum::fromType<QAbstractSocket::SocketError>().valueToKey( error ) );
 
  285void QgsUdpSocketSensor::socketStateChanged( 
const QAbstractSocket::SocketState socketState )
 
  287  switch ( socketState )
 
  289    case QAbstractSocket::ConnectedState:
 
  290    case QAbstractSocket::BoundState:
 
  295    case QAbstractSocket::UnconnectedState:
 
  307  element.setAttribute( QStringLiteral( 
"hostName" ), mHostName );
 
  308  element.setAttribute( QStringLiteral( 
"port" ), QString::number( mPort ) );
 
 
  315  mHostName = element.attribute( QStringLiteral( 
"hostName" ) );
 
  316  mPort = element.attribute( QStringLiteral( 
"port" ) ).toInt();
 
 
  323#if defined( HAVE_QTSERIALPORT ) 
  324QgsSerialPortSensor::QgsSerialPortSensor( QObject *parent )
 
  326  , mSerialPort( new QSerialPort() )
 
  328  connect( mSerialPort, qOverload<QSerialPort::SerialPortError>( &QSerialPort::errorOccurred ), 
this, &QgsSerialPortSensor::handleError );
 
  333QgsSerialPortSensor *QgsSerialPortSensor::create( QObject *parent )
 
  335  return new QgsSerialPortSensor( parent );
 
  338QString QgsSerialPortSensor::type()
 const 
  340  return QLatin1String( 
"serial_port" );
 
  343QString QgsSerialPortSensor::portName()
 const 
  348void QgsSerialPortSensor::setPortName( 
const QString &portName )
 
  350  if ( mPortName == portName )
 
  353  mPortName = portName;
 
  356QSerialPort::BaudRate QgsSerialPortSensor::baudRate()
 const 
  361void QgsSerialPortSensor::setBaudRate( 
const QSerialPort::BaudRate &baudRate )
 
  363  if ( mBaudRate == baudRate )
 
  366  mBaudRate = baudRate;
 
  369QByteArray QgsSerialPortSensor::delimiter()
 const 
  374void QgsSerialPortSensor::setDelimiter( 
const QByteArray &delimiter )
 
  376  if ( mDelimiter == delimiter )
 
  379  mDelimiter = delimiter;
 
  383void QgsSerialPortSensor::parseData()
 
  385  if ( !mDelimiter.isEmpty() )
 
  387    if ( mFirstDelimiterHit )
 
  389      mDataBuffer += mSerialPort->readAll();
 
  390      const auto lastIndex = mDataBuffer.lastIndexOf( mDelimiter );
 
  391      if ( lastIndex > -1 )
 
  394        data.
lastValue = mDataBuffer.mid( 0, lastIndex );
 
  395        mDataBuffer = mDataBuffer.mid( lastIndex + mDelimiter.size() );
 
  402      QByteArray data = mSerialPort->readAll();
 
  403      const auto lastIndex = data.lastIndexOf( mDelimiter );
 
  404      if ( lastIndex > -1 )
 
  406        mFirstDelimiterHit = 
true;
 
  407        mDataBuffer = data.mid( lastIndex + mDelimiter.size() );
 
  420void QgsSerialPortSensor::handleConnect()
 
  422  mSerialPort->setPortName( mPortName );
 
  423  mSerialPort->setBaudRate( mBaudRate );
 
  424  mFirstDelimiterHit = 
false;
 
  426  if ( mSerialPort->open( QIODevice::ReadOnly ) )
 
  436void QgsSerialPortSensor::handleDisconnect()
 
  438  mSerialPort->close();
 
  441void QgsSerialPortSensor::handleError( QSerialPort::SerialPortError error )
 
  443  if ( error == QSerialPort::NoError )
 
  450    case QSerialPort::DeviceNotFoundError:
 
  451      mErrorString = tr( 
"Could not find the serial port device" );
 
  453    case QSerialPort::ReadError:
 
  454      mErrorString = tr( 
"Attempt to read from the serial port returned an error" );
 
  456    case QSerialPort::PermissionError:
 
  457      mErrorString = tr( 
"The connection was refused due to not having enough permission" );
 
  460      mErrorString = tr( 
"%1" ).arg( QMetaEnum::fromType<QSerialPort::SerialPortError>().valueToKey( error ) );
 
  464  emit errorOccurred( mErrorString );
 
  467bool QgsSerialPortSensor::writePropertiesToElement( QDomElement &element, QDomDocument & )
 const 
  469  element.setAttribute( QStringLiteral( 
"portName" ), mPortName );
 
  470  element.setAttribute( QStringLiteral( 
"baudRate" ), 
static_cast<int>( mBaudRate ) );
 
  471  element.setAttribute( QStringLiteral( 
"delimiter" ), QString( mDelimiter ) );
 
  475bool QgsSerialPortSensor::readPropertiesFromElement( 
const QDomElement &element, 
const QDomDocument & )
 
  477  mPortName = element.attribute( QStringLiteral( 
"portName" ) );
 
  478  mBaudRate = 
static_cast< QSerialPort::BaudRate 
>( element.attribute( QStringLiteral( 
"baudRate" ) ).toInt() );
 
  479  mDelimiter = element.attribute( QStringLiteral( 
"delimiter" ) ).toLocal8Bit();
 
@ Connected
Device is successfully connected.
 
@ Disconnected
Device is disconnected.
 
QgsAbstractSensor::SensorData data() const
Returns the latest captured data from the sensor.
 
void setStatus(Qgis::DeviceConnectionStatus status)
Sets the current sensor status.
 
void errorOccurred(const QString &errorString)
Emitted when an error has occurred. The errorString describes the error.
 
void setData(const QgsAbstractSensor::SensorData &data)
Sets the latest captured data from the sensor.
 
An abstract class QIODevice-based sensor classes.
 
void initIODevice(QIODevice *device)
Initiates the I/O device.
 
virtual void parseData()
Parses the data read from the device when available.
 
QIODevice * iODevice() const
Returns the I/O device.
 
~QgsIODeviceSensor() override
 
A TCP socket sensor class.
 
QgsTcpSocketSensor(QObject *parent=nullptr)
Constructor for a TCP socket sensor, bound to the specified parent.
 
void setHostName(const QString &hostName)
Sets the host name the socket connects to.
 
int port() const
Returns the port the socket connects to.
 
void handleConnect() override
Handles the connection to the sensor.
 
QString type() const override
Returns the sensor type.
 
bool writePropertiesToElement(QDomElement &element, QDomDocument &document) const override
Write specific sensor type properties into a DOM element.
 
bool readPropertiesFromElement(const QDomElement &element, const QDomDocument &document) override
Restores specific sensor type properties from a DOM element.
 
void handleDisconnect() override
Handles the disconnection from the sensor.
 
static QgsTcpSocketSensor * create(QObject *parent)
Returns a new TCP socket sensor.
 
void setPort(int port)
Sets the port the socket connects to.
 
QString hostName() const
Returns the host name the socket connects to.
 
A UDP socket sensor class.
 
bool readPropertiesFromElement(const QDomElement &element, const QDomDocument &document) override
Restores specific sensor type properties from a DOM element.
 
static QgsUdpSocketSensor * create(QObject *parent)
Returns a new UDP socket sensor.
 
QString type() const override
Returns the sensor type.
 
void handleDisconnect() override
Handles the disconnection from the sensor.
 
QgsUdpSocketSensor(QObject *parent=nullptr)
Constructor for a UDP socket sensor, bound to the specified parent.
 
bool writePropertiesToElement(QDomElement &element, QDomDocument &document) const override
Write specific sensor type properties into a DOM element.
 
void setHostName(const QString &hostName)
Sets the host name the socket connects to.
 
int port() const
Returns the port the socket connects to.
 
void handleConnect() override
Handles the connection to the sensor.
 
void setPort(int port)
Sets the port the socket connects to.
 
QString hostName() const
Returns the host name the socket connects to.
 
Contains details of a sensor data capture.
 
QVariant lastValue
Last captured sensor value stored as a QVariant.
 
QDateTime lastTimestamp
Timestamp of last captured sensor value.