fwt_software/include/fgc/MqttControlChannel.h

77 lines
2.7 KiB
C++

#pragma once
#include "fgc/ChannelHistory.h"
#include "fgc/IControlChannel.h"
#include <atomic>
#include <memory>
#include <mutex>
#include <string>
#include <vector>
#include <mqtt/async_client.h>
namespace fgc {
// Real control channel over MQTT (Eclipse Paho C++). Subscribes to the tower's
// target_HDG / ControlCode / Command topics and publishes StatusCode / CamEvent /
// CommandReply. Topic scheme: GGS/FWT/<tower>/... (see docs/mqtt-api.md).
// Publishes are QoS 1; retained, except command replies.
//
// Unlike the old MQTTClient it does NOT spin a busy-wait thread; Paho's async
// client delivers callbacks on its own threads.
class MqttControlChannel : public IControlChannel,
public virtual mqtt::callback,
public virtual mqtt::iaction_listener {
public:
// broker_uri: a full Paho serverURI, e.g. "tcp://10.0.0.5:1883"
// (see NetworkConfig::brokerUri).
MqttControlChannel(const std::string& broker_uri, const std::string& tower,
const std::string& user, const std::string& password);
~MqttControlChannel() override;
bool connect() override;
void disconnect() override;
bool connected() const override;
void publishStatus(int code) override;
void publishCamEvent(const CamEvent& event) override;
ControlCommand poll() override;
std::vector<RemoteCommand> takeCommands() override;
void publishCommandReply(const CommandReply& reply) override;
std::vector<ChannelMessage> recentMessages() const override { return history_.recent(); }
ChannelStats channelStats() const override { return history_.stats(); }
private:
// mqtt::callback
void connected(const std::string& cause) override;
void connection_lost(const std::string& cause) override;
void message_arrived(mqtt::const_message_ptr msg) override;
// mqtt::iaction_listener
void on_failure(const mqtt::token& tok) override;
void on_success(const mqtt::token& tok) override {}
void publish(const std::string& topic, const std::string& payload, bool retained = true);
ChannelHistory history_;
std::string broker_uri_;
std::string tower_;
std::string topic_target_hdg_;
std::string topic_control_code_;
std::string topic_status_;
std::string topic_cam_event_;
std::string topic_command_;
std::string topic_command_reply_;
mqtt::async_client client_;
mqtt::connect_options conn_opts_;
std::atomic<bool> connected_{false};
std::mutex mutex_;
ControlCommand sub_data_;
std::vector<RemoteCommand> commands_; // received, not yet taken (under mutex_)
};
} // namespace fgc