mirror of
https://github.com/SlimeVR/SlimeVR-Tracker-ESP.git
synced 2026-04-06 02:01:57 +02:00
Lots of improvements
This commit is contained in:
@@ -21,6 +21,8 @@
|
||||
THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <cstdint>
|
||||
#include <cstring>
|
||||
#include <string_view>
|
||||
|
||||
#include "GlobalVars.h"
|
||||
@@ -406,6 +408,38 @@ void Connection::sendFlexData(uint8_t sensorId, float flexLevel) {
|
||||
));
|
||||
}
|
||||
|
||||
// PACKET_PROVISIONING_NEW_TRACER 29
|
||||
void Connection::sendProvisioningNewTracker(uint8_t mac[6]) {
|
||||
MUST(m_Connected);
|
||||
ProvisioningNewTrackerPacket packet{};
|
||||
memcpy(packet.mac, mac, sizeof(packet.mac));
|
||||
MUST(sendPacket(SendPacketType::ProvisioningNewTracker, packet));
|
||||
}
|
||||
|
||||
// PACKET_PROVISIONING_STATUS 30
|
||||
void Connection::sendProvisioningStatus(
|
||||
uint8_t mac[6],
|
||||
ProvisioningPackets::ConnectionStatus status
|
||||
) {
|
||||
MUST(m_Connected);
|
||||
ProvisioningStatusPacket packet{
|
||||
.status = status,
|
||||
};
|
||||
memcpy(packet.mac, mac, sizeof(packet.mac));
|
||||
MUST(sendPacket(SendPacketType::ProvisioningStatus, packet));
|
||||
}
|
||||
|
||||
// PACKET_PROVISIONING_FAILED 31
|
||||
void Connection::sendProvisioningFailed(
|
||||
uint8_t mac[6],
|
||||
ProvisioningPackets::ConnectionError error
|
||||
) {
|
||||
MUST(m_Connected);
|
||||
ProvisioningFailedPacket packet{.error = error};
|
||||
memcpy(packet.mac, mac, sizeof(packet.mac));
|
||||
MUST(sendPacket(SendPacketType::ProvisioningFailed, packet));
|
||||
}
|
||||
|
||||
#if ENABLE_INSPECTION
|
||||
void Connection::sendInspectionRawIMUData(
|
||||
uint8_t sensorId,
|
||||
|
||||
@@ -25,12 +25,16 @@
|
||||
|
||||
#include <Arduino.h>
|
||||
#include <WiFiUdp.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
#include <cstdint>
|
||||
#include <optional>
|
||||
|
||||
#include "../configuration/SensorConfig.h"
|
||||
#include "c_types.h"
|
||||
#include "featureflags.h"
|
||||
#include "globals.h"
|
||||
#include "network/wifiprovisioning/provisioning-packets.h"
|
||||
#include "packets.h"
|
||||
#include "quat.h"
|
||||
#include "sensors/sensor.h"
|
||||
@@ -98,6 +102,19 @@ public:
|
||||
// PACKET_FLEX_DATA 26
|
||||
void sendFlexData(uint8_t sensorId, float flexLevel);
|
||||
|
||||
// PACKET_PROVISIONING_NEW_TRACER 29
|
||||
void sendProvisioningNewTracker(uint8_t mac[6]);
|
||||
|
||||
// PACKET_PROVISIONING_STATUS 30
|
||||
void sendProvisioningStatus(
|
||||
uint8_t mac[6],
|
||||
ProvisioningPackets::ConnectionStatus status
|
||||
);
|
||||
|
||||
// PACKET_PROVISIONING_FAILED 31
|
||||
void
|
||||
sendProvisioningFailed(uint8_t mac[6], ProvisioningPackets::ConnectionError error);
|
||||
|
||||
#if ENABLE_INSPECTION
|
||||
void sendInspectionRawIMUData(
|
||||
uint8_t sensorId,
|
||||
|
||||
@@ -56,9 +56,9 @@ enum class SendPacketType : uint8_t {
|
||||
AcknowledgeConfigChange = 24,
|
||||
FlexData = 26,
|
||||
// PositionData = 27,
|
||||
ProvisioningNewTracker = 28,
|
||||
ProvisioningStatus = 29,
|
||||
ProvisioningFailed = 30,
|
||||
ProvisioningNewTracker = 29,
|
||||
ProvisioningStatus = 30,
|
||||
ProvisioningFailed = 31,
|
||||
Bundle = 100,
|
||||
Inspection = 105,
|
||||
};
|
||||
@@ -73,7 +73,7 @@ enum class ReceivePacketType : uint8_t {
|
||||
SensorInfo = 15,
|
||||
FeatureFlags = 22,
|
||||
SetConfigFlag = 25,
|
||||
StartWiFiProvisioning = 27,
|
||||
StartWiFiProvisioning = 28,
|
||||
};
|
||||
|
||||
enum class InspectionPacketType : uint8_t {
|
||||
@@ -240,16 +240,16 @@ struct StartWiFiProvisioningPacket {
|
||||
bool start;
|
||||
};
|
||||
|
||||
struct ProvisioningNewTracker {
|
||||
struct ProvisioningNewTrackerPacket {
|
||||
uint8_t mac[6];
|
||||
};
|
||||
|
||||
struct ProvisioningStatus {
|
||||
struct ProvisioningStatusPacket {
|
||||
uint8_t mac[6];
|
||||
SlimeVR::Network::ProvisioningPackets::ConnectionStatus status;
|
||||
};
|
||||
|
||||
struct ProvisioningFailed {
|
||||
struct ProvisioningFailedPacket {
|
||||
uint8_t mac[6];
|
||||
SlimeVR::Network::ProvisioningPackets::ConnectionError error;
|
||||
};
|
||||
|
||||
@@ -53,19 +53,21 @@ bool WiFiNetwork::isConnected() const {
|
||||
void WiFiNetwork::setWiFiCredentials(const char* SSID, const char* pass) {
|
||||
wifiProvisioning.stopSearchForProvider();
|
||||
wifiProvisioning.stopProvisioning();
|
||||
WiFi.persistent(true);
|
||||
tryConnecting(false, SSID, pass);
|
||||
retriedOnG = false;
|
||||
// Reset state, will get back into provisioning if can't connect
|
||||
hadWifi = false;
|
||||
wifiState = WiFiReconnectionStatus::ServerCredAttempt;
|
||||
}
|
||||
|
||||
void WiFiNetwork::setProvisionedWiFiCredentials(const char* SSID, const char* pass) {
|
||||
tryConnecting(false, SSID, pass);
|
||||
retriedOnG = false;
|
||||
wifiState = WiFiReconnectionStatus::ProvisionedAttempt;
|
||||
}
|
||||
|
||||
IPAddress WiFiNetwork::getAddress() { return WiFi.localIP(); }
|
||||
|
||||
void WiFiNetwork::setUp() {
|
||||
// Don't need to save the already saved credentials or the hardcoded ones
|
||||
WiFi.persistent(false);
|
||||
WiFi.persistent(true);
|
||||
wifiHandlerLogger.info("Setting up WiFi");
|
||||
WiFi.mode(WIFI_AP_STA);
|
||||
WiFi.hostname("SlimeVR FBT Tracker");
|
||||
@@ -109,7 +111,6 @@ void WiFiNetwork::setUp() {
|
||||
|
||||
void WiFiNetwork::onConnected() {
|
||||
wifiState = WiFiReconnectionStatus::Success;
|
||||
wifiProvisioning.stopProvisioning();
|
||||
statusManager.setStatus(SlimeVR::Status::WIFI_CONNECTING, false);
|
||||
hadWifi = true;
|
||||
wifiHandlerLogger.info(
|
||||
@@ -201,6 +202,12 @@ void WiFiNetwork::upkeep() {
|
||||
wifiState = WiFiReconnectionStatus::Failed;
|
||||
}
|
||||
return;
|
||||
case WiFiReconnectionStatus::ProvisionedAttempt: // Couldn't connect with
|
||||
// credentials received from
|
||||
// provisioning
|
||||
if (!tryProvisionedCredentials()) {
|
||||
wifiState = WiFiReconnectionStatus::Failed;
|
||||
}
|
||||
case WiFiReconnectionStatus::Failed: // Couldn't connect with second set of
|
||||
// credentials or server credentials
|
||||
if (startedProvisioning) {
|
||||
@@ -347,6 +354,20 @@ bool WiFiNetwork::tryServerCredentials() {
|
||||
return tryConnecting(true);
|
||||
}
|
||||
|
||||
bool WiFiNetwork::tryProvisionedCredentials() {
|
||||
if (WiFi.status() != WL_DISCONNECTED) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (retriedOnG) {
|
||||
return false;
|
||||
}
|
||||
|
||||
retriedOnG = true;
|
||||
|
||||
return tryConnecting(true);
|
||||
}
|
||||
|
||||
bool WiFiNetwork::tryConnecting(bool phyModeG, const char* SSID, const char* pass) {
|
||||
#if ESP8266
|
||||
if (phyModeG) {
|
||||
|
||||
@@ -38,6 +38,7 @@ public:
|
||||
SavedAttempt,
|
||||
HardcodeAttempt,
|
||||
ServerCredAttempt,
|
||||
ProvisionedAttempt,
|
||||
Failed,
|
||||
Success
|
||||
};
|
||||
@@ -53,10 +54,14 @@ public:
|
||||
void setUp();
|
||||
void upkeep();
|
||||
void setWiFiCredentials(const char* SSID, const char* pass);
|
||||
void setProvisionedWiFiCredentials(const char* SSID, const char* pass);
|
||||
static IPAddress getAddress();
|
||||
WiFiReconnectionStatus getWiFiState();
|
||||
bool startedProvisioning = false;
|
||||
|
||||
static String getSSID();
|
||||
static String getPassword();
|
||||
|
||||
private:
|
||||
static constexpr float WiFiTimeoutSeconds = 11;
|
||||
|
||||
@@ -64,12 +69,10 @@ private:
|
||||
void setStaticIPIfDefined();
|
||||
void onConnected();
|
||||
|
||||
static String getSSID();
|
||||
static String getPassword();
|
||||
|
||||
bool trySavedCredentials();
|
||||
bool tryHardcodedCredentials();
|
||||
bool tryServerCredentials();
|
||||
bool tryProvisionedCredentials();
|
||||
bool tryConnecting(
|
||||
bool phyModeG = false,
|
||||
const char* SSID = nullptr,
|
||||
|
||||
27
src/network/wifiprovisioning/provisioning-packets.cpp
Normal file
27
src/network/wifiprovisioning/provisioning-packets.cpp
Normal file
@@ -0,0 +1,27 @@
|
||||
#include "provisioning-packets.h"
|
||||
|
||||
namespace SlimeVR::Network::ProvisioningPackets {
|
||||
|
||||
const char* statusToCstr(ConnectionStatus status) {
|
||||
switch (status) {
|
||||
case ConnectionStatus::Connecting:
|
||||
return "Connecting";
|
||||
case ConnectionStatus::Connected:
|
||||
return "Connected";
|
||||
case ConnectionStatus::ServerFound:
|
||||
return "Server Found";
|
||||
}
|
||||
return "Unknown";
|
||||
}
|
||||
|
||||
const char* errorToCstr(ConnectionError error) {
|
||||
switch (error) {
|
||||
case ConnectionError::ConnectionFailed:
|
||||
return "Connection Failed";
|
||||
case ConnectionError::ServerNotFound:
|
||||
return "Server Not Found";
|
||||
}
|
||||
return "Unknown";
|
||||
}
|
||||
|
||||
} // namespace SlimeVR::Network::ProvisioningPackets
|
||||
@@ -5,12 +5,13 @@
|
||||
namespace SlimeVR::Network::ProvisioningPackets {
|
||||
|
||||
enum class ProvisioningPacketId : uint8_t {
|
||||
ProvisioningAvailable = 0,
|
||||
ProvisioningRequest = 1,
|
||||
ProvisioningStart = 2,
|
||||
ProvisioningStarted = 3,
|
||||
ProvisioningStatus = 4,
|
||||
ProvisioningFailed = 5,
|
||||
ProvisioningAvailable,
|
||||
ProvisioningRequest,
|
||||
ProvisioningStart,
|
||||
ProvisioningStatus,
|
||||
ProvisioningStatusAck,
|
||||
ProvisioningFailed,
|
||||
ProvisioningFailedAck,
|
||||
};
|
||||
|
||||
#pragma pack(push, 1)
|
||||
@@ -26,11 +27,15 @@ enum class ConnectionStatus : uint8_t {
|
||||
ServerFound,
|
||||
};
|
||||
|
||||
const char* statusToCstr(ConnectionStatus status);
|
||||
|
||||
enum class ConnectionError : uint8_t {
|
||||
ConnectionFailed,
|
||||
ServerNotFound,
|
||||
};
|
||||
|
||||
const char* errorToCstr(ConnectionError error);
|
||||
|
||||
struct ProvisioningAvailable
|
||||
: ProvisioningPacket<ProvisioningPacketId::ProvisioningAvailable> {};
|
||||
|
||||
@@ -46,19 +51,22 @@ struct ProvisioningStart : ProvisioningPacket<ProvisioningPacketId::Provisioning
|
||||
char wifiPassword[64] = "";
|
||||
};
|
||||
|
||||
struct ProvisioningStarted
|
||||
: ProvisioningPacket<ProvisioningPacketId::ProvisioningStarted> {};
|
||||
|
||||
struct ProvisioningStatus
|
||||
: ProvisioningPacket<ProvisioningPacketId::ProvisioningStatus> {
|
||||
ConnectionStatus status = ConnectionStatus::Connecting;
|
||||
};
|
||||
|
||||
struct ProvisioningStatusAck
|
||||
: ProvisioningPacket<ProvisioningPacketId::ProvisioningStatusAck> {};
|
||||
|
||||
struct ProvisioningFailed
|
||||
: ProvisioningPacket<ProvisioningPacketId::ProvisioningFailed> {
|
||||
ConnectionError error = ConnectionError::ConnectionFailed;
|
||||
};
|
||||
|
||||
struct ProvisioningFailedAck
|
||||
: ProvisioningPacket<ProvisioningPacketId::ProvisioningFailedAck> {};
|
||||
|
||||
#pragma pack(pop)
|
||||
|
||||
} // namespace SlimeVR::Network::ProvisioningPackets
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
#include <cstdint>
|
||||
#include <optional>
|
||||
|
||||
#include "logging/Logger.h"
|
||||
#include "provisioning-party.h"
|
||||
@@ -8,6 +9,16 @@ namespace SlimeVR::Network {
|
||||
ProvisioningParty::ProvisioningParty(SlimeVR::Logging::Logger& logger) noexcept
|
||||
: logger{logger} {}
|
||||
|
||||
void ProvisioningParty::handleSendResult(bool success) { lastPacketSuccess = success; }
|
||||
|
||||
void ProvisioningParty::resetLastSendResult() { lastPacketSuccess.reset(); }
|
||||
|
||||
std::optional<bool> ProvisioningParty::getLastSendResult() {
|
||||
auto result = lastPacketSuccess;
|
||||
lastPacketSuccess.reset();
|
||||
return result;
|
||||
}
|
||||
|
||||
void ProvisioningParty::addPeer(uint8_t macAddress[6]) const {
|
||||
#if ESP8266
|
||||
esp_now_add_peer(macAddress, ESP_NOW_ROLE_COMBO, 0, nullptr, 0);
|
||||
@@ -25,12 +36,4 @@ void ProvisioningParty::removePeer(uint8_t macAddress[6]) const {
|
||||
esp_now_del_peer(macAddress);
|
||||
}
|
||||
|
||||
void ProvisioningParty::sendMessage(
|
||||
uint8_t receiverMac[6],
|
||||
const uint8_t* data,
|
||||
uint8_t length
|
||||
) const {
|
||||
// TODO:
|
||||
}
|
||||
|
||||
} // namespace SlimeVR::Network
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
#pragma once
|
||||
|
||||
#include <cstdint>
|
||||
#include <optional>
|
||||
|
||||
#if ESP8266
|
||||
#include <espnow.h>
|
||||
@@ -28,16 +29,31 @@ public:
|
||||
virtual void
|
||||
handleMessage(uint8_t macAddress[6], const uint8_t* data, uint8_t length)
|
||||
= 0;
|
||||
virtual void stop() = 0;
|
||||
|
||||
void handleSendResult(bool success);
|
||||
|
||||
protected:
|
||||
uint8_t BroadcastMacAddress[6]{0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
|
||||
|
||||
void addPeer(uint8_t macAddress[6]) const;
|
||||
void removePeer(uint8_t macAddress[6]) const;
|
||||
void sendMessage(uint8_t receiverMac[6], const uint8_t* data, uint8_t length) const;
|
||||
void resetLastSendResult();
|
||||
std::optional<bool> getLastSendResult();
|
||||
|
||||
template <typename Packet>
|
||||
bool sendMessage(uint8_t receiverMac[6], Packet data) const {
|
||||
return esp_now_send(
|
||||
receiverMac,
|
||||
reinterpret_cast<uint8_t*>(&data),
|
||||
sizeof(Packet)
|
||||
)
|
||||
== 0;
|
||||
}
|
||||
|
||||
SlimeVR::Logging::Logger& logger;
|
||||
|
||||
private:
|
||||
std::optional<bool> lastPacketSuccess;
|
||||
};
|
||||
|
||||
} // namespace SlimeVR::Network
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
#include <cstdint>
|
||||
#include <cstring>
|
||||
|
||||
#include "GlobalVars.h"
|
||||
#include "credentials.h"
|
||||
#include "logging/Logger.h"
|
||||
#include "network/wifiprovisioning/provisioning-packets.h"
|
||||
@@ -31,12 +32,7 @@ bool ProvisioningProvider::tick() {
|
||||
}
|
||||
|
||||
if (messageTimeout.elapsed()) {
|
||||
ProvisioningPackets::ProvisioningAvailable packet{};
|
||||
sendMessage(
|
||||
BroadcastMacAddress,
|
||||
reinterpret_cast<uint8_t*>(&packet),
|
||||
sizeof(packet)
|
||||
);
|
||||
sendMessage(BroadcastMacAddress, ProvisioningPackets::ProvisioningAvailable{});
|
||||
messageTimeout.reset();
|
||||
}
|
||||
|
||||
@@ -60,20 +56,43 @@ void ProvisioningProvider::handleMessage(
|
||||
handleProvisioningRequest(macAddress, packet.provisioningPassword);
|
||||
break;
|
||||
}
|
||||
case ProvisioningPackets::ProvisioningPacketId::ProvisioningStarted: {
|
||||
break;
|
||||
}
|
||||
case ProvisioningPackets::ProvisioningPacketId::ProvisioningStatus: {
|
||||
auto packet
|
||||
= *reinterpret_cast<const ProvisioningPackets::ProvisioningStatus*>(data
|
||||
);
|
||||
addPeer(macAddress);
|
||||
sendMessage(macAddress, ProvisioningPackets::ProvisioningStatusAck{});
|
||||
removePeer(macAddress);
|
||||
networkConnection.sendProvisioningStatus(macAddress, packet.status);
|
||||
logger.info(
|
||||
"Tracker with mac address " MACSTR " reported status %d, %s",
|
||||
MAC2STR(macAddress),
|
||||
static_cast<uint8_t>(packet.status),
|
||||
ProvisioningPackets::statusToCstr(packet.status)
|
||||
);
|
||||
break;
|
||||
}
|
||||
case ProvisioningPackets::ProvisioningPacketId::ProvisioningFailed: {
|
||||
auto packet
|
||||
= *reinterpret_cast<const ProvisioningPackets::ProvisioningFailed*>(data
|
||||
);
|
||||
addPeer(macAddress);
|
||||
sendMessage(macAddress, ProvisioningPackets::ProvisioningFailedAck{});
|
||||
removePeer(macAddress);
|
||||
networkConnection.sendProvisioningFailed(macAddress, packet.error);
|
||||
logger.error(
|
||||
"Tracker with mac address " MACSTR " reported error %d, %s",
|
||||
MAC2STR(macAddress),
|
||||
static_cast<uint8_t>(packet.error),
|
||||
ProvisioningPackets::errorToCstr(packet.error)
|
||||
);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void ProvisioningProvider::stop() {}
|
||||
|
||||
void ProvisioningProvider::handleProvisioningRequest(
|
||||
uint8_t macAddress[6],
|
||||
const char* password
|
||||
@@ -83,11 +102,16 @@ void ProvisioningProvider::handleProvisioningRequest(
|
||||
}
|
||||
ProvisioningPackets::ProvisioningStart packet{};
|
||||
// TODO: swap with the getSSID/getPassword function once that gets merged in
|
||||
strcpy(packet.wifiName, WiFi.SSID().c_str());
|
||||
strcpy(packet.wifiPassword, WiFi.psk().c_str());
|
||||
strcpy(packet.wifiName, wifiNetwork.getSSID().c_str());
|
||||
strcpy(packet.wifiPassword, wifiNetwork.getPassword().c_str());
|
||||
addPeer(macAddress);
|
||||
sendMessage(macAddress, reinterpret_cast<uint8_t*>(&packet), sizeof(packet));
|
||||
sendMessage(macAddress, packet);
|
||||
removePeer(macAddress);
|
||||
networkConnection.sendProvisioningNewTracker(macAddress);
|
||||
logger.info(
|
||||
"Provisioning tracker with mac address " MACSTR "...",
|
||||
MAC2STR(macAddress)
|
||||
);
|
||||
}
|
||||
|
||||
} // namespace SlimeVR::Network
|
||||
|
||||
@@ -14,7 +14,6 @@ public:
|
||||
bool tick() final;
|
||||
void handleMessage(uint8_t macAddress[6], const uint8_t* data, uint8_t length)
|
||||
final;
|
||||
void stop() final;
|
||||
|
||||
private:
|
||||
static constexpr float ProvisioningTimeoutSeconds = 60.0f;
|
||||
|
||||
@@ -3,9 +3,13 @@
|
||||
|
||||
#include <cstdint>
|
||||
#include <cstring>
|
||||
#include <type_traits>
|
||||
|
||||
#include "GlobalVars.h"
|
||||
#include "credentials.h"
|
||||
#include "espnow.h"
|
||||
#include "logging/Logger.h"
|
||||
#include "network/wifihandler.h"
|
||||
#include "network/wifiprovisioning/provisioning-packets.h"
|
||||
#include "network/wifiprovisioning/provisioning-party.h"
|
||||
#include "provisioning-target.h"
|
||||
@@ -20,6 +24,7 @@ void ProvisioningTarget::init() {
|
||||
searchTimeout.reset();
|
||||
channelSwitchTimeout.reset();
|
||||
switchChannel(1);
|
||||
addPeer(BroadcastMacAddress);
|
||||
}
|
||||
|
||||
bool ProvisioningTarget::tick() {
|
||||
@@ -36,19 +41,58 @@ bool ProvisioningTarget::tick() {
|
||||
} else {
|
||||
switchChannel(currentChannel + 1);
|
||||
}
|
||||
channelSwitchTimeout.reset();
|
||||
}
|
||||
channelSwitchTimeout.reset();
|
||||
break;
|
||||
}
|
||||
case Status::Authenticating: {
|
||||
case Status::ConnectionStarted: {
|
||||
sendAndWaitForAck(ProvisioningPackets::ProvisioningStatus{
|
||||
.status = ProvisioningPackets::ConnectionStatus::Connecting,
|
||||
});
|
||||
break;
|
||||
}
|
||||
case Status::Connecting: {
|
||||
if (WiFi.isConnected()) {
|
||||
sendAndWaitForAck(ProvisioningPackets::ProvisioningStatus{
|
||||
.status = ProvisioningPackets::ConnectionStatus::Connected
|
||||
});
|
||||
break;
|
||||
}
|
||||
|
||||
if (wifiNetwork.getWiFiState()
|
||||
== WiFiNetwork::WiFiReconnectionStatus::Failed) {
|
||||
sendAndWaitForAck(ProvisioningPackets::ProvisioningFailed{
|
||||
.error = ProvisioningPackets::ConnectionError::ConnectionFailed,
|
||||
});
|
||||
break;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
case Status::SearchingForServer: {
|
||||
if (!searchingForServer) {
|
||||
serverSearchTimeout.reset();
|
||||
searchingForServer = true;
|
||||
}
|
||||
|
||||
if (networkConnection.isConnected()) {
|
||||
sendAndWaitForAck(ProvisioningPackets::ProvisioningStatus{
|
||||
.status = ProvisioningPackets::ConnectionStatus::ServerFound,
|
||||
});
|
||||
break;
|
||||
}
|
||||
|
||||
if (serverSearchTimeout.elapsed()) {
|
||||
sendAndWaitForAck(ProvisioningPackets::ProvisioningFailed{
|
||||
.error = ProvisioningPackets::ConnectionError::ServerNotFound,
|
||||
});
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case Status::Done:
|
||||
printf("Finished\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
@@ -78,33 +122,58 @@ void ProvisioningTarget::handleMessage(
|
||||
startConnection(packet.wifiName, packet.wifiPassword);
|
||||
break;
|
||||
}
|
||||
case ProvisioningPackets::ProvisioningPacketId::ProvisioningStatusAck: {
|
||||
status = static_cast<Status>(static_cast<int>(status) + 1);
|
||||
waitingForAck = false;
|
||||
retryTimeout.reset();
|
||||
break;
|
||||
}
|
||||
case ProvisioningPackets::ProvisioningPacketId::ProvisioningFailedAck: {
|
||||
status = Status::Done;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void ProvisioningTarget::stop() {}
|
||||
|
||||
void ProvisioningTarget::switchChannel(uint8_t channel) {
|
||||
logger.info("Switching to channel %d...", channel);
|
||||
wifi_set_channel(channel);
|
||||
currentChannel = channel;
|
||||
|
||||
esp_now_set_peer_channel(BroadcastMacAddress, channel);
|
||||
}
|
||||
|
||||
void ProvisioningTarget::handleProvisioningOffer(uint8_t macAddress[6]) {
|
||||
if (status != Status::WaitingForProvider) {
|
||||
return;
|
||||
}
|
||||
logger.info("Received provisioning offer from " MACSTR, MAC2STR(macAddress));
|
||||
status = Status::Authenticating;
|
||||
addPeer(macAddress);
|
||||
memcpy(providerMac, macAddress, sizeof(providerMac));
|
||||
|
||||
ProvisioningPackets::ProvisioningRequest packet;
|
||||
strcpy(packet.provisioningPassword, provisioningPassword);
|
||||
sendMessage(providerMac, reinterpret_cast<uint8_t*>(&packet), sizeof(packet));
|
||||
sendMessage(providerMac, packet);
|
||||
}
|
||||
|
||||
void ProvisioningTarget::startConnection(const char* ssid, const char* password) {
|
||||
// TODO:
|
||||
logger.info("Received wifi credentials SSID: %s, password: %s!", ssid, password);
|
||||
logger.info(
|
||||
"Received WiFi credentials SSID %s and password length %zu! Connecting...",
|
||||
ssid,
|
||||
strlen(password)
|
||||
);
|
||||
|
||||
wifiNetwork.setProvisionedWiFiCredentials(ssid, password);
|
||||
status = Status::ConnectionStarted;
|
||||
resetLastSendResult();
|
||||
sendMessage(
|
||||
providerMac,
|
||||
ProvisioningPackets::ProvisioningStatus{
|
||||
.status = ProvisioningPackets::ConnectionStatus::Connecting,
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
} // namespace SlimeVR::Network
|
||||
|
||||
@@ -14,28 +14,45 @@ public:
|
||||
bool tick() final;
|
||||
void handleMessage(uint8_t macAddress[6], const uint8_t* data, uint8_t length)
|
||||
final;
|
||||
void stop() final;
|
||||
|
||||
private:
|
||||
static constexpr float ChannelSwitchSeconds = 0.5f;
|
||||
static constexpr float SearchTimeoutSeconds = 120.0f;
|
||||
static constexpr float RetryIntervalSeconds = 0.25f;
|
||||
static constexpr float ServerSearchTimeoutSeconds = 10.0f;
|
||||
|
||||
enum class Status {
|
||||
WaitingForProvider,
|
||||
Authenticating,
|
||||
ConnectionStarted,
|
||||
Connecting,
|
||||
SearchingForServer,
|
||||
Done,
|
||||
};
|
||||
|
||||
void switchChannel(uint8_t channel);
|
||||
void handleProvisioningOffer(uint8_t macAddress[6]);
|
||||
void startConnection(const char* ssid, const char* password);
|
||||
|
||||
template <typename Packet>
|
||||
void sendAndWaitForAck(Packet packet) {
|
||||
if (waitingForAck && !retryTimeout.elapsed()) {
|
||||
return;
|
||||
}
|
||||
|
||||
sendMessage(providerMac, packet);
|
||||
retryTimeout.reset();
|
||||
waitingForAck = true;
|
||||
}
|
||||
|
||||
TimeOut searchTimeout{SearchTimeoutSeconds};
|
||||
TimeOut channelSwitchTimeout{ChannelSwitchSeconds};
|
||||
TimeOut retryTimeout{RetryIntervalSeconds};
|
||||
TimeOut serverSearchTimeout{ServerSearchTimeoutSeconds};
|
||||
uint8_t currentChannel = 0;
|
||||
Status status = Status::WaitingForProvider;
|
||||
uint8_t providerMac[6] = {};
|
||||
bool waitingForAck = false;
|
||||
bool searchingForServer = false;
|
||||
};
|
||||
|
||||
} // namespace SlimeVR::Network
|
||||
|
||||
@@ -21,6 +21,7 @@
|
||||
THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <cstdint>
|
||||
#include <memory>
|
||||
|
||||
#include "network/wifiprovisioning/provisioning-provider.h"
|
||||
@@ -44,6 +45,10 @@ namespace SlimeVR::Network {
|
||||
void espnowReceiveCallback(uint8_t* macAddress, uint8_t* data, uint8_t length) {
|
||||
wifiProvisioning.handleMessage(macAddress, data, length);
|
||||
}
|
||||
|
||||
void espnowSendCallback(uint8_t* macAddress, uint8_t status) {
|
||||
wifiProvisioning.handleSendResult(status == 0);
|
||||
}
|
||||
#elif ESP32
|
||||
void espnowReceiveCallback(
|
||||
const esp_now_recv_info_t* senderInfo,
|
||||
@@ -139,6 +144,8 @@ void WiFiProvisioning::tick() {
|
||||
|
||||
if (!role->tick()) {
|
||||
role.reset();
|
||||
esp_now_deinit();
|
||||
esp_now_unregister_recv_cb();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -162,11 +169,13 @@ bool WiFiProvisioning::initEspnow() {
|
||||
|
||||
result = esp_now_register_recv_cb(espnowReceiveCallback);
|
||||
if (result != 0) {
|
||||
logger.error("Couldn't register ESP-Now receive callback! Error: %d", result);
|
||||
logger.error("Couldn't register ESP-Now receiver callback! Error: %d", result);
|
||||
esp_now_deinit();
|
||||
return false;
|
||||
}
|
||||
|
||||
esp_now_register_send_cb(espnowSendCallback);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -178,4 +187,8 @@ void WiFiProvisioning::handleMessage(
|
||||
role->handleMessage(macAddress, data, length);
|
||||
}
|
||||
|
||||
void WiFiProvisioning::handleSendResult(bool success) {
|
||||
role->handleSendResult(success);
|
||||
}
|
||||
|
||||
} // namespace SlimeVR::Network
|
||||
|
||||
@@ -49,12 +49,14 @@ public:
|
||||
private:
|
||||
bool initEspnow();
|
||||
void handleMessage(uint8_t* macAddress, const uint8_t* data, uint8_t length);
|
||||
void handleSendResult(bool success);
|
||||
|
||||
std::unique_ptr<ProvisioningParty> role;
|
||||
SlimeVR::Logging::Logger logger{"WiFiProvisioning"};
|
||||
|
||||
#if ESP8266
|
||||
friend void espnowReceiveCallback(uint8_t*, uint8_t*, uint8_t);
|
||||
friend void espnowSendCallback(uint8_t*, uint8_t);
|
||||
#elif ESP32
|
||||
friend void espnowReceiveCallback(
|
||||
const esp_now_recv_info_t* senderInfo,
|
||||
|
||||
Reference in New Issue
Block a user