Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add egeniouss receiver. #5637

Open
wants to merge 24 commits into
base: master
Choose a base branch
from
Open

Add egeniouss receiver. #5637

wants to merge 24 commits into from

Conversation

mohsenD98
Copy link
Collaborator

@mohsenD98 mohsenD98 commented Sep 10, 2024

Enable Egeniouss Receiver Support

Overview

This pull request implements support for Egeniouss receivers in the QField application. A new class, EgenioussReceiver, allows users to establish a TCP connection and interact with Egeniouss devices.


New Class: EgenioussReceiver

The EgenioussReceiver class, derived from AbstractGnssReceiver, has been created. It facilitates a TCP connection to Egeniouss devices, using a fixed host address (localhost) and port (1235).


Activation Instructions

The Egeniouss receiver is automatically enabled upon adding the Egeniouss plugin.


Additional Information

Within the plugin, we have two key functions: appWideEnabled() and appWideDisabled(). These functions are invoked in QField when the plugin is enabled or disabled. They simply toggle the egenioussEnabled property as follows:

plugin.positioningSettings.egenioussEnabled = true;  // To enable

or

plugin.positioningSettings.egenioussEnabled = false; // To disable

By utilizing egenioussEnabled within the positioningSettings, we can control the visibility of the EgenioussReceiver.


Download the Plugin

You can download the Egeniouss plugin here.

@mohsenD98 mohsenD98 self-assigned this Sep 10, 2024
@qfield-fairy
Copy link
Collaborator

qfield-fairy commented Sep 10, 2024

I hope sent utc is millisecond :)
Can we merge deviceChoosers ?
TCP, UDP, Egeniouss?

I'll revert QHostAddress::LocalHost later.
src/core/positioning/egenioussreceiver.h Outdated Show resolved Hide resolved
src/core/positioning/egenioussreceiver.h Outdated Show resolved Hide resolved
src/core/positioning/egenioussreceiver.cpp Outdated Show resolved Hide resolved
src/core/positioning/egenioussreceiver.cpp Outdated Show resolved Hide resolved
src/core/positioning/egenioussreceiver.cpp Outdated Show resolved Hide resolved
src/core/positioning/egenioussreceiver.cpp Outdated Show resolved Hide resolved
src/core/positioning/egenioussreceiver.cpp Outdated Show resolved Hide resolved
src/core/positioning/egenioussreceiver.cpp Outdated Show resolved Hide resolved
src/core/positioning/egenioussreceiver.cpp Outdated Show resolved Hide resolved
src/core/positioning/positioning.cpp Outdated Show resolved Hide resolved
Reproduce crash:
1- open app.
2- grant permissions.
3- app crashed.
4- reopen the app -- OK!
@mohsenD98 mohsenD98 closed this Sep 14, 2024
@mohsenD98 mohsenD98 reopened this Sep 14, 2024
@mohsenD98 mohsenD98 closed this Sep 15, 2024
@mohsenD98 mohsenD98 reopened this Sep 15, 2024
When we launch the app, it requests the internal receiver permission but then immediately change that to external, killing the object that called the permission.
Use plugin manager to call function attached to the plugin Item {} itself when enabling / disabling a plugin.
const QPointer<QObject> object = mLoadedPlugins[pluginPath];

const char *normalizedSignature = QMetaObject::normalizedSignature( ( methodName + "()" ).toStdString().c_str() );
const int methodExists = object->metaObject()->indexOfSlot( normalizedSignature );
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

methodIndex would be a better name. Or have methodExists be a bool and add >= 0 at the end of this line.

@nirvn
Copy link
Member

nirvn commented Sep 19, 2024

@domi4484 , I'm good with this now. Do you want to have a look before we merge?

Copy link
Member

@domi4484 domi4484 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Great thank you @mohsenD98!
I left some comments, @nirvn please take also a look maybe you don't agree on all of them :)

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would move this class to an egeniouss directory inside positioning

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@domi4484 , let's maybe not do this right away. ATM we have our other device classes sitting in positioning (Bluetooth, TCP, UDP, serial) here and having a directory for a single pair of .CPP, .H feels a bit too much.

