FastLED 3.10.6
Loading...
Searching...
No Matches
AutoResearchRemoteNetworkMethods.cpp
Go to the documentation of this file.
1// Network / wireless RPC bindings: WiFi AP + HTTP (startNetServer,
2// startNetClient, runNetClientTest, runNetLoopback, stopNet), OTA HTTP
3// (startOta, stopOta), BLE GATT (startBle, stopBle, bleStatus), media
4// codec (decodeFile), and the async-DMA show() validator (testAsync —
5// here because it lives in the same I/O / driver-async family).
6// Extracted from AutoResearchRemote.cpp as part of #3132 / meta #3127.
7
9#if FL_PLATFORM_HAS_LARGE_MEMORY
10
11// Legacy debug macros (no-ops, kept for debugTest RPC function)
12#define DEBUG_PRINT(x) do {} while(0)
13#define DEBUG_PRINTLN(x) do {} while(0)
14
15#include "AutoResearchRemote.h"
16#include "AutoResearchBle.h"
17#include "AutoResearchNet.h"
18#include "AutoResearchOta.h"
20#include "fl/system/heap.h"
21#include "Common.h"
22#include "AutoResearchTest.h"
23#include "AutoResearchHelpers.h"
25#include "fl/net/port.h"
26#include "fl/net/wifi.h"
27#include "fl/stl/sstream.h"
28#include "fl/stl/unique_ptr.h"
29#include "fl/stl/optional.h"
30#include "fl/stl/json.h"
31#include "fl/task/task.h"
32#include "fl/task/executor.h"
34#include "fl/stl/atomic.h"
35#include "fl/task/promise.h"
36#include "fl/math/simd.h"
37#include "AutoResearchSimd.h"
43#include "fl/chipsets/spi.h"
44#include "fl/channels/config.h"
45#include <Arduino.h>
46
47#include "fl/net/ble.h"
48
49#include "fl/codec/h264.h"
50#include "fl/codec/mp4_parser.h"
52#include "fl/fx/frame.h"
53
54
56 // Register "testAsync" function - verify that show() returns before TX completes (async DMA)
57 // This proves the SPI driver releases back to the main thread while draining.
58 remote.bind("testAsync", [this](const fl::json& args) -> fl::json {
59 fl::json response = fl::json::object();
60
61 // Parse optional parameters from args object
62 int num_leds = 300;
63 fl::string requested_driver;
64 fl::json config;
65 if (args.is_object()) {
66 config = args;
67 } else if (args.is_array() && args.size() >= 1 && args[0].is_object()) {
68 config = args[0];
69 }
70 if (!config.is_null()) {
71 if (config.contains("numLeds") && config["numLeds"].is_int()) {
72 num_leds = static_cast<int>(config["numLeds"].as_int().value());
73 }
74 if (config.contains("driver") && config["driver"].is_string()) {
75 requested_driver = config["driver"].as_string().value();
76 }
77 }
78
79 // Set exclusive driver if requested (by-name path: requested_driver from RPC)
80 if (!requested_driver.empty()) {
81 if (!autoResearchSetExclusiveDriverByName(requested_driver.c_str())) {
82 response.set("success", false);
83 response.set("error", "DriverSetupFailed");
84 fl::sstream msg;
85 msg << "Failed to set '" << requested_driver.c_str() << "' as exclusive driver";
86 response.set("message", msg.str().c_str());
87 return response;
88 }
89 }
90
91 if (num_leds < 10 || num_leds > 1000) {
92 response.set("success", false);
93 response.set("error", "InvalidNumLeds");
94 response.set("message", "numLeds must be 10-1000");
95 return response;
96 }
97
98 // Set up a channel with the specified number of LEDs
99 fl::vector<CRGB> leds(num_leds);
100 for (int i = 0; i < num_leds; i++) {
101 leds[i] = CRGB(0xFF, 0x00, 0x80); // Solid color pattern
102 }
103
104 fl::ChannelConfig channel_config(
105 mState->pin_tx,
107 leds,
108 RGB
109 );
110
111 auto channel = FastLED.add(channel_config);
112 if (!channel) {
113 response.set("success", false);
114 response.set("error", "ChannelCreationFailed");
115 response.set("message", "Failed to create channel");
116 return response;
117 }
118
119 // === DRAW 1: May include one-time SPI hardware init overhead ===
120 uint32_t t0 = micros();
121 FastLED.show();
122 uint32_t t1 = micros();
123 FastLED.wait(5000); // 5 second timeout
124 uint32_t t2 = micros();
125
126 uint32_t show1_us = t1 - t0;
127 uint32_t wait1_us = t2 - t1;
128 uint32_t total1_us = t2 - t0;
129
130 // === DRAW 2: Should be fast (no init overhead) ===
131 uint32_t t3 = micros();
132 FastLED.show();
133 uint32_t t4 = micros();
134 FastLED.wait(5000); // 5 second timeout
135 uint32_t t5 = micros();
136
137 uint32_t show2_us = t4 - t3;
138 uint32_t wait2_us = t5 - t4;
139 uint32_t total2_us = t5 - t3;
140
141 // Clean up channel
143
144 // Determine if async behavior is working on draw 2 (no init overhead):
145 // If async: show_us << total_us (show returns quickly, wait blocks for remainder)
146 // If blocking: show_us ≈ total_us (show blocks for entire TX, wait returns instantly)
147 // Pass criterion: show_us < 50% of total_us (on draw 2)
148 bool passed = (total2_us > 0) && (show2_us < total2_us / 2);
149
150 // Determine driver name
151 fl::string driver_name = "unknown";
152 for (fl::size i = 0; i < mState->drivers_available.size(); i++) {
153 if (mState->drivers_available[i].enabled) {
154 driver_name = mState->drivers_available[i].name;
155 break;
156 }
157 }
158
159 response.set("success", true);
160 response.set("passed", passed);
161 // Draw 1 (with possible init overhead)
162 response.set("show1_us", static_cast<int64_t>(show1_us));
163 response.set("wait1_us", static_cast<int64_t>(wait1_us));
164 response.set("total1_us", static_cast<int64_t>(total1_us));
165 // Draw 2 (steady-state, no init)
166 response.set("show2_us", static_cast<int64_t>(show2_us));
167 response.set("wait2_us", static_cast<int64_t>(wait2_us));
168 response.set("total2_us", static_cast<int64_t>(total2_us));
169 response.set("num_leds", static_cast<int64_t>(num_leds));
170 response.set("driver", driver_name.c_str());
171
172 fl::sstream msg;
173 if (passed) {
174 msg << "Async OK: draw2 show()=" << show2_us
175 << "us, wait()=" << wait2_us
176 << "us, total=" << total2_us << "us"
177 << " (draw1 show=" << show1_us << "us)";
178 } else {
179 msg << "Async FAIL: draw2 show()=" << show2_us
180 << "us out of " << total2_us
181 << "us total (expected <50%)"
182 << " (draw1 show=" << show1_us << "us)";
183 }
184 response.set("message", msg.str().c_str());
185
186 return response;
187 });
188
189 // ========================================================================
190 // Network Validation RPC Functions
191 // ========================================================================
192
193 // Register "startNetServer" - Start WiFi AP + HTTP server for net-server validation
194 remote.bind("startNetServer", [this](const fl::json& args) -> fl::json {
195 mState->net_server_active = true;
196 return startNetServer();
197 });
198
199 // Register "startNetClient" - Start WiFi AP only for net-client validation
200 remote.bind("startNetClient", [this](const fl::json& args) -> fl::json {
201 mState->net_client_active = true;
202 return startNetClient();
203 });
204
205 // Register "runNetClientTest" - ESP32 fetches from host HTTP server
206 // Args: {host_ip: string, port: int}
207 remote.bind("runNetClientTest", [](const fl::json& args) -> fl::json {
208 fl::json response = fl::json::object();
209
210 // Parse arguments - args is the config object
211 if (!args.is_object()) {
212 response.set("success", false);
213 response.set("error", "Expected object with host_ip and port");
214 return response;
215 }
216
217 fl::json host_ip_val = args[fl::string("host_ip")];
218 fl::json port_val = args[fl::string("port")];
219
220 if (!host_ip_val.is_string() || !port_val.is_int()) {
221 response.set("success", false);
222 response.set("error", "Expected {host_ip: string, port: int}");
223 return response;
224 }
225
226 fl::string host_ip = host_ip_val.as_string().value();
227 // Narrowing without a range check silently retargets the request:
228 // 70000 wraps to 4464 (FastLED#3956).
229 const fl::optional<fl::u16> port = fl::net::tryParsePort(port_val.as_int().value());
230 if (!port.has_value()) {
231 response.set("success", false);
232 response.set("error", "port must be in [1, 65535]");
233 return response;
234 }
235
236 return runNetClientTest(host_ip.c_str(), port.value());
237 });
238
239 // Register "runNetLoopback" - Self-contained loopback test (no WiFi needed)
240 // Starts HTTP server on localhost, client GETs 127.0.0.1 endpoints
241 remote.bind("netServerStats", [](const fl::json& args) -> fl::json {
242 (void)args;
243 return netServerStats();
244 });
245
246 remote.bind("runNetLoopback", [](const fl::json& args) -> fl::json {
247 return runNetLoopback();
248 });
249
250 // Register "stopNet" - Stop WiFi AP and HTTP server/client
251 remote.bind("stopNet", [this](const fl::json& args) -> fl::json {
252 mState->net_server_active = false;
253 mState->net_client_active = false;
254 return stopNet();
255 });
256
257 // ========================================================================
258 // WiFi Connection + Network Activity RPC Functions (FastLED#3576 Phase 6)
259 // ========================================================================
260
261 // "wifiConnect" {ssid, password} — async STA join via fl::net::wifi.
262 remote.bind("wifiConnect", [](const fl::json& args) -> fl::json {
263 fl::json response = fl::json::object();
264 fl::string ssid, pass;
265 if (args.contains("ssid") && args["ssid"].is_string()) {
266 ssid = args["ssid"].as_string().value();
267 }
268 if (args.contains("password") && args["password"].is_string()) {
269 pass = args["password"].as_string().value();
270 }
271 if (ssid.empty()) {
272 response.set("success", false);
273 response.set("error", "MissingSsid");
274 return response;
275 }
276 const bool ok = fl::net::wifi::connectSta(ssid.c_str(), pass.c_str());
277 response.set("success", ok);
279 return response;
280 });
281
282 // "wifiAp" {ssid, password, channel} — SoftAP via fl::net::wifi.
283 remote.bind("wifiAp", [](const fl::json& args) -> fl::json {
284 fl::json response = fl::json::object();
285 fl::string ssid, pass;
286 int channel = 1;
287 if (args.contains("ssid") && args["ssid"].is_string()) {
288 ssid = args["ssid"].as_string().value();
289 }
290 if (args.contains("password") && args["password"].is_string()) {
291 pass = args["password"].as_string().value();
292 }
293 if (args.contains("channel") && args["channel"].is_int()) {
294 channel = static_cast<int>(args["channel"].as_int().value());
295 }
296 if (ssid.empty()) {
297 response.set("success", false);
298 response.set("error", "MissingSsid");
299 return response;
300 }
301 const bool ok = fl::net::wifi::startAp(ssid.c_str(), pass.c_str(),
302 static_cast<fl::u8>(channel));
303 response.set("success", ok);
304 response.set("apIp", fl::net::wifi::apIpAddress().c_str());
305 return response;
306 });
307
308 // "wifiStatus" — poll the async join.
309 remote.bind("wifiStatus", [](const fl::json& args) -> fl::json {
310 fl::json response = fl::json::object();
311 response.set("success", true);
313 response.set("connected", fl::net::wifi::isConnected());
314 response.set("ip", fl::net::wifi::ipAddress().c_str());
315 response.set("apIp", fl::net::wifi::apIpAddress().c_str());
316 return response;
317 });
318
319 // "wifiStop" — tear down STA + AP.
320 remote.bind("wifiStop", [](const fl::json& args) -> fl::json {
322 fl::json response = fl::json::object();
323 response.set("success", true);
324 return response;
325 });
326
327 // "netActivity" — runtime network-activity snapshot (the detector
328 // the LED drivers consult for deep-yield decisions).
329 remote.bind("netActivity", [](const fl::json& args) -> fl::json {
330 fl::json response = fl::json::object();
331 response.set("success", true);
332 response.set("wifiActive", fl::NetworkDetector::isWiFiActive());
333 response.set("wifiConnected", fl::NetworkDetector::isWiFiConnected());
334 response.set("bluetoothActive", fl::NetworkDetector::isBluetoothActive());
335 response.set("anyNetworkActive", fl::NetworkDetector::isAnyNetworkActive());
336 response.set("anyNetworkConnected", fl::NetworkDetector::isAnyNetworkConnected());
338 return response;
339 });
340
341 // ========================================================================
342 // OTA Validation RPC Functions
343 // ========================================================================
344
345 // Register "startOta" - Start WiFi AP + OTA HTTP server for OTA validation
346 remote.bind("startOta", [](const fl::json& args) -> fl::json {
347 return startOta();
348 });
349
350 // Register "stopOta" - Stop OTA server and WiFi AP
351 remote.bind("stopOta", [](const fl::json& args) -> fl::json {
352 return stopOta();
353 });
354
355 remote.bind("beginOtaArtifact", [](const fl::json& args) -> fl::json {
356 if (!args.contains("size") || !args["size"].is_int() ||
357 !args.contains("sha256") || !args["sha256"].is_string()) {
358 fl::json response = fl::json::object();
359 response.set("success", false);
360 response.set("error", "Expected size and sha256");
361 return response;
362 }
363 const int64_t size = args["size"].as_int().value();
364 return beginOtaArtifact(size > 0 ? static_cast<size_t>(size) : 0,
365 args["sha256"].as_string().value().c_str());
366 });
367
368 remote.bind("writeOtaArtifact", [](fl::vector<fl::u8> bytes) -> fl::json {
369 return writeOtaArtifact(fl::move(bytes));
370 });
371
372 remote.bind("finishOtaArtifact", [](const fl::json& args) -> fl::json {
373 return finishOtaArtifact();
374 });
375
376 remote.bind("startOtaArtifactServer", [](const fl::json& args) -> fl::json {
377 return startOtaArtifactServer();
378 });
379
380 remote.bind("otaArtifactStatus", [](const fl::json& args) -> fl::json {
381 return otaArtifactStatus();
382 });
383
384 remote.bind("rpOtaUpdateStatus", [](const fl::json& args) -> fl::json {
385 return rpOtaUpdateStatus();
386 });
387
388 remote.bind("applyOtaArtifact", [](const fl::json& args) -> fl::json {
389 if (!args.contains("host") || !args["host"].is_string() ||
390 !args.contains("port") || !args["port"].is_int()) {
391 fl::json response = fl::json::object();
392 response.set("success", false);
393 response.set("error", "Expected host and port");
394 return response;
395 }
396 // `port > 0` alone rejects 65536 only because it happens to
397 // truncate to zero; 65537 would still slip through as port 1.
398 const fl::optional<fl::u16> port =
399 fl::net::tryParsePort(args["port"].as_int().value());
400 if (!port.has_value()) {
401 fl::json response = fl::json::object();
402 response.set("success", false);
403 response.set("error", "port must be in [1, 65535]");
404 return response;
405 }
406 return queueOtaArtifactUpdate(args["host"].as_string().value().c_str(),
407 port.value());
408 });
409
410 // ========================================================================
411 // BLE Validation RPC Functions
412 // ========================================================================
413
414 // Register "startBle" - Start BLE GATT server + create BLE Remote
415 remote.bind("startBle", [this](const fl::json& args) -> fl::json {
416 return this->startBleRemote();
417 });
418
419 // Register "stopBle" - Stop BLE GATT server + destroy BLE Remote
420 remote.bind("stopBle", [this](const fl::json& args) -> fl::json {
421 return this->stopBleRemote();
422 });
423
424 // Register "decodeFile" - Decode a media file and return first 16 pixels
425 // Args: [base64_data_string, extension_string] (base64 auto-decoded to fl::vector<fl::u8>)
426 remote.bind("decodeFile", [](fl::vector<fl::u8> data, fl::string ext) -> fl::json {
427 fl::json response = fl::json::object();
428
429 if (ext != ".mp4") {
430 response.set("success", false);
431 response.set("error", "Only .mp4 supported for device decode");
432 return response;
433 }
434
435 // Parse MP4 container metadata
436 fl::string error;
437 fl::H264Info info = fl::H264::parseH264Info(data, &error);
438 if (!info.isValid) {
439 response.set("success", false);
440 response.set("error", error.c_str());
441 return response;
442 }
443 response.set("width", static_cast<int64_t>(info.width));
444 response.set("height", static_cast<int64_t>(info.height));
445
446 if (!fl::H264::isSupported()) {
447 response.set("success", false);
448 response.set("error", "H264 decoder not supported on this platform");
449 return response;
450 }
451
452 // Create decoder and decode first frame
453 fl::string dec_error;
454 auto decoder = fl::H264::createDecoder(fl::H264Config{}, &dec_error);
455 if (!decoder) {
456 response.set("success", false);
457 response.set("error", dec_error.c_str());
458 return response;
459 }
460
461 auto stream = fl::make_shared<fl::memorybuf>(data.size());
462 stream->write(data);
463
464 if (!decoder->begin(stream)) {
465 fl::string msg;
466 decoder->hasError(&msg);
467 response.set("success", false);
468 response.set("error", msg.empty() ? "Decoder begin() failed" : msg.c_str());
469 return response;
470 }
471
472 auto result = decoder->decode();
473 if (result != fl::DecodeResult::Success) {
474 response.set("success", false);
475 response.set("error", "Decode returned non-success");
476 response.set("decode_result", static_cast<int64_t>(static_cast<int>(result)));
477 decoder->end();
478 return response;
479 }
480
481 fl::Frame frame = decoder->getCurrentFrame();
482 decoder->end();
483
484 if (!frame.isValid()) {
485 response.set("success", false);
486 response.set("error", "Decoded frame is invalid");
487 return response;
488 }
489
490 response.set("success", true);
491 response.set("frame_width", static_cast<int64_t>(frame.getWidth()));
492 response.set("frame_height", static_cast<int64_t>(frame.getHeight()));
493
494 // Return first 16 pixels as [[r,g,b], ...]
495 auto pixels = frame.rgb();
496 fl::json pixel_array = fl::json::array();
497 int count = pixels.size() < 16 ? static_cast<int>(pixels.size()) : 16;
498 for (int i = 0; i < count; i++) {
499 fl::json px = fl::json::array();
500 px.push_back(static_cast<int64_t>(pixels[i].r));
501 px.push_back(static_cast<int64_t>(pixels[i].g));
502 px.push_back(static_cast<int64_t>(pixels[i].b));
503 pixel_array.push_back(px);
504 }
505 response.set("pixels", pixel_array);
506
507 return response;
508 });
509
510 // Register "bleStatus" - Query BLE connection/subscription state
511 remote.bind("bleStatus", [this](const fl::json& args) -> fl::json {
512 fl::json response = fl::json::object();
513 response.set("ble_active", mState->ble_server_active);
514 fl::net::ble::StatusInfo info = fl::net::ble::queryStatus(mBleState);
515 response.set("connected", info.connected);
516 response.set("connected_count", static_cast<int64_t>(info.connectedCount));
517 response.set("tx_char_exists", info.txCharExists);
518 response.set("tx_value_len", static_cast<int64_t>(info.txValueLen));
519 response.set("ring_head", static_cast<int64_t>(info.ringHead));
520 response.set("ring_tail", static_cast<int64_t>(info.ringTail));
521 return response;
522 });
523}
524
525#endif // FL_PLATFORM_HAS_LARGE_MEMORY
CRGB leds[1]
bool autoResearchSetExclusiveDriverByName(const char *name)
AutoResearch-style helper: set an exclusive driver by name.
fl::json runNetLoopback()
Run self-contained loopback test: start HTTP server, client GETs localhost.
fl::json startNetClient()
Start WiFi Soft AP only (for net-client mode).
fl::json runNetClientTest(const char *host_ip, uint16_t port)
Run HTTP client tests against a host server.
fl::json startNetServer()
Start WiFi Soft AP and HTTP server with test endpoints.
fl::json stopNet()
Stop WiFi AP and HTTP server/client, release all resources.
fl::json netServerStats()
Why the RP peer server last abandoned a request (FastLED#3899 diagnostics).
fl::json queueOtaArtifactUpdate(const char *host, uint16_t port)
Queue an RP2350W HTTP update so the RPC response can be sent first.
fl::json writeOtaArtifact(fl::vector< fl::u8 > bytes)
fl::json otaArtifactStatus()
fl::json stopOta()
Stop OTA server and WiFi AP, release all resources.
fl::json finishOtaArtifact()
fl::json startOtaArtifactServer()
fl::json rpOtaUpdateStatus()
Outcome of the last pollOtaArtifactUpdate fetch, readable after the host reconnects.
fl::json startOta()
Start WiFi Soft AP and OTA HTTP server.
fl::json beginOtaArtifact(size_t expected_size, const char *sha256)
Stage one RP2350W firmware artifact on the ESP32-C6 fixture.
Full PARLIO encode bench for ESP32-P4 (post-byte-LUT, #2526 landed).
PARLIO ISR-streaming functional validation (#2548 deep-dive follow-up).
Issue #2994 repro: compounded per-sequence timing drift vs 3.10.3.
Wave8 expansion micro-benchmark for #2526.
FL_DISABLE_WARNING_PUSH FL_DISABLE_WARNING_GLOBAL_CONSTRUCTORS CFastLED FastLED
Global LED strip management instance.
fl::unique_ptr< fl::Remote > remote
Definition RpcClient.ino:43
fl::net::ble — BLE GATT transport layer for JSON-RPC
SPI encoder configuration for clocked LED chipsets.
void bindNetworkMethods(fl::Remote &remote)
fl::json stopBleRemote()
Stop BLE remote (destroys BLE Remote + GATT server)
fl::net::ble::TransportState * mBleState
fl::shared_ptr< AutoResearchState > mState
fl::json startBleRemote()
Start BLE remote (creates BLE GATT server + second Remote instance)
void show(fl::u8 scale)
Update all our controllers with the current led colors, using the passed in brightness.
static void add(fl::ChannelPtr channel)
Add a Channel-based LED controller (from ChannelPtr)
void wait()
Wait for all channel bus transmissions to complete.
void clear(bool writeData=false)
Clear the leds, wiping the local array of data.
fl::u16 getWidth() const
Definition frame.h:59
fl::span< CRGB > rgb()
Definition frame.h:42
fl::u16 getHeight() const
Definition frame.h:60
bool isValid() const
static IDecoderPtr createDecoder(const H264Config &config, fl::string *error_message=nullptr)
static H264Info parseH264Info(fl::span< const fl::u8 > mp4Data, fl::string *error_message=nullptr)
Definition h264.cpp.hpp:196
static bool isSupported()
T & value() FL_NO_EXCEPT
Definition optional.h:112
bool has_value() const FL_NO_EXCEPT
Definition optional.h:42
JSON-RPC server with scheduling support.
Definition remote.h:42
bool empty() const FL_NO_EXCEPT
const char * c_str() const FL_NO_EXCEPT
fl::optional< fl::string > as_string() const FL_NO_EXCEPT
Definition json.h:443
fl::optional< i64 > as_int() const FL_NO_EXCEPT
Definition json.h:398
bool is_int() const FL_NO_EXCEPT
Definition json.h:383
bool is_null() const FL_NO_EXCEPT
Definition json.h:381
void push_back(const json &value) FL_NO_EXCEPT
Definition json.h:918
bool contains(size_t idx) const FL_NO_EXCEPT
Definition json.h:790
bool is_string() const FL_NO_EXCEPT
Definition json.h:388
static json object() FL_NO_EXCEPT
Definition json.h:857
static json array() FL_NO_EXCEPT
Definition json.h:853
static bool isWiFiActive() FL_NO_EXCEPT
static bool isAnyNetworkConnected() FL_NO_EXCEPT
static bool isWiFiConnected() FL_NO_EXCEPT
static bool isAnyNetworkActive() FL_NO_EXCEPT
static bool isBluetoothActive() FL_NO_EXCEPT
string str() const FL_NO_EXCEPT
Definition strstream.h:43
fl::size size() const FL_NO_EXCEPT
constexpr EOrder RGB
Definition eorder.h:17
Task executor — runs registered task runners and manages the run loop.
@ CHANNELS
Remove all channels from controller list.
Definition FastLED.h:668
fl::CRGB CRGB
Definition crgb.h:25
Platform-abstracted heap memory query functions.
FastLED's Elegant JSON Library: fl::json
StatusInfo queryStatus(const TransportState *) FL_NO_EXCEPT
Query BLE connection/subscription diagnostics.
Definition ble.cpp.hpp:30
bool isConnected() FL_NO_EXCEPT
True when the station interface has an IP.
Definition wifi.cpp.hpp:44
const char * toString(Status s) FL_NO_EXCEPT
Human-readable name for a Status value.
Definition wifi.cpp.hpp:18
void stop() FL_NO_EXCEPT
Stop WiFi entirely (STA and AP).
Definition wifi.cpp.hpp:42
bool startAp(const char *, const char *, u8) FL_NO_EXCEPT
Bring up a SoftAP.
Definition wifi.cpp.hpp:41
Status status() FL_NO_EXCEPT
Current connection state.
Definition wifi.cpp.hpp:43
bool connectSta(const char *, const char *) FL_NO_EXCEPT
Start an asynchronous station-mode join.
Definition wifi.cpp.hpp:40
fl::string ipAddress() FL_NO_EXCEPT
Dotted-quad IP of the station interface ("" until connected).
Definition wifi.cpp.hpp:45
fl::string apIpAddress() FL_NO_EXCEPT
Dotted-quad IP of the SoftAP interface ("" when AP is down).
Definition wifi.cpp.hpp:46
fl::optional< u16 > tryParsePort(i64 value)
Convert an untrusted integer to a port number.
Definition port.h:35
unsigned char u8
Definition stdint.h:131
constexpr remove_reference< T >::type && move(T &&t) FL_NO_EXCEPT
Definition move.h:28
constexpr ChipsetTimingConfig makeTimingConfig() FL_NO_EXCEPT
Convert compile-time CHIPSET type to runtime timing config.
Optional< T > optional
Definition optional.h:16
fl::u32 micros()
Universal microsecond timer - returns microseconds since system startup.
shared_ptr< T > make_shared(Args &&... args) FL_NO_EXCEPT
Definition shared_ptr.h:414
expected< T, E > result
Alias for expected (Rust-style naming)
Definition result.h:31
Cross-platform facade for runtime network activity detection.
corkscrew_args args
Definition old.h:149
Range-checked conversion of an untrusted integer to a TCP/UDP port.
Promise-based fluent API for FastLED - standalone async primitives.
Umbrella header for SIMD subsystem.
fl::u32 uint32_t
Definition stdint.h:218
bool isValid
Definition h264.h:16
fl::u16 height
Definition h264.h:12
fl::u16 width
Definition h264.h:11
fl::net::wifi — platform-neutral WiFi connection API (FastLED#3576 Phase 6).