Files
tactility/Tactility/Include/Tactility/hal/gps/GpsDevice.h
T
Ken Van Hoeylandt 3f1bfee3f5 Various improvements (#264)
- Replace C function pointers with C++ `std::function` in `Thread`, `Timer` and `DispatcherThread`
- Rename `SystemEvent`-related functions
- WiFi: fix auto-connect when WiFi disconnects from bad signal
- WiFi: fix auto-connect when WiFi fails to auto-connect
- WiFi: implement disconnect() when tapping connected WiFi ap in WiFi management app
2025-03-30 21:59:31 +02:00

125 lines
3.3 KiB
C++

#pragma once
#include "../Device.h"
#include "GpsConfiguration.h"
#include "Satellites.h"
#include <Tactility/Mutex.h>
#include <Tactility/Thread.h>
#include <minmea.h>
#include <utility>
namespace tt::hal::gps {
enum class GpsResponse {
None,
NotAck,
FrameErrors,
Ok,
};
class GpsDevice : public Device {
public:
typedef int GgaSubscriptionId;
typedef int RmcSubscriptionId;
enum class State {
PendingOn,
On,
Error,
PendingOff,
Off
};
private:
struct GgaSubscription {
GgaSubscriptionId id;
std::shared_ptr<std::function<void(Device::Id id, const minmea_sentence_gga&)>> onData;
};
struct RmcSubscription {
RmcSubscriptionId id;
std::shared_ptr<std::function<void(Device::Id id, const minmea_sentence_rmc&)>> onData;
};
const GpsConfiguration configuration;
Mutex mutex = Mutex(Mutex::Type::Recursive);
std::unique_ptr<Thread> _Nullable thread;
bool threadInterrupted = false;
std::vector<GgaSubscription> ggaSubscriptions;
std::vector<RmcSubscription> rmcSubscriptions;
GgaSubscriptionId lastSatelliteSubscriptionId = 0;
RmcSubscriptionId lastRmcSubscriptionId = 0;
GpsModel model = GpsModel::Unknown;
State state = State::Off;
int32_t threadMain();
bool isThreadInterrupted() const;
void setState(State newState);
public:
explicit GpsDevice(GpsConfiguration configuration) : configuration(std::move(configuration)) {}
~GpsDevice() override = default;
Type getType() const override { return Type::Gps; }
std::string getName() const override {
if (model != GpsModel::Unknown) {
return toString(model);
} else {
return "Unknown GPS";
}
}
std::string getDescription() const override { return ""; }
bool start();
bool stop();
GgaSubscriptionId subscribeGga(const std::function<void(Device::Id deviceId, const minmea_sentence_gga&)>& onData) {
auto lock = mutex.asScopedLock();
lock.lock();
ggaSubscriptions.push_back({
.id = ++lastSatelliteSubscriptionId,
.onData = std::make_shared<std::function<void(Device::Id, const minmea_sentence_gga&)>>(onData)
});
return lastSatelliteSubscriptionId;
}
void unsubscribeGga(GgaSubscriptionId subscriptionId) {
auto lock = mutex.asScopedLock();
lock.lock();
std::erase_if(ggaSubscriptions, [subscriptionId](auto& subscription) { return subscription.id == subscriptionId; });
}
RmcSubscriptionId subscribeRmc(const std::function<void(Device::Id deviceId, const minmea_sentence_rmc&)>& onData) {
auto lock = mutex.asScopedLock();
lock.lock();
rmcSubscriptions.push_back({
.id = ++lastRmcSubscriptionId,
.onData = std::make_shared<std::function<void(Device::Id, const minmea_sentence_rmc&)>>(onData)
});
return lastRmcSubscriptionId;
}
void unsubscribeRmc(GgaSubscriptionId subscriptionId) {
auto lock = mutex.asScopedLock();
lock.lock();
std::erase_if(rmcSubscriptions, [subscriptionId](auto& subscription) { return subscription.id == subscriptionId; });
}
GpsModel getModel() const;
State getState() const;
};
}