Add basic rest_api handler

This commit is contained in:
Lorow
2024-11-02 19:21:34 +01:00
parent 951584035e
commit c96e1c9042
6 changed files with 137 additions and 5 deletions

View File

@@ -0,0 +1,5 @@
idf_component_register(SRCS "RestAPI/RestAPI.cpp"
INCLUDE_DIRS "RestAPI"
# REQUIRES CommandManager mongoose
REQUIRES mongoose
)

View File

@@ -0,0 +1,85 @@
#include "RestAPI.hpp"
RestAPI::RestAPI(std::string url)
{
this->url = url;
// updates
routes.emplace("/api/update/wifi/", &RestAPI::handle_wifi);
routes.emplace("/api/update/device/", &RestAPI::handle_update_device);
routes.emplace("/api/update/camera/", &RestAPI::handle_update_camera);
// post will reset it
// resets
routes.emplace("/api/reset/config/", &RestAPI::handle_reset_config);
routes.emplace("/api/reset/wifi/", &RestAPI::handle_reset_wifi_config);
routes.emplace("/api/reset/txpower/", &RestAPI::handle_reset_txpower_config);
routes.emplace("/api/reset/camera/", &RestAPI::handle_reset_camera_config);
// gets
routes.emplace("/api/get/config/", &RestAPI::handle_get_config);
routes.emplace("/api/reboot/", &RestAPI::handle_reboot);
routes.emplace("/api/reboot/", &RestAPI::handle_reboot);
// reboots
routes.emplace("/api/reboot/device/", &RestAPI::handle_reboot);
routes.emplace("/api/reboot/camera/", &RestAPI::handle_camera_reboot);
// heartbeat
routes.emplace("/api/ping/", &RestAPI::pong);
// special
routes.emplace("/api/save/", &RestAPI::handle_save);
}
void RestAPI::begin()
{
mg_log_set(MG_LL_DEBUG);
mg_mgr_init(&mgr);
// every route is handled through this class, with commands themselves by a command manager
// hence we pass a pointer to this in mg_http_listen
mg_http_listen(&mgr, this->url.c_str(), (mg_event_handler_t)RestAPIHelpers::event_handler, this);
}
void RestAPI::handle_request(struct mg_connection *connection, int event, void *event_data)
{
if (event == MG_EV_HTTP_MSG)
{
struct mg_http_message *message = (struct mg_http_message *)event_data;
std::string uri = std::string(message->uri.buf, message->uri.len);
bool found = false;
for (auto it = this->routes.begin(); it != this->routes.end(); it++)
{
if (it->first == uri)
{
found = true;
RequestContext *context = new RequestContext{
.connection = connection,
};
auto method = it->second;
(*this.*method)(context);
}
}
if (!found)
{
mg_http_reply(connection, 404, "", "Wrong URL");
}
}
}
void RestAPIHelpers::event_handler(struct mg_connection *connection, int event, void *event_data)
{
RestAPI *rest_api_handler = static_cast<RestAPI *>(connection->fn_data);
rest_api_handler->handle_request(connection, event, event_data);
}
void RestAPI::poll()
{
mg_mgr_poll(&mgr, 100);
}
void RestAPI::handle_reboot(RequestContext *context)
{
mg_http_reply(context->connection, 200, "", "Yes sir");
}

View File

@@ -0,0 +1,36 @@
#include <string>
#include <memory>
#include <unordered_map>
#include <mongoose.h>
#include "esp_log.h"
struct RequestContext
{
mg_connection *connection;
};
class RestAPI
{
using route_handler = void (RestAPI::*)(RequestContext *);
typedef std::unordered_map<std::string, route_handler> route_map;
std::string url;
route_map routes;
struct mg_mgr mgr;
private:
void handle_reboot(RequestContext *context);
public:
// this will also need command manager
RestAPI(std::string url);
void begin();
void handle_request(struct mg_connection *connection, int event, void *event_data);
void poll();
};
namespace RestAPIHelpers
{
void event_handler(struct mg_connection *connection, int event, void *event_data);
};