Initial Checkin for WiFi and HTTP Server Framework

This commit is contained in:
Jm Casler 2020-09-12 21:43:41 -07:00
parent b6f71ca1db
commit f129b458ad
9 changed files with 314 additions and 31 deletions

View File

@ -397,3 +397,18 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#define GPS_POWER_CTRL_CH 3
#define LORA_POWER_CTRL_CH 2
// -----------------------------------------------------------------------------
// WiFi Configuration
// -----------------------------------------------------------------------------
//
// Set WiFi credentials using the API (Does this work?)
// meshtastic --setpref WiFi_SSID_NAME yournetwork
// meshtastic --setpref WiFi_SSID_PASSWORD yourpassword
//
// WiFi_Mode
// 0 = Disabled
// 1 = Enabled
#define WiFi_MODE 0
#define WiFi_SSID_NAME "meshtastic"
#define WiFi_SSID_PASSWORD "meshtastic!"

View File

@ -32,6 +32,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#include "main.h"
#include "mesh-pb-constants.h"
#include "utils.h"
#include <WiFi.h>
using namespace meshtastic; /** @todo remove */
@ -708,6 +709,12 @@ void Screen::drawDebugInfoSettingsTrampoline(OLEDDisplay *display, OLEDDisplayUi
screen->debugInfo.drawFrameSettings(display, state, x, y);
}
void Screen::drawDebugInfoWiFiTrampoline(OLEDDisplay *display, OLEDDisplayUiState *state, int16_t x, int16_t y)
{
Screen *screen = reinterpret_cast<Screen *>(state->userData);
screen->debugInfo.drawFrameWiFi(display, state, x, y);
}
// restore our regular frame list
void Screen::setFrames()
@ -739,6 +746,11 @@ void Screen::setFrames()
// call a method on debugInfoScreen object (for more details)
normalFrames[numframes++] = &Screen::drawDebugInfoSettingsTrampoline;
#if WiFi_MODE
// call a method on debugInfoScreen object (for more details)
normalFrames[numframes++] = &Screen::drawDebugInfoWiFiTrampoline;
#endif
ui.setFrames(normalFrames, numframes);
ui.enableAllIndicators();
@ -827,6 +839,32 @@ void DebugInfo::drawFrame(OLEDDisplay *display, OLEDDisplayUiState *state, int16
}
// Jm
void DebugInfo::drawFrameWiFi(OLEDDisplay *display, OLEDDisplayUiState *state, int16_t x, int16_t y)
{
displayedNodeNum = 0; // Not currently showing a node pane
display->setFont(ArialMT_Plain_10);
// The coordinates define the left starting point of the text
display->setTextAlignment(TEXT_ALIGN_LEFT);
if ( WiFi.status() != WL_CONNECTED ) {
display->drawString(x, y, String("WiFi - Not Connected"));
} else {
display->drawString(x, y, String("WiFi - Connected"));
}
display->drawString(x, y + FONT_HEIGHT * 1, WiFi.localIP().toString().c_str());
/* Display a heartbeat pixel that blinks every time the frame is redrawn */
#ifdef SHOW_REDRAWS
if (heartbeat)
display->setPixel(0, 0);
heartbeat = !heartbeat;
#endif
}
void DebugInfo::drawFrameSettings(OLEDDisplay *display, OLEDDisplayUiState *state, int16_t x, int16_t y)
{
displayedNodeNum = 0; // Not currently showing a node pane

View File

@ -17,6 +17,7 @@
#include "concurrency/PeriodicTask.h"
#include "power.h"
#include <string>
#include <WiFi.h>
namespace graphics
{
@ -46,6 +47,7 @@ class DebugInfo
/// Renders the debug screen.
void drawFrame(OLEDDisplay *display, OLEDDisplayUiState *state, int16_t x, int16_t y);
void drawFrameSettings(OLEDDisplay *display, OLEDDisplayUiState *state, int16_t x, int16_t y);
void drawFrameWiFi(OLEDDisplay *display, OLEDDisplayUiState *state, int16_t x, int16_t y);
std::string channelName;
@ -220,6 +222,8 @@ class Screen : public concurrency::PeriodicTask
static void drawDebugInfoSettingsTrampoline(OLEDDisplay *display, OLEDDisplayUiState *state, int16_t x, int16_t y);
static void drawDebugInfoWiFiTrampoline(OLEDDisplay *display, OLEDDisplayUiState *state, int16_t x, int16_t y);
/// Queue of commands to execute in doTask.
TypedQueue<ScreenCmd> cmdQueue;
/// Whether we are using a display

View File

@ -41,6 +41,7 @@
#include "timing.h"
#include <OneButton.h>
#include <Wire.h>
#include "meshwifi/meshwifi.h"
// #include <driver/rtc_io.h>
#ifndef NO_ESP32
@ -325,6 +326,11 @@ void setup()
}
#endif
#if WiFi_MODE
// Initialize Wifi
initWifi();
#endif
if (!rIf)
recordCriticalError(ErrNoRadio);
else
@ -416,5 +422,10 @@ void loop()
// feel slow
msecstosleep = 10;
#if WiFi_MODE
// TODO: This should go into a thread handled by FreeRTOS.
handleWebResponse();
#endif
delay(msecstosleep);
}

