146 lines
5.3 KiB
C
146 lines
5.3 KiB
C
|
|
#pragma once
|
||
|
|
#ifndef ANSCLOUD_GATEWAY_AGENT_H
|
||
|
|
#define ANSCLOUD_GATEWAY_AGENT_H
|
||
|
|
|
||
|
|
#include <anscloud/common/types.h>
|
||
|
|
#include <anscloud/common/i_message_broker.h>
|
||
|
|
#include <string>
|
||
|
|
#include <functional>
|
||
|
|
#include <memory>
|
||
|
|
#include <vector>
|
||
|
|
#include <future>
|
||
|
|
|
||
|
|
#ifdef ANSCLOUD_GATEWAY_EXPORTS
|
||
|
|
#define ANSCLOUD_GATEWAY_API __declspec(dllexport)
|
||
|
|
#else
|
||
|
|
#define ANSCLOUD_GATEWAY_API __declspec(dllimport)
|
||
|
|
#endif
|
||
|
|
|
||
|
|
namespace anscloud {
|
||
|
|
|
||
|
|
//=============================================================================
|
||
|
|
// Gateway Configuration
|
||
|
|
//=============================================================================
|
||
|
|
struct GatewayCredentials {
|
||
|
|
std::string username;
|
||
|
|
std::string password;
|
||
|
|
std::string vhost = "/";
|
||
|
|
};
|
||
|
|
|
||
|
|
struct GatewayAgentConfig {
|
||
|
|
BrokerConfig broker;
|
||
|
|
GatewayCredentials credentials;
|
||
|
|
int device_timeout_seconds = 90;
|
||
|
|
int default_command_timeout_seconds = 30;
|
||
|
|
int max_pending_commands = 1000;
|
||
|
|
};
|
||
|
|
|
||
|
|
struct GatewayStats {
|
||
|
|
uint64_t commands_sent = 0;
|
||
|
|
uint64_t commands_responded = 0;
|
||
|
|
uint64_t commands_timed_out = 0;
|
||
|
|
uint64_t telemetry_received = 0;
|
||
|
|
uint64_t events_received = 0;
|
||
|
|
uint64_t heartbeats_received = 0;
|
||
|
|
int devices_online = 0;
|
||
|
|
int devices_total = 0;
|
||
|
|
int pending_commands = 0;
|
||
|
|
uint64_t uptime_seconds = 0;
|
||
|
|
};
|
||
|
|
|
||
|
|
struct BatchResult {
|
||
|
|
std::vector<std::pair<std::string, CommandResult>> results; // device_id -> result
|
||
|
|
int succeeded = 0;
|
||
|
|
int failed = 0;
|
||
|
|
int timed_out = 0;
|
||
|
|
};
|
||
|
|
|
||
|
|
//=============================================================================
|
||
|
|
// GatewayAgent - CMS gateway for consuming device messages & sending commands
|
||
|
|
//
|
||
|
|
// GatewayAgent gw([](){ return std::make_unique<MyRabbitMQBroker>(); });
|
||
|
|
// gw.configure(config);
|
||
|
|
// gw.on_telemetry([](const DeviceTelemetry& t){ /* store */ });
|
||
|
|
// gw.on_event([](const DeviceEvent& e){ /* process */ });
|
||
|
|
// gw.start();
|
||
|
|
//
|
||
|
|
// auto result = gw.send_command("AIBOX-001", CommandType::GetConfig);
|
||
|
|
//
|
||
|
|
//=============================================================================
|
||
|
|
class ANSCLOUD_GATEWAY_API GatewayAgent {
|
||
|
|
public:
|
||
|
|
explicit GatewayAgent(BrokerFactory factory);
|
||
|
|
~GatewayAgent();
|
||
|
|
|
||
|
|
GatewayAgent(const GatewayAgent&) = delete;
|
||
|
|
GatewayAgent& operator=(const GatewayAgent&) = delete;
|
||
|
|
GatewayAgent(GatewayAgent&&) noexcept;
|
||
|
|
GatewayAgent& operator=(GatewayAgent&&) noexcept;
|
||
|
|
|
||
|
|
//--- Configuration -------------------------------------------------------
|
||
|
|
void configure(const GatewayAgentConfig& config);
|
||
|
|
|
||
|
|
//--- Lifecycle -----------------------------------------------------------
|
||
|
|
bool start();
|
||
|
|
void stop();
|
||
|
|
bool is_running() const;
|
||
|
|
bool is_connected() const;
|
||
|
|
|
||
|
|
//--- Commands (synchronous RPC) ------------------------------------------
|
||
|
|
CommandResult send_command(const std::string& device_id,
|
||
|
|
CommandType type,
|
||
|
|
const std::string& params_json = "{}",
|
||
|
|
int timeout_seconds = 0); // 0 = use default
|
||
|
|
|
||
|
|
std::future<CommandResult> send_command_async(const std::string& device_id,
|
||
|
|
CommandType type,
|
||
|
|
const std::string& params_json = "{}",
|
||
|
|
int timeout_seconds = 0);
|
||
|
|
|
||
|
|
CommandResult send_custom_command(const std::string& device_id,
|
||
|
|
const std::string& custom_type,
|
||
|
|
const std::string& params_json = "{}",
|
||
|
|
int timeout_seconds = 0);
|
||
|
|
|
||
|
|
void send_command_fire_and_forget(const std::string& device_id,
|
||
|
|
CommandType type,
|
||
|
|
const std::string& params_json = "{}");
|
||
|
|
|
||
|
|
BatchResult send_batch_command(const std::vector<std::string>& device_ids,
|
||
|
|
CommandType type,
|
||
|
|
const std::string& params_json = "{}",
|
||
|
|
int timeout_seconds = 0);
|
||
|
|
|
||
|
|
void send_broadcast(const std::string& message);
|
||
|
|
|
||
|
|
//--- Device tracking -----------------------------------------------------
|
||
|
|
std::vector<DeviceState> get_all_devices() const;
|
||
|
|
DeviceState get_device(const std::string& device_id) const;
|
||
|
|
std::vector<DeviceState> get_online_devices() const;
|
||
|
|
bool is_device_online(const std::string& device_id) const;
|
||
|
|
|
||
|
|
//--- Callbacks -----------------------------------------------------------
|
||
|
|
using TelemetryCallback = std::function<void(const DeviceTelemetry&)>;
|
||
|
|
using HeartbeatCallback = std::function<void(const Heartbeat&)>;
|
||
|
|
using EventCallback = std::function<void(const DeviceEvent&)>;
|
||
|
|
using DeviceStatusCallback = std::function<void(const std::string& device_id, DeviceStatus status)>;
|
||
|
|
|
||
|
|
void on_telemetry(TelemetryCallback cb);
|
||
|
|
void on_heartbeat(HeartbeatCallback cb);
|
||
|
|
void on_event(EventCallback cb);
|
||
|
|
void on_device_status_changed(DeviceStatusCallback cb);
|
||
|
|
void on_connection_changed(ConnectionCallback cb);
|
||
|
|
void on_error(ErrorCallback cb);
|
||
|
|
|
||
|
|
//--- Stats ---------------------------------------------------------------
|
||
|
|
GatewayStats get_stats() const;
|
||
|
|
|
||
|
|
private:
|
||
|
|
class Impl;
|
||
|
|
std::unique_ptr<Impl> m_impl;
|
||
|
|
};
|
||
|
|
|
||
|
|
} // namespace anscloud
|
||
|
|
|
||
|
|
#endif // ANSCLOUD_GATEWAY_AGENT_H
|