Skip to content

Commit

Permalink
Use event loops to decouple code (#300)
Browse files Browse the repository at this point in the history
* Initial commit

* Working for GatewayConnection events

* Add EStop to events

* Ditch Arduino WiFi event system

* Ditch Arduino WiFi event system in OtaUpdateManager

* Clean up main.cpp more

* Initialize events before otaupdatemanager to fix crashloop

* Run CPP-Linter

* Isolate EStopManager

* Fix up includes

* Move event_handlers to message_handlers
  • Loading branch information
hhvrc authored Nov 11, 2024
1 parent c208800 commit 6f6adc9
Show file tree
Hide file tree
Showing 35 changed files with 453 additions and 301 deletions.
1 change: 0 additions & 1 deletion include/CommandHandler.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@ namespace OpenShock::CommandHandler {
gpio_num_t GetEstopPin();

bool SetKeepAliveEnabled(bool enabled);
bool SetKeepAlivePaused(bool paused);

bool HandleCommand(ShockerModelType shockerModel, uint16_t shockerId, ShockerCommandType type, uint8_t intensity, uint16_t durationMs);
} // namespace OpenShock::CommandHandler
2 changes: 2 additions & 0 deletions include/EStopManager.h
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
#pragma once

#include "EStopState.h"

#include <hal/gpio_types.h>

#include <cstdint>
Expand Down
12 changes: 12 additions & 0 deletions include/EStopState.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
#pragma once

#include <cstdint>

namespace OpenShock {
enum class EStopState : uint8_t {
Idle,
Active,
ActiveClearing,
AwaitingRelease
};
} // namespace OpenShock
15 changes: 5 additions & 10 deletions include/GatewayClient.h
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
#pragma once

#include "GatewayClientState.h"

#include <WebSocketsClient.h>

#include <cstdint>
Expand All @@ -13,14 +15,7 @@ namespace OpenShock {
GatewayClient(const std::string& authToken);
~GatewayClient();

enum class State : uint8_t {
Disconnected,
Disconnecting,
Connecting,
Connected,
};

constexpr State state() const { return m_state; }
constexpr GatewayClientState state() const { return m_state; }

void connect(const char* lcgFqdn);
void disconnect();
Expand All @@ -31,13 +26,13 @@ namespace OpenShock {
bool loop();

private:
void _setState(State state);
void _setState(GatewayClientState state);
void _sendKeepAlive();
void _sendBootStatus();
void _handleEvent(WStype_t type, uint8_t* payload, std::size_t length);

WebSocketsClient m_webSocket;
int64_t m_lastKeepAlive;
State m_state;
GatewayClientState m_state;
};
} // namespace OpenShock
12 changes: 12 additions & 0 deletions include/GatewayClientState.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
#pragma once

#include <cstdint>

namespace OpenShock {
enum class GatewayClientState : uint8_t {
Disconnected,
Disconnecting,
Connecting,
Connected,
};
} // namespace OpenShock
2 changes: 0 additions & 2 deletions include/VisualStateManager.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,4 @@ namespace OpenShock::VisualStateManager {

void SetCriticalError();
void SetScanningStarted();
void SetEmergencyStopStatus(bool isActive, bool isAwaitingRelease);
void SetWebSocketConnected(bool isConnected);
} // namespace OpenShock::VisualStateManager
22 changes: 22 additions & 0 deletions include/events/Events.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
#pragma once

#include <esp_event.h>

#ifdef __cplusplus
extern "C" {
#endif

ESP_EVENT_DECLARE_BASE(OPENSHOCK_EVENTS);

enum {
OPENSHOCK_EVENT_ESTOP_STATE_CHANGED, // Event for when the EStop activation state changes
OPENSHOCK_EVENT_GATEWAY_CLIENT_STATE_CHANGED, // Event for when the gateway connection state changes
};

#ifdef __cplusplus
}
#endif

namespace OpenShock::Events {
bool Init();
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

#include <cstdint>

namespace OpenShock::EventHandlers::WebSocket {
namespace OpenShock::MessageHandlers::WebSocket {
void HandleGatewayBinary(const uint8_t* data, std::size_t len);
void HandleLocalBinary(uint8_t socketId, const uint8_t* data, std::size_t len);
}
File renamed without changes.
File renamed without changes.
31 changes: 20 additions & 11 deletions src/CaptivePortalInstance.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,9 @@
const char* const TAG = "CaptivePortalInstance";

#include "CommandHandler.h"
#include "event_handlers/WebSocket.h"
#include "GatewayConnectionManager.h"
#include "Logging.h"
#include "message_handlers/WebSocket.h"
#include "serialization/WSLocal.h"
#include "util/FnProxy.h"
#include "util/HexUtils.h"
Expand All @@ -29,7 +29,8 @@ const uint32_t WEBSOCKET_UPDATE_INTERVAL = 10; // 10ms / 100Hz

using namespace OpenShock;

const esp_partition_t* _getStaticPartition() {
const esp_partition_t* _getStaticPartition()
{
const esp_partition_t* partition = esp_partition_find_first(ESP_PARTITION_TYPE_DATA, ESP_PARTITION_SUBTYPE_DATA_SPIFFS, "static0");
if (partition != nullptr) {
return partition;
Expand All @@ -43,7 +44,8 @@ const esp_partition_t* _getStaticPartition() {
return nullptr;
}

const char* _getPartitionHash() {
const char* _getPartitionHash()
{
const esp_partition_t* partition = _getStaticPartition();
if (partition == nullptr) {
return nullptr;
Expand All @@ -63,7 +65,8 @@ CaptivePortalInstance::CaptivePortalInstance()
, m_socketDeFragger(std::bind(&CaptivePortalInstance::handleWebSocketEvent, this, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3, std::placeholders::_4))
, m_fileSystem()
, m_dnsServer()
, m_taskHandle(nullptr) {
, m_taskHandle(nullptr)
{
m_socketServer.onEvent(std::bind(&WebSocketDeFragger::handler, &m_socketDeFragger, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3, std::placeholders::_4));
m_socketServer.begin();
m_socketServer.enableHeartbeat(WEBSOCKET_PING_INTERVAL, WEBSOCKET_PING_TIMEOUT, WEBSOCKET_PING_RETRIES);
Expand Down Expand Up @@ -130,7 +133,8 @@ discord.gg/OpenShock
}
}

CaptivePortalInstance::~CaptivePortalInstance() {
CaptivePortalInstance::~CaptivePortalInstance()
{
if (m_taskHandle != nullptr) {
vTaskDelete(m_taskHandle);
m_taskHandle = nullptr;
Expand All @@ -141,15 +145,17 @@ CaptivePortalInstance::~CaptivePortalInstance() {
m_dnsServer.stop();
}

void CaptivePortalInstance::task() {
void CaptivePortalInstance::task()
{
while (true) {
m_socketServer.loop();
// instance->m_dnsServer.processNextRequest();
vTaskDelay(pdMS_TO_TICKS(WEBSOCKET_UPDATE_INTERVAL));
}
}

void CaptivePortalInstance::handleWebSocketClientConnected(uint8_t socketId) {
void CaptivePortalInstance::handleWebSocketClientConnected(uint8_t socketId)
{
OS_LOGD(TAG, "WebSocket client #%u connected from %s", socketId, m_socketServer.remoteIP(socketId).toString().c_str());

WiFiNetwork connectedNetwork;
Expand All @@ -166,15 +172,18 @@ void CaptivePortalInstance::handleWebSocketClientConnected(uint8_t socketId) {
Serialization::Local::SerializeWiFiNetworksEvent(Serialization::Types::WifiNetworkEventType::Discovered, networks, std::bind(&CaptivePortalInstance::sendMessageBIN, this, socketId, std::placeholders::_1, std::placeholders::_2));
}

void CaptivePortalInstance::handleWebSocketClientDisconnected(uint8_t socketId) {
void CaptivePortalInstance::handleWebSocketClientDisconnected(uint8_t socketId)
{
OS_LOGD(TAG, "WebSocket client #%u disconnected", socketId);
}

void CaptivePortalInstance::handleWebSocketClientError(uint8_t socketId, uint16_t code, const char* message) {
void CaptivePortalInstance::handleWebSocketClientError(uint8_t socketId, uint16_t code, const char* message)
{
OS_LOGE(TAG, "WebSocket client #%u error %u: %s", socketId, code, message);
}

void CaptivePortalInstance::handleWebSocketEvent(uint8_t socketId, WebSocketMessageType type, const uint8_t* payload, std::size_t length) {
void CaptivePortalInstance::handleWebSocketEvent(uint8_t socketId, WebSocketMessageType type, const uint8_t* payload, std::size_t length)
{
switch (type) {
case WebSocketMessageType::Connected:
handleWebSocketClientConnected(socketId);
Expand All @@ -186,7 +195,7 @@ void CaptivePortalInstance::handleWebSocketEvent(uint8_t socketId, WebSocketMess
OS_LOGE(TAG, "Message type is not supported");
break;
case WebSocketMessageType::Binary:
EventHandlers::WebSocket::HandleLocalBinary(socketId, payload, length);
MessageHandlers::WebSocket::HandleLocalBinary(socketId, payload, length);
break;
case WebSocketMessageType::Error:
handleWebSocketClientError(socketId, length, reinterpret_cast<const char*>(payload));
Expand Down
40 changes: 21 additions & 19 deletions src/CommandHandler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ const char* const TAG = "CommandHandler";
#include "Common.h"
#include "config/Config.h"
#include "EStopManager.h"
#include "EStopState.h"
#include "events/Events.h"
#include "Logging.h"
#include "radio/RFTransmitter.h"
#include "ReadWriteMutex.h"
Expand Down Expand Up @@ -151,8 +153,21 @@ bool _internalSetKeepAliveEnabled(bool enabled)
return true;
}

void _handleOpenShockEStopStateChangeEvent(void* event_handler_arg, esp_event_base_t event_base, int32_t event_id, void* event_data)
{
(void)event_handler_arg;
(void)event_base;
(void)event_id;

EStopState state = *reinterpret_cast<EStopState*>(event_data);

_internalSetKeepAliveEnabled(state == EStopState::Idle);
}

bool CommandHandler::Init()
{
esp_err_t err;

static bool initialized = false;
if (initialized) {
OS_LOGW(TAG, "RF Transmitter and EStopManager are already initialized?");
Expand Down Expand Up @@ -200,6 +215,12 @@ bool CommandHandler::Init()
return false;
}

err = esp_event_handler_register(OPENSHOCK_EVENTS, OPENSHOCK_EVENT_ESTOP_STATE_CHANGED, _handleOpenShockEStopStateChangeEvent, nullptr);
if (err != ESP_OK) {
OS_LOGE(TAG, "Failed to register event handler for OPENSHOCK_EVENTS: %s", esp_err_to_name(err));
return false;
}

// TODO: Implement EStopManager pin change logic

return true;
Expand Down Expand Up @@ -277,25 +298,6 @@ bool CommandHandler::SetKeepAliveEnabled(bool enabled)
return true;
}

bool CommandHandler::SetKeepAlivePaused(bool paused)
{
bool keepAliveEnabled = false;
if (!Config::GetRFConfigKeepAliveEnabled(keepAliveEnabled)) {
OS_LOGE(TAG, "Failed to get keep-alive enabled from config");
return false;
}

if (keepAliveEnabled == false && paused == false) {
OS_LOGW(TAG, "Keep-alive is disabled in config, ignoring unpause command");
return false;
}
if (!_internalSetKeepAliveEnabled(!paused)) {
return false;
}

return true;
}

gpio_num_t CommandHandler::GetRfTxPin()
{
if (s_rfTransmitter != nullptr) {
Expand Down
Loading

0 comments on commit 6f6adc9

Please sign in to comment.