View File

@ -10,6 +10,8 @@ extern bool ssd1306_found;
extern bool isCharging;
extern bool isUSBPowered;
// Global Screen singleton.
extern graphics::Screen screen;
//extern Observable<meshtastic::PowerStatus> newPowerStatus; //TODO: move this to main-esp32.cpp somehow or a helper class

View File

@ -15,6 +15,7 @@
#include "mesh-pb-constants.h"
#include <pb_decode.h>
#include <pb_encode.h>
#include "meshwifi/meshwifi.h"
NodeDB nodeDB;
@ -399,6 +400,11 @@ void NodeDB::updateFrom(const MeshPacket &mp)
updateTextMessage = true;
powerFSM.trigger(EVENT_RECEIVED_TEXT_MSG);
notifyObservers(true); // Force an update whether or not our node counts have changed
// Only update the WebUI if WiFi is enabled
#if WiFi_MODE != 0
notifyWebUI();
#endif
}
}
break;

212
src/meshwifi/meshwifi.cpp Normal file
View File

@ -0,0 +1,212 @@
#include "meshwifi.h"
#include <WiFi.h>
#include "configuration.h"
#include "main.h"
#include "NodeDB.h"
#include <WebServer.h>
WebServer webserver(80);
String something = "";
String sender = "";
void initWebServer() {
webserver.onNotFound(handleNotFound);
webserver.on("/", handleJSONChatHistory);
webserver.on("/json/chat/history", handleJSONChatHistory);
//webserver.on("/", []() {
//webserver.send(200, "text/plain", "everything is awesome!");
//});
webserver.begin();
}
void initWifi()
{
strcpy(radioConfig.preferences.wifi_ssid, WiFi_SSID_NAME);
strcpy(radioConfig.preferences.wifi_password, WiFi_SSID_PASSWORD);
if (radioConfig.has_preferences) {
const char *wifiName = radioConfig.preferences.wifi_ssid;
if (*wifiName) {
const char *wifiPsw = radioConfig.preferences.wifi_password;
if (radioConfig.preferences.wifi_ap_mode) {
DEBUG_MSG("STARTING WIFI AP: ssid=%s, ok=%d\n", wifiName, WiFi.softAP(wifiName, wifiPsw));
} else {
WiFi.mode(WIFI_MODE_STA);
WiFi.onEvent(WiFiEvent);
DEBUG_MSG("JOINING WIFI: ssid=%s\n", wifiName);
if (WiFi.begin(wifiName, wifiPsw) == WL_CONNECTED) {
DEBUG_MSG("MY IP ADDRESS: %s\n", WiFi.localIP().toString().c_str());
} else {
DEBUG_MSG("Started Joining WIFI\n");
}
}
}
} else
DEBUG_MSG("Not using WIFI\n");
}
void WiFiEvent(WiFiEvent_t event)
{
DEBUG_MSG("************ [WiFi-event] event: %d ************\n", event);
switch (event) {
case SYSTEM_EVENT_WIFI_READY:
DEBUG_MSG("WiFi interface ready");
break;
case SYSTEM_EVENT_SCAN_DONE:
DEBUG_MSG("Completed scan for access points");
break;
case SYSTEM_EVENT_STA_START:
DEBUG_MSG("WiFi client started");
break;
case SYSTEM_EVENT_STA_STOP:
DEBUG_MSG("WiFi clients stopped");
break;
case SYSTEM_EVENT_STA_CONNECTED:
DEBUG_MSG("Connected to access point");
break;
case SYSTEM_EVENT_STA_DISCONNECTED:
DEBUG_MSG("Disconnected from WiFi access point");
// Reconnect WiFi
reconnectWiFi();
break;
case SYSTEM_EVENT_STA_AUTHMODE_CHANGE:
DEBUG_MSG("Authentication mode of access point has changed");
break;
case SYSTEM_EVENT_STA_GOT_IP:
DEBUG_MSG("Obtained IP address: ");
Serial.println(WiFi.localIP());
// Start web server
initWebServer();
break;
case SYSTEM_EVENT_STA_LOST_IP:
DEBUG_MSG("Lost IP address and IP address is reset to 0");
break;
case SYSTEM_EVENT_STA_WPS_ER_SUCCESS:
DEBUG_MSG("WiFi Protected Setup (WPS): succeeded in enrollee mode");
break;
case SYSTEM_EVENT_STA_WPS_ER_FAILED:
DEBUG_MSG("WiFi Protected Setup (WPS): failed in enrollee mode");
break;
case SYSTEM_EVENT_STA_WPS_ER_TIMEOUT:
DEBUG_MSG("WiFi Protected Setup (WPS): timeout in enrollee mode");
break;
case SYSTEM_EVENT_STA_WPS_ER_PIN:
DEBUG_MSG("WiFi Protected Setup (WPS): pin code in enrollee mode");
break;
case SYSTEM_EVENT_AP_START:
DEBUG_MSG("WiFi access point started");
break;
case SYSTEM_EVENT_AP_STOP:
DEBUG_MSG("WiFi access point stopped");
break;
case SYSTEM_EVENT_AP_STACONNECTED:
DEBUG_MSG("Client connected");
break;
case SYSTEM_EVENT_AP_STADISCONNECTED:
DEBUG_MSG("Client disconnected");
break;
case SYSTEM_EVENT_AP_STAIPASSIGNED:
DEBUG_MSG("Assigned IP address to client");
break;
case SYSTEM_EVENT_AP_PROBEREQRECVED:
DEBUG_MSG("Received probe request");
break;
case SYSTEM_EVENT_GOT_IP6:
DEBUG_MSG("IPv6 is preferred");
break;
case SYSTEM_EVENT_ETH_START:
DEBUG_MSG("Ethernet started");
break;
case SYSTEM_EVENT_ETH_STOP:
DEBUG_MSG("Ethernet stopped");
break;
case SYSTEM_EVENT_ETH_CONNECTED:
DEBUG_MSG("Ethernet connected");
break;
case SYSTEM_EVENT_ETH_DISCONNECTED:
DEBUG_MSG("Ethernet disconnected");
break;
case SYSTEM_EVENT_ETH_GOT_IP:
DEBUG_MSG("Obtained IP address");
break;
default: break;
}
}
void handleJSONChatHistory() {
String out = "";
out += "{\n";
out += " \"data\" : {\n";
out += " \"chat\" : ";
out += "[";
out += "\"" + sender + "\"";
out += ",";
out += "\"" + something + "\"";
out += "]\n";
out += "\n";
out += " }\n";
out += "}\n";
webserver.send ( 200, "application/json", out );
return;
}
void handleWebResponse() {
webserver.handleClient();
}
void handleNotFound() {
String message = "File Not Found\n\n";
message += "URI: ";
message += webserver.uri();
message += "\nMethod: ";
message += (webserver.method() == HTTP_GET) ? "GET" : "POST";
message += "\nArguments: ";
message += webserver.args();
message += "\n";
for (uint8_t i = 0; i < webserver.args(); i++) {
message += " " + webserver.argName(i) + ": " + webserver.arg(i) + "\n";
}
webserver.send(404, "text/plain", message);
/*
*/
}
void reconnectWiFi() {
if ( WiFi.status() != WL_CONNECTED ) {
DEBUG_MSG("... Reconnecting to WiFi access point");
WiFi.begin( );
}
}
void notifyWebUI() {
DEBUG_MSG("************ Got a message! ************\n");
MeshPacket &mp = devicestate.rx_text_message;
NodeInfo *node = nodeDB.getNode(mp.from);
sender = (node && node->has_user) ? node->user.long_name : "???";
static char tempBuf[256]; // mesh.options says this is MeshPacket.encrypted max_size
assert(mp.decoded.which_payload == SubPacket_data_tag);
snprintf(tempBuf, sizeof(tempBuf), "%s", mp.decoded.data.payload.bytes);
something = tempBuf;
}