If we end up needing another class (eg egenioussutils) let's maybe consider moving all of it into an src/core/egeniouss directory)

@@ -288,10 +288,12 @@ void PluginManager::enableAppPlugin( const QString &uuid )
loadPlugin( mAvailableAppPlugins[uuid].path(), mAvailableAppPlugins[uuid].name() );
}
}
callPluginMethod( uuid, "appWideActivated" );
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
callPluginMethod( uuid, "appWideActivated" );
callPluginMethod( uuid, "appWideEnabled" );

to reflect the method wording PluginManager::enableAppPlugin and be consistent with appWideDisabled

{
if ( mTcpSocket->state() == QAbstractSocket::ConnectedState )
{
mSocketState = QAbstractSocket::UnconnectedState;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It feels a bit strange to me that subclasses of postioning device have to manage mSocketState that way. mSocketState and mSocketStateString have a quite risk to get out of sync. Wouldn't be it a cleaner interface to reimplement AbstractGnssReceiver::socketState() and socketStateString in subclasses and get rid of the variables mSocketState and mSocketStateString?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@domi4484 , not a bad idea. Can we do that in a follow up PR?

src/core/positioning/egenioussreceiver.cpp Show resolved Hide resolved
switch ( error )
{
case QAbstractSocket::HostNotFoundError:
mLastError = tr( "Could not find the remote host" );
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I guess with the current interface here you should set mSocketState and mSocketStateString as well

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Correct.

}
if ( static_cast<uint8_t>( mReceivedData[0] ) != 0xFE )
{
return; // Invalid start byte
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Here as well missing error handling

@@ -171,6 +171,9 @@ const QString PositioningDeviceModel::deviceId( const Device &device ) const

case SerialPortDevice:
return QStringLiteral( "serial:%1" ).arg( device.settings.value( QStringLiteral( "address" ) ).toString() );

case EgenioussDevice:
return QStringLiteral( "egeniouss:" );
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would put those prefixes into static const members. For serial:, udp:, and so on as well

Copy link
Member

@nirvn nirvn Sep 23, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good idea, let's do that in a follow up PR though just to keep this manageable

@@ -119,7 +119,7 @@ void TcpReceiver::handleError( QAbstractSocket::SocketError error )
mLastError = tr( "The connection was refused by the remote host" );
break;
default:
mLastError = tr( "UDP receiver error (%1)" ).arg( QMetaEnum::fromType<QAbstractSocket::SocketError>().valueToKey( error ) );
mLastError = tr( "TCP receiver error (%1)" ).arg( QMetaEnum::fromType<QAbstractSocket::SocketError>().valueToKey( error ) );
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In this function also mSocketState and socket state string should be updated

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's defer to different PR here to focus on egeniouss bits

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would put this file into a egeniouss directory. Maybe into positioning/egeniouss and move as well other positioning related files in there to gain some structure

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I suggest this structural change be kept in a separate PR

@@ -45,4 +45,5 @@ Settings {
property int digitizingMeasureType: 1

property bool geofencingPreventDigitizingDuringAlert: false
property bool enableEgeniouss: false
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
property bool enableEgeniouss: false
property bool egenioussEnabled: false

But for positioningActivated we use Active instead of Enable. But in the code we see generally more often "Enabled". Sot not sure which one you should choose 😄

Changes list:
- Rename to `appWideEnabled`
- Rename to `egenioussEnabled`
- Set `mSocketStateString` and `mSocketState`
- Use `const` variables in `onReadyRead`
@mohsenD98 mohsenD98 changed the title WIP: Add egeniouss receiver. Add egeniouss receiver. Sep 23, 2024
@mohsenD98 mohsenD98 marked this pull request as ready for review September 23, 2024 19:19
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants