mirror of
https://github.com/EyeTrackVR/OpenIris.git
synced 2025-11-04 15:39:42 +08:00
large update
- Fully reworked the API code, wifi handler, and serial manager - Added proper APIServer
This commit is contained in:
parent
36bfcf3a3a
commit
687be8afb7
22
ESP/backup/WifiHandler/WifiHandler.hpp
Normal file
22
ESP/backup/WifiHandler/WifiHandler.hpp
Normal file
@ -0,0 +1,22 @@
|
||||
#pragma once
|
||||
#ifndef WIFIHANDLER_HPP
|
||||
#define WIFIHANDLER_HPP
|
||||
#include <memory>
|
||||
#include <WiFi.h>
|
||||
#include "data/StateManager/StateManager.hpp"
|
||||
#include "data/config/project_config.hpp"
|
||||
|
||||
class WiFiHandler
|
||||
{
|
||||
public:
|
||||
WiFiHandler(ProjectConfig *configManager, StateManager<WiFiState_e> *stateManager);
|
||||
virtual ~WiFiHandler();
|
||||
void setupWifi();
|
||||
ProjectConfig *configManager;
|
||||
StateManager<WiFiState_e> *stateManager;
|
||||
private:
|
||||
void setUpADHOC();
|
||||
void adhoc(const char *ssid, const char *password, uint8_t channel);
|
||||
void iniSTA();
|
||||
};
|
||||
#endif // WIFIHANDLER_HPP
|
||||
151
ESP/backup/WifiHandler/wifiHandler.cpp
Normal file
151
ESP/backup/WifiHandler/wifiHandler.cpp
Normal file
@ -0,0 +1,151 @@
|
||||
#include "WifiHandler.hpp"
|
||||
#include <vector>
|
||||
|
||||
WiFiHandler::WiFiHandler(ProjectConfig *configManager, StateManager<WiFiState_e> *stateManager) : configManager(configManager),
|
||||
stateManager(stateManager) {}
|
||||
|
||||
WiFiHandler::~WiFiHandler() {}
|
||||
|
||||
void WiFiHandler::setupWifi()
|
||||
{
|
||||
if (ENABLE_ADHOC || stateManager->getCurrentState() == WiFiState_e::WiFiState_ADHOC)
|
||||
{
|
||||
this->setUpADHOC();
|
||||
return;
|
||||
}
|
||||
log_i("Initializing connection to wifi");
|
||||
stateManager->setState(WiFiState_e::WiFiState_Connecting);
|
||||
|
||||
std::vector<ProjectConfig::WiFiConfig_t> *networks = configManager->getWifiConfigs();
|
||||
int connection_timeout = 30000; // 30 seconds
|
||||
|
||||
int count = 0;
|
||||
unsigned long currentMillis = millis();
|
||||
unsigned long _previousMillis = currentMillis;
|
||||
|
||||
for (auto networkIterator = networks->begin(); networkIterator != networks->end(); ++networkIterator)
|
||||
{
|
||||
log_i("Trying to connect to the %s network", networkIterator->ssid);
|
||||
|
||||
WiFi.begin(networkIterator->ssid.c_str(), networkIterator->password.c_str());
|
||||
count++;
|
||||
|
||||
if (!WiFi.isConnected())
|
||||
log_i("\n\rCould not connect to %s, trying another network\n\r", networkIterator->ssid);
|
||||
else
|
||||
{
|
||||
log_i("\n\rSuccessfully connected to %s\n\r", networkIterator->ssid);
|
||||
stateManager->setState(WiFiState_e::WiFiState_Connected);
|
||||
return;
|
||||
}
|
||||
|
||||
while (WiFi.status() != WL_CONNECTED)
|
||||
{
|
||||
stateManager->setState(ProgramStates::DeviceStates::WiFiState_e::WiFiState_Connecting);
|
||||
currentMillis = millis();
|
||||
Serial.print(".");
|
||||
delay(300);
|
||||
if (((currentMillis - _previousMillis) >= connection_timeout) && count >= networks->size())
|
||||
{
|
||||
log_i("[INFO]: WiFi connection timed out.\n");
|
||||
// we've tried all saved networks, none worked, let's error out
|
||||
log_e("Could not connect to any of the saved networks, check your Wifi credentials");
|
||||
stateManager->setState(WiFiState_e::WiFiState_Error);
|
||||
this->iniSTA();
|
||||
log_i("[INFO]: Attempting to connect to hardcoded network from ini file");
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void WiFiHandler::adhoc(const char *ssid, const char *password, uint8_t channel)
|
||||
{
|
||||
log_i("[INFO]: Setting Access Point...\n");
|
||||
|
||||
log_i("[INFO]: Configuring access point...\n");
|
||||
WiFi.mode(WIFI_AP);
|
||||
|
||||
Serial.printf("\r\nStarting AP. \r\nAP IP address: ");
|
||||
IPAddress IP = WiFi.softAPIP();
|
||||
Serial.printf("[INFO]: AP IP address: %s.\r\n", IP.toString().c_str());
|
||||
|
||||
// You can remove the password parameter if you want the AP to be open.
|
||||
WiFi.softAP(ssid, password, channel); // AP mode with password
|
||||
|
||||
WiFi.setTxPower(WIFI_POWER_11dBm);
|
||||
stateManager->setState(WiFiState_e::WiFiState_ADHOC);
|
||||
}
|
||||
|
||||
/*
|
||||
* *
|
||||
*/
|
||||
void WiFiHandler::setUpADHOC()
|
||||
{
|
||||
log_i("[INFO]: Setting Access Point...\n");
|
||||
size_t ssidLen = strlen(configManager->getAPWifiConfig()->ssid.c_str());
|
||||
size_t passwordLen = strlen(configManager->getAPWifiConfig()->password.c_str());
|
||||
char ssid[ssidLen + 1];
|
||||
char password[passwordLen + 1];
|
||||
uint8_t channel = configManager->getAPWifiConfig()->channel;
|
||||
if (ssidLen > 0 || passwordLen > 0)
|
||||
{
|
||||
strcpy(ssid, configManager->getAPWifiConfig()->ssid.c_str());
|
||||
strcpy(password, configManager->getAPWifiConfig()->password.c_str());
|
||||
channel = configManager->getAPWifiConfig()->channel;
|
||||
}
|
||||
else
|
||||
{
|
||||
strcpy(ssid, WIFI_AP_SSID);
|
||||
strcpy(password, WIFI_AP_PASSWORD);
|
||||
channel = ADHOC_CHANNEL;
|
||||
}
|
||||
|
||||
this->adhoc(ssid, password, channel);
|
||||
|
||||
log_i("[INFO]: Configuring access point...\n");
|
||||
log_d("[DEBUG]: ssid: %s\n", ssid);
|
||||
log_d("[DEBUG]: password: %s\n", password);
|
||||
log_d("[DEBUG]: channel: %d\n", channel);
|
||||
}
|
||||
|
||||
void WiFiHandler::iniSTA()
|
||||
{
|
||||
log_i("[INFO]: Setting up station...\n");
|
||||
int connection_timeout = 30000; // 30 seconds
|
||||
unsigned long currentMillis = millis();
|
||||
unsigned long _previousMillis = currentMillis;
|
||||
|
||||
log_i("Trying to connect to the %s network", WIFI_SSID);
|
||||
|
||||
WiFi.begin(WIFI_SSID, WIFI_PASSWORD, WIFI_CHANNEL);
|
||||
|
||||
if (!WiFi.isConnected())
|
||||
log_i("\n\rCould not connect to %s, please try another network\n\r", WIFI_SSID);
|
||||
else
|
||||
{
|
||||
log_i("\n\rSuccessfully connected to %s\n\r", WIFI_SSID);
|
||||
stateManager->setState(WiFiState_e::WiFiState_Connected);
|
||||
return;
|
||||
}
|
||||
|
||||
while (WiFi.status() != WL_CONNECTED)
|
||||
{
|
||||
stateManager->setState(ProgramStates::DeviceStates::WiFiState_e::WiFiState_Connecting);
|
||||
currentMillis = millis();
|
||||
Serial.print(".");
|
||||
delay(300);
|
||||
if ((currentMillis - _previousMillis) >= connection_timeout)
|
||||
{
|
||||
log_i("[INFO]: WiFi connection timed out.\n");
|
||||
// we've tried all saved networks, none worked, let's error out
|
||||
log_e("Could not connect to any of the save networks, check your Wifi credentials");
|
||||
stateManager->setState(WiFiState_e::WiFiState_Error);
|
||||
this->setUpADHOC();
|
||||
log_w("Setting up adhoc mode");
|
||||
log_w("Please use adhoc mode and the app to set your WiFi credentials and reboot the device");
|
||||
stateManager->setState(WiFiState_e::WiFiState_ADHOC);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -166,9 +166,9 @@ void APIServer::triggerWifiConfigWrite()
|
||||
pass_write = false;
|
||||
channel_write = false;
|
||||
if (network->stateManager->getCurrentState() == WiFiState_e::WiFiState_ADHOC)
|
||||
network->configManager->setWifiConfig(wifiConfig.local_WifiConfig[0].ssid.c_str(), wifiConfig.local_WifiConfig[0].ssid.c_str(), wifiConfig.local_WifiConfig[0].pass.c_str(), &wifiConfig.local_WifiConfig[0].channel, true);
|
||||
network->configManager->setWifiConfig(wifiConfig.local_WifiConfig[0].ssid.c_str(), wifiConfig.local_WifiConfig[0].ssid.c_str(), wifiConfig.local_WifiConfig[0].pass.c_str(), &wifiConfig.local_WifiConfig[0].channel, wifiConfig.local_WifiConfig[0].adhoc, true);
|
||||
else
|
||||
network->configManager->setWifiConfig(wifiConfig.local_WifiConfig[1].ssid.c_str(), wifiConfig.local_WifiConfig[1].ssid.c_str(), wifiConfig.local_WifiConfig[1].pass.c_str(), &wifiConfig.local_WifiConfig[1].channel, true);
|
||||
network->configManager->setWifiConfig(wifiConfig.local_WifiConfig[1].ssid.c_str(), wifiConfig.local_WifiConfig[1].ssid.c_str(), wifiConfig.local_WifiConfig[1].pass.c_str(), &wifiConfig.local_WifiConfig[1].channel, wifiConfig.local_WifiConfig[1].adhoc, true);
|
||||
network->configManager->save();
|
||||
}
|
||||
}
|
||||
@ -70,6 +70,7 @@ private:
|
||||
std::string ssid;
|
||||
std::string pass;
|
||||
uint8_t channel;
|
||||
bool adhoc;
|
||||
};
|
||||
|
||||
struct WifiConfig
|
||||
@ -22,8 +22,7 @@ void ProjectConfig::initConfig()
|
||||
false,
|
||||
"",
|
||||
"",
|
||||
""
|
||||
};
|
||||
""};
|
||||
|
||||
this->config.camera = {
|
||||
0,
|
||||
@ -38,6 +37,7 @@ void ProjectConfig::initConfig()
|
||||
"",
|
||||
"",
|
||||
0,
|
||||
false,
|
||||
},
|
||||
};
|
||||
|
||||
@ -45,6 +45,7 @@ void ProjectConfig::initConfig()
|
||||
"",
|
||||
"",
|
||||
0,
|
||||
false,
|
||||
};
|
||||
}
|
||||
|
||||
@ -82,8 +83,9 @@ void ProjectConfig::load()
|
||||
bool networks_password_success = this->read(buff, this->config.networks[i].password);
|
||||
snprintf(buff, sizeof(buff), "%d_channel", i);
|
||||
bool networks_channel_success = this->read(buff, this->config.networks[i].channel);
|
||||
bool networks_adhoc_success = this->read(buff, this->config.networks[i].adhoc);
|
||||
|
||||
network_info_success = networks_name_success && networks_ssid_success && networks_password_success && networks_channel_success;
|
||||
network_info_success = networks_name_success && networks_ssid_success && networks_password_success && networks_channel_success && networks_adhoc_success;
|
||||
}
|
||||
|
||||
if (!device_success || !camera_success || !network_info_success)
|
||||
@ -123,7 +125,13 @@ void ProjectConfig::save()
|
||||
this->write(buff, this->config.networks[i].password);
|
||||
snprintf(buff, sizeof(buff), "%d_channel", i);
|
||||
this->write(buff, this->config.networks[i].channel);
|
||||
this->write(buff, this->config.networks[i].adhoc);
|
||||
|
||||
}
|
||||
|
||||
log_i("Project config saved and system is rebooting");
|
||||
delay(20000);
|
||||
ESP.restart();
|
||||
}
|
||||
|
||||
void ProjectConfig::reset()
|
||||
@ -167,7 +175,7 @@ void ProjectConfig::setCameraConfig(uint8_t *vflip, uint8_t *framesize, uint8_t
|
||||
}
|
||||
}
|
||||
|
||||
void ProjectConfig::setWifiConfig(const char *networkName, const char *ssid, const char *password, uint8_t *channel, bool shouldNotify)
|
||||
void ProjectConfig::setWifiConfig(const char *networkName, const char *ssid, const char *password, uint8_t *channel, bool adhoc, bool shouldNotify)
|
||||
{
|
||||
WiFiConfig_t *networkToUpdate = nullptr;
|
||||
|
||||
@ -185,6 +193,7 @@ void ProjectConfig::setWifiConfig(const char *networkName, const char *ssid, con
|
||||
(char *)ssid,
|
||||
(char *)password,
|
||||
*channel,
|
||||
adhoc,
|
||||
},
|
||||
};
|
||||
if (shouldNotify)
|
||||
@ -193,12 +202,13 @@ void ProjectConfig::setWifiConfig(const char *networkName, const char *ssid, con
|
||||
log_d("Updating wifi config");
|
||||
}
|
||||
|
||||
void ProjectConfig::setAPWifiConfig(const char *ssid, const char *password, uint8_t *channel, bool shouldNotify)
|
||||
void ProjectConfig::setAPWifiConfig(const char *ssid, const char *password, uint8_t *channel, bool adhoc, bool shouldNotify)
|
||||
{
|
||||
this->config.ap_network = {
|
||||
(char *)ssid,
|
||||
(char *)password,
|
||||
*channel,
|
||||
adhoc,
|
||||
};
|
||||
|
||||
log_d("Updating access point config");
|
||||
|
||||
@ -45,6 +45,7 @@ public:
|
||||
std::string ssid;
|
||||
std::string password;
|
||||
uint8_t channel;
|
||||
bool adhoc;
|
||||
};
|
||||
|
||||
struct AP_WiFiConfig_t
|
||||
@ -52,6 +53,7 @@ public:
|
||||
std::string ssid;
|
||||
std::string password;
|
||||
uint8_t channel;
|
||||
bool adhoc;
|
||||
};
|
||||
|
||||
struct TrackerConfig_t
|
||||
@ -69,8 +71,8 @@ public:
|
||||
|
||||
void setDeviceConfig(const char *name, const char *OTAPassword, int *OTAPort, bool shouldNotify);
|
||||
void setCameraConfig(uint8_t *vflip, uint8_t *framesize, uint8_t *href, uint8_t *quality, bool shouldNotify);
|
||||
void setWifiConfig(const char *networkName, const char *ssid, const char *password, uint8_t *channel, bool shouldNotify);
|
||||
void setAPWifiConfig(const char *ssid, const char *password, uint8_t *channel, bool shouldNotify);
|
||||
void setWifiConfig(const char *networkName, const char *ssid, const char *password, uint8_t *channel, bool adhoc, bool shouldNotify);
|
||||
void setAPWifiConfig(const char *ssid, const char *password, uint8_t *channel, bool adhoc, bool shouldNotify);
|
||||
|
||||
private:
|
||||
const char *configFileName;
|
||||
|
||||
@ -1,4 +1,6 @@
|
||||
#pragma once
|
||||
#ifndef OBSERVER_HPP
|
||||
#define OBSERVER_HPP
|
||||
#include <set>
|
||||
|
||||
namespace ObserverEvent
|
||||
@ -44,4 +46,6 @@ public:
|
||||
++iterator;
|
||||
}
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
#endif // !OBSERVER_HPP
|
||||
80
ESP/lib/src/data/utilities/helpers.cpp
Normal file
80
ESP/lib/src/data/utilities/helpers.cpp
Normal file
@ -0,0 +1,80 @@
|
||||
#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;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
void split(std::string str, 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.push_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.push_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;
|
||||
}
|
||||
10
ESP/lib/src/data/utilities/helpers.hpp
Normal file
10
ESP/lib/src/data/utilities/helpers.hpp
Normal file
@ -0,0 +1,10 @@
|
||||
#include <string>
|
||||
#include <sstream>
|
||||
#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);
|
||||
}
|
||||
@ -1,12 +1,10 @@
|
||||
#pragma once
|
||||
#ifndef MAKE_UNIQUE_HPP
|
||||
#define MAKE_UNIQUE_HPP
|
||||
#include <memory>
|
||||
#include <cstddef>
|
||||
#include <type_traits>
|
||||
#include <utility>
|
||||
namespace Utilities
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief override the STD namespace to add make_unique function
|
||||
@ -53,4 +51,6 @@ namespace std
|
||||
template <class T, class... Args>
|
||||
typename _Unique_if<T>::_Known_bound
|
||||
make_unique(Args &&...) = delete;
|
||||
}
|
||||
}
|
||||
|
||||
#endif // !MAKE_UNIQUE_HPP
|
||||
54
ESP/lib/src/data/utilities/network_utilities.cpp
Normal file
54
ESP/lib/src/data/utilities/network_utilities.cpp
Normal file
@ -0,0 +1,54 @@
|
||||
#include "network_utilities.hpp"
|
||||
|
||||
void Network_Utilities::SetupWifiScan()
|
||||
{
|
||||
// Set WiFi to station mode and disconnect from an AP if it was previously connected
|
||||
WiFi.mode(WIFI_STA);
|
||||
WiFi.disconnect(); // Disconnect from the access point if connected before
|
||||
delay(100);
|
||||
|
||||
Serial.println("Setup done");
|
||||
}
|
||||
|
||||
bool Network_Utilities::LoopWifiScan()
|
||||
{
|
||||
// WiFi.scanNetworks will return the number of networks found
|
||||
log_i("[INFO]: Beginning WiFi Scanner");
|
||||
int networks = WiFi.scanNetworks();
|
||||
log_i("[INFO]: scan done");
|
||||
|
||||
log_i("%d networks found", networks);
|
||||
for (int i = networks; i--;)
|
||||
{
|
||||
// Print SSID and RSSI for each network found
|
||||
//! Add method here to interface with the API and forward the scanned networks to the API
|
||||
log_i("%d: %s (%d) %s\n", i - 1, WiFi.SSID(i), WiFi.RSSI(i), (WiFi.encryptionType(i) == WIFI_AUTH_OPEN) ? " " : "*");
|
||||
my_delay(0.02L); // delay 20ms
|
||||
}
|
||||
|
||||
// Wait a bit before scanning again
|
||||
delay(5000);
|
||||
return (networks > 0);
|
||||
}
|
||||
|
||||
// Take measurements of the Wi-Fi strength and return the average result.
|
||||
int Network_Utilities::getStrength(int points) // TODO: add to JSON doc
|
||||
{
|
||||
int32_t rssi = 0, averageRSSI = 0;
|
||||
|
||||
for (int i = 0; i < points; i++)
|
||||
{
|
||||
rssi += WiFi.RSSI();
|
||||
delay(20);
|
||||
}
|
||||
|
||||
averageRSSI = rssi / points;
|
||||
return averageRSSI;
|
||||
}
|
||||
|
||||
void Network_Utilities::my_delay(volatile long delay_time)
|
||||
{
|
||||
delay_time = delay_time * 1e6L;
|
||||
for (volatile long count = delay_time; count > 0L; count--)
|
||||
;
|
||||
}
|
||||
16
ESP/lib/src/data/utilities/network_utilities.hpp
Normal file
16
ESP/lib/src/data/utilities/network_utilities.hpp
Normal file
@ -0,0 +1,16 @@
|
||||
#pragma once
|
||||
#ifndef UTILITIES_hpp
|
||||
#define UTILITIES_hpp
|
||||
#include <Arduino.h>
|
||||
#include "network/wifihandler/WifiHandler.hpp"
|
||||
#include <unordered_map>
|
||||
namespace Network_Utilities
|
||||
{
|
||||
bool LoopWifiScan();
|
||||
void SetupWifiScan();
|
||||
void my_delay(volatile long delay_time);
|
||||
int CheckWifiState();
|
||||
int getStrength(int points);
|
||||
String generateDeviceID();
|
||||
}
|
||||
#endif // !UTILITIES_hpp
|
||||
@ -1,340 +0,0 @@
|
||||
#include "serialmanager.hpp"
|
||||
|
||||
#if SERIAL_CMD_DBG_EN
|
||||
|
||||
static void printHex(Stream &port, uint8_t *data, uint8_t length);
|
||||
static void printHex(Stream &port, uint16_t *data, uint8_t length);
|
||||
|
||||
void printHex(Stream &port, uint8_t *data, uint8_t length) // prints 8-bit data in hex with leading zeroes
|
||||
{
|
||||
for (int i = 0; i < length; i++)
|
||||
{
|
||||
// port.print("0x");
|
||||
if (data[i] < 0x10)
|
||||
{
|
||||
port.print("0");
|
||||
}
|
||||
port.print(data[i], HEX);
|
||||
port.print(" ");
|
||||
}
|
||||
}
|
||||
|
||||
void printHex(Stream &port, uint16_t *data, uint8_t length) // prints 16-bit data in hex with leading zeroes
|
||||
{
|
||||
for (int i = 0; i < length; i++)
|
||||
{
|
||||
// port.print("0x");
|
||||
uint8_t MSB = byte(data[i] >> 8);
|
||||
uint8_t LSB = byte(data[i]);
|
||||
if (MSB < 0x10)
|
||||
{
|
||||
port.print("0");
|
||||
}
|
||||
port.print(MSB, HEX);
|
||||
if (LSB < 0x10)
|
||||
{
|
||||
port.print("0");
|
||||
}
|
||||
port.print(LSB, HEX);
|
||||
port.print(" ");
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
SerialManager2::SerialManager2() : userErrorHandler(NULL), _serial(NULL), ManagerCount(0), _serialManager2Active(false), newData(false)
|
||||
{
|
||||
clear();
|
||||
}
|
||||
|
||||
void SerialManager2::begin(Stream &serialPort)
|
||||
{
|
||||
/* Save Serial Port configurations */
|
||||
_serial = &serialPort;
|
||||
}
|
||||
|
||||
// This checks the Serial stream for characters, and assembles them into a buffer.
|
||||
// When the terminator character (defined by EOL constant) is seen, it starts parsing the
|
||||
// buffer for a prefix Manager, and calls handlers setup by addManager() method
|
||||
void SerialManager2::loop(unsigned long timeout)
|
||||
{
|
||||
log_d("Listening to serial");
|
||||
_serialManager2Active = true;
|
||||
Serial.setTimeout(timeout);
|
||||
static bool recvInProgress = false;
|
||||
char startDelimiter = '<'; //! we need to decide on a delimiter for the start of a message
|
||||
char endDelimiter = '>'; //! we need to decide on a delimiter for the end of a message
|
||||
char c;
|
||||
while ((available() > 0) && !newData)
|
||||
{
|
||||
c = read();
|
||||
if (recvInProgress)
|
||||
{
|
||||
if (c != endDelimiter)
|
||||
{
|
||||
bufferHandler(c);
|
||||
}
|
||||
else
|
||||
{
|
||||
recvInProgress = false;
|
||||
newData = true;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (c == startDelimiter)
|
||||
{
|
||||
recvInProgress = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
delay(timeout);
|
||||
_serialManager2Active = false;
|
||||
}
|
||||
|
||||
/* Clear buffer */
|
||||
void SerialManager2::clear(void)
|
||||
{
|
||||
memset(buffer, 0, SERIAL_CMD_BUFF_LEN);
|
||||
pBuff = buffer;
|
||||
}
|
||||
|
||||
/*
|
||||
* Send error response
|
||||
* NOTE: Will execute user defined callback (defined using addDefault method),
|
||||
* if no user defined callback it will send the ERROR message (sendERROR method).
|
||||
*/
|
||||
void SerialManager2::error(void)
|
||||
{
|
||||
if (NULL != userErrorHandler)
|
||||
{
|
||||
(*userErrorHandler)();
|
||||
}
|
||||
|
||||
clear(); /* Clear buffer */
|
||||
}
|
||||
|
||||
// Retrieve the next token ("word" or "argument") from the Manager buffer.
|
||||
// returns a NULL if no more tokens exist.
|
||||
char *SerialManager2::next(void)
|
||||
{
|
||||
return strtok_r(NULL, delimiters, &last);
|
||||
}
|
||||
|
||||
void SerialManager2::bufferHandler(char c)
|
||||
{
|
||||
int len;
|
||||
char *lastChars = NULL;
|
||||
|
||||
if ((pBuff - buffer) > (SERIAL_CMD_BUFF_LEN - 2)) /* Check buffer overflow */
|
||||
{
|
||||
error(); /* Send ERROR, Buffer overflow */
|
||||
}
|
||||
|
||||
*pBuff++ = c; /* Put character into buffer */
|
||||
*pBuff = '\0'; /* Always null terminate strings */
|
||||
|
||||
if ((pBuff - buffer) > 2) /* Check buffer length */
|
||||
{
|
||||
/* Get EOL */
|
||||
len = strlen(buffer);
|
||||
lastChars = buffer + len - 2;
|
||||
|
||||
/* Compare last chars to EOL */
|
||||
if (0 == strcmp(lastChars, EOL))
|
||||
{
|
||||
|
||||
// *lastChars = '\0'; /* Replace EOL with NULL terminator */
|
||||
|
||||
#if (SERIAL_CMD_DBG_EN == 1)
|
||||
log_d("Received: %s", buffer);
|
||||
#endif
|
||||
|
||||
if (ManagerHandler())
|
||||
{
|
||||
clear();
|
||||
}
|
||||
else
|
||||
{
|
||||
error();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Return true if match was found */
|
||||
bool SerialManager2::ManagerHandler(void)
|
||||
{
|
||||
int i;
|
||||
bool ret = false;
|
||||
char *token = NULL;
|
||||
char *offset = NULL;
|
||||
char userInput[SERIAL_CMD_BUFF_LEN];
|
||||
|
||||
memcpy(userInput, buffer, SERIAL_CMD_BUFF_LEN);
|
||||
|
||||
/* Search for Manager at start of buffer */
|
||||
token = strtok_r(buffer, delimiters, &last);
|
||||
|
||||
#if SERIAL_CMD_DBG_EN
|
||||
print("User input: (");
|
||||
printHex(Serial, (uint8_t *)userInput, SERIAL_CMD_BUFF_LEN);
|
||||
println(")");
|
||||
#endif
|
||||
|
||||
if (NULL != token)
|
||||
{
|
||||
|
||||
#if SERIAL_CMD_DBG_EN
|
||||
log_d("Token: %s", token);
|
||||
#endif
|
||||
|
||||
for (i = 0; (i < ManagerCount); i++)
|
||||
{
|
||||
|
||||
#if SERIAL_CMD_DBG_EN
|
||||
print("Case: \"");
|
||||
print(ManagerList[i].Manager);
|
||||
print("\" ");
|
||||
#endif
|
||||
|
||||
/* Compare the token against the list of known Managers */
|
||||
if (0 == strncmp(token, ManagerList[i].Manager, SERIAL_CMD_BUFF_LEN))
|
||||
{
|
||||
|
||||
#if SERIAL_CMD_DBG_EN
|
||||
log_d("- Match Found!");
|
||||
#endif
|
||||
offset = (char *)(userInput + strlen(token));
|
||||
|
||||
/* Check for query Manager */
|
||||
if (0 == strncmp(offset, "=?", 2))
|
||||
{
|
||||
#if SERIAL_CMD_DBG_EN
|
||||
log_d("Run test callback");
|
||||
#endif
|
||||
if (NULL != *ManagerList[i].test)
|
||||
{
|
||||
/* Run test callback */
|
||||
(*ManagerList[i].test)();
|
||||
}
|
||||
}
|
||||
else if (('?' == *offset) && (NULL != *ManagerList[i].read))
|
||||
{
|
||||
#if SERIAL_CMD_DBG_EN
|
||||
log_d("Run read callback");
|
||||
#endif
|
||||
/* Run read callback */
|
||||
(*ManagerList[i].read)();
|
||||
}
|
||||
else if (('=' == *offset) && (NULL != *ManagerList[i].write))
|
||||
{
|
||||
#if (SERIAL_CMD_DBG_EN == 1)
|
||||
log_d("Run write callback");
|
||||
#endif
|
||||
/* Run write callback */
|
||||
(*ManagerList[i].write)();
|
||||
}
|
||||
else if (NULL != *ManagerList[i].execute)
|
||||
{
|
||||
#if SERIAL_CMD_DBG_EN
|
||||
log_d("Run execute callback");
|
||||
#endif
|
||||
/* Run execute callback */
|
||||
(*ManagerList[i].execute)();
|
||||
}
|
||||
else
|
||||
{
|
||||
log_e("INVALID");
|
||||
ret = false;
|
||||
break;
|
||||
}
|
||||
|
||||
ret = true;
|
||||
break;
|
||||
}
|
||||
|
||||
#if SERIAL_CMD_DBG_EN
|
||||
else
|
||||
{
|
||||
log_e("- Not a match!");
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
// Adds a "Manager" and a handler function to the list of available Managers.
|
||||
// This is used for matching a found token in the buffer, and gives the pointer
|
||||
// to the handler function to deal with it.
|
||||
void SerialManager2::addManager(char *cmd, void (*test)(), void (*read)(), void (*write)(), void (*execute)())
|
||||
{
|
||||
|
||||
#if SERIAL_CMD_DBG_EN
|
||||
print("[");
|
||||
print(ManagerCount);
|
||||
print("] New Manager: ");
|
||||
println(cmd);
|
||||
#endif
|
||||
|
||||
ManagerList = (serialManager2Callback *)realloc(ManagerList, (ManagerCount + 1) * sizeof(serialManager2Callback));
|
||||
strncpy(ManagerList[ManagerCount].Manager, cmd, SERIAL_CMD_BUFF_LEN);
|
||||
ManagerList[ManagerCount].test = test;
|
||||
ManagerList[ManagerCount].read = read;
|
||||
ManagerList[ManagerCount].write = write;
|
||||
ManagerList[ManagerCount].execute = execute;
|
||||
ManagerCount++;
|
||||
}
|
||||
|
||||
/* Optional user-defined function to call when an error occurs, default is NULL */
|
||||
void SerialManager2::addError(void (*callback)())
|
||||
{
|
||||
userErrorHandler = callback;
|
||||
}
|
||||
|
||||
int SerialManager2::available()
|
||||
{
|
||||
int bytes = 0;
|
||||
if (NULL != _serial)
|
||||
{
|
||||
bytes = _serial->available();
|
||||
}
|
||||
return bytes;
|
||||
}
|
||||
|
||||
int SerialManager2::read()
|
||||
{
|
||||
int bytes = 0;
|
||||
if (NULL != _serial)
|
||||
{
|
||||
bytes = _serial->read();
|
||||
}
|
||||
return bytes;
|
||||
}
|
||||
|
||||
int SerialManager2::peek()
|
||||
{
|
||||
int bytes = 0;
|
||||
if (NULL != _serial)
|
||||
{
|
||||
bytes = _serial->peek();
|
||||
}
|
||||
return bytes;
|
||||
}
|
||||
|
||||
void SerialManager2::flush()
|
||||
{
|
||||
if (NULL != _serial)
|
||||
{
|
||||
_serial->flush();
|
||||
}
|
||||
}
|
||||
|
||||
size_t SerialManager2::write(uint8_t x)
|
||||
{
|
||||
(void)x;
|
||||
return 0;
|
||||
}
|
||||
|
||||
SerialManager2 serialManager2;
|
||||
@ -1,158 +0,0 @@
|
||||
#ifndef SERIALMANAGER2_HPP
|
||||
#define SERIALMANAGER2_HPP
|
||||
#include <Arduino.h>
|
||||
#include <string.h>
|
||||
|
||||
#define SERIAL_CMD_DBG_EN 0
|
||||
#define SERIAL_CMD_BUFF_LEN 100 /* Max length for each serial Manager */
|
||||
|
||||
/* Data structure to hold Manager/Handler function key-value pairs */
|
||||
typedef struct
|
||||
{
|
||||
char Manager[SERIAL_CMD_BUFF_LEN];
|
||||
void (*test)();
|
||||
void (*read)();
|
||||
void (*write)();
|
||||
void (*execute)();
|
||||
} serialManager2Callback;
|
||||
|
||||
/*
|
||||
* Token delimiters (setup '=', query '?', separator ',')
|
||||
*/
|
||||
const char delimiters[] = "=,?\r\n";
|
||||
|
||||
/*
|
||||
* End Of Line: <CR><LF>
|
||||
* <CR> = <Carriage Return, 0x0D, 13, '\r'>
|
||||
* <LF> = <Line Feed, 0x0A, 10, '\n'>
|
||||
*/
|
||||
const char EOL[] = "\r\n";
|
||||
|
||||
class SerialManager2 : public Stream
|
||||
{
|
||||
public:
|
||||
SerialManager2();
|
||||
virtual ~SerialManager2();
|
||||
|
||||
/**
|
||||
* Start connection to serial port
|
||||
*
|
||||
* @param serialPort - Serial port to listen for Managers
|
||||
* @param baud - Baud rate
|
||||
*/
|
||||
void begin(Stream &serialPort);
|
||||
|
||||
/**
|
||||
* Execute this function inside Arduino's loop function.
|
||||
*/
|
||||
void loop(unsigned long timeout);
|
||||
|
||||
/**
|
||||
* Add a new Manager
|
||||
*
|
||||
* @param cmd - Manager to listen
|
||||
* @param test - Test Manager callback
|
||||
* @param read - Read Manager callback
|
||||
* @param write - Write Manager callback
|
||||
* @param execute - Execute Manager callback
|
||||
*/
|
||||
void addManager(char *cmd, void (*test)(), void (*read)(), void (*write)(), void (*execute)());
|
||||
|
||||
/**
|
||||
* Add a read-only Manager
|
||||
*
|
||||
* @param cmd - Manager to listen
|
||||
* @param callback - Read Manager callback
|
||||
*/
|
||||
void addTestManager(char *cmd, void (*callback)())
|
||||
{
|
||||
addManager(cmd, callback, NULL, NULL, NULL);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a read-only Manager
|
||||
*
|
||||
* @param cmd - Manager to listen
|
||||
* @param callback - Read Manager callback
|
||||
*/
|
||||
void addReadManager(char *cmd, void (*callback)())
|
||||
{
|
||||
addManager(cmd, NULL, callback, NULL, NULL);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a write-only Manager
|
||||
*
|
||||
* @param cmd - Manager to listen
|
||||
* @param callback - Write Manager callback
|
||||
*/
|
||||
void addWriteManager(char *cmd, void (*callback)())
|
||||
{
|
||||
addManager(cmd, NULL, NULL, callback, NULL);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a execute-only Manager
|
||||
*
|
||||
* @param cmd - Manager to listen
|
||||
* @param callback - Execute Manager callback
|
||||
*/
|
||||
void addExecuteManager(char *cmd, void (*callback)())
|
||||
{
|
||||
addManager(cmd, NULL, NULL, NULL, callback);
|
||||
}
|
||||
|
||||
/**
|
||||
* Default function to execute when no match is found
|
||||
*
|
||||
* @param callback - Function to execute when Manager is received
|
||||
*/
|
||||
void addError(void (*callback)());
|
||||
|
||||
/* Return next argument found in Manager buffer */
|
||||
char *next(void);
|
||||
|
||||
/* variable to track state of newdata in the buffer */
|
||||
bool newData;
|
||||
|
||||
/*
|
||||
* Virtual methods to match Stream class
|
||||
*/
|
||||
size_t write(uint8_t);
|
||||
int available();
|
||||
int read();
|
||||
int peek();
|
||||
void flush();
|
||||
|
||||
|
||||
private:
|
||||
/* Setup serial port */
|
||||
void setup(unsigned long baud);
|
||||
/* Sets the Manager buffer to all '\0' (nulls) */
|
||||
void clear(void);
|
||||
/* Send error message and clear buffer */
|
||||
void error();
|
||||
/* Process buffer */
|
||||
void bufferHandler(char c);
|
||||
/* Check for Manager instances and handle callbacks and queries */
|
||||
bool ManagerHandler(void);
|
||||
/* User defined error handler */
|
||||
void (*userErrorHandler)();
|
||||
/* Serial Port handler */
|
||||
Stream *_serial;
|
||||
/* Actual definition for Manager/handler array */
|
||||
serialManager2Callback *ManagerList;
|
||||
/* Buffer of stored characters while waiting for terminator character */
|
||||
char buffer[SERIAL_CMD_BUFF_LEN];
|
||||
/* Pointer to buffer, used to store data in the buffer */
|
||||
char *pBuff;
|
||||
/* State variable used by strtok_r during processing */
|
||||
char *last;
|
||||
/* Number of available Managers registered by new() */
|
||||
uint8_t ManagerCount;
|
||||
|
||||
bool _serialManager2Active;
|
||||
|
||||
};
|
||||
extern SerialManager2 serialManager2;
|
||||
#endif // SerialManager2_h
|
||||
@ -1,126 +1,83 @@
|
||||
#include "serialmanager.hpp"
|
||||
|
||||
std::unordered_map<std::string, SerialManager::Serial_Commands> SerialManager::command_map = {
|
||||
{"", NO_INPUT},
|
||||
{"device_config", DEVICE_CONFIG},
|
||||
{"camera_config", CAMERA_CONFIG},
|
||||
{"wifi_config", WIFI_CONFIG}};
|
||||
|
||||
void readStr(const char *inStr);
|
||||
|
||||
SerialManager::SerialManager(ProjectConfig *projectConfig) : projectConfig(projectConfig),
|
||||
serialManagerActive(false),
|
||||
newData(false),
|
||||
tempBuffer{0},
|
||||
serialBuffer{0},
|
||||
device_config_name{0},
|
||||
device_config_OTAPassword{0},
|
||||
device_config_OTAPort(0),
|
||||
camera_config_vflip{0},
|
||||
camera_config_href{0},
|
||||
camera_config_framesize{0},
|
||||
camera_config_quality{0},
|
||||
wifi_config_name{0},
|
||||
wifi_config_ssid{0},
|
||||
wifi_config_password{0},
|
||||
wifi_config_channel(0) {}
|
||||
serReader(std::make_unique<serialStr>())
|
||||
{
|
||||
}
|
||||
|
||||
SerialManager::~SerialManager() {}
|
||||
|
||||
void SerialManager::listenToSerial(unsigned long timeout)
|
||||
void SerialManager::begin()
|
||||
{
|
||||
log_d("Listening to serial");
|
||||
serialManagerActive = true;
|
||||
Serial.setTimeout(timeout);
|
||||
|
||||
static bool recvInProgress = false;
|
||||
static uint8_t index = 0; // index
|
||||
char startDelimiter = '<'; //! we need to decide on a delimiter for the start of a message
|
||||
char endDelimiter = '>'; //! we need to decide on a delimiter for the end of a message
|
||||
char receivedChar; // to test for received data on the line
|
||||
|
||||
while ((Serial.available() > 0) && !newData)
|
||||
{
|
||||
serialManagerActive = true;
|
||||
receivedChar = Serial.read();
|
||||
if (recvInProgress)
|
||||
{
|
||||
if (receivedChar != endDelimiter)
|
||||
{
|
||||
serialBuffer[index] = receivedChar;
|
||||
index++;
|
||||
if (index >= sizeof(serialBuffer))
|
||||
{
|
||||
log_e("Serial buffer overflow");
|
||||
index = 0;
|
||||
recvInProgress = false;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
recvInProgress = false;
|
||||
serialBuffer[index] = '\0';
|
||||
index = 0;
|
||||
newData = true;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (receivedChar == startDelimiter)
|
||||
{
|
||||
recvInProgress = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
serialManagerActive = false;
|
||||
serReader->setCallback(readStr);
|
||||
}
|
||||
|
||||
void SerialManager::parseData()
|
||||
void readStr(const char *inStr)
|
||||
{
|
||||
log_d("Parsing data");
|
||||
char *strtokIndx; // this is used by strtok() as an index
|
||||
Serial.print("command : ");
|
||||
Serial.println(inStr);
|
||||
std::string raw = inStr;
|
||||
std::vector<std::string> command;
|
||||
Helpers::split(raw, ":", command); //! gives us the command and the value - "command:value"
|
||||
std::vector<std::string> command_value;
|
||||
Helpers::split(command[1], ",", command_value); //! gives us the command and the value - "command:value"
|
||||
|
||||
//! Parse the data
|
||||
//* Device Config *//
|
||||
strtokIndx = strtok(tempBuffer, ","); // get the first part
|
||||
strcpy(device_config_name, strtokIndx); // copy it to buffer
|
||||
//! The following line uses strdup to return a char* to lwrCase
|
||||
char *lwr_case = strdup(command[0].c_str());
|
||||
lwrCase(lwr_case); //! converts the command to lowercase
|
||||
|
||||
strtokIndx = strtok(NULL, ","); // get the second part
|
||||
strcpy(device_config_OTAPassword, strtokIndx);
|
||||
|
||||
strtokIndx = strtok(NULL, ",");
|
||||
device_config_OTAPort = atoi(strtokIndx);
|
||||
|
||||
//* Camera Config *//
|
||||
strtokIndx = strtok(NULL, ",");
|
||||
camera_config_vflip = atoi(strtokIndx);
|
||||
|
||||
strtokIndx = strtok(NULL, ",");
|
||||
camera_config_framesize = atoi(strtokIndx);
|
||||
|
||||
strtokIndx = strtok(NULL, ",");
|
||||
camera_config_href = atoi(strtokIndx);
|
||||
|
||||
strtokIndx = strtok(NULL, ",");
|
||||
camera_config_quality = atoi(strtokIndx);
|
||||
|
||||
//* Wifi Config *//
|
||||
strtokIndx = strtok(tempBuffer, ",");
|
||||
strcpy(wifi_config_name, strtokIndx);
|
||||
|
||||
strtokIndx = strtok(NULL, ",");
|
||||
strcpy(wifi_config_ssid, strtokIndx);
|
||||
|
||||
strtokIndx = strtok(NULL, ",");
|
||||
strcpy(wifi_config_password, strtokIndx);
|
||||
|
||||
strtokIndx = strtok(NULL, ",");
|
||||
wifi_config_channel = atoi(strtokIndx);
|
||||
switch (SerialManager::command_map[lwr_case])
|
||||
{
|
||||
case SerialManager::NO_INPUT:
|
||||
break;
|
||||
case SerialManager::DEVICE_CONFIG:
|
||||
break;
|
||||
case SerialManager::CAMERA_CONFIG:
|
||||
break;
|
||||
case SerialManager::WIFI_CONFIG:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void SerialManager::handleSerial()
|
||||
{
|
||||
listenToSerial(30000L); // test for serial input every 30 seconds
|
||||
if (newData) // input received
|
||||
if (Serial.available() > 0)
|
||||
{
|
||||
strcpy(tempBuffer, serialBuffer); // this temporary copy is necessary to protect the original data because strtok() used in parseData() replaces the commas with \0
|
||||
parseData(); // split the data into tokens and store them in the data structure
|
||||
projectConfig->setDeviceConfig(device_config_name, device_config_OTAPassword, &device_config_OTAPort, true); // set the values in the project config
|
||||
projectConfig->setCameraConfig(&camera_config_vflip, &camera_config_framesize, &camera_config_href, &camera_config_quality, true); // set the values in the project config
|
||||
projectConfig->setWifiConfig(wifi_config_name, wifi_config_ssid, wifi_config_password, &wifi_config_channel, true); // set the values in the project config
|
||||
projectConfig->save(); // save the config to the EEPROM
|
||||
newData = false; // reset new data
|
||||
delay(10);
|
||||
std::string raw = Serial.readStringUntil('#').c_str();
|
||||
// String s = "{\"a\":\"b\"}";
|
||||
|
||||
while (Serial.available() > 0)
|
||||
{
|
||||
Serial.read();
|
||||
}
|
||||
log_d("Received Serial Data: %s", raw.c_str());
|
||||
|
||||
DeserializationError error = deserializeJson(jsonDoc, raw);
|
||||
if (error)
|
||||
{
|
||||
log_e("deserializeJson() failed: %s", error.c_str());
|
||||
return;
|
||||
}
|
||||
|
||||
const char *device_config_name = jsonDoc["device_config_name"];
|
||||
const char *device_config_OTAPassword = jsonDoc["device_config_OTAPassword"];
|
||||
const char *device_config_OTAPort = jsonDoc["device_config_OTAPort"];
|
||||
const char *camera_config_vflip = jsonDoc["camera_config_vflip"];
|
||||
const char *camera_config_href = jsonDoc["camera_config_href"];
|
||||
const char *camera_config_framesize = jsonDoc["camera_config_framesize"];
|
||||
const char *camera_config_quality = jsonDoc["camera_config_quality"];
|
||||
const char *wifi_config_name = jsonDoc["wifi_config_name"];
|
||||
const char *wifi_config_ssid = jsonDoc["wifi_config_ssid"];
|
||||
const char *wifi_config_password = jsonDoc["wifi_config_password"];
|
||||
const char *wifi_config_channel = jsonDoc["wifi_config_channel"];
|
||||
}
|
||||
}
|
||||
@ -2,8 +2,16 @@
|
||||
#ifndef SERIAL_MANAGER_HPP
|
||||
#define SERIAL_MANAGER_HPP
|
||||
#include <Arduino.h>
|
||||
#include <unordered_map>
|
||||
#include <string>
|
||||
#include <memory>
|
||||
#include <serialStr.h>
|
||||
#include <strTools.h>
|
||||
#include <ArduinoJSON.h>
|
||||
|
||||
#include "data/config/project_config.hpp"
|
||||
#include "data/utilities/makeunique.hpp"
|
||||
#include "data/utilities/helpers.hpp"
|
||||
|
||||
class SerialManager
|
||||
{
|
||||
@ -11,36 +19,25 @@ public:
|
||||
SerialManager(ProjectConfig *projectConfig);
|
||||
virtual ~SerialManager();
|
||||
|
||||
void begin();
|
||||
void handleSerial();
|
||||
|
||||
bool serialManagerActive;
|
||||
friend void readStr(const char *inStr);
|
||||
|
||||
/* Device Config Variables */
|
||||
char device_config_name[32];
|
||||
char device_config_OTAPassword[100];
|
||||
int device_config_OTAPort;
|
||||
|
||||
/* Camera Config Variables */
|
||||
uint8_t camera_config_vflip;
|
||||
uint8_t camera_config_framesize;
|
||||
uint8_t camera_config_href;
|
||||
uint8_t camera_config_quality;
|
||||
|
||||
/* Wifi Config Variables */
|
||||
char wifi_config_name[32];
|
||||
char wifi_config_ssid[100];
|
||||
char wifi_config_password[100];
|
||||
uint8_t wifi_config_channel;
|
||||
|
||||
private:
|
||||
|
||||
void listenToSerial(unsigned long timeout);
|
||||
void parseData();
|
||||
|
||||
char serialBuffer[1000]; //! Need to find the appropriate size for this - count the maximum possible size of a message
|
||||
char tempBuffer[sizeof(serialBuffer) / sizeof(serialBuffer[0])];
|
||||
bool newData;
|
||||
protected:
|
||||
ProjectConfig *projectConfig;
|
||||
std::unique_ptr<serialStr> serReader;
|
||||
|
||||
enum Serial_Commands
|
||||
{
|
||||
NO_INPUT,
|
||||
DEVICE_CONFIG,
|
||||
CAMERA_CONFIG,
|
||||
WIFI_CONFIG
|
||||
};
|
||||
|
||||
static std::unordered_map<std::string, Serial_Commands> command_map;
|
||||
StaticJsonDocument<1024> jsonDoc;
|
||||
};
|
||||
|
||||
#endif // SERIAL_MANAGER_HPP
|
||||
@ -2,6 +2,7 @@
|
||||
#ifndef WIFIHANDLER_HPP
|
||||
#define WIFIHANDLER_HPP
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <WiFi.h>
|
||||
#include "data/StateManager/StateManager.hpp"
|
||||
#include "data/config/project_config.hpp"
|
||||
@ -9,14 +10,25 @@
|
||||
class WiFiHandler
|
||||
{
|
||||
public:
|
||||
WiFiHandler(ProjectConfig *configManager, StateManager<WiFiState_e> *stateManager);
|
||||
WiFiHandler(ProjectConfig *configManager, StateManager<WiFiState_e> *stateManager,
|
||||
std::string ssid,
|
||||
std::string password,
|
||||
uint8_t channel);
|
||||
virtual ~WiFiHandler();
|
||||
void setupWifi();
|
||||
|
||||
ProjectConfig *configManager;
|
||||
StateManager<WiFiState_e> *stateManager;
|
||||
|
||||
bool _enable_adhoc;
|
||||
|
||||
private:
|
||||
void setUpADHOC();
|
||||
void adhoc(const char *ssid, const char *password, uint8_t channel);
|
||||
void iniSTA();
|
||||
|
||||
std::string ssid;
|
||||
std::string password;
|
||||
uint8_t channel;
|
||||
};
|
||||
#endif // WIFIHANDLER_HPP
|
||||
|
||||
@ -1,22 +1,41 @@
|
||||
#include "WifiHandler.hpp"
|
||||
#include <vector>
|
||||
|
||||
WiFiHandler::WiFiHandler(ProjectConfig *configManager, StateManager<WiFiState_e> *stateManager) : configManager(configManager),
|
||||
stateManager(stateManager) {}
|
||||
WiFiHandler::WiFiHandler(ProjectConfig *configManager,
|
||||
StateManager<WiFiState_e> *stateManager,
|
||||
std::string ssid,
|
||||
std::string password,
|
||||
uint8_t channel) : configManager(configManager),
|
||||
stateManager(stateManager),
|
||||
ssid(ssid),
|
||||
password(password),
|
||||
channel(channel),
|
||||
_enable_adhoc(false) {}
|
||||
|
||||
WiFiHandler::~WiFiHandler() {}
|
||||
|
||||
void WiFiHandler::setupWifi()
|
||||
{
|
||||
if (ENABLE_ADHOC || stateManager->getCurrentState() == WiFiState_e::WiFiState_ADHOC)
|
||||
if (this->_enable_adhoc || stateManager->getCurrentState() == WiFiState_e::WiFiState_ADHOC)
|
||||
{
|
||||
this->setUpADHOC();
|
||||
return;
|
||||
}
|
||||
|
||||
log_i("Initializing connection to wifi");
|
||||
stateManager->setState(WiFiState_e::WiFiState_Connecting);
|
||||
|
||||
std::vector<ProjectConfig::WiFiConfig_t> *networks = configManager->getWifiConfigs();
|
||||
|
||||
// check size of networks
|
||||
if (networks->size() == 0)
|
||||
{
|
||||
log_e("No networks found in config");
|
||||
this->iniSTA();
|
||||
stateManager->setState(WiFiState_e::WiFiState_Error);
|
||||
return;
|
||||
}
|
||||
|
||||
int connection_timeout = 30000; // 30 seconds
|
||||
|
||||
int count = 0;
|
||||
@ -26,19 +45,9 @@ void WiFiHandler::setupWifi()
|
||||
for (auto networkIterator = networks->begin(); networkIterator != networks->end(); ++networkIterator)
|
||||
{
|
||||
log_i("Trying to connect to the %s network", networkIterator->ssid);
|
||||
|
||||
WiFi.begin(networkIterator->ssid.c_str(), networkIterator->password.c_str());
|
||||
count++;
|
||||
|
||||
if (!WiFi.isConnected())
|
||||
log_i("\n\rCould not connect to %s, trying another network\n\r", networkIterator->ssid);
|
||||
else
|
||||
{
|
||||
log_i("\n\rSuccessfully connected to %s\n\r", networkIterator->ssid);
|
||||
stateManager->setState(WiFiState_e::WiFiState_Connected);
|
||||
return;
|
||||
}
|
||||
|
||||
while (WiFi.status() != WL_CONNECTED)
|
||||
{
|
||||
stateManager->setState(ProgramStates::DeviceStates::WiFiState_e::WiFiState_Connecting);
|
||||
@ -50,12 +59,20 @@ void WiFiHandler::setupWifi()
|
||||
log_i("[INFO]: WiFi connection timed out.\n");
|
||||
// we've tried all saved networks, none worked, let's error out
|
||||
log_e("Could not connect to any of the saved networks, check your Wifi credentials");
|
||||
stateManager->setState(WiFiState_e::WiFiState_Error);
|
||||
stateManager->setState(WiFiState_e::WiFiState_Disconnected);
|
||||
log_i("[INFO]: Attempting to connect to hardcoded network");
|
||||
this->iniSTA();
|
||||
log_i("[INFO]: Attempting to connect to hardcoded network from ini file");
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (!WiFi.isConnected())
|
||||
log_i("\n\rCould not connect to %s, trying another network\n\r", networkIterator->ssid);
|
||||
else
|
||||
{
|
||||
log_i("\n\rSuccessfully connected to %s\n\r", networkIterator->ssid);
|
||||
stateManager->setState(WiFiState_e::WiFiState_Connected);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -72,14 +89,14 @@ void WiFiHandler::adhoc(const char *ssid, const char *password, uint8_t channel)
|
||||
|
||||
// You can remove the password parameter if you want the AP to be open.
|
||||
WiFi.softAP(ssid, password, channel); // AP mode with password
|
||||
|
||||
WiFi.setTxPower(WIFI_POWER_11dBm);
|
||||
|
||||
stateManager->setState(WiFiState_e::WiFiState_ADHOC);
|
||||
}
|
||||
|
||||
/*
|
||||
* *
|
||||
*/
|
||||
* *
|
||||
*/
|
||||
void WiFiHandler::setUpADHOC()
|
||||
{
|
||||
log_i("[INFO]: Setting Access Point...\n");
|
||||
@ -96,9 +113,9 @@ void WiFiHandler::setUpADHOC()
|
||||
}
|
||||
else
|
||||
{
|
||||
strcpy(ssid, WIFI_AP_SSID);
|
||||
strcpy(password, WIFI_AP_PASSWORD);
|
||||
channel = ADHOC_CHANNEL;
|
||||
strcpy(ssid, "OpenIris");
|
||||
strcpy(password, "12345678");
|
||||
channel = 1;
|
||||
}
|
||||
|
||||
this->adhoc(ssid, password, channel);
|
||||
@ -116,18 +133,17 @@ void WiFiHandler::iniSTA()
|
||||
unsigned long currentMillis = millis();
|
||||
unsigned long _previousMillis = currentMillis;
|
||||
|
||||
log_i("Trying to connect to the %s network", WIFI_SSID);
|
||||
log_i("Trying to connect to the %s network", this->ssid.c_str());
|
||||
|
||||
WiFi.begin(WIFI_SSID, WIFI_PASSWORD, WIFI_CHANNEL);
|
||||
|
||||
if (!WiFi.isConnected())
|
||||
log_i("\n\rCould not connect to %s, please try another network\n\r", WIFI_SSID);
|
||||
else
|
||||
// check size of networks
|
||||
if (this->ssid.size() == 0)
|
||||
{
|
||||
log_i("\n\rSuccessfully connected to %s\n\r", WIFI_SSID);
|
||||
stateManager->setState(WiFiState_e::WiFiState_Connected);
|
||||
log_e("No networks passed into the constructor");
|
||||
this->setUpADHOC();
|
||||
stateManager->setState(WiFiState_e::WiFiState_Error);
|
||||
return;
|
||||
}
|
||||
WiFi.begin(this->ssid.c_str(), this->password.c_str(), this->channel);
|
||||
|
||||
while (WiFi.status() != WL_CONNECTED)
|
||||
{
|
||||
@ -148,4 +164,13 @@ void WiFiHandler::iniSTA()
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!WiFi.isConnected())
|
||||
log_i("\n\rCould not connect to %s, please try another network\n\r", this->ssid.c_str());
|
||||
else
|
||||
{
|
||||
log_i("\n\rSuccessfully connected to %s\n\r", this->ssid.c_str());
|
||||
stateManager->setState(WiFiState_e::WiFiState_Connected);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
297
ESP/lib/src/network/api/baseAPI/baseAPI.cpp
Normal file
297
ESP/lib/src/network/api/baseAPI/baseAPI.cpp
Normal file
@ -0,0 +1,297 @@
|
||||
#include "baseAPI.hpp"
|
||||
|
||||
BaseAPI::BaseAPI(int CONTROL_PORT,
|
||||
WiFiHandler *network,
|
||||
CameraHandler *camera,
|
||||
StateManager<WiFiState_e> *stateManager,
|
||||
std::string api_url) : API_Utilities(CONTROL_PORT,
|
||||
network,
|
||||
camera,
|
||||
stateManager,
|
||||
api_url) {}
|
||||
|
||||
BaseAPI::~BaseAPI() {}
|
||||
|
||||
void BaseAPI::begin()
|
||||
{
|
||||
this->setupServer();
|
||||
//! i have changed this to use lambdas instead of std::bind to avoid the overhead. Lambdas are always more preferable.
|
||||
server->on("/", 0b00000001, [&](AsyncWebServerRequest *request)
|
||||
{ request->send(200); });
|
||||
|
||||
// preflight cors check
|
||||
server->on("/", 0b01000000, [&](AsyncWebServerRequest *request)
|
||||
{
|
||||
AsyncWebServerResponse* response = request->beginResponse(204);
|
||||
response->addHeader("Access-Control-Allow-Methods", "PUT,POST,GET,OPTIONS");
|
||||
response->addHeader("Access-Control-Allow-Headers", "Accept, Content-Type, Authorization");
|
||||
response->addHeader("Access-Control-Allow-Credentials", "true");
|
||||
request->send(response); });
|
||||
|
||||
DefaultHeaders::Instance().addHeader("Access-Control-Allow-Origin", "*");
|
||||
|
||||
// std::bind(&BaseAPI::API_Utilities::notFound, &api_utilities, std::placeholders::_1);
|
||||
server->onNotFound([&](AsyncWebServerRequest *request)
|
||||
{ notFound(request); });
|
||||
}
|
||||
|
||||
void BaseAPI::setupServer()
|
||||
{
|
||||
localWifiConfig = {
|
||||
.ssid = "",
|
||||
.pass = "",
|
||||
.channel = 0,
|
||||
.adhoc = false,
|
||||
};
|
||||
|
||||
localAPWifiConfig = {
|
||||
.ssid = "",
|
||||
.pass = "",
|
||||
.channel = 0,
|
||||
.adhoc = false,
|
||||
};
|
||||
}
|
||||
|
||||
//*********************************************************************************************
|
||||
//! Command Functions
|
||||
//*********************************************************************************************
|
||||
void BaseAPI::setWiFi(AsyncWebServerRequest *request)
|
||||
{
|
||||
switch (_networkMethodsMap_enum[request->method()])
|
||||
{
|
||||
case POST:
|
||||
{
|
||||
int params = request->params();
|
||||
for (int i = 0; i < params; i++)
|
||||
{
|
||||
AsyncWebParameter *param = request->getParam(i);
|
||||
if (network->stateManager->getCurrentState() == WiFiState_e::WiFiState_ADHOC)
|
||||
{
|
||||
localAPWifiConfig.ssid = param->value().c_str();
|
||||
localAPWifiConfig.pass = param->value().c_str();
|
||||
localAPWifiConfig.channel = atoi(param->value().c_str());
|
||||
localAPWifiConfig.adhoc = atoi(param->value().c_str());
|
||||
}
|
||||
else
|
||||
{
|
||||
localWifiConfig.ssid = param->value().c_str();
|
||||
localWifiConfig.pass = param->value().c_str();
|
||||
localWifiConfig.channel = atoi(param->value().c_str());
|
||||
localWifiConfig.adhoc = atoi(param->value().c_str());
|
||||
}
|
||||
}
|
||||
ssid_write = true;
|
||||
pass_write = true;
|
||||
channel_write = true;
|
||||
request->send(200, MIMETYPE_JSON, "{\"msg\":\"Done. Wifi Creds have been set.\"}");
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
request->send(400, MIMETYPE_JSON, "{\"msg\":\"Invalid Request\"}");
|
||||
request->redirect("/");
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* * Trigger in main loop to save config to flash
|
||||
* ? Should we force the users to update all config params before triggering a config write?
|
||||
*/
|
||||
void BaseAPI::triggerWifiConfigWrite()
|
||||
{
|
||||
if (ssid_write && pass_write && channel_write)
|
||||
{
|
||||
ssid_write = false;
|
||||
pass_write = false;
|
||||
channel_write = false;
|
||||
if (network->stateManager->getCurrentState() == WiFiState_e::WiFiState_ADHOC)
|
||||
network->configManager->setAPWifiConfig(localAPWifiConfig.ssid.c_str(), localAPWifiConfig.pass.c_str(), &localAPWifiConfig.channel, localAPWifiConfig.adhoc, true);
|
||||
else
|
||||
network->configManager->setWifiConfig(localWifiConfig.ssid.c_str(), localWifiConfig.ssid.c_str(), localWifiConfig.pass.c_str(), &localWifiConfig.channel, localAPWifiConfig.adhoc, true);
|
||||
network->configManager->save();
|
||||
}
|
||||
}
|
||||
|
||||
void BaseAPI::handleJson(AsyncWebServerRequest *request)
|
||||
{
|
||||
std::string type = request->pathArg(0).c_str();
|
||||
switch (_networkMethodsMap_enum[request->method()])
|
||||
{
|
||||
case POST:
|
||||
{
|
||||
switch (json_TypesMap.at(type))
|
||||
{
|
||||
case DATA:
|
||||
{
|
||||
break;
|
||||
}
|
||||
case SETTINGS:
|
||||
{
|
||||
break;
|
||||
}
|
||||
case CONFIG:
|
||||
{
|
||||
break;
|
||||
}
|
||||
default:
|
||||
request->send(400, MIMETYPE_JSON, "{\"msg\":\"Invalid Request\"}");
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case GET:
|
||||
{
|
||||
switch (json_TypesMap.at(type))
|
||||
{
|
||||
case DATA:
|
||||
{
|
||||
network->configManager->getDeviceConfig()->data_json = true;
|
||||
Network_Utilities::my_delay(1L);
|
||||
String temp = network->configManager->getDeviceConfig()->data_json_string;
|
||||
request->send(200, MIMETYPE_JSON, temp);
|
||||
temp = "";
|
||||
break;
|
||||
}
|
||||
case SETTINGS:
|
||||
{
|
||||
network->configManager->getDeviceConfig()->config_json = true;
|
||||
Network_Utilities::my_delay(1L);
|
||||
String temp = network->configManager->getDeviceConfig()->config_json_string;
|
||||
request->send(200, MIMETYPE_JSON, temp);
|
||||
temp = "";
|
||||
break;
|
||||
}
|
||||
case CONFIG:
|
||||
{
|
||||
network->configManager->getDeviceConfig()->settings_json = true;
|
||||
Network_Utilities::my_delay(1L);
|
||||
String temp = network->configManager->getDeviceConfig()->settings_json_string;
|
||||
request->send(200, MIMETYPE_JSON, temp);
|
||||
temp = "";
|
||||
break;
|
||||
}
|
||||
default:
|
||||
request->send(400, MIMETYPE_JSON, "{\"msg\":\"Invalid Request\"}");
|
||||
break;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
request->send(400, MIMETYPE_JSON, "{\"msg\":\"Invalid Request\"}");
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void BaseAPI::rebootDevice(AsyncWebServerRequest *request)
|
||||
{
|
||||
switch (_networkMethodsMap_enum[request->method()])
|
||||
{
|
||||
case GET:
|
||||
{
|
||||
delay(20000);
|
||||
request->send(200, MIMETYPE_JSON, "{\"msg\":\"Rebooting Device\"}");
|
||||
ESP.restart();
|
||||
}
|
||||
default:
|
||||
{
|
||||
request->send(400, MIMETYPE_JSON, "{\"msg\":\"Invalid Request\"}");
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void BaseAPI::factoryReset(AsyncWebServerRequest *request)
|
||||
{
|
||||
switch (_networkMethodsMap_enum[request->method()])
|
||||
{
|
||||
case GET:
|
||||
{
|
||||
log_d("Factory Reset");
|
||||
network->configManager->reset();
|
||||
request->send(200, MIMETYPE_JSON, "{\"msg\":\"Factory Reset\"}");
|
||||
}
|
||||
default:
|
||||
{
|
||||
request->send(400, MIMETYPE_JSON, "{\"msg\":\"Invalid Request\"}");
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Remove a command handler from the API
|
||||
*
|
||||
* @param request
|
||||
* @return \c void
|
||||
*/
|
||||
void BaseAPI::deleteRoute(AsyncWebServerRequest *request)
|
||||
{
|
||||
log_i("Request: %s", request->url().c_str());
|
||||
int params = request->params();
|
||||
auto it_map = route_map.find(request->pathArg(0).c_str());
|
||||
log_i("Request: %s", request->pathArg(0).c_str());
|
||||
if (it_map != route_map.end())
|
||||
{
|
||||
auto it = it_map->second.find(request->pathArg(1).c_str());
|
||||
if (it != it_map->second.end())
|
||||
{
|
||||
switch (_networkMethodsMap_enum[request->method()])
|
||||
{
|
||||
case DELETE:
|
||||
{
|
||||
route_map.erase(it_map->first);
|
||||
request->send(200, MIMETYPE_JSON, "{\"msg\":\"OK - Command handler removed\"}");
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
request->send(400, MIMETYPE_JSON, "{\"msg\":\"Invalid Request\"}");
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
request->send(404);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
request->send(404);
|
||||
}
|
||||
}
|
||||
|
||||
//*********************************************************************************************
|
||||
//! Camera Command Functions
|
||||
//*********************************************************************************************
|
||||
|
||||
void BaseAPI::setCamera(AsyncWebServerRequest *request)
|
||||
{
|
||||
switch (_networkMethodsMap_enum[request->method()])
|
||||
{
|
||||
case GET:
|
||||
{
|
||||
int params = request->params();
|
||||
for (int i = 0; i < params; i++)
|
||||
{
|
||||
AsyncWebParameter *param = request->getParam(i);
|
||||
camera->setCameraResolution((framesize_t)atoi(param->value().c_str()));
|
||||
camera->setVFlip(atoi(param->value().c_str()));
|
||||
camera->setHFlip(atoi(param->value().c_str()));
|
||||
}
|
||||
request->send(200, MIMETYPE_JSON, "{\"msg\":\"Done. Camera Settings have been set.\"}");
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
request->send(400, MIMETYPE_JSON, "{\"msg\":\"Invalid Request\"}");
|
||||
request->redirect("/");
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
84
ESP/lib/src/network/api/baseAPI/baseAPI.hpp
Normal file
84
ESP/lib/src/network/api/baseAPI/baseAPI.hpp
Normal file
@ -0,0 +1,84 @@
|
||||
#ifndef BASEAPI_HPP
|
||||
#define BASEAPI_HPP
|
||||
#include "network/wifihandler/wifiHandler.hpp"
|
||||
#include "network/api/utilities/apiUtilities.hpp"
|
||||
|
||||
class BaseAPI : public API_Utilities
|
||||
{
|
||||
protected:
|
||||
struct LocalWifiConfig
|
||||
{
|
||||
std::string ssid;
|
||||
std::string pass;
|
||||
uint8_t channel;
|
||||
bool adhoc;
|
||||
};
|
||||
|
||||
LocalWifiConfig localWifiConfig;
|
||||
|
||||
struct LocalAPWifiConfig
|
||||
{
|
||||
std::string ssid;
|
||||
std::string pass;
|
||||
uint8_t channel;
|
||||
};
|
||||
|
||||
LocalWifiConfig localAPWifiConfig;
|
||||
|
||||
enum JSON_TYPES
|
||||
{
|
||||
CONFIG,
|
||||
SETTINGS,
|
||||
DATA,
|
||||
STATUS,
|
||||
COMMANDS,
|
||||
WIFI,
|
||||
WIFIAP,
|
||||
};
|
||||
|
||||
std::unordered_map<std::string, JSON_TYPES> json_TypesMap = {
|
||||
{"config", CONFIG},
|
||||
{"settings", SETTINGS},
|
||||
{"data", DATA},
|
||||
{"status", STATUS},
|
||||
{"commands", COMMANDS},
|
||||
{"wifi", WIFI},
|
||||
{"wifiap", WIFIAP},
|
||||
};
|
||||
|
||||
protected:
|
||||
/* Commands */
|
||||
void setWiFi(AsyncWebServerRequest *request);
|
||||
void handleJson(AsyncWebServerRequest *request);
|
||||
void factoryReset(AsyncWebServerRequest *request);
|
||||
void rebootDevice(AsyncWebServerRequest *request);
|
||||
void deleteRoute(AsyncWebServerRequest *request);
|
||||
|
||||
/* Camera Handler */
|
||||
void setCamera(AsyncWebServerRequest *request);
|
||||
|
||||
using call_back_function_t = void (BaseAPI::*)(AsyncWebServerRequest *);
|
||||
typedef call_back_function_t (*call_back_function_ptr)(AsyncWebServerRequest *);
|
||||
|
||||
/* Route Command types */
|
||||
using route_method = void (BaseAPI::*)(AsyncWebServerRequest *);
|
||||
// typedef void (*callback)(AsyncWebServerRequest *);
|
||||
typedef std::unordered_map<std::string, route_method> route_t;
|
||||
typedef std::unordered_map<std::string, route_t> route_map_t;
|
||||
|
||||
route_t routes;
|
||||
route_map_t route_map;
|
||||
|
||||
public:
|
||||
BaseAPI(int CONTROL_PORT,
|
||||
WiFiHandler *network,
|
||||
CameraHandler *camera,
|
||||
StateManager<WiFiState_e> *stateManager,
|
||||
std::string api_url);
|
||||
virtual ~BaseAPI();
|
||||
virtual void begin();
|
||||
virtual void setupServer();
|
||||
void triggerWifiConfigWrite();
|
||||
};
|
||||
|
||||
#endif // BASEAPI_HPP
|
||||
116
ESP/lib/src/network/api/utilities/apiUtilities.cpp
Normal file
116
ESP/lib/src/network/api/utilities/apiUtilities.cpp
Normal file
@ -0,0 +1,116 @@
|
||||
#include "apiUtilities.hpp"
|
||||
|
||||
//! These have to be called before the constructor of the class because they are static
|
||||
//! C++ 11 does not have inline variables, sadly. So we have to do this.
|
||||
const char *API_Utilities::MIMETYPE_HTML{"text/html"};
|
||||
// const char *BaseAPI::MIMETYPE_CSS{"text/css"};
|
||||
// const char *BaseAPI::MIMETYPE_JS{"application/javascript"};
|
||||
// const char *BaseAPI::MIMETYPE_PNG{"image/png"};
|
||||
// const char *BaseAPI::MIMETYPE_JPG{"image/jpeg"};
|
||||
// const char *BaseAPI::MIMETYPE_ICO{"image/x-icon"};
|
||||
const char *API_Utilities::MIMETYPE_JSON{"application/json"};
|
||||
|
||||
bool API_Utilities::ssid_write = false;
|
||||
bool API_Utilities::pass_write = false;
|
||||
bool API_Utilities::channel_write = false;
|
||||
|
||||
//*********************************************************************************************
|
||||
//! API Utilities
|
||||
//*********************************************************************************************
|
||||
|
||||
API_Utilities::API_Utilities(int CONTROL_PORT,
|
||||
WiFiHandler *network,
|
||||
CameraHandler *camera,
|
||||
StateManager<WiFiState_e> *stateManager,
|
||||
std::string api_url) : server(new AsyncWebServer(CONTROL_PORT)),
|
||||
stateManager(stateManager),
|
||||
network(network),
|
||||
camera(camera),
|
||||
api_url(api_url) {}
|
||||
API_Utilities::~API_Utilities() {}
|
||||
std::string API_Utilities::shaEncoder(std::string data)
|
||||
{
|
||||
const char *data_c = data.c_str();
|
||||
int size = 64;
|
||||
uint8_t hash[size];
|
||||
mbedtls_md_context_t ctx;
|
||||
mbedtls_md_type_t md_type = MBEDTLS_MD_SHA512;
|
||||
|
||||
const size_t len = strlen(data_c);
|
||||
mbedtls_md_init(&ctx);
|
||||
mbedtls_md_setup(&ctx, mbedtls_md_info_from_type(md_type), 0);
|
||||
mbedtls_md_starts(&ctx);
|
||||
mbedtls_md_update(&ctx, (const unsigned char *)data_c, len);
|
||||
mbedtls_md_finish(&ctx, hash);
|
||||
mbedtls_md_free(&ctx);
|
||||
|
||||
std::string hash_string = "";
|
||||
for (uint16_t i = 0; i < size; i++)
|
||||
{
|
||||
std::string hex = String(hash[i], HEX).c_str();
|
||||
if (hex.length() < 2)
|
||||
{
|
||||
hex = "0" + hex;
|
||||
}
|
||||
hash_string += hex;
|
||||
}
|
||||
return hash_string;
|
||||
}
|
||||
|
||||
void API_Utilities::notFound(AsyncWebServerRequest *request) const
|
||||
{
|
||||
if (_networkMethodsMap.find(request->method()) != _networkMethodsMap.end())
|
||||
{
|
||||
log_i("%s: http://%s%s/\n", _networkMethodsMap.at(request->method()).c_str(), request->host().c_str(), request->url().c_str());
|
||||
char buffer[100];
|
||||
snprintf(buffer, sizeof(buffer), "Request %s Not found: %s", _networkMethodsMap.at(request->method()).c_str(), request->url().c_str());
|
||||
request->send(404, "text/plain", buffer);
|
||||
}
|
||||
else
|
||||
{
|
||||
request->send(404, "text/plain", "Request Not found using unknown method");
|
||||
}
|
||||
}
|
||||
|
||||
// Read File from SPIFFS
|
||||
/* String API_Utilities::readFile(fs::FS &fs, std::string path)
|
||||
{
|
||||
log_i("Reading file: %s\r\n", path.c_str());
|
||||
|
||||
File file = fs.open(path.c_str());
|
||||
if (!file || file.isDirectory())
|
||||
{
|
||||
log_e("[INFO]: Failed to open file for reading");
|
||||
return String();
|
||||
}
|
||||
|
||||
String fileContent;
|
||||
while (file.available())
|
||||
{
|
||||
fileContent = file.readStringUntil('\n');
|
||||
break;
|
||||
}
|
||||
return fileContent;
|
||||
}
|
||||
|
||||
// Write file to SPIFFS
|
||||
void API_Utilities::writeFile(fs::FS &fs, std::string path, std::string message)
|
||||
{
|
||||
log_i("[Writing File]: Writing file: %s\r\n", path);
|
||||
Network_Utilities::my_delay(0.1L);
|
||||
|
||||
File file = fs.open(path.c_str(), FILE_WRITE);
|
||||
if (!file)
|
||||
{
|
||||
log_i("[Writing File]: failed to open file for writing");
|
||||
return;
|
||||
}
|
||||
if (file.print(message.c_str()))
|
||||
{
|
||||
log_i("[Writing File]: file written");
|
||||
}
|
||||
else
|
||||
{
|
||||
log_i("[Writing File]: file write failed");
|
||||
}
|
||||
} */
|
||||
98
ESP/lib/src/network/api/utilities/apiUtilities.hpp
Normal file
98
ESP/lib/src/network/api/utilities/apiUtilities.hpp
Normal file
@ -0,0 +1,98 @@
|
||||
#ifndef APIUTILITIES_HPP
|
||||
#define APIUTILITIES_HPP
|
||||
|
||||
#include <unordered_map>
|
||||
#include <string>
|
||||
|
||||
|
||||
#define WEBSERVER_H
|
||||
|
||||
/* #define XHTTP_GET 0b00000001;
|
||||
#define XHTTP_POST 0b00000010;
|
||||
#define XHTTP_DELETE 0b00000100;
|
||||
#define XHTTP_PUT 0b00001000;
|
||||
#define XHTTP_PATCH 0b00010000;
|
||||
#define XHTTP_HEAD 0b00100000;
|
||||
#define XHTTP_OPTIONS 0b01000000;
|
||||
#define XHTTP_ANY 0b01111111; */
|
||||
|
||||
#define HTTP_ANY 0b01111111
|
||||
#define HTTP_GET 0b00000001
|
||||
|
||||
#include <ESPAsyncWebServer.h>
|
||||
#include <AsyncTCP.h>
|
||||
#include "mbedtls/md.h"
|
||||
#include "data/utilities/network_utilities.hpp"
|
||||
#include "data/StateManager/StateManager.hpp"
|
||||
#include "io/camera/cameraHandler.hpp"
|
||||
|
||||
class API_Utilities
|
||||
{
|
||||
public:
|
||||
API_Utilities(int CONTROL_PORT,
|
||||
WiFiHandler *network,
|
||||
CameraHandler *camera,
|
||||
StateManager<WiFiState_e> *stateManager,
|
||||
std::string api_url);
|
||||
virtual ~API_Utilities();
|
||||
|
||||
protected:
|
||||
void notFound(AsyncWebServerRequest *request) const;
|
||||
/* String readFile(fs::FS &fs, std::string path);
|
||||
void writeFile(fs::FS &fs, std::string path, std::string message); */
|
||||
std::string shaEncoder(std::string data);
|
||||
std::unordered_map<int, std::string> _networkMethodsMap = {
|
||||
{0, "NULL"},
|
||||
{0b00000001, "GET"},
|
||||
{0b00000010, "POST"},
|
||||
{0b00001000, "PUT"},
|
||||
{0b00000100, "DELETE"},
|
||||
{0b00010000, "PATCH"},
|
||||
{0b01000000, "OPTIONS"},
|
||||
};
|
||||
|
||||
enum RequestMethods
|
||||
{
|
||||
NULL_METHOD,
|
||||
GET,
|
||||
POST,
|
||||
PUT,
|
||||
DELETE,
|
||||
PATCH,
|
||||
OPTIONS,
|
||||
};
|
||||
|
||||
std::unordered_map<int, RequestMethods> _networkMethodsMap_enum = {
|
||||
{0, NULL_METHOD},
|
||||
{0b00000001, GET},
|
||||
{0b00000010, POST},
|
||||
{0b00001000, PUT},
|
||||
{0b00000100, DELETE},
|
||||
{0b00010000, PATCH},
|
||||
{0b01000000, OPTIONS},
|
||||
};
|
||||
|
||||
protected:
|
||||
AsyncWebServer *server;
|
||||
WiFiHandler *network;
|
||||
CameraHandler *camera;
|
||||
StateManager<WiFiState_e> *stateManager;
|
||||
typedef std::unordered_map<std::string, WebRequestMethodComposite> networkMethodsMap_t;
|
||||
|
||||
protected:
|
||||
std::string api_url;
|
||||
|
||||
static bool ssid_write;
|
||||
static bool pass_write;
|
||||
static bool channel_write;
|
||||
|
||||
static const char *MIMETYPE_HTML;
|
||||
/* static const char *MIMETYPE_CSS; */
|
||||
/* static const char *MIMETYPE_JS; */
|
||||
/* static const char *MIMETYPE_PNG; */
|
||||
/* static const char *MIMETYPE_JPG; */
|
||||
/* static const char *MIMETYPE_ICO; */
|
||||
static const char *MIMETYPE_JSON;
|
||||
};
|
||||
|
||||
#endif // APIUTILITIES_HPP
|
||||
115
ESP/lib/src/network/api/webserverHandler.cpp
Normal file
115
ESP/lib/src/network/api/webserverHandler.cpp
Normal file
@ -0,0 +1,115 @@
|
||||
#include "webserverHandler.hpp"
|
||||
|
||||
//*********************************************************************************************
|
||||
//! API Server
|
||||
//*********************************************************************************************
|
||||
|
||||
APIServer::APIServer(int CONTROL_PORT,
|
||||
WiFiHandler *network,
|
||||
CameraHandler *camera,
|
||||
StateManager<WiFiState_e> *stateManager,
|
||||
std::string api_url) : BaseAPI(CONTROL_PORT,
|
||||
network,
|
||||
camera,
|
||||
stateManager,
|
||||
api_url) {}
|
||||
|
||||
APIServer::~APIServer() {}
|
||||
|
||||
void APIServer::begin()
|
||||
{
|
||||
log_d("Initializing REST API");
|
||||
this->setupServer();
|
||||
BaseAPI::begin();
|
||||
|
||||
char buffer[1000];
|
||||
snprintf(buffer, sizeof(buffer), "^\\%s\\/([a-zA-Z0-9]+)\\/command\\/([a-zA-Z0-9]+)$", this->api_url.c_str());
|
||||
log_d("API URL: %s", buffer);
|
||||
server->on(buffer, 0b01111111, [&](AsyncWebServerRequest *request)
|
||||
{ handleRequest(request); });
|
||||
|
||||
server->begin();
|
||||
}
|
||||
|
||||
void APIServer::setupServer()
|
||||
{
|
||||
// Set case NULL_METHOD routes
|
||||
routes.emplace("wifi", &APIServer::setWiFi);
|
||||
routes.emplace("reset_config", &APIServer::factoryReset);
|
||||
routes.emplace("reboot_device", &APIServer::rebootDevice);
|
||||
routes.emplace("set_json", &APIServer::handleJson);
|
||||
routes.emplace("set_camera", &APIServer::setCamera);
|
||||
routes.emplace("delete_route", &APIServer::deleteRoute);
|
||||
|
||||
routeHandler("builtin", routes); // add new map to the route map
|
||||
}
|
||||
|
||||
void APIServer::findParam(AsyncWebServerRequest *request, const char *param, String &value)
|
||||
{
|
||||
if (request->hasParam(param))
|
||||
{
|
||||
value = request->getParam(param)->value();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Add a command handler to the API
|
||||
*
|
||||
* @param index
|
||||
* @param funct
|
||||
* @return \c vector<string> a list of the indexes of the command handlers
|
||||
*/
|
||||
std::vector<std::string> APIServer::routeHandler(std::string index, route_t route)
|
||||
{
|
||||
route_map.emplace(index, route);
|
||||
std::vector<std::string> indexes;
|
||||
indexes.reserve(route.size());
|
||||
|
||||
for (const auto &key : route)
|
||||
{
|
||||
indexes.push_back(key.first);
|
||||
}
|
||||
|
||||
return indexes;
|
||||
}
|
||||
|
||||
void APIServer::handleRequest(AsyncWebServerRequest *request)
|
||||
{
|
||||
// Get the route
|
||||
log_i("Request: %s", request->url().c_str());
|
||||
int params = request->params();
|
||||
auto it_map = route_map.find(request->pathArg(0).c_str());
|
||||
log_i("Request: %s", request->pathArg(0).c_str());
|
||||
auto it_method = it_map->second.find(request->pathArg(1).c_str());
|
||||
log_i("Request: %s", request->pathArg(1).c_str());
|
||||
|
||||
for (int i = 0; i < params; i++)
|
||||
{
|
||||
AsyncWebParameter *param = request->getParam(i);
|
||||
{
|
||||
{
|
||||
if (it_map != route_map.end())
|
||||
{
|
||||
if (it_method != it_map->second.end())
|
||||
{
|
||||
(*this.*(it_method->second))(request);
|
||||
}
|
||||
else
|
||||
{
|
||||
request->send(400, MIMETYPE_JSON, "{\"msg\":\"Invalid Command\"}");
|
||||
request->redirect("/");
|
||||
return;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
request->send(400, MIMETYPE_JSON, "{\"msg\":\"Invalid Map Index\"}");
|
||||
request->redirect("/");
|
||||
return;
|
||||
}
|
||||
}
|
||||
log_i("%s[%s]: %s\n", _networkMethodsMap[request->method()].c_str(), param->name().c_str(), param->value().c_str());
|
||||
}
|
||||
}
|
||||
request->send(200, MIMETYPE_JSON, "{\"msg\":\"Command executed\"}");
|
||||
}
|
||||
26
ESP/lib/src/network/api/webserverHandler.hpp
Normal file
26
ESP/lib/src/network/api/webserverHandler.hpp
Normal file
@ -0,0 +1,26 @@
|
||||
#pragma once
|
||||
#ifndef XWEBSERVERHANDLER_HPP
|
||||
#define XWEBSERVERHANDLER_HPP
|
||||
|
||||
#include "network/api/baseAPI/baseAPI.hpp"
|
||||
|
||||
class APIServer : public BaseAPI
|
||||
{
|
||||
public:
|
||||
APIServer(int CONTROL_PORT,
|
||||
WiFiHandler *network,
|
||||
CameraHandler* camera,
|
||||
StateManager<WiFiState_e> *stateManager,
|
||||
std::string api_url);
|
||||
|
||||
virtual ~APIServer();
|
||||
void begin();
|
||||
void setupServer();
|
||||
|
||||
void findParam(AsyncWebServerRequest *request, const char *param, String &value);
|
||||
void updateCommandHandlers();
|
||||
std::vector<std::string> routeHandler(std::string index, route_t route);
|
||||
void handleRequest(AsyncWebServerRequest *request);
|
||||
|
||||
};
|
||||
#endif // WEBSERVERHANDLER_HPP
|
||||
@ -8,7 +8,9 @@ void MDNSHandler::startMDNS()
|
||||
{
|
||||
stateManager->setState(MDNSState_e::MDNSState_Starting);
|
||||
MDNS.addService("openIrisTracker", "tcp", 80);
|
||||
MDNS.addServiceTxt("openIrisTracker", "tcp", "stream_port", String(80));
|
||||
char port[20];
|
||||
//!Add service needs leading _ on ESP32 implementation for some reason (according to the docs)
|
||||
MDNS.addServiceTxt("_openIrisTracker", "_tcp", "_stream_port", (const char*)Helpers::itoa(80, port, 10)); //! convert int to const char* using a very efficient implemenation of itoa
|
||||
log_i("MDNS initialized!");
|
||||
stateManager->setState(MDNSState_e::MDNSState_Started);
|
||||
}
|
||||
|
||||
@ -2,6 +2,7 @@
|
||||
#include <ESPmDNS.h>
|
||||
#include "data/StateManager/StateManager.hpp"
|
||||
#include "data/utilities/Observer.hpp"
|
||||
#include "data/utilities/helpers.hpp"
|
||||
#include "data/config/project_config.hpp"
|
||||
|
||||
class MDNSHandler : public IObserver
|
||||
|
||||
@ -1,4 +1,6 @@
|
||||
#pragma once
|
||||
#ifndef STREAM_SERVER_HPP
|
||||
#define STREAM_SERVER_HPP
|
||||
#define PART_BOUNDARY "123456789000000000000987654321"
|
||||
#include <Arduino.h>
|
||||
#include "esp_camera.h"
|
||||
@ -19,3 +21,5 @@ public:
|
||||
StreamServer(int STREAM_PORT) : STREAM_SERVER_PORT(STREAM_PORT) {}
|
||||
int startStreamServer();
|
||||
};
|
||||
|
||||
#endif // STREAM_SERVER_HPP
|
||||
|
||||
@ -14,14 +14,14 @@ default_envs = esp32Cam ; do not change this value
|
||||
; The below options are available for all environments
|
||||
; The ssid and password are requried for the trackers to connect to your network!!!
|
||||
[wifi]
|
||||
ssid="" ; your wifi network name goes here
|
||||
password="" ; your wifi network password goes here
|
||||
ssid="LoveHouse2G" ; your wifi network name goes here
|
||||
password="vxwby2Gwtswp" ; your wifi network password goes here
|
||||
channel=1 ; wifi channel
|
||||
ap_ssid="EyeTrackVR" ; your AP wifi network name goes here
|
||||
ap_password="test" ; Place your AP Wifi password here
|
||||
OTAPassword="" ; if empty, no password will be required
|
||||
OTAServerPort=3232
|
||||
enableADHOC=0 ; 0 = disable, 1 = enable
|
||||
enableADHOC=1 ; 0 = disable, 1 = enable
|
||||
adhocChannel=1 ; channel to use for adhoc network
|
||||
|
||||
; DO NOT EDIT BELOW THIS LINE UNLESS YOU KNOW WHAT YOU ARE DOING
|
||||
@ -104,6 +104,8 @@ build_flags =
|
||||
|
||||
-DBOARD_HAS_PSRAM
|
||||
|
||||
-DASYNCWEBSERVER_REGEX ; add regex support to AsyncWebServer
|
||||
|
||||
-mfix-esp32-psram-cache-issue
|
||||
|
||||
;-I include
|
||||
@ -118,9 +120,11 @@ upload_speed = 921600
|
||||
release_version = 0.0.1 ; increase this value every release build
|
||||
lib_deps =
|
||||
esp32-camera
|
||||
leftcoast/LC_baseTools@^1.5
|
||||
https://github.com/ZanzyTHEbar/EasyPreferencesLibrary.git
|
||||
https://github.com/me-no-dev/ESPAsyncWebServer.git
|
||||
https://github.com/me-no-dev/AsyncTCP.git
|
||||
https://github.com/bblanchon/ArduinoJson.git
|
||||
|
||||
build_type = debug
|
||||
|
||||
@ -132,26 +136,25 @@ monitor_speed = ${common.monitor_speed}
|
||||
monitor_rts = ${common.monitor_rts}
|
||||
monitor_dtr = ${common.monitor_dtr}
|
||||
monitor_filters = ${common.monitor_filters}
|
||||
build_flags =
|
||||
${common.build_flags}
|
||||
build_flags = ${common.build_flags}
|
||||
|
||||
; CAMERA PINOUT DEFINITIONS
|
||||
-DPWDN_GPIO_NUM=${pinoutsESPCAM.PWDN_GPIO_NUM} ; Set the PWDN pin
|
||||
-DRESET_GPIO_NUM=${pinoutsESPCAM.RESET_GPIO_NUM} ; Set the RESET pin
|
||||
-DXCLK_GPIO_NUM=${pinoutsESPCAM.XCLK_GPIO_NUM} ; Set the XCLK pin
|
||||
-DSIOD_GPIO_NUM=${pinoutsESPCAM.SIOD_GPIO_NUM} ; Set the SIOD pin
|
||||
-DSIOC_GPIO_NUM=${pinoutsESPCAM.SIOC_GPIO_NUM} ; Set the SIOC pin
|
||||
-DY9_GPIO_NUM=${pinoutsESPCAM.Y9_GPIO_NUM} ; Set the Y9 pin
|
||||
-DY8_GPIO_NUM=${pinoutsESPCAM.Y8_GPIO_NUM} ; Set the Y8 pin
|
||||
-DY7_GPIO_NUM=${pinoutsESPCAM.Y7_GPIO_NUM} ; Set the Y7 pin
|
||||
-DY6_GPIO_NUM=${pinoutsESPCAM.Y6_GPIO_NUM} ; Set the Y6 pin
|
||||
-DY5_GPIO_NUM=${pinoutsESPCAM.Y5_GPIO_NUM} ; Set the Y5 pin
|
||||
-DY4_GPIO_NUM=${pinoutsESPCAM.Y4_GPIO_NUM} ; Set the Y4 pin
|
||||
-DY3_GPIO_NUM=${pinoutsESPCAM.Y3_GPIO_NUM} ; Set the Y3 pin
|
||||
-DY2_GPIO_NUM=${pinoutsESPCAM.Y2_GPIO_NUM} ; Set the Y2 pin
|
||||
-DVSYNC_GPIO_NUM=${pinoutsESPCAM.VSYNC_GPIO_NUM} ; Set the VSYNC pin
|
||||
-DHREF_GPIO_NUM=${pinoutsESPCAM.HREF_GPIO_NUM} ; Set the HREF pin
|
||||
-DPCLK_GPIO_NUM=${pinoutsESPCAM.PCLK_GPIO_NUM} ; Set the PCLK pin
|
||||
; CAMERA PINOUT DEFINITIONS
|
||||
-DPWDN_GPIO_NUM=${pinoutsESPCAM.PWDN_GPIO_NUM} ; Set the PWDN pin
|
||||
-DRESET_GPIO_NUM=${pinoutsESPCAM.RESET_GPIO_NUM} ; Set the RESET pin
|
||||
-DXCLK_GPIO_NUM=${pinoutsESPCAM.XCLK_GPIO_NUM} ; Set the XCLK pin
|
||||
-DSIOD_GPIO_NUM=${pinoutsESPCAM.SIOD_GPIO_NUM} ; Set the SIOD pin
|
||||
-DSIOC_GPIO_NUM=${pinoutsESPCAM.SIOC_GPIO_NUM} ; Set the SIOC pin
|
||||
-DY9_GPIO_NUM=${pinoutsESPCAM.Y9_GPIO_NUM} ; Set the Y9 pin
|
||||
-DY8_GPIO_NUM=${pinoutsESPCAM.Y8_GPIO_NUM} ; Set the Y8 pin
|
||||
-DY7_GPIO_NUM=${pinoutsESPCAM.Y7_GPIO_NUM} ; Set the Y7 pin
|
||||
-DY6_GPIO_NUM=${pinoutsESPCAM.Y6_GPIO_NUM} ; Set the Y6 pin
|
||||
-DY5_GPIO_NUM=${pinoutsESPCAM.Y5_GPIO_NUM} ; Set the Y5 pin
|
||||
-DY4_GPIO_NUM=${pinoutsESPCAM.Y4_GPIO_NUM} ; Set the Y4 pin
|
||||
-DY3_GPIO_NUM=${pinoutsESPCAM.Y3_GPIO_NUM} ; Set the Y3 pin
|
||||
-DY2_GPIO_NUM=${pinoutsESPCAM.Y2_GPIO_NUM} ; Set the Y2 pin
|
||||
-DVSYNC_GPIO_NUM=${pinoutsESPCAM.VSYNC_GPIO_NUM} ; Set the VSYNC pin
|
||||
-DHREF_GPIO_NUM=${pinoutsESPCAM.HREF_GPIO_NUM} ; Set the HREF pin
|
||||
-DPCLK_GPIO_NUM=${pinoutsESPCAM.PCLK_GPIO_NUM} ; Set the PCLK pin
|
||||
|
||||
build_unflags = ${common.build_unflags}
|
||||
board_build.partitions = ${common.board_build.partitions}
|
||||
|
||||
@ -5,41 +5,49 @@
|
||||
#include <io/camera/cameraHandler.hpp>
|
||||
#include <io/LEDManager/LEDManager.hpp>
|
||||
#include <network/stream/streamServer.hpp>
|
||||
#include <network/webserver/webserverHandler.hpp>
|
||||
#include <network/api/webserverHandler.hpp>
|
||||
#include <data/config/project_config.hpp>
|
||||
#include <io/SerialManager/serialmanager.hpp> // Basic Serial Manager
|
||||
//#include <io/SerialManager/SerialManager2/serialmanager.hpp> // Advanced Serial MAnager //! Finish this to update the serial manager
|
||||
//#include <io/SerialManager/serialmanager.hpp> // Basic Serial Manager
|
||||
//#include <io/SerialManager/SerialManager2/serialmanager.hpp // Advanced Serial MAnager //! Finish this to update the serial manager
|
||||
|
||||
#include <network/OTA/OTA.hpp>
|
||||
|
||||
uint8_t STREAM_SERVER_PORT = 80;
|
||||
uint8_t CONTROL_SERVER_PORT = 81;
|
||||
int STREAM_SERVER_PORT = 80;
|
||||
int CONTROL_SERVER_PORT = 81;
|
||||
|
||||
// Create smart pointers to the various classes that will be used in the program to make sure that they are deleted when the program ends
|
||||
// This is done to make sure that the memory is freed when the program ends and we are not left with dangling pointers to memory that is no longer in use
|
||||
// Make unique is a templated function that takes a class and returns a unique pointer to that class -
|
||||
// it is used to create a unique pointer to a class and ensure exception safety
|
||||
std::unique_ptr<ProjectConfig> deviceConfig = std::make_unique<ProjectConfig>();
|
||||
OTA ota(&*deviceConfig);
|
||||
std::unique_ptr<SerialManager> serialManager = std::make_unique<SerialManager>(&*deviceConfig);
|
||||
std::unique_ptr<WiFiHandler> wifiHandler = std::make_unique<WiFiHandler>(&*deviceConfig, &wifiStateManager);
|
||||
std::unique_ptr<LEDManager> ledManager = std::make_unique<LEDManager>(33);
|
||||
std::shared_ptr<CameraHandler> cameraHandler = std::make_shared<CameraHandler>(&*deviceConfig); //! Create a shared pointer to the camera handler
|
||||
std::unique_ptr<APIServer> apiServer = std::make_unique<APIServer>(CONTROL_SERVER_PORT, &*cameraHandler, &*wifiHandler); //! Dereference the shared pointer to get the address of the camera handler
|
||||
std::unique_ptr<MDNSHandler> mdnsHandler = std::make_unique<MDNSHandler>(&mdnsStateManager, &*deviceConfig);
|
||||
std::unique_ptr<StreamServer> streamServer = std::make_unique<StreamServer>(STREAM_SERVER_PORT);
|
||||
ProjectConfig deviceConfig;
|
||||
OTA ota(&deviceConfig);
|
||||
LEDManager ledManager(33);
|
||||
CameraHandler cameraHandler(&deviceConfig);
|
||||
//SerialManager serialManager(&deviceConfig);
|
||||
WiFiHandler wifiHandler(&deviceConfig, &wifiStateManager, WIFI_SSID, WIFI_PASSWORD, 1);
|
||||
//APIServer apiServer(CONTROL_SERVER_PORT, &wifiHandler, &cameraHandler, &wifiStateManager, "/control");
|
||||
MDNSHandler mdnsHandler(&mdnsStateManager, &deviceConfig);
|
||||
StreamServer streamServer(STREAM_SERVER_PORT);
|
||||
|
||||
void setup()
|
||||
{
|
||||
Serial.begin(115200);
|
||||
Serial.setDebugOutput(true);
|
||||
ledManager->begin();
|
||||
deviceConfig->initConfig();
|
||||
deviceConfig->load();
|
||||
cameraHandler->setupCamera();
|
||||
ledManager.begin();
|
||||
deviceConfig.initConfig();
|
||||
deviceConfig.load();
|
||||
cameraHandler.setupCamera();
|
||||
|
||||
wifiHandler->setupWifi();
|
||||
mdnsHandler->startMDNS();
|
||||
/* auto localConfig = deviceConfig.getAPWifiConfig();
|
||||
if (localConfig->adhoc == true)
|
||||
{
|
||||
|
||||
} */
|
||||
|
||||
wifiHandler._enable_adhoc = ENABLE_ADHOC;
|
||||
|
||||
wifiHandler.setupWifi();
|
||||
mdnsHandler.startMDNS();
|
||||
|
||||
switch (wifiStateManager.getCurrentState())
|
||||
{
|
||||
@ -56,8 +64,8 @@ void setup()
|
||||
}
|
||||
case WiFiState_e::WiFiState_Connected:
|
||||
{
|
||||
apiServer->startAPIServer();
|
||||
streamServer->startStreamServer();
|
||||
//apiServer.begin();
|
||||
streamServer.startStreamServer();
|
||||
log_d("[SETUP]: Starting Stream Server");
|
||||
break;
|
||||
}
|
||||
@ -76,7 +84,7 @@ void setup()
|
||||
void loop()
|
||||
{
|
||||
ota.HandleOTAUpdate();
|
||||
ledManager->displayStatus();
|
||||
apiServer->triggerWifiConfigWrite();
|
||||
// serialManager->handleSerial();
|
||||
ledManager.displayStatus();
|
||||
//apiServer.triggerWifiConfigWrite();
|
||||
// serialManager.handleSerial();
|
||||
}
|
||||
Loading…
Reference in New Issue
Block a user