Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
159 changes: 115 additions & 44 deletions src/WifiControl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ WifiControl::WifiControl(Mount *mount, LcdMenu *lcdMenu)
{
_mount = mount;
_lcdMenu = lcdMenu;
clearCmd();
}

void WifiControl::setup()
Expand Down Expand Up @@ -61,8 +62,15 @@ void WifiControl::startAccessPointMode()
WiFi.setHostname(WIFI_HOSTNAME);
#endif

WiFi.softAP(WIFI_HOSTNAME, WIFI_AP_MODE_WPAKEY);
WiFi.mode(WIFI_AP);
WiFi.softAPConfig(local_ip, gateway, subnet);
if (!WiFi.softAP(WIFI_HOSTNAME, WIFI_AP_MODE_WPAKEY))
{
LOG(DEBUG_WIFI, "[WIFI]: AP mode could not be started!");
return;
}

establishServers();
}

String wifiStatus(int status)
Expand Down Expand Up @@ -106,54 +114,82 @@ String WifiControl::getStatus()
result += "Infra-Fail-To-AP,";
}

result += wifiStatus(WiFi.status()) + ",";
if (WIFI_MODE != WIFI_MODE_AP_ONLY)
{
result += wifiStatus(WiFi.status()) + ",";
}
#if defined(ESP32)
result += WiFi.getHostname();
result += ",";
#endif

result += "," + WiFi.localIP().toString() + ":" + WIFI_PORT;
result += "," + String(WIFI_INFRASTRUCTURE_MODE_SSID) + "," + String(WIFI_HOSTNAME);
result += getIP() + ":" + WIFI_PORT + ",";
if (WIFI_MODE != WIFI_MODE_AP_ONLY)
{
result += String(WIFI_INFRASTRUCTURE_MODE_SSID) + ",";
}
result += String(WIFI_HOSTNAME);

return result;
}

void WifiControl::establishServers()
{
delete _tcpServer;
_tcpServer = new WiFiServer(WIFI_PORT);
_tcpServer->begin();
_tcpServer->setNoDelay(true);

delete _udp;
_udp = new WiFiUDP();
_udp->begin(WIFI_UDP_DISCOVERY_PORT);
}

String WifiControl::getIP()
{
return WIFI_MODE == WIFI_MODE_DISABLED ? "NONE"
: WIFI_MODE == WIFI_MODE_AP_ONLY ? WiFi.softAPIP().toString()
: WiFi.localIP().toString();
}

void WifiControl::clearCmd()
{
_currCmd = "";
_currCmd.reserve(_defaultCapacity);
}

void WifiControl::loop()
{
if (WIFI_MODE == WIFI_MODE_DISABLED)
{
return;
}
if (_status != WiFi.status())

if (WIFI_MODE != WIFI_MODE_AP_ONLY)
{
_status = WiFi.status();
LOG(DEBUG_WIFI, "[WIFI]: Connected status changed to %s", wifiStatus(_status).c_str());
if (_status == WL_CONNECTED)
if (_status != WiFi.status())
{
delete _tcpServer;
_tcpServer = new WiFiServer(WIFI_PORT);
_tcpServer->begin();
_tcpServer->setNoDelay(true);

delete _udp;
_udp = new WiFiUDP();
_udp->begin(4031);

LOG(DEBUG_WIFI,
"[WIFI]: Connecting to SSID %s at %s:%d",
WIFI_INFRASTRUCTURE_MODE_SSID,
WiFi.localIP().toString().c_str(),
WIFI_PORT);
_status = WiFi.status();
LOG(DEBUG_WIFI, "[WIFI]: Connected status changed to %s", wifiStatus(_status).c_str());
if (_status == WL_CONNECTED)
{
establishServers();
LOG(DEBUG_WIFI,
"[WIFI]: Connecting to SSID %s at %s:%d",
WIFI_INFRASTRUCTURE_MODE_SSID,
WiFi.localIP().toString().c_str(),
WIFI_PORT);
}
}
if (_status != WL_CONNECTED)
{
infraToAPFailover();
return;
}
}

_mount->loop();

if (_status != WL_CONNECTED)
{
infraToAPFailover();
return;
}

tcpLoop();
udpLoop();
}
Expand All @@ -172,26 +208,55 @@ void WifiControl::infraToAPFailover()