22
src/meshwifi/meshwifi.h Normal file
View File

@ -0,0 +1,22 @@
#pragma once
#include <Arduino.h>
#include <functional>
#include <WiFi.h>
void handleNotFound();
void reconnectWiFi();
void initWifi();
void initWebServer();
void handleWebResponse();
void notifyWebUI();
void handleJSONChatHistory();
void WiFiEvent(WiFiEvent_t event);

View File

@ -1,10 +1,9 @@
#include "BluetoothUtil.h"
#include "BluetoothSoftwareUpdate.h"
#include "NimbleBluetoothAPI.h"
#include "NodeDB.h" // FIXME - we shouldn't really douch this here - we are using it only because we currently do wifi setup when ble gets turned on
#include "PhoneAPI.h"
#include "PowerFSM.h"
#include "WiFi.h"
#include <WiFi.h>
#include "configuration.h"
#include "esp_bt.h"
#include "host/util/util.h"
@ -503,32 +502,6 @@ void reinitBluetooth()
nimble_port_freertos_init(ble_host_task);
}
void initWifi()
{
// Note: Wifi is not yet supported ;-)
strcpy(radioConfig.preferences.wifi_ssid, "");
strcpy(radioConfig.preferences.wifi_password, "");
if (radioConfig.has_preferences) {
const char *wifiName = radioConfig.preferences.wifi_ssid;
if (*wifiName) {
const char *wifiPsw = radioConfig.preferences.wifi_password;
if (radioConfig.preferences.wifi_ap_mode) {
DEBUG_MSG("STARTING WIFI AP: ssid=%s, ok=%d\n", wifiName, WiFi.softAP(wifiName, wifiPsw));
} else {
WiFi.mode(WIFI_MODE_STA);
DEBUG_MSG("JOINING WIFI: ssid=%s\n", wifiName);
if (WiFi.begin(wifiName, wifiPsw) == WL_CONNECTED) {
DEBUG_MSG("MY IP ADDRESS: %s\n", WiFi.localIP().toString().c_str());
} else {
DEBUG_MSG("Started Joining WIFI\n");
}
}
}
} else
DEBUG_MSG("Not using WIFI\n");
}
bool bluetoothOn;
// Enable/disable bluetooth.
@ -542,11 +515,11 @@ void setBluetoothEnable(bool on)
Serial.printf("Pre BT: %u heap size\n", ESP.getFreeHeap());
// ESP_ERROR_CHECK( heap_trace_start(HEAP_TRACE_LEAKS) );
reinitBluetooth();
initWifi();
//initWifi();
} else {
// We have to totally teardown our bluetooth objects to prevent leaks
deinitBLE();
WiFi.mode(WIFI_MODE_NULL); // shutdown wifi
//WiFi.mode(WIFI_MODE_NULL); // shutdown wifi
Serial.printf("Shutdown BT: %u heap size\n", ESP.getFreeHeap());
// ESP_ERROR_CHECK( heap_trace_stop() );
// heap_trace_dump();