Introduce a very lightweight html5 + css2.1+ stateful stream parser, along
the same lines as the lws json and cbor ones.
This is interesting primarily because of just how low-resource it is for
modest css + html, it uses an lwsac to hold the entirity of the css in
memory at once but the html is parsed in chunks without any need to keep
previous chunks around (chunks may be as small as 1 byte).
A user callback receives element entry and exit callbacks with payload and
all attributes parsed out, CSS related to the active element stack is
parsed to provide a list of active css attributes, which takes heap for the
duration of the parsing.
In effect this provides rich information about the html and css state to
the callback, which has the job of producing the layout in a user-defined
way.
As such, there is no DOM in memory at one time, there is only a stack of
active elements like <html><body><div>xxx with their associated attributes
(like class). So as it is, it does not support DOM modification such as
JS changing elements after parsing, although elements with interesting IDs
could be kept around by the callback. There is a corresponding tiny and
relatively flat heap usage regardless of html size.
Default CSS is specified as recommended in the CSS 2.1 standard.
Inline <style></style> elements are supported, but not pre-html5 style= in
element attributes, since these are incompatible with strict CSP.
What the attributes should mean on your system, eg, font-size, font-family
etc is left for the user callback to decide, along with how to lay out the
items using the CSS attributes, and render them.
Fixed point 32.32 constants are used (fraction expressed at parts in 100M)
instead of floating point.
If you have presentation needs, even on a constrained display on a
constrained microcontroller, this makes it feasible to use standardized
markup and styling instead of roll your own.
This provides an alternative esp32-specific SPI driver with ops that can be
swapped in place of the gpio bitbang one.
The pinmux info and lws gpio driver and other data in the spi bitbang
struct are used as-is by the DMA one.
New ops are provided which are able to allocate and free DMA-able memory so
the device drivers can prepare directly usable buffers. Bounce through to
DMA-able buffers is also transparently supported.
This adds optional display list support to lws_display, using DLOs (Display
List Objects). DLOs for rectangle / rounded rectangle (with circle as the
degenerate case), PNGs, JPEG and compressed, antialiased bitmapped fonts
and text primitives are provided.
Logical DLOs are instantiated on heap and listed into an lws_display_list
owner, DLOs handle attributes like position, bounding box, colour +
opacity, and local error diffusion backing buffer.
When the display list is complete, it can be rasterized a line at a time,
with scoped error diffusion resolved, such that no allocation for the
framebuffer is required at any point. DLOs are freed as the rasterization
moves beyond their bounding box.
Adds a platform registry binding names and other metadata to lws_display
fonts / PNGs / JPEGs. Provides registration, destruction and best match
selection apis.
Introduce a rewritten picojpeg that is able to operate statefully and
rasterize into an internal line ringbuffer, emitting a line of pixels
at a time to the caller. This is the JPEG equivalent of the lws
PNG decoder.
JPEG is based around 8- or 16- line height MCU blocks, depending on
the chroma coding, mandating a corresponding internal line buffer
requirement.
Example total heap requirement for various kinds of 600px width jpeg
decoding:
Grayscale: 6.5KB
RGB 4:4:4: 16.4KB
RGB 4:2:2v: 16.4KB
RGB 4:4:2h: 31KB
RGB 4:4:0: 31KB
No other allocations occur during decode.
Stateful stream parsing means decode can be paused for lack of input
at any time and resumed seamlessly when more input becomes available.
Add a rewritten version of upng that decodes statefully line by line, and so
does not require a bitmap buffer for the output. This compares to original
upng approach that needs heap allocations for the input, the whole output
and intermediate allocations.
Instead of buffers for input, decompression and output, it only allocates
2 x lines of RGBA pixels (ie, a few KB), and 32KB of decompressed data for
backward references in the decoder, and decodes as needed into the 2-line
buffer to produce line rasterized results. For a 600px width PNG, this is
just 40KB heap for the duration.
This introduces a fixed precision signed 32.32 fractional type that can
work on devices without an FPU.
The integer part works as an int32_t, the fractional part represents the
fractional proportion expressed as part of 100M, so 8 fractional decimal
digit precision which is more than enough for many applications.
Add and Sub are reasonably fast as they are scaled on to a combined
uint64_t, Multiply is a little slower as it takes four uint64_t multiplies
that are summed, and divide is expensive but accurate, done bitwise taking
up to 32 iterations involving uint64_t div and mod.
mbedtls seemed to realize that they went overboard with the privacy stuff
on v3.0 and removed some of it. Introduce support for those members that
are only private on exactly v3.0 and unprotected before and after.
This adds apis that enable usage of compressed backtraces in heap
instrumentation.
A decompressor tool is also provided that emits a textual
call stack suitable for use with addr2line.
Adds an example for NXP RT595S eval board, using serialized SS over CDC /
ACM USB composite device, one ttyACM for logs and the other for the SSS
link.
lws_sequencer and lws_abstract were both false starts trying to do the
functionality of secure streams.
Since Secure Streams does a better job for both and there are no known
out-of-tree users of them, let's remove them and focus on Secure Streams.
This is a NOP for existing usecases.
At the moment the only implemented transport for serialized SS is wsi, it's
typically used with Unix Domain Sockets, but it also works over tcp the
same.
It generalizes the interface between serialized chunks and the
transport, separately for client and proxy. The wsi transport is migrated
to use the new transport ops structs.
It will then be possible to "bring your own transport", so long as it is
reliable, and in-order, both for proxy and client / sspc.
We also adapt minimal-secure-streams-binance to build the -client variant
via SS proxy as well.
LWS_ONLY_SSPC is added so libwebsockets can be produced with just sspc
client support even for tiny targets.
A new embedded minimal example for rpi pico is also provided that
demonstrates using Serialized SS over a UART to an SS proxy, to implement
the SS Binance example on the pico, even though it has no networking itself.
This provides very memory-efficient CBOR stream parsing
and writing.
The parser converts pieces of CBOR into callbacks that define
the structure and collate string and blobs into buffer chunks
for extensible and easy access.
It is fragementation-safe and does not need all the CBOR in
the same place at one time, chunks of CBOR are parsed and
discarded as provided.
It does not allocate and just needs a few hundred bytes of
stack for even huge CBOR objects. Huge strings and blobs
are handled without needing memory to hold them atomically.
Includes ./minimal-examples/api-tests/api-test-lecp that
unit tests it against 82 official example CBORs and
26 additional test vectors from COSE (just checking the CBOR
parsing).
The writing apis allow printf style semantics with a variety
of CBOR-aware %-formats. The apis write into a context that
manages output buffer usage, if the output buffer fills,
then the apis return with an AGAIN code that lets you issue
and reset the output buffer and repeat the api all to issue
more output. The subsequent calls can occur much later or
from a different function context, so this is perfect for
WRITEABLE-mediated output from the network parts of lws.
See ./READMEs/README.cbor-lecp.md
Adapt mbedtls support for compatibility with v3, while maintaining
compatibility with v2.
Notice v3 has removed the ability to encrypt with pubkey and
decrypt with privkey. Openssl still has it, atm with v3 these
fall back to encrypt with privkey and decrypt with pubkey.
> The RSA module no longer supports private-key operations with the
> public key or vice versa. As a consequence, RSA operation functions
> no longer have a mode parameter. If you were calling RSA operations
> with the normal mode (public key for verification or encryption,
> private key for signature or decryption), remove the
> MBEDTLS_MODE_PUBLIC or MBEDTLS_MODE_PRIVATE argument. If you were
> calling RSA operations with the wrong mode, which rarely makes sense
>from a security perspective, this is no longer supported.
This provides a build option LWS_WITH_CONMON that lets user code recover
detailed connection stats on client connections with the LCCSCF_CONMON
flag.
In addition to latencies for dns, socket connection, tls and first protocol
response where possible, it also provides the user code an unfiltered list
of DNS responses that the client received, and the peer it actually
succeded to connect to.
There are a few build options that are trying to keep and report
various statistics
- DETAILED_LATENCY
- SERVER_STATUS
- WITH_STATS
remove all those and establish a generic rplacement, lws_metrics.
lws_metrics makes its stats available via an lws_system ops function
pointer that the user code can set.
Openmetrics export is supported, for, eg, prometheus scraping.
openssl v3-alpha11 has marked EC_KEY pieces as deprecated... we use it in
LWS_WITH_GENCRYPTO but the related RSA etc pieces were already deprecated
for that. We use EC_KEY pieces in vhost init...
The apis are not removed but deprecated, we should have a way to keep
trucking, but as it is the deprecation warning is promoted to an error.
Let's add LWS_SUPPRESS_DEPRECATED_API_WARNINGS option off by default. If
enabled at cmake, external deprecated api warnings are suppressed. This
gives a general workaround for now for opensslv3.
In addition, even if you don't do that, let's notice we are on openssl v3
and don't build the EC curve selection stuff, I don't think anyone is
actually using it anyway.
This is a huge patch that should be a global NOP.
For unix type platforms it enables -Wconversion to issue warnings (-> error)
for all automatic casts that seem less than ideal but are normally concealed
by the toolchain.
This is things like passing an int to a size_t argument. Once enabled, I
went through all args on my default build (which build most things) and
tried to make the removed default cast explicit.
With that approach it neither change nor bloat the code, since it compiles
to whatever it was doing before, just with the casts made explicit... in a
few cases I changed some length args from int to size_t but largely left
the causes alone.
From now on, new code that is relying on less than ideal casting
will complain and nudge me to improve it by warnings.
This is complicated by the fact extern on a function declaration implies
visibility... we have to make LWS_EXTERN empty when building static.
And, setting target_compile_definitions() doesn't work inside macros,
so it has to be set explicitly for the plugins.
Checking the symbol status needs nm -C -D as per
https://stackoverflow.com/questions/37934388/symbol-visibility-not-working-as-expected
after this patch, libwebsockets.a shows no symbols when checked like that and
the static-linked minimal examples only show -U for their other dynamic
imports.
In a handful of cases we use LWS_EXTERN on extern data declarations,
those then need to change to explicit extern.
Event lib support as it has been isn't scaling well, at the low level
libevent and libev headers have a namespace conflict so they can't
both be built into the same image, and at the distro level, binding
all the event libs to libwebsockets.so makes a bloaty situation for
packaging, lws will drag in all the event libs every time.
This patch implements the plan discussed here
https://github.com/warmcat/libwebsockets/issues/1980
and refactors the event lib support so they are built into isolated
plugins and bound at runtime according to what the application says
it wants to use. The event lib plugins can be packaged individually
so that only the needed sets of support are installed (perhaps none
of them if the user code is OK with the default poll() loop). And
dependent user code can mark the specific event loop plugin package
as required so pieces are added as needed.
The eventlib-foreign example is also refactored to build the selected
lib support isolated.
A readme is added detailing the changes and how to use them.
https://libwebsockets.org/git/libwebsockets/tree/READMEs/README.event-libs.md
Move the common plugin scanning dir stuff to be based on lws_dir, which
already builds for windows. Previously this was done via dirent for unix
and libuv for windows.
Reduce the dl plat stuff to just wrap instantiation and destruction of
dynlibs, establish common code in lib/misc/dir.c for plugin scanning
itself.
Migrate the libuv windows dl stuff to windows-plugins.c, so that he's
available even if later libuv loop support becomes and event lib plugin.
Remove the existing api exports scheme for plugins, just export a const struct
now which has a fixed header type but then whatever you want afterwards depending
on the class / purpose of the plugin. Place a "class" string in the header so
there can be different kinds of plugins implying different types exported.
Make the plugin apis public and add support for filter by class string, and
per instantation / destruction callbacks so the subclassed header type can
do its thing for the plugin class. The user provides a linked-list base
for his class of plugins, so he can manage them completely separately and
in user code / user export types.
Rip out some last hangers-on from generic sessions / tables.
This is all aimed at making the plugins support general enough so it can
provide event lib plugins later.
The old esp32 -factory stuff along with the lws support doesn't have a
future in its old form. It has users but the ratio of effort to
contribution is really especially bad. I haven't updated it for more
than a year since esp-idf changes broke the original stuff.
Freertos plat is alive and well and getting a lot of new use, ESP-32 is
supported both there and by modern lws_drivers pieces, including in CI
on real hardware, any further effort will be invested in that direction
instead of more vendor api-specific code (outside of wrapper
implementation).
lws_drivers wraps any SDK apis in generic lws apis such that your code
just uses those, enabling it to become SDK / SoC / vendor independent.
Its first implementation is on esp-idf, the low and mid-level features
that were in the old -factory are already available using that and
new technologies like lws_struct and Secure Streams.
Add lws_display and minimal example support for esp32-wrover to match wsp32-heltec-wb32
Since no usable buttons that don't affect something else on wrover kit, assumes
a button to 0V on GPIO14.
- Add low level system message distibution framework
- Add support for local Secure Streams to participate using _lws_smd streamtype
- Add apit test and minimal example
- Add SS proxy support for _lws_smd
See minimal-secure-streams-smd README.md
Make a start on generic peripheral and bus drivers to provide
meta-functionality regardless of platform.
On the one hand this simply provides...
- bitbang i2c on top of esp-idf gpio apis
- ssd1306 oled chip driver as found on Heltec WB32
- modifications to the minimal example test for esp32 to use that
... on the other hand, those capabilities are provided by creating:
- an abstract i2c class object
- an abstract gpio class object
- i2c class implementation using the abstract gpio for bitbang
- an abstract display class object
- an abstract display state (brightness, animated change,
on/off/init tracking, autodim after inactive, auto-off /
blanking after inactive)
... with the intention, eg, you only have to add a platform
implementation for the gpio to be able to use the i2c-based
display drivers and state handling, and i2c bitbang, without
any other modifications.
Establish a new distributed CMake architecture with CMake code related to
a source directory moving to be in the subdir in its own CMakeLists.txt.
In particular, there's now one in ./lib which calls through to ones
further down the directory tree like ./lib/plat/xxx, ./lib/roles/xxx etc.
This cuts the main CMakelists.txt from 98KB -> 33KB, about a 66% reduction,
and it's much easier to maintain sub-CMakeLists.txt that are in the same
directory as the sources they manage, and conceal all the details that that
level.
Child CMakelists.txt become responsible for:
- include_directories() definition (this is not supported by CMake
directly, it passes it back up via PARENT_SCOPE vars in helper
macros)
- Addition child CMakeLists.txt inclusion, for example toplevel ->
role -> role subdir
- Source file addition to the build
- Dependent library path resolution... this is now a private thing
in the child CMakeLists.txt, it just passes back any adaptations
to include_directories() and the LIB_LIST without filling the
parent namespace with the details