void WifiControl::tcpLoop()
{
if (client && client.connected())
if (!_tcpServer)
return;

if (!client.connected())
{
while (client.available())
if (_currCmd.length() != 0)
{
LOG(DEBUG_WIFI, "[WIFITCP]: Available bytes %d. Peeking.", client.available());
clearCmd();
}
client = _tcpServer->accept();
if (!client.connected())
return;
}

int avail;
while ((avail = client.available()) != 0)
{
LOG(DEBUG_WIFI, "[WIFITCP]: Available bytes %d. Peeking.", avail);

// Peek first byte and check for ACK (0x06) handshake
LOG(DEBUG_WIFI, "[WIFITCP]: First byte is %x", client.peek());
if (client.peek() == 0x06)
// Peek first byte and check for ACK (0x06) handshake
if (_currCmd.length() == 0)
{
int peek = client.peek();
LOG(DEBUG_WIFI, "[WIFITCP]: First byte is %x", peek);
if (peek == 0x06)
{
client.read();
LOG(DEBUG_WIFI, "[WIFITCP]: Query <-- Handshake request");
client.write("P");
LOG(DEBUG_WIFI, "[WIFITCP]: Reply --> P (polar mode)");
_mount->loop();
}
}

int recv;
while ((recv = client.read()) != -1)
{
// Prevent newlines from polluting the command string
if (recv == '\n' || recv == '\r')
{
_mount->loop();
continue;
}
else

_currCmd += (char) recv;
if (recv == '#')
{
String cmd = client.readStringUntil('#');
LOG(DEBUG_WIFI, "[WIFITCP]: Query <-- %s#", cmd.c_str());
const char *retVal = _cmdProcessor->processCommand(cmd);
LOG(DEBUG_WIFI, "[WIFITCP]: Query <-- %s", _currCmd.c_str());
const char *retVal = _cmdProcessor->processCommand(_currCmd);

if (retVal[0] != '\0')
{
Expand All @@ -202,27 +267,33 @@ void WifiControl::tcpLoop()
{
LOG(DEBUG_WIFI, "[WIFITCP]: No Reply");
}
clearCmd();
}

// Prevent memory overconsumption
if (_currCmd.length() == _maxCapacity)
{
LOG(DEBUG_WIFI, "[WIFITCP]: Command string reached maximum capacity --> clear");
clearCmd();
}
_mount->loop();
}
}
else
{
client = _tcpServer->available();
}
}

void WifiControl::udpLoop()
{
if (!_udp)
return;

int packetSize = _udp->parsePacket();
if (packetSize)
{
String lookingFor = "skyfi:";
String reply = "skyfi:";
reply += WIFI_HOSTNAME;
reply += "@";
reply += WiFi.localIP().toString();
reply += getIP();
LOG(DEBUG_WIFI,
"[WIFIUDP]: Received %d bytes from %s, port %d",
packetSize,
Expand All @@ -236,7 +307,7 @@ void WifiControl::udpLoop()
incomingPacket[lookingFor.length()] = 0;
if (lookingFor.equalsIgnoreCase(incomingPacket))
{
_udp->beginPacket(_udp->remoteIP(), 4031);
_udp->beginPacket(_udp->remoteIP(), WIFI_UDP_DISCOVERY_PORT);
/*unsigned char bytes[255];
reply.getBytes(bytes, 255);
_udp->write(bytes, reply.length());*/
Expand Down
10 changes: 9 additions & 1 deletion src/WifiControl.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@
#include <WiFiSTA.h>
#endif

#define WIFI_UDP_DISCOVERY_PORT 4031

// Forward declarations
class Mount;
class LcdMenu;
Expand All @@ -29,17 +31,23 @@ class WifiControl
void infraToAPFailover();
void tcpLoop();
void udpLoop();
wl_status_t _status;
void establishServers();
void clearCmd();
String getIP();
wl_status_t _status = WL_DISCONNECTED;
Mount *_mount;
LcdMenu *_lcdMenu;
MeadeCommandProcessor *_cmdProcessor;

WiFiServer *_tcpServer = nullptr;
WiFiUDP *_udp = nullptr;
WiFiClient client;
String _currCmd;

unsigned long _infraStart = 0;
unsigned long _infraWait = 30000; // 30 second timeout for
static constexpr size_t _defaultCapacity = 32;
static constexpr size_t _maxCapacity = 128;
};

extern WifiControl wifiControl;
Expand Down
Loading