mirror of
https://github.com/ByteWelder/Tactility.git
synced 2026-02-18 10:53:17 +00:00
Development service work in progress
This commit is contained in:
parent
b7b11e88a8
commit
e66033c1c6
@ -6,7 +6,7 @@ set(CMAKE_CXX_STANDARD_REQUIRED ON)
|
||||
if (DEFINED ENV{ESP_IDF_VERSION})
|
||||
file(GLOB_RECURSE SOURCE_FILES Source/*.c*)
|
||||
|
||||
list(APPEND REQUIRES_LIST TactilityCore lvgl driver elf_loader lv_screenshot QRCode esp_lvgl_port minmea esp_wifi nvs_flash spiffs vfs fatfs lwip)
|
||||
list(APPEND REQUIRES_LIST TactilityCore lvgl driver elf_loader lv_screenshot QRCode esp_lvgl_port minmea esp_wifi nvs_flash spiffs vfs fatfs lwip esp_http_server)
|
||||
if ("${IDF_TARGET}" STREQUAL "esp32s3")
|
||||
list(APPEND REQUIRES_LIST esp_tinyusb)
|
||||
endif ()
|
||||
|
||||
@ -0,0 +1,62 @@
|
||||
#pragma once
|
||||
#ifdef ESP_PLATFORM
|
||||
|
||||
#include "Tactility/service/Service.h"
|
||||
|
||||
#include <Tactility/Mutex.h>
|
||||
|
||||
#include <esp_event.h>
|
||||
#include <esp_http_server.h>
|
||||
#include <Tactility/kernel/SystemEvents.h>
|
||||
|
||||
namespace tt::service::development {
|
||||
|
||||
class Development final : public Service {
|
||||
|
||||
Mutex mutex = Mutex(Mutex::Type::Recursive);
|
||||
httpd_handle_t server = nullptr;
|
||||
bool enabled = false;
|
||||
kernel::SystemEventSubscription networkConnectEventSubscription = 0;
|
||||
kernel::SystemEventSubscription networkDisconnectEventSubscription = 0;
|
||||
std::string deviceResponse;
|
||||
|
||||
httpd_uri_t getDeviceEndpoint = {
|
||||
.uri = "/device",
|
||||
.method = HTTP_GET,
|
||||
.handler = getDevice,
|
||||
.user_ctx = this
|
||||
};
|
||||
|
||||
void onNetworkConnected();
|
||||
void onNetworkDisconnected();
|
||||
|
||||
void startServer();
|
||||
void stopServer();
|
||||
|
||||
static esp_err_t getDevice(httpd_req_t* request);
|
||||
|
||||
public:
|
||||
|
||||
// region Overrides
|
||||
|
||||
void onStart(ServiceContext& service) override;
|
||||
void onStop(ServiceContext& service) override;
|
||||
|
||||
// endregion Overrides
|
||||
|
||||
// region Internal API
|
||||
|
||||
void setEnabled(bool enabled);
|
||||
|
||||
bool isEnabled() const;
|
||||
|
||||
bool isStarted() const;
|
||||
|
||||
// region Internal API
|
||||
};
|
||||
|
||||
std::shared_ptr<Development> findService();
|
||||
|
||||
}
|
||||
|
||||
#endif // ESP_PLATFORM
|
||||
@ -20,6 +20,7 @@ namespace service::gps { extern const ServiceManifest manifest; }
|
||||
namespace service::wifi { extern const ServiceManifest manifest; }
|
||||
namespace service::sdcard { extern const ServiceManifest manifest; }
|
||||
#ifdef ESP_PLATFORM
|
||||
namespace service::development { extern const ServiceManifest manifest; }
|
||||
namespace service::espnow { extern const ServiceManifest manifest; }
|
||||
#endif
|
||||
|
||||
@ -33,6 +34,7 @@ static void registerAndStartSystemServices() {
|
||||
addService(service::sdcard::manifest);
|
||||
addService(service::wifi::manifest);
|
||||
#ifdef ESP_PLATFORM
|
||||
addService(service::development::manifest);
|
||||
addService(service::espnow::manifest);
|
||||
#endif
|
||||
}
|
||||
|
||||
@ -118,7 +118,7 @@ static void statusbar_pubsub_event(TT_UNUSED const void* message, void* obj) {
|
||||
}
|
||||
}
|
||||
|
||||
static void onNetworkConnected(TT_UNUSED kernel::SystemEvent event) {
|
||||
static void onTimeChanged(TT_UNUSED kernel::SystemEvent event) {
|
||||
if (statusbar_data.mutex.lock(100 / portTICK_PERIOD_MS)) {
|
||||
statusbar_data.time_update_timer->stop();
|
||||
statusbar_data.time_update_timer->start(5);
|
||||
@ -139,7 +139,7 @@ static void statusbar_constructor(const lv_obj_class_t* class_p, lv_obj_t* obj)
|
||||
statusbar_data.time_update_timer->start(50 / portTICK_PERIOD_MS);
|
||||
statusbar_data.systemEventSubscription = kernel::subscribeSystemEvent(
|
||||
kernel::SystemEvent::Time,
|
||||
onNetworkConnected
|
||||
onTimeChanged
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
193
Tactility/Source/service/development/Development.cpp
Normal file
193
Tactility/Source/service/development/Development.cpp
Normal file
@ -0,0 +1,193 @@
|
||||
#ifdef ESP_PLATFORM
|
||||
|
||||
#include "Tactility/service/development/Development.h"
|
||||
|
||||
#include "Tactility/TactilityHeadless.h"
|
||||
#include "Tactility/service/ServiceManifest.h"
|
||||
#include "Tactility/service/ServiceRegistry.h"
|
||||
|
||||
#include <cstring>
|
||||
#include <esp_wifi.h>
|
||||
#include <sstream>
|
||||
|
||||
namespace tt::service::development {
|
||||
|
||||
extern const ServiceManifest manifest;
|
||||
|
||||
constexpr const char* TAG = "DevService";
|
||||
|
||||
|
||||
static char* rest_read_buffer(httpd_req_t* request) {
|
||||
static char buffer[1024];
|
||||
int contentLength = request->content_len;
|
||||
int currentLength = 0;
|
||||
int received = 0;
|
||||
if (contentLength >= 1024) {
|
||||
// Respond with 500 Internal Server Error
|
||||
httpd_resp_send_err(request, HTTPD_500_INTERNAL_SERVER_ERROR, "content too long");
|
||||
return NULL;
|
||||
}
|
||||
while (currentLength < contentLength) {
|
||||
received = httpd_req_recv(request, buffer + currentLength, contentLength);
|
||||
if (received <= 0) {
|
||||
// Respond with 500 Internal Server Error
|
||||
httpd_resp_send_err(request, HTTPD_500_INTERNAL_SERVER_ERROR, "Failed to post control value");
|
||||
return NULL;
|
||||
}
|
||||
currentLength += received;
|
||||
}
|
||||
buffer[contentLength] = '\0';
|
||||
return buffer;
|
||||
}
|
||||
|
||||
void Development::onStart(ServiceContext& service) {
|
||||
auto lock = mutex.asScopedLock();
|
||||
lock.lock();
|
||||
|
||||
networkConnectEventSubscription = kernel::subscribeSystemEvent(
|
||||
kernel::SystemEvent::NetworkConnected,
|
||||
[this](kernel::SystemEvent) { onNetworkConnected(); }
|
||||
);
|
||||
networkConnectEventSubscription = kernel::subscribeSystemEvent(
|
||||
kernel::SystemEvent::NetworkDisconnected,
|
||||
[this](kernel::SystemEvent) { onNetworkDisconnected(); }
|
||||
);
|
||||
|
||||
setEnabled(true);
|
||||
}
|
||||
|
||||
void Development::onStop(ServiceContext& service) {
|
||||
auto lock = mutex.asScopedLock();
|
||||
lock.lock();
|
||||
|
||||
kernel::unsubscribeSystemEvent(networkConnectEventSubscription);
|
||||
kernel::unsubscribeSystemEvent(networkDisconnectEventSubscription);
|
||||
|
||||
if (isEnabled()) {
|
||||
setEnabled(false);
|
||||
}
|
||||
}
|
||||
|
||||
// region Enable/disable
|
||||
|
||||
void Development::setEnabled(bool enabled) {
|
||||
auto lock = mutex.asScopedLock();
|
||||
lock.lock();
|
||||
this->enabled = enabled;
|
||||
}
|
||||
|
||||
bool Development::isEnabled() const {
|
||||
auto lock = mutex.asScopedLock();
|
||||
lock.lock();
|
||||
return enabled;
|
||||
}
|
||||
|
||||
// region Enable/disable
|
||||
|
||||
// region Handlers
|
||||
|
||||
void Development::startServer() {
|
||||
auto lock = mutex.asScopedLock();
|
||||
lock.lock();
|
||||
|
||||
if (isStarted()) {
|
||||
TT_LOG_W(TAG, "Already started");
|
||||
return;
|
||||
}
|
||||
|
||||
ESP_LOGI(TAG, "Starting server");
|
||||
|
||||
std::stringstream stream;
|
||||
stream << "{";
|
||||
stream << "\"cpuFamily\" : \"" << CONFIG_IDF_TARGET << "\"";
|
||||
stream << "}";
|
||||
deviceResponse = stream.str();
|
||||
|
||||
httpd_config_t config = HTTPD_DEFAULT_CONFIG();
|
||||
|
||||
config.server_port = 6666;
|
||||
config.uri_match_fn = httpd_uri_match_wildcard;
|
||||
|
||||
if (httpd_start(&server, &config) == ESP_OK) {
|
||||
httpd_register_uri_handler(server, &getDeviceEndpoint);
|
||||
TT_LOG_I(TAG, "Started on port %d", config.server_port);
|
||||
} else {
|
||||
TT_LOG_E(TAG, "Failed to start");
|
||||
}
|
||||
}
|
||||
|
||||
void Development::stopServer() {
|
||||
auto lock = mutex.asScopedLock();
|
||||
lock.lock();
|
||||
|
||||
if (!isStarted()) {
|
||||
TT_LOG_W(TAG, "Not started");
|
||||
return;
|
||||
}
|
||||
|
||||
TT_LOG_I(TAG, "Stopping server");
|
||||
if (httpd_stop(server) != ESP_OK) {
|
||||
TT_LOG_W(TAG, "Error while stopping");
|
||||
}
|
||||
server = nullptr;
|
||||
}
|
||||
|
||||
bool Development::isStarted() const {
|
||||
auto lock = mutex.asScopedLock();
|
||||
lock.lock();
|
||||
return server != nullptr;
|
||||
}
|
||||
|
||||
void Development::onNetworkConnected() {
|
||||
TT_LOG_I(TAG, "onNetworkConnected");
|
||||
mutex.withLock([this] {
|
||||
if (isEnabled() && !isStarted()) {
|
||||
startServer();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
void Development::onNetworkDisconnected() {
|
||||
TT_LOG_I(TAG, "onNetworkDisconnected");
|
||||
mutex.withLock([this] {
|
||||
if (isStarted()) {
|
||||
stopServer();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// endregion
|
||||
|
||||
// region endpoints
|
||||
|
||||
esp_err_t Development::getDevice(httpd_req_t* request) {
|
||||
if (httpd_resp_set_type(request, "application/json") != ESP_OK) {
|
||||
TT_LOG_W(TAG, "Failed to send header");
|
||||
return ESP_FAIL;
|
||||
}
|
||||
|
||||
auto* service = static_cast<Development*>(request->user_ctx);
|
||||
|
||||
if (httpd_resp_sendstr(request, service->deviceResponse.c_str()) != ESP_OK) {
|
||||
TT_LOG_W(TAG, "Failed to send response body");
|
||||
return ESP_FAIL;
|
||||
}
|
||||
|
||||
TT_LOG_I(TAG, "[200] /device from");
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
std::shared_ptr<Development> findService() {
|
||||
return std::static_pointer_cast<Development>(
|
||||
findServiceById(manifest.id)
|
||||
);
|
||||
}
|
||||
|
||||
extern const ServiceManifest manifest = {
|
||||
.id = "Development",
|
||||
.createService = create<Development>
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif // ESP_PLATFORM
|
||||
@ -12,6 +12,7 @@
|
||||
|
||||
#include <atomic>
|
||||
#include <cstring>
|
||||
#include <Tactility/kernel/SystemEvents.h>
|
||||
#include <sys/cdefs.h>
|
||||
|
||||
namespace tt::service::wifi {
|
||||
@ -476,6 +477,7 @@ static void eventHandler(TT_UNUSED void* arg, esp_event_base_t event_base, int32
|
||||
}
|
||||
wifi->setRadioState(RadioState::On);
|
||||
publish_event_simple(wifi, EventType::Disconnected);
|
||||
kernel::publishSystemEvent(kernel::SystemEvent::NetworkDisconnected);
|
||||
} else if (event_base == IP_EVENT && event_id == IP_EVENT_STA_GOT_IP) {
|
||||
auto* event = static_cast<ip_event_got_ip_t*>(event_data);
|
||||
TT_LOG_I(TAG, "eventHandler: got ip:" IPSTR, IP2STR(&event->ip_info.ip));
|
||||
@ -485,6 +487,7 @@ static void eventHandler(TT_UNUSED void* arg, esp_event_base_t event_base, int32
|
||||
// TODO: Make thread-safe
|
||||
wifi->pause_auto_connect = false; // Resume auto-connection
|
||||
}
|
||||
kernel::publishSystemEvent(kernel::SystemEvent::NetworkConnected);
|
||||
} else if (event_base == WIFI_EVENT && event_id == WIFI_EVENT_SCAN_DONE) {
|
||||
auto* event = static_cast<wifi_event_sta_scan_done_t*>(event_data);
|
||||
TT_LOG_I(TAG, "eventHandler: wifi scanning done (scan id %u)", event->scan_id);
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user