import os R = r"C:\Projects\CMSCore" def w(rel, txt): p = os.path.join(R, rel) os.makedirs(os.path.dirname(p), exist_ok=True) with open(p, "w", encoding="utf-8", newline="\r\n") as f: f.write(txt.lstrip("\n")) print(f" OK: {rel}") # ============================================================================ # 9. device_agent_c.cpp # ============================================================================ w("anscloud-device/src/device_agent_c.cpp", r'''#include #include #include #include #include using namespace anscloud; static char* alloc_copy(const std::string& s) { char* p = new char[s.size() + 1]; memcpy(p, s.c_str(), s.size() + 1); return p; } extern "C" { AnsDeviceHandle ansdevice_create(void) { return new DeviceAgent(); } void ansdevice_destroy(AnsDeviceHandle h) { delete static_cast(h); } bool ansdevice_configure(AnsDeviceHandle h, void* broker_ptr, const char* config_json) { if (!h || !broker_ptr) return false; auto* agent = static_cast(h); auto* broker = static_cast(broker_ptr); // TODO: parse config_json into DeviceAgentConfig DeviceAgentConfig cfg; // For now just a minimal config cfg.device_id = "device"; cfg.verbose_logging = true; agent->configure(broker, cfg); return true; } void ansdevice_set_command_handler(AnsDeviceHandle h, AnsDeviceCmdHandlerFn fn, void* user_data) { if (!h || !fn) return; auto* agent = static_cast(h); agent->set_command_handler([fn, user_data](const Command& cmd) -> CommandResponse { std::string cmd_json = json::serialize(cmd); const char* resp_str = fn(user_data, cmd_json.c_str()); CommandResponse resp; if (resp_str) { resp = json::deserialize_response(resp_str); ansdevice_free_string(resp_str); } return resp; }); } void ansdevice_on_connection_changed(AnsDeviceHandle h, AnsDeviceConnectionFn fn, void* ud) { if (!h || !fn) return; static_cast(h)->on_connection_changed( [fn, ud](bool c, const std::string& info) { fn(ud, c, info.c_str()); }); } void ansdevice_on_error(AnsDeviceHandle h, AnsDeviceErrorFn fn, void* ud) { if (!h || !fn) return; static_cast(h)->on_error( [fn, ud](int code, const std::string& msg) { fn(ud, code, msg.c_str()); }); } void ansdevice_on_broadcast(AnsDeviceHandle h, AnsDeviceBroadcastFn fn, void* ud) { if (!h || !fn) return; static_cast(h)->on_broadcast( [fn, ud](const std::string& msg) { fn(ud, msg.c_str()); }); } bool ansdevice_start(AnsDeviceHandle h) { return h ? static_cast(h)->start() : false; } void ansdevice_stop(AnsDeviceHandle h) { if (h) static_cast(h)->stop(); } bool ansdevice_is_running(AnsDeviceHandle h) { return h ? static_cast(h)->is_running() : false; } bool ansdevice_is_connected(AnsDeviceHandle h){ return h ? static_cast(h)->is_connected() : false; } bool ansdevice_publish_event(AnsDeviceHandle h, const char* event_json) { if (!h || !event_json) return false; DeviceEvent evt = json::deserialize_event(event_json); return static_cast(h)->publish_event(evt); } bool ansdevice_send_heartbeat(AnsDeviceHandle h) { return h ? static_cast(h)->send_heartbeat() : false; } bool ansdevice_send_metrics(AnsDeviceHandle h) { return h ? static_cast(h)->send_metrics() : false; } const char* ansdevice_get_status(AnsDeviceHandle h) { if (!h) return alloc_copy("{}"); auto s = static_cast(h)->get_status(); // Simple JSON std::string j = "{\"connected\":" + std::string(s.connected ? "true" : "false") + ",\"running\":" + std::string(s.running ? "true" : "false") + ",\"uptime_seconds\":" + std::to_string(s.uptime_seconds) + ",\"commands_received\":" + std::to_string(s.commands_received) + ",\"commands_executed\":" + std::to_string(s.commands_executed) + ",\"heartbeats_sent\":" + std::to_string(s.heartbeats_sent) + "}"; return alloc_copy(j); } void ansdevice_free_string(const char* str) { delete[] str; } const char* ansdevice_version(void) { return "1.0.0"; } } // extern "C" ''') # ============================================================================ # 10. gateway_agent.h # ============================================================================ w("anscloud-gateway/include/anscloud/gateway/gateway_agent.h", r'''#pragma once // ========================================================================== // ANSCloud SDK - Gateway Agent (CMS side) // // Manages CMS gateway lifecycle: // - Connects to broker via IMessageBroker (your existing RabbitMQ API) // - Consumes telemetry, heartbeats, events, status from all devices // - Sends commands to devices (synchronous RPC via correlation_id) // - Tracks device online/offline state // ========================================================================== #include #include #include #include #include #include namespace anscloud { // -------------------------------------------------------------------------- // Configuration // -------------------------------------------------------------------------- struct GatewayAgentConfig { int device_timeout_seconds = 90; // mark offline if no heartbeat int default_command_timeout_seconds = 30; int max_pending_commands = 1000; bool verbose_logging = false; }; // -------------------------------------------------------------------------- // Command result (from synchronous RPC) // -------------------------------------------------------------------------- struct CommandResult { bool success = false; CommandStatus status = CommandStatus::Timeout; std::string result_json; std::string error_message; double execution_time_ms = 0.0; }; // -------------------------------------------------------------------------- // Device state as tracked by the gateway // -------------------------------------------------------------------------- struct DeviceState { std::string device_id; DeviceStatus status = DeviceStatus::Unknown; std::string firmware_version; std::string ansvis_version; std::string ip_address; std::string last_heartbeat; // ISO 8601 timestamp std::string last_telemetry; uint64_t uptime_seconds = 0; SystemMetrics last_metrics; uint32_t camera_count = 0; }; // -------------------------------------------------------------------------- // Batch command result // -------------------------------------------------------------------------- struct BatchResult { std::vector> results; // device_id -> result int succeeded = 0; int failed = 0; int timed_out = 0; }; // -------------------------------------------------------------------------- // Gateway statistics // -------------------------------------------------------------------------- struct GatewayStats { uint64_t commands_sent = 0; uint64_t responses_received = 0; uint64_t timeouts = 0; uint64_t telemetry_received = 0; uint64_t heartbeats_received= 0; uint64_t events_received = 0; uint32_t devices_online = 0; uint32_t devices_total = 0; uint32_t pending_commands = 0; uint64_t uptime_seconds = 0; }; // -------------------------------------------------------------------------- // GatewayAgent // -------------------------------------------------------------------------- class GatewayAgent { public: GatewayAgent(); ~GatewayAgent(); GatewayAgent(const GatewayAgent&) = delete; GatewayAgent& operator=(const GatewayAgent&) = delete; // --- Setup --- void configure(IMessageBroker* broker, const GatewayAgentConfig& config); // --- Lifecycle --- bool start(); void stop(); bool is_running() const; bool is_connected() const; // --- Commands --- // Synchronous RPC: sends command, blocks until response or timeout CommandResult send_command( const std::string& device_id, CommandType type, const std::string& params_json = "{}", int timeout_seconds = 0 // 0 = use default ); // Async version std::future send_command_async( const std::string& device_id, CommandType type, const std::string& params_json = "{}", int timeout_seconds = 0 ); // Fire-and-forget (no response expected) bool send_command_fire_and_forget( const std::string& device_id, CommandType type, const std::string& params_json = "{}" ); // Send to multiple devices BatchResult send_batch_command( const std::vector& device_ids, CommandType type, const std::string& params_json = "{}", int timeout_seconds = 0 ); // Broadcast to all devices bool send_broadcast(const std::string& message_json); // --- Device tracking --- std::vector get_all_devices() const; DeviceState get_device(const std::string& device_id) const; std::vector get_online_devices() const; bool is_device_online(const std::string& device_id) const; // --- Callbacks --- void on_telemetry(TelemetryCallback cb); void on_heartbeat(HeartbeatCallback cb); void on_event(EventCallback cb); void on_device_status_changed(StatusCallback cb); void on_connection_changed(ConnectionCallback cb); void on_error(ErrorCallback cb); // --- Stats --- GatewayStats get_stats() const; private: struct Impl; std::unique_ptr m_impl; }; } // namespace anscloud ''') print(" [9-10] device_agent_c.cpp, gateway_agent.h done")