diff --git a/examples/companion_radio/main.cpp b/examples/companion_radio/main.cpp index a3168a44..f81b9ffc 100644 --- a/examples/companion_radio/main.cpp +++ b/examples/companion_radio/main.cpp @@ -1081,7 +1081,13 @@ public: }; #ifdef ESP32 - #ifdef BLE_PIN_CODE + #ifdef WIFI_SSID + #include + SerialWifiInterface serial_interface; + #ifndef TCP_PORT + #define TCP_PORT 5000 + #endif + #elif defined(BLE_PIN_CODE) #include SerialBLEInterface serial_interface; #else @@ -1170,7 +1176,10 @@ void setup() { SPIFFS.begin(true); the_mesh.begin(SPIFFS, trng); -#ifdef BLE_PIN_CODE +#ifdef WIFI_SSID + WiFi.begin(WIFI_SSID, WIFI_PWD); + serial_interface.begin(TCP_PORT); +#elif defined(BLE_PIN_CODE) char dev_name[32+10]; sprintf(dev_name, "MeshCore-%s", the_mesh.getNodeName()); serial_interface.begin(dev_name, BLE_PIN_CODE); diff --git a/platformio.ini b/platformio.ini index 9294d157..f4035214 100644 --- a/platformio.ini +++ b/platformio.ini @@ -188,6 +188,25 @@ lib_deps = ${Heltec_lora32_v3.lib_deps} densaugeo/base64 @ ~1.4.0 +[env:Heltec_v3_companion_radio_wifi] +extends = Heltec_lora32_v3 +build_flags = + ${Heltec_lora32_v3.build_flags} + -D MAX_CONTACTS=100 + -D MAX_GROUP_CHANNELS=1 + -D BLE_PIN_CODE=123456 + -D BLE_DEBUG_LOGGING=1 + -D WIFI_SSID="\"myssid\"" + -D WIFI_PWD="\"mypwd\"" +; -D ENABLE_PRIVATE_KEY_IMPORT=1 +; -D ENABLE_PRIVATE_KEY_EXPORT=1 +; -D MESH_PACKET_LOGGING=1 +; -D MESH_DEBUG=1 +build_src_filter = ${Heltec_lora32_v3.build_src_filter} + +<../examples/companion_radio/main.cpp> +lib_deps = + ${Heltec_lora32_v3.lib_deps} + densaugeo/base64 @ ~1.4.0 + ; ================ [Xiao_esp32_C3] extends = esp32_base diff --git a/src/helpers/esp32/SerialWifiInterface.cpp b/src/helpers/esp32/SerialWifiInterface.cpp new file mode 100644 index 00000000..169f7c0a --- /dev/null +++ b/src/helpers/esp32/SerialWifiInterface.cpp @@ -0,0 +1,98 @@ +#include "SerialWifiInterface.h" +#include + +void SerialWifiInterface::begin(int port) { + // wifi setup is handled outside of this class, only starts the server + server.begin(port); +} + +// ---------- public methods +void SerialWifiInterface::enable() { + if (_isEnabled) return; + + _isEnabled = true; + clearBuffers(); +} + +void SerialWifiInterface::disable() { + _isEnabled = false; +} + +size_t SerialWifiInterface::writeFrame(const uint8_t src[], size_t len) { + if (len > MAX_FRAME_SIZE) { + Serial.printf("writeFrame(), frame too big, len=%d\n", len); + return 0; + } + + if (deviceConnected && len > 0) { + if (send_queue_len >= FRAME_QUEUE_SIZE) { + Serial.println("writeFrame(), send_queue is full!"); + return 0; + } + + send_queue[send_queue_len].len = len; // add to send queue + memcpy(send_queue[send_queue_len].buf, src, len); + send_queue_len++; + + return len; + } + return 0; +} + +#define SER_WRITE_MIN_INTERVAL 0 + +bool SerialWifiInterface::isWriteBusy() const { + return millis() < _last_write + SER_WRITE_MIN_INTERVAL; // still too soon to start another write? +} + +size_t SerialWifiInterface::checkRecvFrame(uint8_t dest[]) { + if (isWriteBusy()) + return 0; + + if (!client) client = server.available(); + + if (client.connected()) { + if (!deviceConnected) { + Serial.println("Got connexion"); + deviceConnected = true; + } + } else { + if (deviceConnected) { + deviceConnected = false; + Serial.println("Disconnected"); + } + } + + if (deviceConnected) { + if (send_queue_len > 0) { // first, check send queue + + _last_write = millis(); + int len = send_queue[0].len; + + uint8_t pkt[3+len]; // use same header as serial interface so client can delimit frames + pkt[0] = '>'; + pkt[1] = (len & 0xFF); // LSB + pkt[2] = (len >> 8); // MSB + memcpy(&pkt[3], send_queue[0].buf, send_queue[0].len); + client.write(pkt, 3 + len); + send_queue_len--; + for (int i = 0; i < send_queue_len; i++) { // delete top item from queue + send_queue[i] = send_queue[i + 1]; + } + } else { + int len = client.available(); + if (len > 0) { + uint8_t buf[MAX_FRAME_SIZE + 4]; + client.readBytes(buf, len); + memcpy(dest, buf+3, len-3); // remove header (don't even check ... problems are on the other dir) + return len-3; + } + } + } + + return 0; +} + +bool SerialWifiInterface::isConnected() const { + return deviceConnected; //pServer != NULL && pServer->getConnectedCount() > 0; +} \ No newline at end of file diff --git a/src/helpers/esp32/SerialWifiInterface.h b/src/helpers/esp32/SerialWifiInterface.h new file mode 100644 index 00000000..2e7e638f --- /dev/null +++ b/src/helpers/esp32/SerialWifiInterface.h @@ -0,0 +1,51 @@ +#pragma once + +#include "../BaseSerialInterface.h" +#include + +class SerialWifiInterface : public BaseSerialInterface { + bool deviceConnected; + bool _isEnabled; + uint32_t _pin_code; + unsigned long _last_write; + unsigned long adv_restart_time; + + WiFiServer server; + WiFiClient client; + + struct Frame { + uint8_t len; + uint8_t buf[MAX_FRAME_SIZE]; + }; + + #define FRAME_QUEUE_SIZE 4 + int recv_queue_len; + Frame recv_queue[FRAME_QUEUE_SIZE]; + int send_queue_len; + Frame send_queue[FRAME_QUEUE_SIZE]; + + void clearBuffers() { recv_queue_len = 0; send_queue_len = 0; } + +protected: + +public: + SerialWifiInterface() : server(WiFiServer()), client(WiFiClient()) { + deviceConnected = false; + _isEnabled = false; + _last_write = 0; + send_queue_len = recv_queue_len = 0; + } + + void begin(int port); + + // BaseSerialInterface methods + void enable() override; + void disable() override; + bool isEnabled() const override { return _isEnabled; } + + bool isConnected() const override; + bool isWriteBusy() const override; + + size_t writeFrame(const uint8_t src[], size_t len) override; + size_t checkRecvFrame(uint8_t dest[]) override; +};