feat(gateway_network): integrate GatewayBridgeService and add bridge handling
- Updated CMakeLists.txt to require gateway_bridge component. - Modified GatewayNetworkService to include a pointer to GatewayBridgeService. - Added new HTTP handlers for bridge GET and POST requests. - Implemented query utility functions for handling request parameters. - Enhanced response handling for bridge actions with JSON responses. Co-authored-by: Copilot <copilot@github.com>
This commit is contained in:
@@ -1,7 +1,7 @@
|
||||
idf_component_register(
|
||||
SRCS "src/gateway_network.cpp"
|
||||
INCLUDE_DIRS "include"
|
||||
REQUIRES dali_domain esp_event esp_http_server esp_netif esp_wifi freertos gateway_controller gateway_runtime log lwip espressif__cjson
|
||||
REQUIRES dali_domain esp_event esp_http_server esp_netif esp_wifi freertos gateway_bridge gateway_controller gateway_runtime log lwip espressif__cjson
|
||||
)
|
||||
|
||||
set_property(TARGET ${COMPONENT_LIB} PROPERTY CXX_STANDARD 17)
|
||||
@@ -21,6 +21,7 @@ namespace gateway {
|
||||
|
||||
class GatewayController;
|
||||
class DaliDomainService;
|
||||
class GatewayBridgeService;
|
||||
struct DaliRawFrame;
|
||||
|
||||
struct GatewayNetworkServiceConfig {
|
||||
@@ -48,7 +49,9 @@ struct GatewayNetworkServiceConfig {
|
||||
class GatewayNetworkService {
|
||||
public:
|
||||
GatewayNetworkService(GatewayController& controller, GatewayRuntime& runtime,
|
||||
DaliDomainService& dali_domain, GatewayNetworkServiceConfig config = {});
|
||||
DaliDomainService& dali_domain,
|
||||
GatewayNetworkServiceConfig config = {},
|
||||
GatewayBridgeService* bridge_service = nullptr);
|
||||
|
||||
esp_err_t start();
|
||||
|
||||
@@ -58,6 +61,8 @@ class GatewayNetworkService {
|
||||
static esp_err_t HandleInfoGet(httpd_req_t* req);
|
||||
static esp_err_t HandleCommandGet(httpd_req_t* req);
|
||||
static esp_err_t HandleCommandPost(httpd_req_t* req);
|
||||
static esp_err_t HandleBridgeGet(httpd_req_t* req);
|
||||
static esp_err_t HandleBridgePost(httpd_req_t* req);
|
||||
static esp_err_t HandleLedOnGet(httpd_req_t* req);
|
||||
static esp_err_t HandleLedOffGet(httpd_req_t* req);
|
||||
static esp_err_t HandleJqJsGet(httpd_req_t* req);
|
||||
@@ -91,12 +96,14 @@ class GatewayNetworkService {
|
||||
std::string deviceInfoJson() const;
|
||||
std::string deviceInfoDoubleEncodedJson() const;
|
||||
std::string gatewaySnapshotJson();
|
||||
esp_err_t sendBridgeResponse(httpd_req_t* req, bool post);
|
||||
void setStatusLed(bool on);
|
||||
|
||||
GatewayController& controller_;
|
||||
GatewayRuntime& runtime_;
|
||||
DaliDomainService& dali_domain_;
|
||||
GatewayNetworkServiceConfig config_;
|
||||
GatewayBridgeService* bridge_service_{nullptr};
|
||||
bool started_{false};
|
||||
httpd_handle_t http_server_{nullptr};
|
||||
esp_netif_t* wifi_sta_netif_{nullptr};
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
#include "gateway_network.hpp"
|
||||
|
||||
#include "dali_domain.hpp"
|
||||
#include "gateway_bridge.hpp"
|
||||
#include "gateway_controller.hpp"
|
||||
#include "gateway_runtime.hpp"
|
||||
|
||||
@@ -18,6 +19,7 @@
|
||||
#include <algorithm>
|
||||
#include <cstdio>
|
||||
#include <cstring>
|
||||
#include <cstdlib>
|
||||
#include <string_view>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
@@ -182,14 +184,79 @@ esp_err_t RegisterUri(httpd_handle_t server, const char* uri, httpd_method_t met
|
||||
return httpd_register_uri_handler(server, &route);
|
||||
}
|
||||
|
||||
std::string QueryValue(httpd_req_t* req, const char* key) {
|
||||
if (req == nullptr || key == nullptr) {
|
||||
return {};
|
||||
}
|
||||
const size_t len = httpd_req_get_url_query_len(req) + 1;
|
||||
if (len <= 1) {
|
||||
return {};
|
||||
}
|
||||
std::string query(len, '\0');
|
||||
if (httpd_req_get_url_query_str(req, query.data(), query.size()) != ESP_OK) {
|
||||
return {};
|
||||
}
|
||||
char value[64] = {0};
|
||||
if (httpd_query_key_value(query.c_str(), key, value, sizeof(value)) != ESP_OK) {
|
||||
return {};
|
||||
}
|
||||
return std::string(value);
|
||||
}
|
||||
|
||||
std::string QueryString(httpd_req_t* req) {
|
||||
if (req == nullptr) {
|
||||
return {};
|
||||
}
|
||||
const size_t len = httpd_req_get_url_query_len(req) + 1;
|
||||
if (len <= 1) {
|
||||
return {};
|
||||
}
|
||||
std::string query(len, '\0');
|
||||
if (httpd_req_get_url_query_str(req, query.data(), query.size()) != ESP_OK) {
|
||||
return {};
|
||||
}
|
||||
if (!query.empty() && query.back() == '\0') {
|
||||
query.pop_back();
|
||||
}
|
||||
return query;
|
||||
}
|
||||
|
||||
std::optional<uint8_t> QueryGatewayId(httpd_req_t* req) {
|
||||
const auto raw = QueryValue(req, "gw");
|
||||
if (raw.empty()) {
|
||||
return std::nullopt;
|
||||
}
|
||||
char* end = nullptr;
|
||||
const long parsed = std::strtol(raw.c_str(), &end, 10);
|
||||
if (end == raw.c_str() || *end != '\0' || parsed < 0 || parsed > 255) {
|
||||
return std::nullopt;
|
||||
}
|
||||
return static_cast<uint8_t>(parsed);
|
||||
}
|
||||
|
||||
esp_err_t SendJsonResponse(httpd_req_t* req, const GatewayBridgeHttpResponse& response) {
|
||||
if (response.err == ESP_ERR_INVALID_ARG) {
|
||||
return httpd_resp_send_err(req, HTTPD_400_BAD_REQUEST, response.body.c_str());
|
||||
}
|
||||
if (response.err == ESP_ERR_NOT_FOUND) {
|
||||
return httpd_resp_send_err(req, HTTPD_404_NOT_FOUND, response.body.c_str());
|
||||
}
|
||||
if (response.err != ESP_OK) {
|
||||
return httpd_resp_send_err(req, HTTPD_500_INTERNAL_SERVER_ERROR, response.body.c_str());
|
||||
}
|
||||
httpd_resp_set_type(req, "application/json");
|
||||
return httpd_resp_send(req, response.body.data(), response.body.size());
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
GatewayNetworkService::GatewayNetworkService(GatewayController& controller,
|
||||
GatewayRuntime& runtime,
|
||||
DaliDomainService& dali_domain,
|
||||
GatewayNetworkServiceConfig config)
|
||||
GatewayNetworkServiceConfig config,
|
||||
GatewayBridgeService* bridge_service)
|
||||
: controller_(controller), runtime_(runtime), dali_domain_(dali_domain), config_(config),
|
||||
udp_lock_(xSemaphoreCreateMutex()) {}
|
||||
bridge_service_(bridge_service), udp_lock_(xSemaphoreCreateMutex()) {}
|
||||
|
||||
esp_err_t GatewayNetworkService::start() {
|
||||
if (started_) {
|
||||
@@ -635,6 +702,8 @@ esp_err_t GatewayNetworkService::startHttpServer() {
|
||||
{"/info", HTTP_GET, &GatewayNetworkService::HandleInfoGet},
|
||||
{"/dali/cmd", HTTP_GET, &GatewayNetworkService::HandleCommandGet},
|
||||
{"/dali/cmd", HTTP_POST, &GatewayNetworkService::HandleCommandPost},
|
||||
{"/bridge", HTTP_GET, &GatewayNetworkService::HandleBridgeGet},
|
||||
{"/bridge", HTTP_POST, &GatewayNetworkService::HandleBridgePost},
|
||||
{"/led/1", HTTP_GET, &GatewayNetworkService::HandleLedOnGet},
|
||||
{"/led/0", HTTP_GET, &GatewayNetworkService::HandleLedOffGet},
|
||||
{"/jq.js", HTTP_GET, &GatewayNetworkService::HandleJqJsGet},
|
||||
@@ -1227,6 +1296,42 @@ esp_err_t GatewayNetworkService::HandleCommandPost(httpd_req_t* req) {
|
||||
return httpd_resp_sendstr(req, "ok");
|
||||
}
|
||||
|
||||
esp_err_t GatewayNetworkService::HandleBridgeGet(httpd_req_t* req) {
|
||||
auto* service = static_cast<GatewayNetworkService*>(req->user_ctx);
|
||||
if (service == nullptr) {
|
||||
return ESP_FAIL;
|
||||
}
|
||||
return service->sendBridgeResponse(req, false);
|
||||
}
|
||||
|
||||
esp_err_t GatewayNetworkService::HandleBridgePost(httpd_req_t* req) {
|
||||
auto* service = static_cast<GatewayNetworkService*>(req->user_ctx);
|
||||
if (service == nullptr) {
|
||||
return ESP_FAIL;
|
||||
}
|
||||
return service->sendBridgeResponse(req, true);
|
||||
}
|
||||
|
||||
esp_err_t GatewayNetworkService::sendBridgeResponse(httpd_req_t* req, bool post) {
|
||||
if (bridge_service_ == nullptr) {
|
||||
return httpd_resp_send_err(req, HTTPD_404_NOT_FOUND, "Bridge service is not enabled");
|
||||
}
|
||||
|
||||
const std::string action = QueryValue(req, "action");
|
||||
const auto gateway_id = QueryGatewayId(req);
|
||||
const int selected_gateway_id = gateway_id.has_value() ? gateway_id.value() : -1;
|
||||
if (!post) {
|
||||
return SendJsonResponse(req, bridge_service_->handleGet(action, selected_gateway_id,
|
||||
QueryString(req)));
|
||||
}
|
||||
|
||||
std::string body;
|
||||
if (ReadRequestBody(req, body) != ESP_OK) {
|
||||
return httpd_resp_send_err(req, HTTPD_400_BAD_REQUEST, "Bad Request");
|
||||
}
|
||||
return SendJsonResponse(req, bridge_service_->handlePost(action, selected_gateway_id, body));
|
||||
}
|
||||
|
||||
esp_err_t GatewayNetworkService::HandleLedOnGet(httpd_req_t* req) {
|
||||
auto* service = static_cast<GatewayNetworkService*>(req->user_ctx);
|
||||
if (service == nullptr) {
|
||||
|
||||
Reference in New Issue
Block a user