FastLED 3.10.8
Loading...
Searching...
No Matches

◆ createSerialRequestSource()

fl::function< fl::optional< fl::json >()> fl::createSerialRequestSource ( const char * prefix = "")
inline

Definition at line 120 of file serial.h.

120 {
121 return [prefix]() -> fl::optional<fl::json> {
122 // Non-blocking check - any data available?
123 int avail = fl::available();
124 if (avail <= 0) {
125 return fl::nullopt;
126 }
127
128 // Data available - read a complete line.
129 // On Arduino platforms, fl::readLine() delegates to Serial.readStringUntil()
130 // which uses yield() (immediate context switch) for fast USB CDC multi-packet
131 // assembly. On other platforms, falls back to character-by-character reading.
132 auto line = fl::readLine('\n', '\r', fl::optional<u32>(1000));
133 if (!line.has_value() || line->empty()) {
134 return fl::nullopt;
135 }
136
137 // Use string_view for zero-copy prefix stripping and trimming
138 fl::string_view view = *line;
139
140 // Strip prefix if present
141 if (prefix && prefix[0] != '\0') {
142 if (view.starts_with(prefix)) {
143 view.remove_prefix(fl::strlen(prefix));
144 }
145 }
146
147 // Trim leading whitespace
148 while (!view.empty() && fl::isspace(view.front())) {
149 view.remove_prefix(1);
150 }
151
152 // Trim trailing whitespace
153 while (!view.empty() && fl::isspace(view.back())) {
154 view.remove_suffix(1);
155 }
156
157 // Only parse if input starts with '{'
158 if (view.empty() || view[0] != '{') {
159 // A short line here is ordinary serial noise -- boot banners,
160 // stray newlines -- and warning about it would drown the log.
161 // A long one is almost certainly a request that arrived damaged,
162 // and dropping that silently is expensive to debug: the caller
163 // sees no reply and no error, indistinguishable from an idle
164 // link, while the device keeps answering everything else. That
165 // is exactly how a receive-buffer truncation presented in
166 // FastLED#3956 -- 735 bytes transmitted, nothing returned, and
167 // no layer saying anything.
168 // Measure what arrived, not what survived normalisation: the
169 // view above has had its prefix stripped and whitespace trimmed,
170 // so a 64-byte line can fall under the threshold and stay silent,
171 // and the reported count would understate what was received.
172 if (line->size() >= kDroppedRequestWarnBytes) {
173 FL_WARN("[RPC] discarded a " << (static_cast<unsigned>(line->size())) << " byte line that does not begin with '{'; a request that arrived truncated looks exactly like this");
174 }
175 return fl::nullopt;
176 }
177
178 // Single copy when parsing JSON (unavoidable - JSON needs owned string)
179 fl::string input(view);
180 return fl::json::parse(input);
181 };
182}
static json parse(const fl::string &txt) FL_NO_EXCEPT
Definition json.h:842
void remove_suffix(fl::size n) FL_NO_EXCEPT
constexpr const char & back() const FL_NO_EXCEPT
Definition string_view.h:90
constexpr bool empty() const FL_NO_EXCEPT
void remove_prefix(fl::size n) FL_NO_EXCEPT
bool starts_with(string_view sv) const FL_NO_EXCEPT
constexpr const char & front() const FL_NO_EXCEPT
Definition string_view.h:86
#define FL_WARN(...)
Definition log.h:437
fl::optional< fl::string > readLine(char delimiter, char skipChar, fl::optional< u32 > timeoutMs) FL_NO_EXCEPT
bool isspace(char c) FL_NO_EXCEPT
Check if character is whitespace (space, tab, newline, carriage return)
Definition cctype.h:18
Optional< T > optional
Definition optional.h:16
constexpr nullopt_t nullopt
Definition optional.h:13
constexpr fl::size kDroppedRequestWarnBytes
Create a JSON-RPC RequestSource that reads from fl:: serial input.
Definition serial.h:117
int available() FL_NO_EXCEPT
FASTLED_FORCE_INLINE size_t strlen(const char *s) FL_NO_EXCEPT
Definition cstring.h:56

References available(), fl::string_view::back(), fl::string_view::empty(), FL_NO_EXCEPT, FL_WARN, fl::string_view::front(), isspace(), kDroppedRequestWarnBytes, nullopt, fl::json::parse(), readLine(), fl::string_view::remove_prefix(), fl::string_view::remove_suffix(), fl::string_view::starts_with(), and strlen().

Referenced by createSerialTransport().

+ Here is the call graph for this function:
+ Here is the caller graph for this function: