diff --git a/src/configuration.h b/src/configuration.h index e70f1fda4..e2098fd0d 100644 --- a/src/configuration.h +++ b/src/configuration.h @@ -397,3 +397,18 @@ along with this program. If not, see . #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!" \ No newline at end of file diff --git a/src/graphics/Screen.cpp b/src/graphics/Screen.cpp index 5229f5660..4a6418b9e 100644 --- a/src/graphics/Screen.cpp +++ b/src/graphics/Screen.cpp @@ -32,6 +32,7 @@ along with this program. If not, see . #include "main.h" #include "mesh-pb-constants.h" #include "utils.h" +#include 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(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 diff --git a/src/graphics/Screen.h b/src/graphics/Screen.h index c9ab85449..8f5a6de2a 100644 --- a/src/graphics/Screen.h +++ b/src/graphics/Screen.h @@ -17,6 +17,7 @@ #include "concurrency/PeriodicTask.h" #include "power.h" #include +#include 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 cmdQueue; /// Whether we are using a display diff --git a/src/main.cpp b/src/main.cpp index f7af6d232..13b28debf 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -41,6 +41,7 @@ #include "timing.h" #include #include +#include "meshwifi/meshwifi.h" // #include #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); } diff --git a/src/main.h b/src/main.h index fb64d9ff0..39b1364f6 100644 --- a/src/main.h +++ b/src/main.h @@ -10,6 +10,8 @@ extern bool ssd1306_found; extern bool isCharging; extern bool isUSBPowered; + + // Global Screen singleton. extern graphics::Screen screen; //extern Observable newPowerStatus; //TODO: move this to main-esp32.cpp somehow or a helper class @@ -23,4 +25,4 @@ const char *getDeviceName(); void getMacAddr(uint8_t *dmac); -void nrf52Setup(), esp32Setup(), nrf52Loop(), esp32Loop(); \ No newline at end of file +void nrf52Setup(), esp32Setup(), nrf52Loop(), esp32Loop(); diff --git a/src/mesh/NodeDB.cpp b/src/mesh/NodeDB.cpp index 93d0787d3..22d4675a3 100644 --- a/src/mesh/NodeDB.cpp +++ b/src/mesh/NodeDB.cpp @@ -15,6 +15,7 @@ #include "mesh-pb-constants.h" #include #include +#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; diff --git a/src/meshwifi/meshwifi.cpp b/src/meshwifi/meshwifi.cpp new file mode 100644 index 000000000..254c852d9 --- /dev/null +++ b/src/meshwifi/meshwifi.cpp @@ -0,0 +1,212 @@ +#include "meshwifi.h" +#include +#include "configuration.h" +#include "main.h" +#include "NodeDB.h" +#include + +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; + +} \ No newline at end of file diff --git a/src/meshwifi/meshwifi.h b/src/meshwifi/meshwifi.h new file mode 100644 index 000000000..e6b456e22 --- /dev/null +++ b/src/meshwifi/meshwifi.h @@ -0,0 +1,22 @@ +#pragma once + +#include +#include +#include + +void handleNotFound(); + +void reconnectWiFi(); + +void initWifi(); + +void initWebServer(); + +void handleWebResponse(); + +void notifyWebUI(); + +void handleJSONChatHistory(); + +void WiFiEvent(WiFiEvent_t event); + diff --git a/src/nimble/BluetoothUtil.cpp b/src/nimble/BluetoothUtil.cpp index 490bc13d4..20b5aace4 100644 --- a/src/nimble/BluetoothUtil.cpp +++ b/src/nimble/BluetoothUtil.cpp @@ -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 #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();