xref: /aosp_15_r20/external/libwebsockets/lib/abstract/README.md (revision 1c60b9aca93fdbc9b5f19b2d2194c91294b22281)
1*1c60b9acSAndroid Build Coastguard Worker# Abstract protocols and transports
2*1c60b9acSAndroid Build Coastguard Worker
3*1c60b9acSAndroid Build Coastguard Worker## Overview
4*1c60b9acSAndroid Build Coastguard Worker
5*1c60b9acSAndroid Build Coastguard WorkerUntil now protocol implementations in lws have been done directly
6*1c60b9acSAndroid Build Coastguard Workerto the network-related apis inside lws.
7*1c60b9acSAndroid Build Coastguard Worker
8*1c60b9acSAndroid Build Coastguard WorkerIn an effort to separate out completely network implementation
9*1c60b9acSAndroid Build Coastguard Workerdetails from protocol specification, lws now supports
10*1c60b9acSAndroid Build Coastguard Worker"abstract protocols" and "abstract transports".
11*1c60b9acSAndroid Build Coastguard Worker
12*1c60b9acSAndroid Build Coastguard Worker![lws_abstract overview](/doc-assets/abstract-overview.svg)
13*1c60b9acSAndroid Build Coastguard Worker
14*1c60b9acSAndroid Build Coastguard WorkerThe concept is that the implementation is split into two separate
15*1c60b9acSAndroid Build Coastguard Workerchunks of code hidden behind "ops" structs... the "abstract protocol"
16*1c60b9acSAndroid Build Coastguard Workerimplementation is responsible for the logical protocol operation
17*1c60b9acSAndroid Build Coastguard Workerand reads and writes only memory buffers.
18*1c60b9acSAndroid Build Coastguard Worker
19*1c60b9acSAndroid Build Coastguard WorkerThe "abstract transport" implementation is responsible for sending
20*1c60b9acSAndroid Build Coastguard Workerand receiving buffers on some kind of transport, and again is hidden
21*1c60b9acSAndroid Build Coastguard Workerbehind a standardized ops struct.
22*1c60b9acSAndroid Build Coastguard Worker
23*1c60b9acSAndroid Build Coastguard WorkerIn the system, both the abstract protocols and transports are
24*1c60b9acSAndroid Build Coastguard Workerfound by their name.
25*1c60b9acSAndroid Build Coastguard Worker
26*1c60b9acSAndroid Build Coastguard WorkerAn actual "connection" is created by calling a generic api
27*1c60b9acSAndroid Build Coastguard Worker`lws_abs_bind_and_create_instance()` to instantiate the
28*1c60b9acSAndroid Build Coastguard Workercombination of a protocol and a transport.
29*1c60b9acSAndroid Build Coastguard Worker
30*1c60b9acSAndroid Build Coastguard WorkerThis makes it possible to confidently offer the same protocol on
31*1c60b9acSAndroid Build Coastguard Workercompletely different transports, eg, like serial, or to wire
32*1c60b9acSAndroid Build Coastguard Workerup the protocol implementation to a test jig sending canned
33*1c60b9acSAndroid Build Coastguard Workertest vectors and confirming the response at buffer level, without
34*1c60b9acSAndroid Build Coastguard Workerany network.  The abstract protocol itself has no relationship
35*1c60b9acSAndroid Build Coastguard Workerto the transport at all and is completely unchanged by changes
36*1c60b9acSAndroid Build Coastguard Workerto the transport.
37*1c60b9acSAndroid Build Coastguard Worker
38*1c60b9acSAndroid Build Coastguard WorkerIn addition, generic tokens to control settings in both the
39*1c60b9acSAndroid Build Coastguard Workerprotocol and the transport are passed in at instantiation-time,
40*1c60b9acSAndroid Build Coastguard Workereg, controlling the IP address targeted by the transport.
41*1c60b9acSAndroid Build Coastguard Worker
42*1c60b9acSAndroid Build Coastguard Workerlws SMTP client support has been rewritten to use the new scheme,
43*1c60b9acSAndroid Build Coastguard Workerand lws provides a raw socket transport built-in.
44*1c60b9acSAndroid Build Coastguard Worker
45*1c60b9acSAndroid Build Coastguard Worker## Public API
46*1c60b9acSAndroid Build Coastguard Worker
47*1c60b9acSAndroid Build Coastguard WorkerThe public api for defining abstract protocols and transports is
48*1c60b9acSAndroid Build Coastguard Workerfound at
49*1c60b9acSAndroid Build Coastguard Worker
50*1c60b9acSAndroid Build Coastguard Worker - [abstract.h](https://libwebsockets.org/git/libwebsockets/tree/include/libwebsockets/abstract/abstract.h)
51*1c60b9acSAndroid Build Coastguard Worker - [protocols.h](https://libwebsockets.org/git/libwebsockets/tree/include/libwebsockets/abstract/protocols.h)
52*1c60b9acSAndroid Build Coastguard Worker - [transports.h](https://libwebsockets.org/git/libwebsockets/tree/include/libwebsockets/abstract/transports.h)
53*1c60b9acSAndroid Build Coastguard Worker
54*1c60b9acSAndroid Build Coastguard Worker### `lws_abs_t`
55*1c60b9acSAndroid Build Coastguard Worker
56*1c60b9acSAndroid Build Coastguard WorkerThe main structure that defines the abstraction is `lws_abs_t`,
57*1c60b9acSAndroid Build Coastguard Workerthis is a name and then pointers to the protocol and transport,
58*1c60b9acSAndroid Build Coastguard Workeroptional tokens to control both the protocol and transport,
59*1c60b9acSAndroid Build Coastguard Workerand pointers to private allocations for both the
60*1c60b9acSAndroid Build Coastguard Workerprotocol and transport when instantiated.
61*1c60b9acSAndroid Build Coastguard Worker
62*1c60b9acSAndroid Build Coastguard WorkerThe transport is selected using
63*1c60b9acSAndroid Build Coastguard Worker
64*1c60b9acSAndroid Build Coastguard Worker```
65*1c60b9acSAndroid Build Coastguard WorkerLWS_VISIBLE LWS_EXTERN const lws_abs_transport_t *
66*1c60b9acSAndroid Build Coastguard Workerlws_abs_transport_get_by_name(const char *name);
67*1c60b9acSAndroid Build Coastguard Worker```
68*1c60b9acSAndroid Build Coastguard Worker
69*1c60b9acSAndroid Build Coastguard Workerand similarly the protocol by
70*1c60b9acSAndroid Build Coastguard Worker
71*1c60b9acSAndroid Build Coastguard Worker```
72*1c60b9acSAndroid Build Coastguard WorkerLWS_VISIBLE LWS_EXTERN const lws_abs_protocol_t *
73*1c60b9acSAndroid Build Coastguard Workerlws_abs_protocol_get_by_name(const char *name);
74*1c60b9acSAndroid Build Coastguard Worker```
75*1c60b9acSAndroid Build Coastguard Worker
76*1c60b9acSAndroid Build Coastguard WorkerAt the moment only "`raw-skt`" is defined as an lws built-in, athough
77*1c60b9acSAndroid Build Coastguard Workeryou can also create your own mock transport the same way for creating
78*1c60b9acSAndroid Build Coastguard Workertest jigs.
79*1c60b9acSAndroid Build Coastguard Worker
80*1c60b9acSAndroid Build Coastguard Worker|transport op|meaning|
81*1c60b9acSAndroid Build Coastguard Worker|---|---|
82*1c60b9acSAndroid Build Coastguard Worker|`tx()`|transmit a buffer|
83*1c60b9acSAndroid Build Coastguard Worker|`client_conn()`|start a connection to a peer|
84*1c60b9acSAndroid Build Coastguard Worker|`close()`|request to close the connection to a peer|
85*1c60b9acSAndroid Build Coastguard Worker|`ask_for_writeable()`|request a `writeable()` callback when tx can be used|
86*1c60b9acSAndroid Build Coastguard Worker|`set_timeout()`|set a timeout that will close the connection if reached|
87*1c60b9acSAndroid Build Coastguard Worker|`state()`|check if the connection is established and can carry traffic|
88*1c60b9acSAndroid Build Coastguard Worker
89*1c60b9acSAndroid Build Coastguard WorkerThese are called by the protocol to get things done and make queries
90*1c60b9acSAndroid Build Coastguard Workerthrough the abstract transport.
91*1c60b9acSAndroid Build Coastguard Worker
92*1c60b9acSAndroid Build Coastguard Worker|protocol op|meaning|
93*1c60b9acSAndroid Build Coastguard Worker|---|---|
94*1c60b9acSAndroid Build Coastguard Worker|`accept()`|The peer has accepted the transport connection|
95*1c60b9acSAndroid Build Coastguard Worker|`rx()`|The peer has sent us some payload|
96*1c60b9acSAndroid Build Coastguard Worker|`writeable()`|The connection to the peer can take more tx|
97*1c60b9acSAndroid Build Coastguard Worker|`closed()`|The connection to the peer has closed|
98*1c60b9acSAndroid Build Coastguard Worker|`heartbeat()`|Called periodically even when no network events|
99*1c60b9acSAndroid Build Coastguard Worker
100*1c60b9acSAndroid Build Coastguard WorkerThese are called by the transport to inform the protocol of events
101*1c60b9acSAndroid Build Coastguard Workerand traffic.
102*1c60b9acSAndroid Build Coastguard Worker
103*1c60b9acSAndroid Build Coastguard Worker### Instantiation
104*1c60b9acSAndroid Build Coastguard Worker
105*1c60b9acSAndroid Build Coastguard WorkerThe user fills an lws_abs_t and passes a pointer to it to
106*1c60b9acSAndroid Build Coastguard Worker`lws_abs_bind_and_create_instance()` to create an instantiation
107*1c60b9acSAndroid Build Coastguard Workerof the protocol + transport.
108*1c60b9acSAndroid Build Coastguard Worker
109*1c60b9acSAndroid Build Coastguard Worker### `lws_token_map_t`
110*1c60b9acSAndroid Build Coastguard Worker
111*1c60b9acSAndroid Build Coastguard WorkerThe abstract protocol has no idea about a network or network addresses
112*1c60b9acSAndroid Build Coastguard Workeror ports or whatever... it may not even be hooked up to one.
113*1c60b9acSAndroid Build Coastguard Worker
114*1c60b9acSAndroid Build Coastguard WorkerIf the transport it is bound to wants things like that, they are passed
115*1c60b9acSAndroid Build Coastguard Workerin using an array of `lws_token_map_t` at instantiation time.
116*1c60b9acSAndroid Build Coastguard Worker
117*1c60b9acSAndroid Build Coastguard WorkerFor example this is passed to the raw socket protocol in the smtp client
118*1c60b9acSAndroid Build Coastguard Workerminimal example to control where it would connect to:
119*1c60b9acSAndroid Build Coastguard Worker
120*1c60b9acSAndroid Build Coastguard Worker```
121*1c60b9acSAndroid Build Coastguard Workerstatic const lws_token_map_t smtp_abs_tokens[] = {
122*1c60b9acSAndroid Build Coastguard Worker{
123*1c60b9acSAndroid Build Coastguard Worker	.u = { .value = "127.0.0.1" },
124*1c60b9acSAndroid Build Coastguard Worker	.name_index = LTMI_PEER_DNS_ADDRESS,
125*1c60b9acSAndroid Build Coastguard Worker}, {
126*1c60b9acSAndroid Build Coastguard Worker	.u = { .lvalue = 25l },
127*1c60b9acSAndroid Build Coastguard Worker	.name_index = LTMI_PEER_PORT,
128*1c60b9acSAndroid Build Coastguard Worker}};
129*1c60b9acSAndroid Build Coastguard Worker```
130*1c60b9acSAndroid Build Coastguard Worker
131*1c60b9acSAndroid Build Coastguard Worker## Steps for adding new abstract protocols
132*1c60b9acSAndroid Build Coastguard Worker
133*1c60b9acSAndroid Build Coastguard Worker - add the public header in `./include/libwebsockets/abstract/protocols/`
134*1c60b9acSAndroid Build Coastguard Worker - add a directory under `./lib/abstract/protocols/`
135*1c60b9acSAndroid Build Coastguard Worker - add your protocol sources in the new directory
136*1c60b9acSAndroid Build Coastguard Worker - in CMakeLists.txt:
137*1c60b9acSAndroid Build Coastguard Worker   - add an `LWS_WITH_xxx` for your protocol
138*1c60b9acSAndroid Build Coastguard Worker   - search for "using any abstract protocol" and add your `LWS_WITH_xxx` to
139*1c60b9acSAndroid Build Coastguard Worker     the if so it also sets `LWS_WITH_ABSTRACT` if any set
140*1c60b9acSAndroid Build Coastguard Worker   - add a clause to append your source to SOURCES if `LWS_WITH_xxx` enabled
141*1c60b9acSAndroid Build Coastguard Worker - add your `lws_abs_protocol` to the list `available_abs_protocols` in
142*1c60b9acSAndroid Build Coastguard Worker   `./lib/abstract/abstract.c`
143*1c60b9acSAndroid Build Coastguard Worker
144*1c60b9acSAndroid Build Coastguard Worker## Steps for adding new abstract transports
145*1c60b9acSAndroid Build Coastguard Worker
146*1c60b9acSAndroid Build Coastguard Worker - add the public header in `./include/libwebsockets/abstract/transports/`
147*1c60b9acSAndroid Build Coastguard Worker - add your transport sources under `./lib/abstract/transports/`
148*1c60b9acSAndroid Build Coastguard Worker - in CMakeLists.txt append your transport sources to SOURCES if `LWS_WITH_ABSTRACT`
149*1c60b9acSAndroid Build Coastguard Worker   and any other cmake conditionals
150*1c60b9acSAndroid Build Coastguard Worker - add an extern for your transport `lws_protocols` in `./lib/core-net/private.h`
151*1c60b9acSAndroid Build Coastguard Worker - add your transport `lws_protocols` to `available_abstract_protocols` in
152*1c60b9acSAndroid Build Coastguard Worker   `./lib/core-net/vhost.c`
153*1c60b9acSAndroid Build Coastguard Worker - add your `lws_abs_transport` to the list `available_abs_transports` in
154*1c60b9acSAndroid Build Coastguard Worker   `./lib/abstract/abstract.c`
155*1c60b9acSAndroid Build Coastguard Worker
156*1c60b9acSAndroid Build Coastguard Worker# Protocol testing
157*1c60b9acSAndroid Build Coastguard Worker
158*1c60b9acSAndroid Build Coastguard Worker## unit tests
159*1c60b9acSAndroid Build Coastguard Worker
160*1c60b9acSAndroid Build Coastguard Workerlws features an abstract transport designed to facilitate unit testing.  This
161*1c60b9acSAndroid Build Coastguard Workercontains an lws_sequencer that performs the steps of tests involving sending the
162*1c60b9acSAndroid Build Coastguard Workerprotocol test vector buffers and confirming the response of the protocol matches
163*1c60b9acSAndroid Build Coastguard Workerthe test vectors.
164*1c60b9acSAndroid Build Coastguard Worker
165*1c60b9acSAndroid Build Coastguard Worker## test-sequencer
166*1c60b9acSAndroid Build Coastguard Worker
167*1c60b9acSAndroid Build Coastguard Workertest-sequencer is a helper that sequences running an array of unit tests and
168*1c60b9acSAndroid Build Coastguard Workercollects the statistics and gives a PASS / FAIL result.
169*1c60b9acSAndroid Build Coastguard Worker
170*1c60b9acSAndroid Build Coastguard WorkerSee the SMTP client api test for an example of how to use.
171