Merge pull request #3357 from skandragon/feat/picow-wifi-ble
Add WiFi to RPI PicoW (and perhaps others)
This commit is contained in:
34 files changed
+612
-59
No files matched your search
@@ -20,10 +20,12 @@ for item in menv.get("CPPDEFINES", []):
|
||||
src_filter.append("+<helpers/stm32/*>")
|
||||
elif item == "ESP32":
|
||||
src_filter.append("+<helpers/esp32/*>")
|
||||
src_filter.append("+<helpers/wifi/*>")
|
||||
elif item == "NRF52_PLATFORM":
|
||||
src_filter.append("+<helpers/nrf52/*>")
|
||||
elif item == "RP2040_PLATFORM":
|
||||
src_filter.append("+<helpers/rp2040/*>")
|
||||
src_filter.append("+<helpers/wifi/*>")
|
||||
|
||||
# DISPLAY HANDLING
|
||||
elif isinstance(item, tuple) and item[0] == "DISPLAY_CLASS":
|
||||
|
||||
@@ -1,6 +1,9 @@
|
||||
#include "MyMesh.h"
|
||||
|
||||
#include <Arduino.h> // needed for PlatformIO
|
||||
#ifdef ENABLE_WIFI_INTERFACE
|
||||
#include <WiFi.h>
|
||||
#endif
|
||||
#include <Mesh.h>
|
||||
|
||||
#define CMD_APP_START 1
|
||||
@@ -932,6 +935,7 @@ MyMesh::MyMesh(mesh::Radio &radio, mesh::RNG &rng, mesh::RTCClock &rtc, SimpleMe
|
||||
_serial(NULL), telemetry(MAX_PACKET_PAYLOAD - 4), _store(&store), _ui(ui), _iter(0) {
|
||||
_iter_started = false;
|
||||
_cli_rescue = false;
|
||||
cli_command[0] = 0;
|
||||
offline_queue_len = 0;
|
||||
app_target_ver = 0;
|
||||
clearPendingReqs();
|
||||
@@ -2160,6 +2164,54 @@ bool MyMesh::handleCommand(const char* command, uint32_t sender_timestamp, char*
|
||||
return true;
|
||||
}
|
||||
|
||||
#ifdef ENABLE_WIFI_INTERFACE
|
||||
if (memcmp(command, "set wifi.ssid ", 14) == 0) {
|
||||
StrHelper::strncpy(_prefs.wifi_ssid, &command[14], sizeof(_prefs.wifi_ssid));
|
||||
savePrefs();
|
||||
sprintf(reply, "> wifi.ssid is now %s (set wifi.pwd too, then reboot)", _prefs.wifi_ssid);
|
||||
return true;
|
||||
}
|
||||
if (memcmp(command, "set wifi.pwd ", 13) == 0) {
|
||||
StrHelper::strncpy(_prefs.wifi_pwd, &command[13], sizeof(_prefs.wifi_pwd));
|
||||
savePrefs();
|
||||
strcpy(reply, "> wifi.pwd updated (reboot to apply)");
|
||||
return true;
|
||||
}
|
||||
if (strcmp(command, "set wifi.clear") == 0) {
|
||||
_prefs.wifi_ssid[0] = 0;
|
||||
_prefs.wifi_pwd[0] = 0;
|
||||
savePrefs();
|
||||
strcpy(reply, "> wifi config cleared (reboot to apply)");
|
||||
return true;
|
||||
}
|
||||
if (strcmp(command, "get wifi.ssid") == 0) { // no 'get wifi.pwd', by design
|
||||
sprintf(reply, "> %s", _prefs.getWifiSSID()[0] ? _prefs.getWifiSSID() : "(not set)");
|
||||
return true;
|
||||
}
|
||||
if (memcmp(command, "set wifi.enabled ", 17) == 0) {
|
||||
_prefs.wifi_enabled = atoi(&command[17]) ? 1 : 0;
|
||||
savePrefs();
|
||||
sprintf(reply, "> wifi.enabled is now %d (reboot to apply)", _prefs.wifi_enabled);
|
||||
return true;
|
||||
}
|
||||
if (strcmp(command, "get wifi.enabled") == 0) {
|
||||
sprintf(reply, "> %d", _prefs.wifi_enabled);
|
||||
return true;
|
||||
}
|
||||
if (strcmp(command, "get wifi.status") == 0) {
|
||||
strcpy(reply, WiFi.status() == WL_CONNECTED ? "> connected" : "> disconnected");
|
||||
return true;
|
||||
}
|
||||
if (strcmp(command, "get wifi.ip") == 0) {
|
||||
if (WiFi.status() == WL_CONNECTED) {
|
||||
sprintf(reply, "> %s", WiFi.localIP().toString().c_str());
|
||||
} else {
|
||||
strcpy(reply, "> (not connected)");
|
||||
}
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (strcmp(command, "board") == 0) {
|
||||
strcpy(reply, board.getManufacturerName());
|
||||
return true;
|
||||
@@ -2390,6 +2442,11 @@ void MyMesh::loop() {
|
||||
checkCLIRescueCmd();
|
||||
} else {
|
||||
checkSerialInterface();
|
||||
#if defined(ENABLE_WIFI_INTERFACE) && defined(RP2040_PLATFORM) && !defined(ENABLE_USB_INTERFACE)
|
||||
// RP2040 WiFi builds are headless and have no way into the rescue CLI (that needs a
|
||||
// display + long-press), so serve config commands on the otherwise unused USB serial
|
||||
checkCLIRescueCmd();
|
||||
#endif
|
||||
}
|
||||
|
||||
// is there are pending dirty contacts write needed?
|
||||
|
||||
@@ -48,6 +48,16 @@ public:
|
||||
char default_scope_name[31];
|
||||
uint8_t default_scope_key[16];
|
||||
int8_t tz_offset = 0;
|
||||
#ifdef ENABLE_WIFI_INTERFACE
|
||||
#ifndef WIFI_SSID
|
||||
#define WIFI_SSID ""
|
||||
#endif
|
||||
char wifi_ssid[33] = {0}; // if empty, the compile-time WIFI_SSID is used
|
||||
char wifi_pwd[64] = {0};
|
||||
uint8_t wifi_enabled = 1; // enabled by default to allow wifi only builds to work. wifi won't be started if ssid is empty
|
||||
// use ssid from prefs, or fallback to ssid from build flags
|
||||
const char* getWifiSSID() const { return wifi_ssid[0] ? wifi_ssid : WIFI_SSID; }
|
||||
#endif
|
||||
|
||||
private:
|
||||
class RadioPrefs : public CommonRadioPrefs {
|
||||
@@ -164,6 +174,21 @@ private:
|
||||
|
||||
DynamicConfigSerializer custom;
|
||||
|
||||
#ifdef ENABLE_WIFI_INTERFACE
|
||||
class WiFiPrefs : public ConfigSerializer {
|
||||
NodePrefs* _parent;
|
||||
protected:
|
||||
void structure() override {
|
||||
def("ssid", _parent->wifi_ssid, sizeof(_parent->wifi_ssid));
|
||||
def("pwd", _parent->wifi_pwd, sizeof(_parent->wifi_pwd));
|
||||
def("enabled", _parent->wifi_enabled);
|
||||
}
|
||||
public:
|
||||
WiFiPrefs(NodePrefs* parent) : _parent(parent) { }
|
||||
};
|
||||
WiFiPrefs wifi;
|
||||
#endif
|
||||
|
||||
protected:
|
||||
void structure() override {
|
||||
def("name", node_name, sizeof(node_name));
|
||||
@@ -176,9 +201,16 @@ protected:
|
||||
def("repeat", repeat);
|
||||
def("comp", companion);
|
||||
def("custom", custom);
|
||||
#ifdef ENABLE_WIFI_INTERFACE
|
||||
def("wifi", wifi);
|
||||
#endif
|
||||
}
|
||||
public:
|
||||
NodePrefs() : radio(this), gps(this), companion(this), custom(&radio) {
|
||||
NodePrefs() : radio(this), gps(this), companion(this), custom(&radio)
|
||||
#ifdef ENABLE_WIFI_INTERFACE
|
||||
, wifi(this)
|
||||
#endif
|
||||
{
|
||||
node_name[0] = 0;
|
||||
default_scope_name[0] = 0;
|
||||
memset(default_scope_key, 0, sizeof(default_scope_key));
|
||||
|
||||
@@ -26,19 +26,38 @@ MultiSerialInterface interface_manager;
|
||||
// include nrf52 bluetooth interface
|
||||
#include <helpers/nrf52/SerialBLEInterface.h>
|
||||
SerialBLEInterface bluetooth_interface;
|
||||
#elif defined(RP2040_PLATFORM)
|
||||
// include rp2040 (Pico W / CYW43) bluetooth interface
|
||||
#include <helpers/rp2040/SerialBLEInterface.h>
|
||||
SerialBLEInterface bluetooth_interface;
|
||||
#else
|
||||
#error "SerialBLEInterface is not defined for this platform"
|
||||
#endif
|
||||
#endif
|
||||
|
||||
// include wifi interface
|
||||
#ifdef WIFI_SSID
|
||||
#ifdef ENABLE_WIFI_INTERFACE
|
||||
#ifndef WIFI_SSID
|
||||
#define WIFI_SSID ""
|
||||
#endif
|
||||
#ifndef WIFI_PWD
|
||||
#define WIFI_PWD ""
|
||||
#endif
|
||||
#ifndef TCP_PORT
|
||||
#define TCP_PORT 5000
|
||||
#endif
|
||||
#ifdef ESP32
|
||||
// include esp32 wifi interface
|
||||
#include <helpers/esp32/SerialWifiInterface.h>
|
||||
#ifndef WIFI_RETRY_INTERVAL
|
||||
#if defined(RP2040_PLATFORM)
|
||||
#define WIFI_RETRY_INTERVAL 30000 // each attempt blocks loop(), so retry less often
|
||||
#else
|
||||
#define WIFI_RETRY_INTERVAL 10000 // millis between reconnect attempts
|
||||
#endif
|
||||
#endif
|
||||
#ifndef WIFI_RETRY_TIMEOUT
|
||||
#define WIFI_RETRY_TIMEOUT 5000 // RP2040: cap on how long one join may block loop()
|
||||
#endif
|
||||
#if defined(ESP32) || defined(RP2040_PLATFORM)
|
||||
#include <helpers/wifi/SerialWifiInterface.h>
|
||||
SerialWifiInterface wifi_interface;
|
||||
#else
|
||||
#error "SerialWifiInterface is not defined for this platform"
|
||||
@@ -108,9 +127,13 @@ void halt() {
|
||||
}
|
||||
|
||||
/* WIFI RECONNECT TRACKERS */
|
||||
#if defined(ESP32) && defined(WIFI_SSID)
|
||||
#ifdef ENABLE_WIFI_INTERFACE
|
||||
bool wifi_needs_reconnect = false;
|
||||
unsigned long last_wifi_reconnect_attempt = 0;
|
||||
char wifi_ssid[33] = WIFI_SSID; // replaced by stored prefs at boot, if set
|
||||
char wifi_pwd[64] = WIFI_PWD;
|
||||
bool wifi_was_connected = false;
|
||||
bool wifi_enabled = false; // set at boot from prefs; false also when the effective SSID is blank
|
||||
#endif
|
||||
|
||||
void setup() {
|
||||
@@ -191,23 +214,46 @@ void setup() {
|
||||
#endif
|
||||
|
||||
// add wifi interface
|
||||
#ifdef WIFI_SSID
|
||||
board.setInhibitSleep(true); // prevent sleep when WiFi is active
|
||||
WiFi.setAutoReconnect(true);
|
||||
#ifdef ENABLE_WIFI_INTERFACE
|
||||
// use wifi ssid and password from prefs if ssid is not empty, otherwise use the build flag defaults
|
||||
if (the_mesh.getNodePrefs()->wifi_ssid[0]) {
|
||||
strcpy(wifi_ssid, the_mesh.getNodePrefs()->wifi_ssid);
|
||||
strcpy(wifi_pwd, the_mesh.getNodePrefs()->wifi_pwd);
|
||||
}
|
||||
// only start wifi if enabled and ssid is not empty
|
||||
wifi_enabled = the_mesh.getNodePrefs()->wifi_enabled;
|
||||
if (wifi_enabled && wifi_ssid[0]) {
|
||||
#if defined(ESP32)
|
||||
board.setInhibitSleep(true); // prevent sleep when WiFi is active
|
||||
WiFi.setAutoReconnect(true);
|
||||
|
||||
WiFi.onEvent([](WiFiEvent_t event, WiFiEventInfo_t info){
|
||||
if (event == ARDUINO_EVENT_WIFI_STA_DISCONNECTED) {
|
||||
WIFI_DEBUG_PRINTLN("WiFi disconnected. Flagging for reconnect...");
|
||||
wifi_needs_reconnect = true;
|
||||
} else if (event == ARDUINO_EVENT_WIFI_STA_GOT_IP) {
|
||||
WIFI_DEBUG_PRINTLN("WiFi connected successfully!");
|
||||
wifi_needs_reconnect = false;
|
||||
}
|
||||
});
|
||||
WiFi.onEvent([](WiFiEvent_t event, WiFiEventInfo_t info){
|
||||
if (event == ARDUINO_EVENT_WIFI_STA_DISCONNECTED) {
|
||||
WIFI_DEBUG_PRINTLN("WiFi disconnected. Flagging for reconnect...");
|
||||
wifi_needs_reconnect = true;
|
||||
} else if (event == ARDUINO_EVENT_WIFI_STA_GOT_IP) {
|
||||
WIFI_DEBUG_PRINTLN("WiFi connected successfully!");
|
||||
wifi_needs_reconnect = false;
|
||||
}
|
||||
});
|
||||
#endif
|
||||
|
||||
WiFi.begin(WIFI_SSID, WIFI_PWD);
|
||||
wifi_interface.begin(TCP_PORT);
|
||||
interface_manager.addInterface(InterfaceType::WiFi, &wifi_interface);
|
||||
WIFI_DEBUG_PRINTLN("connecting to %s", wifi_ssid);
|
||||
|
||||
#if defined(RP2040_PLATFORM)
|
||||
// the join itself blocks inside the core (CYW43::begin busy-waits for the
|
||||
// association), so every attempt stalls the mesh loop. beginNoBlock() only skips the
|
||||
// extra DHCP wait. Give the first connect a full window, then bound the retries below.
|
||||
WiFi.beginNoBlock(wifi_ssid, wifi_pwd);
|
||||
last_wifi_reconnect_attempt = millis(); // let DHCP finish before the poll can retry
|
||||
#else
|
||||
WiFi.begin(wifi_ssid, wifi_pwd);
|
||||
#endif
|
||||
wifi_interface.begin(TCP_PORT);
|
||||
interface_manager.addInterface(InterfaceType::WiFi, &wifi_interface);
|
||||
} else {
|
||||
WIFI_DEBUG_PRINTLN("wifi disabled");
|
||||
}
|
||||
#endif
|
||||
|
||||
// add usb interface
|
||||
@@ -262,13 +308,34 @@ void loop() {
|
||||
#endif
|
||||
}
|
||||
|
||||
#if defined(ESP32) && defined(WIFI_SSID)
|
||||
// Safely attempt to reconnect every 10 seconds if flagged
|
||||
if (wifi_needs_reconnect && (millis() - last_wifi_reconnect_attempt > 10000)) {
|
||||
WIFI_DEBUG_PRINTLN("Attempting manual WiFi reconnect...");
|
||||
WiFi.disconnect();
|
||||
WiFi.reconnect();
|
||||
last_wifi_reconnect_attempt = millis();
|
||||
#ifdef ENABLE_WIFI_INTERFACE
|
||||
if (wifi_enabled) {
|
||||
// RP2040 has no WiFi event callbacks, so poll the link state instead
|
||||
#if defined(RP2040_PLATFORM)
|
||||
wifi_needs_reconnect = (WiFi.status() != WL_CONNECTED);
|
||||
if (wifi_was_connected == wifi_needs_reconnect) { // link state changed
|
||||
wifi_was_connected = !wifi_needs_reconnect;
|
||||
if (wifi_was_connected) {
|
||||
WIFI_DEBUG_PRINTLN("connected, listening on %s:%d", WiFi.localIP().toString().c_str(), TCP_PORT);
|
||||
} else {
|
||||
WIFI_DEBUG_PRINTLN("link lost");
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
// Safely attempt to reconnect if flagged. On RP2040 each attempt blocks the mesh loop
|
||||
// for up to WIFI_RETRY_TIMEOUT, so retry less often and cap how long a join may stall.
|
||||
if (wifi_needs_reconnect && (millis() - last_wifi_reconnect_attempt > WIFI_RETRY_INTERVAL)) {
|
||||
WIFI_DEBUG_PRINTLN("Attempting manual WiFi reconnect to %s (status %d)...", wifi_ssid, WiFi.status());
|
||||
#if defined(RP2040_PLATFORM)
|
||||
WiFi.setTimeout(WIFI_RETRY_TIMEOUT);
|
||||
WiFi.beginNoBlock(wifi_ssid, wifi_pwd); // no reconnect() on this platform
|
||||
#else
|
||||
WiFi.disconnect();
|
||||
WiFi.reconnect();
|
||||
#endif
|
||||
last_wifi_reconnect_attempt = millis();
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
@@ -3,7 +3,7 @@
|
||||
#include "../MyMesh.h"
|
||||
#include "target.h"
|
||||
#include <time.h>
|
||||
#ifdef WIFI_SSID
|
||||
#ifdef ENABLE_WIFI_INTERFACE
|
||||
#include <WiFi.h>
|
||||
#endif
|
||||
|
||||
@@ -260,7 +260,7 @@ public:
|
||||
sprintf(tmp, "%02d/%02d/%d", dt.day(), dt.month(), dt.year());
|
||||
display.drawTextCentered(display.width() / 2, 80, tmp);
|
||||
#endif
|
||||
#ifdef WIFI_SSID
|
||||
#ifdef ENABLE_WIFI_INTERFACE
|
||||
IPAddress ip = WiFi.localIP();
|
||||
snprintf(tmp, sizeof(tmp), "IP: %d.%d.%d.%d", ip[0], ip[1], ip[2], ip[3]);
|
||||
display.setTextSize(1);
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
#include "target.h"
|
||||
#include "u8g2_icons.h"
|
||||
|
||||
#ifdef WIFI_SSID
|
||||
#ifdef ENABLE_WIFI_INTERFACE
|
||||
#include <WiFi.h>
|
||||
#endif
|
||||
|
||||
@@ -173,7 +173,7 @@ public:
|
||||
display.setCursor(0, 19);
|
||||
display.print(tmp);
|
||||
|
||||
#ifdef WIFI_SSID
|
||||
#ifdef ENABLE_WIFI_INTERFACE
|
||||
IPAddress ip = WiFi.localIP();
|
||||
snprintf(tmp, sizeof(tmp), "IP: %d.%d.%d.%d", ip[0], ip[1], ip[2], ip[3]);
|
||||
display.setTextSize(1);
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
#include "ConfigSerializer.h"
|
||||
#include <stdlib.h> // atoi/atol/atof (Arduino.h pulls this in on-device, native builds do not)
|
||||
|
||||
bool ConfigSerializer::saveSerial(Stream& s) {
|
||||
Context context(&s, OP::WRITE);
|
||||
@@ -62,6 +63,7 @@ int ConfigSerializer::Context::readNext() {
|
||||
case EXPECT_COMMA_OR_KEY:
|
||||
if (c == ',') { rd_mode = EXPECT_KEY; return TOK_WHITESPACE; }
|
||||
case EXPECT_KEY:
|
||||
if (rd_len == 0 && c == '}') { rd_mode = EXPECT_COMMA_OR_KEY_OR_CLOSE; return TOK_END_OBJ; } // empty object, eg. 'custom:{}'
|
||||
if (rd_len > 0 && c == ':') { rd_buf[rd_len] = 0; rd_len = 0; rd_mode = EXPECT_VAL_OR_OBJ; return TOK_KEY; }
|
||||
if (rd_len == 0 && is_whitespace(c)) return TOK_WHITESPACE;
|
||||
if (rd_len < CONFIG_MAX_KEYLEN-1 && is_key_char(c)) { rd_buf[rd_len++] = c; return TOK_WHITESPACE; }
|
||||
|
||||
@@ -0,0 +1,201 @@
|
||||
// only built when the env enables the core BLE stack (build_as_lib.py globs this dir)
|
||||
#ifdef PIO_FRAMEWORK_ARDUINO_ENABLE_BLUETOOTH
|
||||
#include "SerialBLEInterface.h"
|
||||
#include <BluetoothLock.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
// Nordic UART 6E4000xx-B5A3-F393-E0A9-E50E24DCCA9E, as raw bytes: the core lib's string
|
||||
// parser uses sscanf("%llx"), which newlib-nano on the RP2040 doesn't support (yields all zeros)
|
||||
#define NUS_UUID(n) { 0x6E, 0x40, 0x00, n, 0xB5, 0xA3, 0xF3, 0x93, 0xE0, 0xA9, 0xE5, 0x0E, 0x24, 0xDC, 0xCA, 0x9E }
|
||||
static const uint8_t SERVICE_UUID[16] = NUS_UUID(0x01);
|
||||
static const uint8_t CHARACTERISTIC_UUID_RX[16] = NUS_UUID(0x02);
|
||||
static const uint8_t CHARACTERISTIC_UUID_TX[16] = NUS_UUID(0x03);
|
||||
|
||||
// The BLE core lib's own setValue()/notify path reallocs the value buffer on every call,
|
||||
// so a second frame queued before the radio drained the first would corrupt it. We keep our
|
||||
// own frame queue and drive att_server_notify() from the can-send-now callback instead.
|
||||
|
||||
SerialBLEInterface::SerialBLEInterface()
|
||||
: BLEService(BLEUUID(SERVICE_UUID)),
|
||||
_rx(BLEUUID(CHARACTERISTIC_UUID_RX), BLEWrite, nullptr, ATT_SECURITY_AUTHENTICATED, ATT_SECURITY_AUTHENTICATED),
|
||||
_tx(BLEUUID(CHARACTERISTIC_UUID_TX), BLERead | BLENotify, nullptr, ATT_SECURITY_AUTHENTICATED, ATT_SECURITY_AUTHENTICATED)
|
||||
{
|
||||
_isEnabled = false;
|
||||
_tx_pending = false;
|
||||
send_queue_len = 0;
|
||||
recv_queue_len = 0;
|
||||
memset(&_can_send, 0, sizeof(_can_send));
|
||||
_rx.setCallbacks(this);
|
||||
addCharacteristic(&_rx);
|
||||
addCharacteristic(&_tx);
|
||||
}
|
||||
|
||||
void SerialBLEInterface::begin(const char* prefix, char* name, uint32_t pin_code) {
|
||||
// JustWorks here only makes the server request pairing on connect; caps are overridden below
|
||||
BLE.setSecurity(BLESecurityJustWorks);
|
||||
// adv data carries the 128-bit service UUID, leaving room for only 8 name chars;
|
||||
// the full name goes in the scan response
|
||||
BLE.begin(prefix);
|
||||
|
||||
if (strcmp(name, "@@MAC") == 0) {
|
||||
bd_addr_t a;
|
||||
gap_local_bd_addr(a);
|
||||
sprintf(name, "%02X%02X%02X%02X%02X%02X", a[0], a[1], a[2], a[3], a[4], a[5]); // modify (IN-OUT param)
|
||||
}
|
||||
char dev_name[32+16];
|
||||
snprintf(dev_name, sizeof(dev_name), "%s%s", prefix, name);
|
||||
|
||||
BLE.server()->setName(dev_name); // GAP device name characteristic
|
||||
BLE.server()->addService(this);
|
||||
BLE.server()->setCallbacks(this);
|
||||
|
||||
// static passkey pairing with MITM protection, matching the esp32/nrf52 interfaces
|
||||
sm_set_io_capabilities(IO_CAPABILITY_DISPLAY_ONLY);
|
||||
sm_set_authentication_requirements(SM_AUTHREQ_MITM_PROTECTION | SM_AUTHREQ_BONDING);
|
||||
sm_use_fixed_passkey_in_display_role(pin_code);
|
||||
|
||||
size_t n = strlen(dev_name);
|
||||
if (n > sizeof(_scan_rsp) - 2) n = sizeof(_scan_rsp) - 2;
|
||||
_scan_rsp[0] = n + 1;
|
||||
_scan_rsp[1] = BLUETOOTH_DATA_TYPE_COMPLETE_LOCAL_NAME;
|
||||
memcpy(&_scan_rsp[2], dev_name, n);
|
||||
gap_scan_response_set_data(n + 2, _scan_rsp);
|
||||
|
||||
BLE_DEBUG_PRINTLN("begin: name=%s", dev_name);
|
||||
}
|
||||
|
||||
void SerialBLEInterface::clearBuffers() {
|
||||
send_queue_len = 0;
|
||||
recv_queue_len = 0;
|
||||
_tx_pending = false; // a stale registration just fires into an empty queue; BTstack ignores double-adds
|
||||
}
|
||||
|
||||
void SerialBLEInterface::onConnect(BLEServer* s) {
|
||||
BLE_DEBUG_PRINTLN("connected handle=0x%04X", _tx.conHandle());
|
||||
clearBuffers();
|
||||
}
|
||||
|
||||
void SerialBLEInterface::onDisconnect(BLEServer* s) {
|
||||
BLE_DEBUG_PRINTLN("disconnected");
|
||||
clearBuffers(); // BTstack re-enables advertising on its own
|
||||
}
|
||||
|
||||
void SerialBLEInterface::onWrite(BLECharacteristic* c) {
|
||||
if (c != &_rx) return;
|
||||
size_t len = _rx.valueLen();
|
||||
if (len == 0 || len > MAX_FRAME_SIZE) {
|
||||
BLE_DEBUG_PRINTLN("onWrite: bad frame len=%u", (unsigned)len);
|
||||
return;
|
||||
}
|
||||
if (recv_queue_len >= FRAME_QUEUE_SIZE) {
|
||||
BLE_DEBUG_PRINTLN("onWrite: recv queue full, dropping frame");
|
||||
return;
|
||||
}
|
||||
recv_queue[recv_queue_len].len = len;
|
||||
memcpy(recv_queue[recv_queue_len].buf, _rx.valueData(), len);
|
||||
recv_queue_len++;
|
||||
}
|
||||
|
||||
// caller holds the BT lock (or is in the BT context)
|
||||
void SerialBLEInterface::kickSend() {
|
||||
if (_tx_pending) return;
|
||||
_tx_pending = true;
|
||||
_can_send.callback = onCanSend;
|
||||
_can_send.context = this;
|
||||
if (att_server_register_can_send_now_callback(&_can_send, _tx.conHandle()) != 0) {
|
||||
_tx_pending = false;
|
||||
}
|
||||
}
|
||||
|
||||
// BT context: one notification per can-send-now, re-arm while frames remain
|
||||
void SerialBLEInterface::sendNext() {
|
||||
_tx_pending = false;
|
||||
if (send_queue_len == 0) return;
|
||||
if (!isConnected()) {
|
||||
BLE_DEBUG_PRINTLN("sendNext: not connected, clearing send queue");
|
||||
send_queue_len = 0;
|
||||
return;
|
||||
}
|
||||
uint16_t h = _tx.conHandle();
|
||||
Frame& f = send_queue[0];
|
||||
uint16_t mtu = att_server_get_mtu(h);
|
||||
if (f.len + 3 > mtu) {
|
||||
// att would silently truncate; drop instead (client must negotiate MTU >= MAX_FRAME_SIZE+3)
|
||||
BLE_DEBUG_PRINTLN("sendNext: frame len=%u exceeds mtu=%u, dropping", f.len, mtu);
|
||||
} else {
|
||||
uint8_t err = att_server_notify(h, _tx.valueHandle(), f.buf, f.len);
|
||||
if (err == BTSTACK_ACL_BUFFERS_FULL) {
|
||||
kickSend();
|
||||
return;
|
||||
}
|
||||
if (err) {
|
||||
BLE_DEBUG_PRINTLN("sendNext: notify failed err=%u, dropping", err);
|
||||
} else {
|
||||
BLE_DEBUG_PRINTLN("writeBytes: sz=%u, hdr=%u", f.len, f.buf[0]);
|
||||
}
|
||||
}
|
||||
send_queue_len--;
|
||||
memmove(&send_queue[0], &send_queue[1], send_queue_len * sizeof(Frame));
|
||||
if (send_queue_len > 0) kickSend();
|
||||
}
|
||||
|
||||
void SerialBLEInterface::enable() {
|
||||
if (_isEnabled) return;
|
||||
_isEnabled = true;
|
||||
clearBuffers();
|
||||
BLE.startAdvertising(true);
|
||||
}
|
||||
|
||||
void SerialBLEInterface::disconnect() {
|
||||
uint16_t h = _tx.conHandle();
|
||||
if (h) gap_disconnect(h);
|
||||
}
|
||||
|
||||
void SerialBLEInterface::disable() {
|
||||
_isEnabled = false;
|
||||
BLE_DEBUG_PRINTLN("disable");
|
||||
disconnect();
|
||||
BLE.stopAdvertising();
|
||||
}
|
||||
|
||||
bool SerialBLEInterface::isConnected() const {
|
||||
// notifications can only be enabled once the link is authenticated (CCCD inherits the perms)
|
||||
return _isEnabled && _tx.conHandle() != 0 && _tx.notifyEnabled();
|
||||
}
|
||||
|
||||
bool SerialBLEInterface::isWriteBusy() const {
|
||||
return send_queue_len >= (FRAME_QUEUE_SIZE * 2 / 3);
|
||||
}
|
||||
|
||||
size_t SerialBLEInterface::writeFrame(const uint8_t src[], size_t len) {
|
||||
if (len == 0 || len > MAX_FRAME_SIZE) {
|
||||
BLE_DEBUG_PRINTLN("writeFrame(), frame too big, len=%u", (unsigned)len);
|
||||
return 0;
|
||||
}
|
||||
if (!isConnected()) return 0;
|
||||
|
||||
BluetoothLock lock;
|
||||
if (send_queue_len >= FRAME_QUEUE_SIZE) {
|
||||
BLE_DEBUG_PRINTLN("writeFrame(), send_queue is full!");
|
||||
return 0;
|
||||
}
|
||||
send_queue[send_queue_len].len = len;
|
||||
memcpy(send_queue[send_queue_len].buf, src, len);
|
||||
send_queue_len++;
|
||||
kickSend();
|
||||
return len;
|
||||
}
|
||||
|
||||
size_t SerialBLEInterface::checkRecvFrame(uint8_t dest[]) {
|
||||
BluetoothLock lock;
|
||||
if (recv_queue_len == 0) return 0;
|
||||
|
||||
size_t len = recv_queue[0].len;
|
||||
memcpy(dest, recv_queue[0].buf, len);
|
||||
recv_queue_len--;
|
||||
memmove(&recv_queue[0], &recv_queue[1], recv_queue_len * sizeof(Frame));
|
||||
BLE_DEBUG_PRINTLN("readBytes: sz=%u, hdr=%u", (unsigned)len, dest[0]);
|
||||
return len;
|
||||
}
|
||||
#endif
|
||||
@@ -0,0 +1,75 @@
|
||||
#pragma once
|
||||
|
||||
#include "../BaseSerialInterface.h"
|
||||
#include <BLE.h>
|
||||
#include <btstack.h>
|
||||
|
||||
// Nordic UART service over the arduino-pico BLE library (BTstack on the CYW43).
|
||||
// Build with -D PIO_FRAMEWORK_ARDUINO_ENABLE_BLUETOOTH so the core links liblwip-bt.
|
||||
class SerialBLEInterface : public BaseSerialInterface, BLEService, BLEServerCallbacks, BLECharacteristicCallbacks {
|
||||
// subclass only to reach the protected connection/notify state
|
||||
struct Characteristic : public BLECharacteristic {
|
||||
using BLECharacteristic::BLECharacteristic;
|
||||
uint16_t valueHandle() const { return _valueHandle; }
|
||||
uint16_t conHandle() const { return con_handle; }
|
||||
bool notifyEnabled() const { return _notificationEnabled; }
|
||||
};
|
||||
|
||||
struct Frame {
|
||||
uint8_t len;
|
||||
uint8_t buf[MAX_FRAME_SIZE];
|
||||
};
|
||||
|
||||
#define FRAME_QUEUE_SIZE 8
|
||||
|
||||
Characteristic _rx;
|
||||
Characteristic _tx;
|
||||
bool _isEnabled;
|
||||
bool _tx_pending; // a can-send-now callback is registered
|
||||
btstack_context_callback_registration_t _can_send;
|
||||
uint8_t _scan_rsp[31]; // complete local name; BTstack keeps the pointer
|
||||
|
||||
uint8_t send_queue_len;
|
||||
Frame send_queue[FRAME_QUEUE_SIZE];
|
||||
uint8_t recv_queue_len;
|
||||
Frame recv_queue[FRAME_QUEUE_SIZE];
|
||||
|
||||
void clearBuffers();
|
||||
void kickSend();
|
||||
void sendNext();
|
||||
static void onCanSend(void* ctx) { ((SerialBLEInterface*)ctx)->sendNext(); }
|
||||
|
||||
// BLE library callbacks (run in the BT context)
|
||||
void onWrite(BLECharacteristic* c) override;
|
||||
void onConnect(BLEServer* s) override;
|
||||
void onDisconnect(BLEServer* s) override;
|
||||
|
||||
public:
|
||||
SerialBLEInterface();
|
||||
|
||||
/**
|
||||
* init the BLE interface.
|
||||
* @param prefix a prefix for the device name
|
||||
* @param name IN/OUT - a name for the device (combined with prefix). If "@@MAC", is modified and returned
|
||||
* @param pin_code the BLE security pin
|
||||
*/
|
||||
void begin(const char* prefix, char* name, uint32_t pin_code);
|
||||
|
||||
void disconnect();
|
||||
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;
|
||||
};
|
||||
|
||||
#if BLE_DEBUG_LOGGING && ARDUINO
|
||||
#include <Arduino.h>
|
||||
#define BLE_DEBUG_PRINT(F, ...) Serial.printf("BLE: " F, ##__VA_ARGS__)
|
||||
#define BLE_DEBUG_PRINTLN(F, ...) Serial.printf("BLE: " F "\n", ##__VA_ARGS__)
|
||||
#else
|
||||
#define BLE_DEBUG_PRINT(...) {}
|
||||
#define BLE_DEBUG_PRINTLN(...) {}
|
||||
#endif
|
||||
File renamed without changes.
File renamed without changes.
@@ -185,6 +185,47 @@ TEST(ConfigSerializer, LoadSerial_IgnoreUnknowns) {
|
||||
EXPECT_TRUE(match);
|
||||
}
|
||||
|
||||
class TestNested : public ConfigSerializer {
|
||||
class Inner : public ConfigSerializer {
|
||||
protected:
|
||||
void structure() override { } // no properties, so it writes as '{}'
|
||||
};
|
||||
Inner inner;
|
||||
protected:
|
||||
void structure() override {
|
||||
def("age", age);
|
||||
def("inner", inner);
|
||||
def("name", name, sizeof(name)); // comes *after* the empty sub-object
|
||||
}
|
||||
public:
|
||||
int32_t age;
|
||||
char name[16];
|
||||
};
|
||||
|
||||
TEST(ConfigSerializer, LoadSerial_EmptyObject) {
|
||||
MockInputStream s("{age:" TEST_INT_S ",inner:{},name:\"Scott\"}");
|
||||
TestNested data;
|
||||
data.name[0] = 0;
|
||||
|
||||
bool success = data.loadSerial(s);
|
||||
EXPECT_TRUE(success);
|
||||
|
||||
EXPECT_EQ(TEST_INT, data.age);
|
||||
bool match = strcmp("Scott", data.name) == 0;
|
||||
EXPECT_TRUE(match); // properties after an empty object must still load
|
||||
}
|
||||
|
||||
TEST(ConfigSerializer, LoadSerial_EmptyObjectWithWhitespace) {
|
||||
MockInputStream s("{age:" TEST_INT_S ",inner:{ },name:\"Scott\"}");
|
||||
TestNested data;
|
||||
data.name[0] = 0;
|
||||
|
||||
bool success = data.loadSerial(s);
|
||||
EXPECT_TRUE(success);
|
||||
bool match = strcmp("Scott", data.name) == 0;
|
||||
EXPECT_TRUE(match);
|
||||
}
|
||||
|
||||
TEST(DynamicConfigSerializer, GetSet_Basic) {
|
||||
DynamicConfigSerializer data;
|
||||
|
||||
|
||||
@@ -173,6 +173,7 @@ extends = Heltec_RC32
|
||||
build_flags =
|
||||
${Heltec_RC32.build_flags}
|
||||
-I examples/companion_radio/ui-new
|
||||
-D ENABLE_WIFI_INTERFACE
|
||||
-D DISPLAY_CLASS=NullDisplayDriver
|
||||
-D MAX_CONTACTS=350
|
||||
-D MAX_GROUP_CHANNELS=40
|
||||
@@ -185,6 +186,7 @@ build_src_filter = ${Heltec_RC32.build_src_filter}
|
||||
+<helpers/ui/buzzer.cpp>
|
||||
+<helpers/ui/NullDisplayDriver.cpp>
|
||||
+<helpers/esp32/*.cpp>
|
||||
+<helpers/wifi/*.cpp>
|
||||
+<../examples/companion_radio/*.cpp>
|
||||
+<../examples/companion_radio/ui-new/*.cpp>
|
||||
lib_deps =
|
||||
@@ -314,6 +316,7 @@ extends = Heltec_RC32_with_display
|
||||
build_flags =
|
||||
${Heltec_RC32_with_display.build_flags}
|
||||
-I examples/companion_radio/ui-new
|
||||
-D ENABLE_WIFI_INTERFACE
|
||||
-D UI_HAS_ROTARY_INPUT
|
||||
-D MAX_CONTACTS=350
|
||||
-D MAX_GROUP_CHANNELS=40
|
||||
@@ -324,6 +327,7 @@ build_flags =
|
||||
build_src_filter = ${Heltec_RC32_with_display.build_src_filter}
|
||||
+<helpers/ui/buzzer.cpp>
|
||||
+<helpers/esp32/*.cpp>
|
||||
+<helpers/wifi/*.cpp>
|
||||
+<../examples/companion_radio/*.cpp>
|
||||
+<../examples/companion_radio/ui-new/*.cpp>
|
||||
lib_deps =
|
||||
|
||||
@@ -182,6 +182,7 @@ extends = Heltec_tracker_v2
|
||||
build_flags =
|
||||
${Heltec_tracker_v2.build_flags}
|
||||
-I examples/companion_radio/ui-new
|
||||
-D ENABLE_WIFI_INTERFACE
|
||||
-D MAX_CONTACTS=350
|
||||
-D MAX_GROUP_CHANNELS=40
|
||||
-D DISPLAY_CLASS=ST7735Display
|
||||
@@ -195,6 +196,7 @@ build_src_filter = ${Heltec_tracker_v2.build_src_filter}
|
||||
+<helpers/ui/ST7735Display.cpp>
|
||||
+<helpers/ui/MomentaryButton.cpp>
|
||||
+<helpers/esp32/*.cpp>
|
||||
+<helpers/wifi/*.cpp>
|
||||
+<../examples/companion_radio/*.cpp>
|
||||
+<../examples/companion_radio/ui-new/*.cpp>
|
||||
lib_deps =
|
||||
|
||||
@@ -178,6 +178,7 @@ extends = Heltec_lora32_v2
|
||||
build_flags =
|
||||
${Heltec_lora32_v2.build_flags}
|
||||
-I examples/companion_radio/ui-new
|
||||
-D ENABLE_WIFI_INTERFACE
|
||||
-D DISPLAY_CLASS=SSD1306Display
|
||||
-D MAX_CONTACTS=160
|
||||
-D MAX_GROUP_CHANNELS=8
|
||||
@@ -189,6 +190,7 @@ build_flags =
|
||||
; -D MESH_DEBUG=1
|
||||
build_src_filter = ${Heltec_lora32_v2.build_src_filter}
|
||||
+<helpers/esp32/*.cpp>
|
||||
+<helpers/wifi/*.cpp>
|
||||
+<helpers/ui/SSD1306Display.cpp>
|
||||
+<helpers/ui/MomentaryButton.cpp>
|
||||
+<../examples/companion_radio/*.cpp>
|
||||
|
||||
@@ -185,6 +185,7 @@ extends = Heltec_lora32_v3
|
||||
build_flags =
|
||||
${Heltec_lora32_v3.build_flags}
|
||||
-I examples/companion_radio/ui-new
|
||||
-D ENABLE_WIFI_INTERFACE
|
||||
-D MAX_CONTACTS=350
|
||||
-D MAX_GROUP_CHANNELS=40
|
||||
-D DISPLAY_CLASS=SSD1306Display
|
||||
@@ -198,6 +199,7 @@ build_src_filter = ${Heltec_lora32_v3.build_src_filter}
|
||||
+<helpers/ui/SSD1306Display.cpp>
|
||||
+<helpers/ui/MomentaryButton.cpp>
|
||||
+<helpers/esp32/*.cpp>
|
||||
+<helpers/wifi/*.cpp>
|
||||
+<../examples/companion_radio/*.cpp>
|
||||
+<../examples/companion_radio/ui-new/*.cpp>
|
||||
lib_deps =
|
||||
@@ -340,6 +342,7 @@ lib_deps =
|
||||
extends = Heltec_lora32_v3
|
||||
build_flags =
|
||||
${Heltec_lora32_v3.build_flags}
|
||||
-D ENABLE_WIFI_INTERFACE
|
||||
-D MAX_CONTACTS=350
|
||||
-D MAX_GROUP_CHANNELS=40
|
||||
-D WIFI_DEBUG_LOGGING=1
|
||||
@@ -350,6 +353,7 @@ build_flags =
|
||||
; -D MESH_DEBUG=1
|
||||
build_src_filter = ${Heltec_lora32_v3.build_src_filter}
|
||||
+<helpers/esp32/*.cpp>
|
||||
+<helpers/wifi/*.cpp>
|
||||
+<../examples/companion_radio/*.cpp>
|
||||
lib_deps =
|
||||
${Heltec_lora32_v3.lib_deps}
|
||||
|
||||
@@ -228,6 +228,7 @@ extends = heltec_v4_oled
|
||||
build_flags =
|
||||
${heltec_v4_oled.build_flags}
|
||||
-I examples/companion_radio/ui-new
|
||||
-D ENABLE_WIFI_INTERFACE
|
||||
-D MAX_CONTACTS=350
|
||||
-D MAX_GROUP_CHANNELS=40
|
||||
-D OFFLINE_QUEUE_SIZE=256
|
||||
@@ -241,6 +242,7 @@ build_src_filter = ${heltec_v4_oled.build_src_filter}
|
||||
+<helpers/ui/SSD1306Display.cpp>
|
||||
+<helpers/ui/MomentaryButton.cpp>
|
||||
+<helpers/esp32/*.cpp>
|
||||
+<helpers/wifi/*.cpp>
|
||||
+<../examples/companion_radio/*.cpp>
|
||||
+<../examples/companion_radio/ui-new/*.cpp>
|
||||
lib_deps =
|
||||
@@ -393,6 +395,7 @@ extends = heltec_v4_tft
|
||||
build_flags =
|
||||
${heltec_v4_tft.build_flags}
|
||||
-I examples/companion_radio/ui-new
|
||||
-D ENABLE_WIFI_INTERFACE
|
||||
-D MAX_CONTACTS=350
|
||||
-D MAX_GROUP_CHANNELS=40
|
||||
-D OFFLINE_QUEUE_SIZE=256
|
||||
@@ -406,6 +409,7 @@ build_src_filter = ${heltec_v4_tft.build_src_filter}
|
||||
+<helpers/ui/ST7789LCDDisplay.cpp>
|
||||
+<helpers/ui/MomentaryButton.cpp>
|
||||
+<helpers/esp32/*.cpp>
|
||||
+<helpers/wifi/*.cpp>
|
||||
+<../examples/companion_radio/*.cpp>
|
||||
+<../examples/companion_radio/ui-new/*.cpp>
|
||||
lib_deps =
|
||||
|
||||
@@ -175,6 +175,7 @@ extends = heltec_v4_r8_oled
|
||||
build_flags =
|
||||
${heltec_v4_r8_oled.build_flags}
|
||||
-I examples/companion_radio/ui-new
|
||||
-D ENABLE_WIFI_INTERFACE
|
||||
-D MAX_CONTACTS=350
|
||||
-D MAX_GROUP_CHANNELS=40
|
||||
-D OFFLINE_QUEUE_SIZE=256
|
||||
@@ -186,6 +187,7 @@ build_src_filter = ${heltec_v4_r8_oled.build_src_filter}
|
||||
+<helpers/ui/SSD1306Display.cpp>
|
||||
+<helpers/ui/MomentaryButton.cpp>
|
||||
+<helpers/esp32/*.cpp>
|
||||
+<helpers/wifi/*.cpp>
|
||||
+<../examples/companion_radio/*.cpp>
|
||||
+<../examples/companion_radio/ui-new/*.cpp>
|
||||
lib_deps =
|
||||
@@ -300,6 +302,7 @@ extends = heltec_v4_r8_tft
|
||||
build_flags =
|
||||
${heltec_v4_r8_tft.build_flags}
|
||||
-I examples/companion_radio/ui-new
|
||||
-D ENABLE_WIFI_INTERFACE
|
||||
-D MAX_CONTACTS=350
|
||||
-D MAX_GROUP_CHANNELS=40
|
||||
-D OFFLINE_QUEUE_SIZE=256
|
||||
@@ -311,6 +314,7 @@ build_src_filter = ${heltec_v4_r8_tft.build_src_filter}
|
||||
+<helpers/ui/ST7789LCDDisplay.cpp>
|
||||
+<helpers/ui/MomentaryButton.cpp>
|
||||
+<helpers/esp32/*.cpp>
|
||||
+<helpers/wifi/*.cpp>
|
||||
+<../examples/companion_radio/*.cpp>
|
||||
+<../examples/companion_radio/ui-new/*.cpp>
|
||||
lib_deps =
|
||||
|
||||
@@ -153,6 +153,7 @@ extends = LilyGo_TBeam_1W
|
||||
build_flags =
|
||||
${LilyGo_TBeam_1W.build_flags}
|
||||
-I examples/companion_radio/ui-new
|
||||
-D ENABLE_WIFI_INTERFACE
|
||||
-D MAX_CONTACTS=350
|
||||
-D MAX_GROUP_CHANNELS=40
|
||||
-D OFFLINE_QUEUE_SIZE=256
|
||||
@@ -165,6 +166,7 @@ build_flags =
|
||||
; -D MESH_DEBUG=1
|
||||
build_src_filter = ${LilyGo_TBeam_1W.build_src_filter}
|
||||
+<helpers/esp32/*.cpp>
|
||||
+<helpers/wifi/*.cpp>
|
||||
+<../examples/companion_radio/*.cpp>
|
||||
+<../examples/companion_radio/ui-new/*.cpp>
|
||||
lib_deps =
|
||||
|
||||
@@ -148,6 +148,7 @@ extends = T_Beam_S3_Supreme_SX1262
|
||||
build_flags =
|
||||
${T_Beam_S3_Supreme_SX1262.build_flags}
|
||||
-I examples/companion_radio/ui-new
|
||||
-D ENABLE_WIFI_INTERFACE
|
||||
-D MAX_CONTACTS=350
|
||||
-D MAX_GROUP_CHANNELS=40
|
||||
-D OFFLINE_QUEUE_SIZE=256
|
||||
@@ -160,6 +161,7 @@ build_flags =
|
||||
; -D CORE_DEBUG_LEVEL=4
|
||||
build_src_filter = ${T_Beam_S3_Supreme_SX1262.build_src_filter}
|
||||
+<helpers/esp32/*.cpp>
|
||||
+<helpers/wifi/*.cpp>
|
||||
+<helpers/ui/MomentaryButton.cpp>
|
||||
+<../examples/companion_radio/*.cpp>
|
||||
+<../examples/companion_radio/ui-new/*.cpp>
|
||||
|
||||
@@ -132,6 +132,7 @@ extends = LilyGo_TLora_V2_1_1_6
|
||||
build_flags =
|
||||
${LilyGo_TLora_V2_1_1_6.build_flags}
|
||||
-I examples/companion_radio/ui-new
|
||||
-D ENABLE_WIFI_INTERFACE
|
||||
-D MAX_CONTACTS=160
|
||||
-D MAX_GROUP_CHANNELS=8
|
||||
-D WIFI_SSID='"ssid"'
|
||||
@@ -140,6 +141,7 @@ build_flags =
|
||||
-D OFFLINE_QUEUE_SIZE=128
|
||||
build_src_filter = ${LilyGo_TLora_V2_1_1_6.build_src_filter}
|
||||
+<helpers/esp32/*.cpp>
|
||||
+<helpers/wifi/*.cpp>
|
||||
+<helpers/ui/MomentaryButton.cpp>
|
||||
+<../examples/companion_radio/*.cpp>
|
||||
+<../examples/companion_radio/ui-new/*.cpp>
|
||||
|
||||
@@ -171,6 +171,7 @@ extends = meshnology_w12
|
||||
build_flags =
|
||||
${meshnology_w12.build_flags}
|
||||
-I examples/companion_radio/ui-new
|
||||
-D ENABLE_WIFI_INTERFACE
|
||||
-D MAX_CONTACTS=350
|
||||
-D MAX_GROUP_CHANNELS=40
|
||||
-D OFFLINE_QUEUE_SIZE=256
|
||||
@@ -184,6 +185,7 @@ build_src_filter = ${meshnology_w12.build_src_filter}
|
||||
+<helpers/ui/SSD1306Display.cpp>
|
||||
+<helpers/ui/MomentaryButton.cpp>
|
||||
+<helpers/esp32/*.cpp>
|
||||
+<helpers/wifi/*.cpp>
|
||||
+<../examples/companion_radio/*.cpp>
|
||||
+<../examples/companion_radio/ui-new/*.cpp>
|
||||
lib_deps =
|
||||
|
||||
@@ -143,6 +143,7 @@ extends = nibble_screen_connect_base
|
||||
build_flags =
|
||||
${nibble_screen_connect_base.build_flags}
|
||||
-I examples/companion_radio/ui-new
|
||||
-D ENABLE_WIFI_INTERFACE
|
||||
-D DISPLAY_CLASS=SSD1306Display
|
||||
-D MAX_CONTACTS=300
|
||||
-D MAX_GROUP_CHANNELS=8
|
||||
@@ -154,6 +155,7 @@ build_src_filter = ${nibble_screen_connect_base.build_src_filter}
|
||||
+<helpers/ui/SSD1306Display.cpp>
|
||||
+<helpers/ui/MomentaryButton.cpp>
|
||||
+<helpers/esp32/*.cpp>
|
||||
+<helpers/wifi/*.cpp>
|
||||
+<../examples/companion_radio/*.cpp>
|
||||
+<../examples/companion_radio/ui-new/*.cpp>
|
||||
lib_deps =
|
||||
|
||||
@@ -140,6 +140,7 @@ extends = nibble_zero_connect_base
|
||||
build_flags =
|
||||
${nibble_zero_connect_base.build_flags}
|
||||
-I examples/companion_radio/ui-new
|
||||
-D ENABLE_WIFI_INTERFACE
|
||||
-D DISPLAY_CLASS=SSD1306Display
|
||||
-D MAX_CONTACTS=300
|
||||
-D MAX_GROUP_CHANNELS=8
|
||||
@@ -150,6 +151,7 @@ build_src_filter = ${nibble_zero_connect_base.build_src_filter}
|
||||
+<helpers/ui/SSD1306Display.cpp>
|
||||
+<helpers/ui/MomentaryButton.cpp>
|
||||
+<helpers/esp32/*.cpp>
|
||||
+<helpers/wifi/*.cpp>
|
||||
+<../examples/companion_radio/*.cpp>
|
||||
+<../examples/companion_radio/ui-new/*.cpp>
|
||||
lib_deps =
|
||||
|
||||
@@ -172,6 +172,7 @@ extends = rak3112
|
||||
build_flags =
|
||||
${rak3112.build_flags}
|
||||
-I examples/companion_radio/ui-orig
|
||||
-D ENABLE_WIFI_INTERFACE
|
||||
-D MAX_CONTACTS=350
|
||||
-D MAX_GROUP_CHANNELS=40
|
||||
-D WIFI_DEBUG_LOGGING=1
|
||||
@@ -182,6 +183,7 @@ build_flags =
|
||||
; -D MESH_DEBUG=1
|
||||
build_src_filter = ${rak3112.build_src_filter}
|
||||
+<helpers/esp32/*.cpp>
|
||||
+<helpers/wifi/*.cpp>
|
||||
+<../examples/companion_radio/*.cpp>
|
||||
+<../examples/companion_radio/ui-orig/*.cpp>
|
||||
lib_deps =
|
||||
|
||||
@@ -67,34 +67,60 @@ lib_deps = ${rpi_picow.lib_deps}
|
||||
densaugeo/base64 @ ~1.4.0
|
||||
lib_ignore = BLE
|
||||
|
||||
; [env:PicoW_companion_radio_ble]
|
||||
; extends = rpi_picow
|
||||
; build_flags = ${rpi_picow.build_flags}
|
||||
; -D MAX_CONTACTS=100
|
||||
; -D MAX_GROUP_CHANNELS=8
|
||||
; -D BLE_PIN_CODE=123456
|
||||
; -D BLE_DEBUG_LOGGING=1
|
||||
; ; -D MESH_PACKET_LOGGING=1
|
||||
; ; -D MESH_DEBUG=1
|
||||
; build_src_filter = ${rpi_picow.build_src_filter}
|
||||
; +<../examples/companion_radio/*.cpp>
|
||||
; lib_deps = ${rpi_picow.lib_deps}
|
||||
; densaugeo/base64 @ ~1.4.0
|
||||
[env:PicoW_companion_radio_ble]
|
||||
extends = rpi_picow
|
||||
build_flags = ${rpi_picow.build_flags}
|
||||
-D MAX_CONTACTS=100
|
||||
-D MAX_GROUP_CHANNELS=8
|
||||
-D PIO_FRAMEWORK_ARDUINO_ENABLE_BLUETOOTH
|
||||
-D BLE_PIN_CODE=123456
|
||||
-D BLE_DEBUG_LOGGING=1
|
||||
; -D MESH_PACKET_LOGGING=1
|
||||
; -D MESH_DEBUG=1
|
||||
build_src_filter = ${rpi_picow.build_src_filter}
|
||||
+<helpers/rp2040/SerialBLEInterface.cpp>
|
||||
+<../examples/companion_radio/*.cpp>
|
||||
lib_deps = ${rpi_picow.lib_deps}
|
||||
densaugeo/base64 @ ~1.4.0
|
||||
|
||||
; [env:PicoW_companion_radio_wifi]
|
||||
; extends = rpi_picow
|
||||
; build_flags = ${rpi_picow.build_flags}
|
||||
; -D MAX_CONTACTS=100
|
||||
; -D MAX_GROUP_CHANNELS=8
|
||||
; -D WIFI_DEBUG_LOGGING=1
|
||||
; -D WIFI_SSID='"myssid"'
|
||||
; -D WIFI_PWD='"mypwd"'
|
||||
; ; -D MESH_PACKET_LOGGING=1
|
||||
; ; -D MESH_DEBUG=1
|
||||
; build_src_filter = ${rpi_picow.build_src_filter}
|
||||
; +<../examples/companion_radio/*.cpp>
|
||||
; lib_deps = ${rpi_picow.lib_deps}
|
||||
; densaugeo/base64 @ ~1.4.0
|
||||
; USB + WiFi + BLE together; the interface manager fans frames out to all of them
|
||||
[env:PicoW_companion_radio]
|
||||
extends = rpi_picow
|
||||
build_flags = ${rpi_picow.build_flags}
|
||||
-D MAX_CONTACTS=100
|
||||
-D MAX_GROUP_CHANNELS=8
|
||||
-D ENABLE_USB_INTERFACE
|
||||
-D ENABLE_WIFI_INTERFACE
|
||||
-D PIO_FRAMEWORK_ARDUINO_ENABLE_BLUETOOTH
|
||||
-D BLE_PIN_CODE=123456
|
||||
; NOTE: DO NOT ENABLE --> -D BLE_DEBUG_LOGGING=1 (shares Serial with the USB interface)
|
||||
; NOTE: DO NOT ENABLE --> -D WIFI_DEBUG_LOGGING=1
|
||||
; -D MESH_PACKET_LOGGING=1
|
||||
; -D MESH_DEBUG=1
|
||||
build_src_filter = ${rpi_picow.build_src_filter}
|
||||
+<helpers/rp2040/SerialBLEInterface.cpp>
|
||||
+<helpers/wifi/*.cpp>
|
||||
+<../examples/companion_radio/*.cpp>
|
||||
lib_deps = ${rpi_picow.lib_deps}
|
||||
densaugeo/base64 @ ~1.4.0
|
||||
|
||||
[env:PicoW_companion_radio_wifi]
|
||||
extends = rpi_picow
|
||||
build_flags = ${rpi_picow.build_flags}
|
||||
-D ENABLE_WIFI_INTERFACE
|
||||
-D MAX_CONTACTS=100
|
||||
-D MAX_GROUP_CHANNELS=8
|
||||
-D WIFI_DEBUG_LOGGING=1
|
||||
-D WIFI_SSID='""' ; no default network, configure with 'set wifi.ssid' / 'set wifi.pwd'
|
||||
-D WIFI_PWD='""'
|
||||
; -D MESH_PACKET_LOGGING=1
|
||||
; -D MESH_DEBUG=1
|
||||
build_src_filter = ${rpi_picow.build_src_filter}
|
||||
+<helpers/wifi/*.cpp>
|
||||
+<../examples/companion_radio/*.cpp>
|
||||
lib_deps = ${rpi_picow.lib_deps}
|
||||
densaugeo/base64 @ ~1.4.0
|
||||
lib_ignore = BLE
|
||||
|
||||
[env:PicoW_terminal_chat]
|
||||
extends = rpi_picow
|
||||
|
||||
@@ -224,6 +224,7 @@ extends = Station_G2
|
||||
build_flags =
|
||||
${Station_G2.build_flags}
|
||||
-I examples/companion_radio/ui-new
|
||||
-D ENABLE_WIFI_INTERFACE
|
||||
-D MAX_CONTACTS=350
|
||||
-D MAX_GROUP_CHANNELS=40
|
||||
-D WIFI_DEBUG_LOGGING=1
|
||||
@@ -234,6 +235,7 @@ build_flags =
|
||||
; -D MESH_DEBUG=1
|
||||
build_src_filter = ${Station_G2.build_src_filter}
|
||||
+<helpers/esp32/*.cpp>
|
||||
+<helpers/wifi/*.cpp>
|
||||
+<../examples/companion_radio/*.cpp>
|
||||
+<../examples/companion_radio/ui-new/*.cpp>
|
||||
lib_deps =
|
||||
|
||||
@@ -139,6 +139,7 @@ extends = Station_G3_ESP32
|
||||
build_flags =
|
||||
${Station_G3_ESP32.build_flags}
|
||||
-I examples/companion_radio/ui-new
|
||||
-D ENABLE_WIFI_INTERFACE
|
||||
-D MAX_CONTACTS=350
|
||||
-D MAX_GROUP_CHANNELS=40
|
||||
-D WIFI_DEBUG_LOGGING=1
|
||||
@@ -149,6 +150,7 @@ build_flags =
|
||||
; -D MESH_DEBUG=1
|
||||
build_src_filter = ${Station_G3_ESP32.build_src_filter}
|
||||
+<helpers/esp32/*.cpp>
|
||||
+<helpers/wifi/*.cpp>
|
||||
+<../examples/companion_radio/*.cpp>
|
||||
+<../examples/companion_radio/ui-new/*.cpp>
|
||||
lib_deps =
|
||||
|
||||
@@ -176,6 +176,7 @@ extends = ThinkNode_M2
|
||||
build_flags =
|
||||
${ThinkNode_M2.build_flags}
|
||||
-I examples/companion_radio/ui-new
|
||||
-D ENABLE_WIFI_INTERFACE
|
||||
-D MAX_CONTACTS=350
|
||||
-D MAX_GROUP_CHANNELS=40
|
||||
-D OFFLINE_QUEUE_SIZE=256
|
||||
@@ -184,6 +185,7 @@ build_flags =
|
||||
-D WIFI_PWD='"mypwd"'
|
||||
build_src_filter = ${ThinkNode_M2.build_src_filter}
|
||||
+<helpers/esp32/*.cpp>
|
||||
+<helpers/wifi/*.cpp>
|
||||
+<helpers/ui/MomentaryButton.cpp>
|
||||
+<helpers/ui/buzzer.cpp>
|
||||
+<../examples/companion_radio/*.cpp>
|
||||
|
||||
@@ -190,6 +190,7 @@ extends = ThinkNode_M5
|
||||
build_flags =
|
||||
${ThinkNode_M5.build_flags}
|
||||
-I examples/companion_radio/ui-new
|
||||
-D ENABLE_WIFI_INTERFACE
|
||||
-D MAX_CONTACTS=350
|
||||
-D MAX_GROUP_CHANNELS=40
|
||||
-D OFFLINE_QUEUE_SIZE=256
|
||||
@@ -198,6 +199,7 @@ build_flags =
|
||||
-D WIFI_PWD='"mypwd"'
|
||||
build_src_filter = ${ThinkNode_M5.build_src_filter}
|
||||
+<helpers/esp32/*.cpp>
|
||||
+<helpers/wifi/*.cpp>
|
||||
+<helpers/ui/MomentaryButton.cpp>
|
||||
+<../examples/companion_radio/*.cpp>
|
||||
+<../examples/companion_radio/ui-new/*.cpp>
|
||||
|
||||
@@ -135,6 +135,7 @@ extends = ThinkNode_M7
|
||||
build_flags =
|
||||
${ThinkNode_M7.build_flags}
|
||||
-I examples/companion_radio/ui-orig
|
||||
-D ENABLE_WIFI_INTERFACE
|
||||
-D MAX_CONTACTS=350
|
||||
-D MAX_GROUP_CHANNELS=40
|
||||
-D DISPLAY_CLASS=NullDisplayDriver
|
||||
@@ -145,6 +146,7 @@ build_flags =
|
||||
; -D MESH_PACKET_LOGGING=1
|
||||
build_src_filter = ${ThinkNode_M7.build_src_filter}
|
||||
+<helpers/esp32/*.cpp>
|
||||
+<helpers/wifi/*.cpp>
|
||||
+<helpers/ui/MomentaryButton.cpp>
|
||||
+<helpers/ui/NullDisplayDriver.cpp>
|
||||
+<../examples/companion_radio/*.cpp>
|
||||
|
||||
@@ -137,6 +137,7 @@ extends = ThinkNode_M9
|
||||
build_flags =
|
||||
${ThinkNode_M9.build_flags}
|
||||
-I examples/companion_radio/ui-new
|
||||
-D ENABLE_WIFI_INTERFACE
|
||||
-D MAX_CONTACTS=350
|
||||
-D MAX_GROUP_CHANNELS=40
|
||||
-D WIFI_DEBUG_LOGGING=1
|
||||
@@ -146,6 +147,7 @@ build_flags =
|
||||
; -D MESH_PACKET_LOGGING=1
|
||||
build_src_filter = ${ThinkNode_M9.build_src_filter}
|
||||
+<helpers/esp32/*.cpp>
|
||||
+<helpers/wifi/*.cpp>
|
||||
+<helpers/ui/buzzer.cpp>
|
||||
+<helpers/ui/MomentaryButton.cpp>
|
||||
+<../examples/companion_radio/*.cpp>
|
||||
|
||||
@@ -115,8 +115,10 @@ extends = Xiao_esp32_C3
|
||||
build_src_filter = ${Xiao_esp32_C3.build_src_filter}
|
||||
+<../examples/companion_radio/*.cpp>
|
||||
+<helpers/esp32/*.cpp>
|
||||
+<helpers/wifi/*.cpp>
|
||||
build_flags =
|
||||
${Xiao_esp32_C3.build_flags}
|
||||
-D ENABLE_WIFI_INTERFACE
|
||||
-D MAX_CONTACTS=350
|
||||
-D MAX_GROUP_CHANNELS=40
|
||||
-D OFFLINE_QUEUE_SIZE=256
|
||||
|
||||
@@ -202,11 +202,13 @@ extends = Xiao_S3_WIO
|
||||
build_src_filter = ${Xiao_S3_WIO.build_src_filter}
|
||||
+<helpers/ui/NullDisplayDriver.cpp>
|
||||
+<helpers/esp32/*.cpp>
|
||||
+<helpers/wifi/*.cpp>
|
||||
+<helpers/ui/MomentaryButton.cpp>
|
||||
+<../examples/companion_radio/*.cpp>
|
||||
build_flags =
|
||||
${Xiao_S3_WIO.build_flags}
|
||||
-I examples/companion_radio/ui-new
|
||||
-D ENABLE_WIFI_INTERFACE
|
||||
-D MAX_CONTACTS=350
|
||||
-D MAX_GROUP_CHANNELS=40
|
||||
-D OFFLINE_QUEUE_SIZE=256
|
||||
|
||||
Reference in new issue
Block a user