#pragma once #include "fgc/IControlChannel.h" #include #include #include #include #include namespace fgc { // Real control channel over MQTT (Eclipse Paho C++). Subscribes to the tower's // target_HDG / ControlCode topics and publishes StatusCode / CamEvent. Topic // scheme: GGS/FWT//... (see docs/mqtt-api.md). Publishes are QoS 1, // retained. // // 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: MqttControlChannel(const std::string& broker_ip, 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; 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); std::string tower_; std::string topic_target_hdg_; std::string topic_control_code_; std::string topic_status_; std::string topic_cam_event_; mqtt::async_client client_; mqtt::connect_options conn_opts_; std::atomic connected_{false}; std::mutex mutex_; ControlCommand sub_data_; }; } // namespace fgc