Initial changes, cleanup and improvements

This commit is contained in:
Lorow 2024-08-15 20:13:01 +02:00
parent d3c402525c
commit 4705e41476
11 changed files with 220 additions and 256 deletions

View File

@ -1,99 +1,93 @@
#include "helpers.hpp"
char *Helpers::itoa(int value, char *result, int base)
{
// check that the base if valid
if (base < 2 || base > 36)
{
*result = '\0';
return result;
}
char *ptr = result, *ptr1 = result, tmp_char;
int tmp_value;
do
{
tmp_value = value;
value /= base;
*ptr++ = "zyxwvutsrqponmlkjihgfedcba9876543210123456789abcdefghijklmnopqrstuvwxyz"[35 + (tmp_value - value * base)];
} while (value);
// Apply negative sign
if (tmp_value < 0)
*ptr++ = '-';
*ptr-- = '\0';
while (ptr1 < ptr)
{
tmp_char = *ptr;
*ptr-- = *ptr1;
*ptr1++ = tmp_char;
}
char* Helpers::itoa(int value, char* result, int base) {
// check that the base if valid
if (base < 2 || base > 36) {
*result = '\0';
return result;
}
char *ptr = result, *ptr1 = result, tmp_char;
int tmp_value;
do {
tmp_value = value;
value /= base;
*ptr++ =
"zyxwvutsrqponmlkjihgfedcba9876543210123456789abcdefghijklmnopqrstuvwxy"
"z"[35 + (tmp_value - value * base)];
} while (value);
// Apply negative sign
if (tmp_value < 0)
*ptr++ = '-';
*ptr-- = '\0';
while (ptr1 < ptr) {
tmp_char = *ptr;
*ptr-- = *ptr1;
*ptr1++ = tmp_char;
}
return result;
}
void split(const std::string &str, const std::string &splitBy, std::vector<std::string> &tokens)
{
/* Store the original string in the array, so we can loop the rest
* of the algorithm. */
tokens.emplace_back(str);
void split(const std::string& str,
const std::string& splitBy,
std::vector<std::string>& tokens) {
/* Store the original string in the array, so we can loop the rest
* of the algorithm. */
tokens.emplace_back(str);
// Store the split index in a 'size_t' (unsigned integer) type.
size_t splitAt;
// Store the size of what we're splicing out.
size_t splitLen = splitBy.size();
// Create a string for temporarily storing the fragment we're processing.
std::string frag;
// Loop infinitely - break is internal.
while (true)
{
/* Store the last string in the vector, which is the only logical
* candidate for processing. */
frag = tokens.back();
/* The index where the split is. */
splitAt = frag.find(splitBy);
// If we didn't find a new split point...
if (splitAt == std::string::npos)
{
// Break the loop and (implicitly) return.
break;
}
/* Put everything from the left side of the split where the string
* being processed used to be. */
tokens.back() = frag.substr(0, splitAt);
/* Push everything from the right side of the split to the next empty
* index in the vector. */
tokens.emplace_back(frag.substr(splitAt + splitLen, frag.size() - (splitAt + splitLen)));
// Store the split index in a 'size_t' (unsigned integer) type.
size_t splitAt;
// Store the size of what we're splicing out.
size_t splitLen = splitBy.size();
// Create a string for temporarily storing the fragment we're processing.
std::string frag;
// Loop infinitely - break is internal.
while (true) {
/* Store the last string in the vector, which is the only logical
* candidate for processing. */
frag = tokens.back();
/* The index where the split is. */
splitAt = frag.find(splitBy);
// If we didn't find a new split point...
if (splitAt == std::string::npos) {
// Break the loop and (implicitly) return.
break;
}
/* Put everything from the left side of the split where the string
* being processed used to be. */
tokens.back() = frag.substr(0, splitAt);
/* Push everything from the right side of the split to the next empty
* index in the vector. */
tokens.emplace_back(
frag.substr(splitAt + splitLen, frag.size() - (splitAt + splitLen)));
}
}
std::vector<std::string> Helpers::split(const std::string &s, char delimiter)
{
std::vector<std::string> parts;
std::string part;
std::istringstream tokenStream(s);
while (std::getline(tokenStream, part, delimiter))
{
parts.push_back(part);
}
return parts;
std::vector<std::string> Helpers::split(const std::string& s, char delimiter) {
std::vector<std::string> parts;
std::string part;
std::istringstream tokenStream(s);
while (std::getline(tokenStream, part, delimiter)) {
parts.push_back(part);
}
return parts;
}
void Helpers::update_progress_bar(int progress, int total)
{
int barWidth = 70;
void Helpers::update_progress_bar(int progress, int total) {
int barWidth = 70;
std::cout << "\r[";
int pos = barWidth * progress / total;
for (int i = 0; i < barWidth; ++i)
{
if (i < pos)
std::cout << "=";
else if (i == pos)
std::cout << ">";
else
std::cout << " ";
}
std::cout << "] " << int(progress * 100.0 / total) << " %\r";
std::cout.flush();
std::cout << "\r[";
int pos = barWidth * progress / total;
for (int i = 0; i < barWidth; ++i) {
if (i < pos)
std::cout << "=";
else if (i == pos)
std::cout << ">";
else
std::cout << " ";
}
std::cout << "] " << int(progress * 100.0 / total) << " %\r";
std::cout.flush();
}

View File

@ -1,37 +1,41 @@
#ifndef HELPERS_HPP
#define HELPERS_HPP
#include <string>
#include <sstream>
#include <vector>
#include <iostream>
#include <memory>
#include <sstream>
#include <string>
#include <vector>
namespace Helpers
{
char *itoa(int value, char *result, int base);
void split(std::string str, std::string splitBy, std::vector<std::string> &tokens);
std::vector<std::string> split(const std::string &s, char delimiter);
void update_progress_bar(int progress, int total);
const unsigned char ETVR_HEADER[] = {0xFF, 0xA0, 0xFF, 0xA1, 0x01};
const char* const ETVR_HEADER_BYTES = "\xff\xa0\xff\xa1";
/// @brief
/// @tparam ...Args
/// @param format
/// @param ...args
/// @return
template <typename... Args>
std::string format_string(const std::string &format, Args... args)
{
int size_s = std::snprintf(nullptr, 0, format.c_str(), args...) + 1; // Extra space for '\0'
if (size_s <= 0)
{
std::cout << "Error during formatting.";
return "";
}
auto size = static_cast<size_t>(size_s);
std::unique_ptr<char[]> buf(new char[size]);
std::snprintf(buf.get(), size, format.c_str(), args...);
return std::string(buf.get(), buf.get() + size - 1); // We don't want the '\0' inside
namespace Helpers {
char* itoa(int value, char* result, int base);
void split(std::string str,
std::string splitBy,
std::vector<std::string>& tokens);
std::vector<std::string> split(const std::string& s, char delimiter);
void update_progress_bar(int progress, int total);
/// @brief
/// @tparam ...Args
/// @param format
/// @param ...args
/// @return
template <typename... Args>
std::string format_string(const std::string& format, Args... args) {
int size_s = std::snprintf(nullptr, 0, format.c_str(), args...) +
1; // Extra space for '\0'
if (size_s <= 0) {
std::cout << "Error during formatting.";
return "";
}
}
auto size = static_cast<size_t>(size_s);
std::unique_ptr<char[]> buf(new char[size]);
std::snprintf(buf.get(), size, format.c_str(), args...);
return std::string(buf.get(),
buf.get() + size - 1); // We don't want the '\0' inside
}
} // namespace Helpers
#endif // HELPERS_HPP
#endif // HELPERS_HPP

View File

@ -9,6 +9,7 @@
*between blinks.
*/
// TODO rethink this
LEDManager::ledStateMap_t LEDManager::ledStateMap = {
{LEDStates_e::_LedStateNone, {{0, 500}}},
{LEDStates_e::_Improv_Error,
@ -58,7 +59,7 @@ LEDManager::~LEDManager() {}
void LEDManager::begin() {
pinMode(_ledPin, OUTPUT);
// the defualt state is _LedStateNone so we're fine
// the default state is _LedStateNone so we're fine
this->currentState = ledStateManager.getCurrentState();
this->currentPatternIndex = 0;
BlinkPatterns_t pattern =
@ -66,7 +67,12 @@ void LEDManager::begin() {
this->toggleLED(pattern.state);
this->nextStateChangeMillis = pattern.delayTime;
log_d("begin %d", this->currentPatternIndex);
log_d("Led manager began with: %d", this->currentPatternIndex);
#ifdef CONFIG_CAMERA_MODULE_SWROOM_BABBLE_S3
log_d("Setting up LED for the Babble board");
this->setupBabbeLed();
#endif
}
/**
@ -120,6 +126,19 @@ void LEDManager::handleLED() {
log_d("updated stage %d", this->currentPatternIndex);
}
#ifdef CONFIG_CAMERA_MODULE_SWROOM_BABBLE_S3
void LEDManager::setupBabbeLed() {
// Set IR emitter strength to 100%.
const int ledPin = 1; // Replace this with a command endpoint eventually.
const int freq = 5000;
const int ledChannel = 0;
const int resolution = 8;
const int dutyCycle = 255;
ledcSetup(ledChannel, freq, resolution);
ledcAttachPin(ledPin, ledChannel);
ledcWrite(ledChannel, dutyCycle);
}
#endif
/**
* @brief Turn the LED on or off
*

View File

@ -1,36 +1,38 @@
#ifndef LEDMANAGER_HPP
#define LEDMANAGER_HPP
#include <vector>
#include <Arduino.h>
#include <data/StateManager/StateManager.hpp>
#include <unordered_map>
#include <vector>
class LEDManager
{
public:
LEDManager(byte pin);
virtual ~LEDManager();
class LEDManager {
public:
LEDManager(byte pin);
virtual ~LEDManager();
void begin();
void handleLED();
void toggleLED(bool state) const;
void begin();
void handleLED();
void toggleLED(bool state) const;
#ifdef CONFIG_CAMERA_MODULE_SWROOM_BABBLE_S3
void setupBabbeLed();
#endif
private:
byte _ledPin;
unsigned long nextStateChangeMillis = 0;
bool _ledState;
private:
byte _ledPin;
unsigned long nextStateChangeMillis = 0;
bool _ledState;
struct BlinkPatterns_t
{
int state;
int delayTime;
};
struct BlinkPatterns_t {
int state;
int delayTime;
};
typedef std::unordered_map<LEDStates_e, std::vector<BlinkPatterns_t>> ledStateMap_t;
static ledStateMap_t ledStateMap;
static std::vector<LEDStates_e> keepAliveStates;
LEDStates_e currentState;
unsigned int currentPatternIndex = 0;
typedef std::unordered_map<LEDStates_e, std::vector<BlinkPatterns_t>>
ledStateMap_t;
static ledStateMap_t ledStateMap;
static std::vector<LEDStates_e> keepAliveStates;
LEDStates_e currentState;
unsigned int currentPatternIndex = 0;
};
#endif // LEDMANAGER_HPP
#endif // LEDMANAGER_HPP

View File

@ -1,17 +0,0 @@
#ifndef HASH_H_
#define HASH_H_
#include <stdint.h>
#include <string>
// #define DEBUG_SHA1
void sha1(const uint8_t* data, uint32_t size, uint8_t hash[20]);
void sha1(const char* data, uint32_t size, uint8_t hash[20]);
void sha1(const std::string& data, uint8_t hash[20]);
std::string sha1(const uint8_t* data, uint32_t size);
std::string sha1(const char* data, uint32_t size);
std::string sha1(const std::string& data);
#endif /* HASH_H_ */

View File

@ -102,17 +102,6 @@ void BaseAPI::setWiFi(AsyncWebServerRequest* request) {
projectConfig.setWifiConfig(networkName, ssid, password, channel, power,
adhoc, true);
/* if (WiFiStateManager->getCurrentState() ==
WiFiState_e::WiFiState_ADHOC)
{
projectConfig.setAPWifiConfig(ssid, password, &channel, adhoc,
true);
}
else
{
} */
request->send(200, MIMETYPE_JSON,
"{\"msg\":\"Done. Wifi Creds have been set.\"}");
break;

View File

@ -3,7 +3,6 @@
//! Warning do not format this file with clang-format or it will break the code
#include <unordered_map>
#include <string>
#include <unordered_map>
@ -31,7 +30,6 @@ constexpr int HTTP_ANY = 0b01111111;
#include <ESPAsyncWebServer.h>
#include <FS.h>
#include "Hash.h"
#include "data/utilities/network_utilities.hpp"
#include "tasks/tasks.hpp"
@ -100,33 +98,34 @@ class BaseAPI {
typedef std::unordered_map<std::string, WebRequestMethodComposite>
networkMethodsMap_t;
ProjectConfig &projectConfig;
/// @brief Local instance of the AsyncWebServer - so that we dont need to use new and delete
AsyncWebServer server;
ProjectConfig& projectConfig;
/// @brief Local instance of the AsyncWebServer - so that we dont need to use
/// new and delete
AsyncWebServer server;
#ifndef SIM_ENABLED
CameraHandler &camera;
CameraHandler& camera;
#endif // SIM_ENABLED
public :
BaseAPI(ProjectConfig& projectConfig,
public:
BaseAPI(ProjectConfig& projectConfig,
#ifndef SIM_ENABLED
CameraHandler& camera,
CameraHandler& camera,
#endif // SIM_ENABLED
const std::string& api_url,
const std::string& api_url,
#ifndef SIM_ENABLED
int port = 81
int port = 81
#else
int port = 80
int port = 80
#endif
);
virtual ~BaseAPI();
virtual void begin();
void checkAuthentication(AsyncWebServerRequest* request,
const char* login,
const char* password);
void beginOTA();
void notFound(AsyncWebServerRequest* request) const;
virtual ~BaseAPI();
virtual void begin();
void checkAuthentication(AsyncWebServerRequest* request,
const char* login,
const char* password);
void beginOTA();
void notFound(AsyncWebServerRequest* request) const;
};
#endif // BASEAPI_HPP

View File

@ -6,7 +6,8 @@ MDNSHandler::MDNSHandler(ProjectConfig& configManager)
bool MDNSHandler::startMDNS() {
const std::string service = "_openiristracker";
auto mdnsConfig = configManager.getMDNSConfig();
if (!MDNS.begin(mdnsConfig.hostname.c_str())) // lowercase only - as this will be the url
if (!MDNS.begin(mdnsConfig.hostname
.c_str())) // lowercase only - as this will be the url
{
mdnsStateManager.setState(MDNSState_e::MDNSState_Error);
log_e("Error initializing MDNS");

View File

@ -1,7 +1,4 @@
#include "wifihandler.hpp"
#include <WiFi.h>
#include "data/StateManager/StateManager.hpp"
#include "data/utilities/helpers.hpp"
WiFiHandler::WiFiHandler(ProjectConfig& configManager,
const std::string& ssid,
@ -18,10 +15,11 @@ WiFiHandler::WiFiHandler(ProjectConfig& configManager,
WiFiHandler::~WiFiHandler() {}
void WiFiHandler::begin() {
// just to be sure, we reeset everything before we do anything, some boards were having problems otherwise
// just to be sure, we reeset everything before we do anything, some boards
// were having problems otherwise
WiFi.disconnect();
// we purposefully set the lowest min required security level, some boards have problems connecting otherwise
// we purposefully set the lowest min required security level, some boards
// have problems connecting otherwise
// https://github.com/espressif/arduino-esp32/issues/8770
WiFi.setMinSecurity(WIFI_AUTH_WEP);
@ -33,7 +31,9 @@ void WiFiHandler::begin() {
return;
}
log_d("ADHOC is disabled, setting up STA network and checking transmission power \n\r");
log_d(
"ADHOC is disabled, setting up STA network and checking transmission "
"power \n\r");
auto txpower = configManager.getWiFiTxPowerConfig();
log_d("Setting Wifi Power to: %d", txpower.power);
log_d("Setting WiFi sleep mode to NONE \n\r");
@ -46,14 +46,9 @@ void WiFiHandler::begin() {
if (networks.empty()) {
log_i("No networks found in config, trying the default one \n\r");
if (this->iniSTA(
this->ssid,
this->password,
this->channel,
(wifi_power_t)txpower.power
)
) {
if (this->iniSTA(this->ssid, this->password, this->channel,
(wifi_power_t)txpower.power)) {
return;
}
@ -139,12 +134,11 @@ bool WiFiHandler::iniSTA(const std::string& ssid,
const std::string& password,
uint8_t channel,
wifi_power_t power) {
// since networks may not have a password, we only need to check if we have an ssid
// bail if we don't
if (ssid == ""){
// since networks may not have a password, we only need to check if we have an
// ssid bail if we don't
if (ssid == "") {
log_d("ssid missing, bailing");
return false;
return false;
}
unsigned long currentMillis = millis();
@ -159,8 +153,9 @@ bool WiFiHandler::iniSTA(const std::string& ssid,
INADDR_NONE); // need to call before setting hostname
log_d("Setting hostname %s \n\r");
WiFi.setHostname(mdnsConfig.hostname.c_str());
log_i("Setting TX power to: %d \n\r", (uint8_t)power);
WiFi.setTxPower(power); // https://github.com/espressif/arduino-esp32/issues/5698
log_i("Setting TX power to: %d \n\r", (uint8_t)power);
WiFi.setTxPower(
power); // https://github.com/espressif/arduino-esp32/issues/5698
WiFi.begin(ssid.c_str(), password.c_str(), channel);
log_d("Waiting for WiFi to connect... \n\r");

View File

@ -1,8 +1,12 @@
#pragma once
#ifndef WIFIHANDLER_HPP
#define WIFIHANDLER_HPP
#include <WiFi.h>
#include <string>
#include "data/StateManager/StateManager.hpp"
#include "data/config/project_config.hpp"
#include "data/utilities/helpers.hpp"
#include "data/utilities/Observer.hpp"
class WiFiHandler : public IObserver<ConfigState_e> {
@ -29,7 +33,6 @@ class WiFiHandler : public IObserver<ConfigState_e> {
ProjectConfig& configManager;
bool _enable_adhoc;
std::string ssid;
std::string password;

View File

@ -6,18 +6,16 @@
* @param mdnsName The mDNS hostname to use
*/
ProjectConfig deviceConfig("openiris", MDNS_HOSTNAME);
CommandManager commandManager(&deviceConfig);
CommandManager commandManager(deviceConfig);
SerialManager serialManager(&commandManager);
#ifdef CONFIG_CAMERA_MODULE_ESP32S3_XIAO_SENSE
LEDManager ledManager(LED_BUILTIN);
#elif CONFIG_CAMERA_MODULE_SWROOM_BABBLE_S3
LEDManager ledManager(38);
#else
LEDManager ledManager(33);
#endif // ESP32S3_XIAO_SENSE
#endif
#ifndef SIM_ENABLED
CameraHandler cameraHandler(deviceConfig);
@ -30,10 +28,10 @@ WiFiHandler wifiHandler(deviceConfig,
WIFI_CHANNEL,
ENABLE_ADHOC);
MDNSHandler mdnsHandler(deviceConfig);
#ifdef SIM_ENABLED
APIServer apiServer(deviceConfig, wifiStateManager, "/control");
#else
APIServer apiServer(deviceConfig, cameraHandler, "/control");
#ifndef SIM_ENABLED
StreamServer streamServer;
#endif // SIM_ENABLED
@ -45,37 +43,22 @@ void etvr_eye_tracker_web_init() {
log_d("[SETUP]: Starting MDNS Handler");
mdnsHandler.startMDNS();
switch (wifiStateManager.getCurrentState()) {
case WiFiState_e::WiFiState_Disconnected: {
//! TODO: Implement
break;
}
case WiFiState_e::WiFiState_ADHOC: {
auto wifiState = wifiStateManager.getCurrentState();
#ifndef SIM_ENABLED
if (wifiState == WiFiState_e::WiFiState_Connected ||
wifiState == WiFiState_e::WiFiState_ADHOC) {
{
log_d("[SETUP]: Starting Stream Server");
streamServer.startStreamServer();
#endif // SIM_ENABLED
auto result = streamServer.startTCPStreamServer();
// streamServer.startStreamServer();
// auto result = streamServer.startUDPStreamServer();
log_d("[SETUP]: Stream Server state: %s",
result ? "Connected" : "Failed to connect");
log_d("[SETUP]: Starting API Server");
apiServer.setup();
break;
}
case WiFiState_e::WiFiState_Connected: {
#ifndef SIM_ENABLED
log_d("[SETUP]: Starting Stream Server");
streamServer.startStreamServer();
#endif // SIM_ENABLED
log_d("[SETUP]: Starting API Server");
apiServer.setup();
break;
}
case WiFiState_e::WiFiState_Connecting: {
//! TODO: Implement
break;
}
case WiFiState_e::WiFiState_Error: {
//! TODO: Implement
break;
}
}
}
#endif // ETVR_EYE_TRACKER_WEB_API
@ -86,22 +69,10 @@ void setup() {
Logo::printASCII();
ledManager.begin();
#ifdef CONFIG_CAMERA_MODULE_SWROOM_BABBLE_S3 // Set IR emitter strength to 100%.
const int ledPin = 1; // Replace this with a command endpoint eventually.
const int freq = 5000;
const int ledChannel = 0;
const int resolution = 8;
const int dutyCycle = 255;
ledcSetup(ledChannel, freq, resolution);
ledcAttachPin(1, ledChannel);
ledcWrite(ledChannel, dutyCycle);
#endif
#ifndef SIM_ENABLED
deviceConfig.attach(cameraHandler);
#endif // SIM_ENABLED
deviceConfig.load();
serialManager.init();
#ifndef ETVR_EYE_TRACKER_USB_API
@ -112,6 +83,10 @@ void setup() {
}
void loop() {
#ifndef ETVR_EYE_TRACKER_USB_API
streamServer.sendTCPFrame();
#endif
// streamServer.sendUDPFrame();
ledManager.handleLED();
serialManager.run();
}