feat: http bindings matching crosspoint-reader, plus generated Lua stubs

The http table copies crosspoint-reader's signatures exactly -- get/head/delete/post/
patch returning (body|nil, status), download taking maxBytes/expectedSize/sha256, the
same 50000 byte body cap and the same -1 for a request that never left the device --
so a script that talks to a server runs on either firmware. docs/lua-api-parity.md
records that, and every other place the two APIs agree, differ for a reason, or differ
because nobody noticed.

Two crosspoint behaviours are deliberately not copied. It reinterprets a string in
argument 2 of a GET as a request body, which turns a mistyped headers table into a
silent protocol error. More seriously it calls setInsecure() on every request, so TLS
is encrypted but unauthenticated on the very path a firmware update would use; this
verifies against the root bundle already sitting in the framework, and the emulator
confirms expired.badssl.com is refused while a wrong sha256 deletes the file.

Downloading exposed two failures worth naming. A 2KB read buffer on the stack tripped
the loop task's canary because a TLS handshake had already spent it, and the
hand-rolled read loop spun forever on a stream that stopped producing -- HTTPClient's
own writeToStream handles both, so the loop is gone and the loop task gets 16KB.

scripts/gen_lua_stubs.py generates stubs/esp32lcd.lua in the same LuaLS format
crosspoint uses, reading annotations off the luaL_Reg tables so a module's docs sit
with its registration. make test runs --check, which crosspoint's copy never wired up.
This commit is contained in:
2026-08-01 17:33:47 -04:00
parent 2cdb7b3702
commit 6f2d618b8d
14 changed files with 1125 additions and 36 deletions
+13 -4
View File
@@ -36,10 +36,19 @@ static int l_input_touched(lua_State* L) {
}
void registerInput(lua_State* L) {
static const luaL_Reg lib[] = {{"getTouch", l_input_getTouch},
{"getRawTouch", l_input_getRawTouch},
{"touched", l_input_touched},
{nullptr, nullptr}};
static const luaL_Reg lib[] = {
// --- Current touch point, calibrated and rotated.
// @return integer|nil X, or nil when the panel is not touched.
// @return integer|nil Y.
{"getTouch", l_input_getTouch},
// --- Current touch point as raw ADC readings, for calibration.
// @return integer|nil X, or nil when the panel is not touched.
// @return integer|nil Y.
{"getRawTouch", l_input_getRawTouch},
// --- Whether the panel is being touched.
// @return boolean
{"touched", l_input_touched},
{nullptr, nullptr}};
luaL_newlib(L, lib);
lua_setglobal(L, "input");
}