libwebsockets
Lightweight C library for HTML5 websockets
lws-system.h
Go to the documentation of this file.
1 /*
2 * libwebsockets - small server side websockets and web server implementation
3 *
4 * Copyright (C) 2010 - 2021 Andy Green <andy@warmcat.com>
5 *
6 * Permission is hereby granted, free of charge, to any person obtaining a copy
7 * of this software and associated documentation files (the "Software"), to
8 * deal in the Software without restriction, including without limitation the
9 * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
10 * sell copies of the Software, and to permit persons to whom the Software is
11 * furnished to do so, subject to the following conditions:
12 *
13 * The above copyright notice and this permission notice shall be included in
14 * all copies or substantial portions of the Software.
15 *
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
21 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
22 * IN THE SOFTWARE.
23 *
24 * This provides a clean way to interface lws user code to be able to
25 * work unchanged on different systems for fetching common system information,
26 * and performing common system operations like reboot.
27 */
28
29/*
30 * Types of system blob that can be set and retreived
31 */
32
33typedef enum {
44
45#if defined(LWS_WITH_SECURE_STREAMS_AUTH_SIGV4)
46 /* extend 4 more auth blobs, each has 2 slots */
47 LWS_SYSBLOB_TYPE_EXT_AUTH1,
48 LWS_SYSBLOB_TYPE_EXT_AUTH2 = LWS_SYSBLOB_TYPE_EXT_AUTH1 + 2,
49 LWS_SYSBLOB_TYPE_EXT_AUTH3 = LWS_SYSBLOB_TYPE_EXT_AUTH2 + 2,
50 LWS_SYSBLOB_TYPE_EXT_AUTH4 = LWS_SYSBLOB_TYPE_EXT_AUTH3 + 2,
51 LWS_SYSBLOB_TYPE_EXT_AUTH4_1,
52#endif
53
54 LWS_SYSBLOB_TYPE_COUNT /* ... always last */
55} lws_system_blob_item_t;
56
57/* opaque generic blob whose content may be on-the-heap or pointed-to
58 * directly case by case. When it's on the heap, it can be produced by
59 * appending (it's a buflist underneath). Either way, it can be consumed by
60 * copying out a given length from a given offset.
61 */
62
63typedef struct lws_system_blob lws_system_blob_t;
64
65LWS_EXTERN LWS_VISIBLE void
66lws_system_blob_direct_set(lws_system_blob_t *b, const uint8_t *ptr, size_t len);
67
68LWS_EXTERN LWS_VISIBLE void
70
71LWS_EXTERN LWS_VISIBLE int
72lws_system_blob_heap_append(lws_system_blob_t *b, const uint8_t *ptr, size_t len);
73
74LWS_EXTERN LWS_VISIBLE size_t
75lws_system_blob_get_size(lws_system_blob_t *b);
76
77/* return 0 and sets *ptr to point to blob data if possible, nonzero = fail */
78LWS_EXTERN LWS_VISIBLE int
80
81LWS_EXTERN LWS_VISIBLE int
82lws_system_blob_get(lws_system_blob_t *b, uint8_t *ptr, size_t *len, size_t ofs);
83
84LWS_EXTERN LWS_VISIBLE void
86
87/*
88 * Get the opaque blob for index idx of various system blobs. Returns 0 if
89 * *b was set otherwise nonzero means out of range
90 */
91
92LWS_EXTERN LWS_VISIBLE lws_system_blob_t *
93lws_system_get_blob(struct lws_context *context, lws_system_blob_item_t type,
94 int idx);
95
96/*
97 * Lws view of system state... normal operation from user code perspective is
98 * dependent on implicit (eg, knowing the date for cert validation) and
99 * explicit dependencies.
100 *
101 * Bit of lws and user code can register notification handlers that can enforce
102 * dependent operations before state transitions can complete.
103 */
104
105typedef enum { /* keep system_state_names[] in sync in context.c */
107
108 LWS_SYSTATE_CONTEXT_CREATED, /* context was just created */
109 LWS_SYSTATE_INITIALIZED, /* protocols initialized. Lws itself
110 * can operate normally */
111 LWS_SYSTATE_IFACE_COLDPLUG, /* existing net ifaces iterated */
112 LWS_SYSTATE_DHCP, /* at least one net iface configured */
113 LWS_SYSTATE_CPD_PRE_TIME, /* Captive portal detect without valid
114 * time, good for non-https tests... if
115 * you care about it, implement and
116 * call lws_system_ops_t
117 * .captive_portal_detect_request()
118 * and move the state forward according
119 * to the result. */
120 LWS_SYSTATE_TIME_VALID, /* ntpclient ran, or hw time valid...
121 * tls cannot work until we reach here
122 */
123 LWS_SYSTATE_CPD_POST_TIME, /* Captive portal detect after time was
124 * time, good for https tests... if
125 * you care about it, implement and
126 * call lws_system_ops_t
127 * .captive_portal_detect_request()
128 * and move the state forward according
129 * to the result. */
130
131 LWS_SYSTATE_POLICY_VALID, /* user code knows how to operate... */
132 LWS_SYSTATE_REGISTERED, /* device has an identity... */
133 LWS_SYSTATE_AUTH1, /* identity used for main auth token */
134 LWS_SYSTATE_AUTH2, /* identity used for optional auth */
135
136 LWS_SYSTATE_ONE_TIME_UPDATES, /* pre-OPERATIONAL one-time updates,
137 * when a firmware needs to perform
138 * one-time upgrades to state before
139 * OPERATIONAL */
140
141 LWS_SYSTATE_OPERATIONAL, /* user code can operate normally */
142
143 LWS_SYSTATE_POLICY_INVALID, /* user code is changing its policies
144 * drop everything done with old
145 * policy, switch to new then enter
146 * LWS_SYSTATE_POLICY_VALID */
147 LWS_SYSTATE_CONTEXT_DESTROYING, /* Context is being destroyed */
148 LWS_SYSTATE_AWAITING_MODAL_UPDATING, /* We're negotiating with the
149 * user code for update mode */
150 LWS_SYSTATE_MODAL_UPDATING, /* We're updating the firmware */
151} lws_system_states_t;
152
153/* Captive Portal Detect -related */
154
155typedef enum {
156 LWS_CPD_UNKNOWN = 0, /* test didn't happen ince last DHCP acq yet */
157 LWS_CPD_INTERNET_OK, /* no captive portal: our CPD test passed OK,
158 * we can go out on the internet */
159 LWS_CPD_CAPTIVE_PORTAL, /* we inferred we're behind a captive portal */
160 LWS_CPD_NO_INTERNET, /* we couldn't touch anything */
161} lws_cpd_result_t;
162
163typedef void (*lws_attach_cb_t)(struct lws_context *context, int tsi, void *opaque);
164struct lws_attach_item;
165
166LWS_EXTERN LWS_VISIBLE int
167lws_tls_jit_trust_got_cert_cb(struct lws_context *cx, void *got_opaque,
168 const uint8_t *skid, size_t skid_len,
169 const uint8_t *der, size_t der_len);
170
171typedef struct lws_system_ops {
172 int (*reboot)(void);
173 int (*set_clock)(lws_usec_t us);
174 int (*attach)(struct lws_context *context, int tsi, lws_attach_cb_t cb,
175 lws_system_states_t state, void *opaque,
176 struct lws_attach_item **get);
177 /**< if \p get is NULL, add an attach callback request to the pt for
178 * \p cb with arg \p opaque, that should be called when we're at or past
179 * system state \p state.
180 *
181 * If \p get is non-NULL, look for the first listed item on the pt whose
182 * state situation is ready, and set *get to point to it. If no items,
183 * or none where the system state is right, set *get to NULL.
184 *
185 * It's done like this so (*attach) can perform system-specific
186 * locking outside of lws core, for both getting and adding items the
187 * same so it is thread-safe. A non-threadsafe helper
188 * __lws_system_attach() is provided to do the actual work inside the
189 * system-specific locking.
190 */
191 int (*captive_portal_detect_request)(struct lws_context *context);
192 /**< Check if we can go out on the internet cleanly, or if we are being
193 * redirected or intercepted by a captive portal.
194 * Start the check that proceeds asynchronously, and report the results
195 * by calling lws_captive_portal_detect_result() api
196 */
197
198#if defined(LWS_WITH_NETWORK)
200 /**< metric \p item is reporting an event of kind \p rpt,
201 * held in \p mdata... return 0 to leave the metric object as it is,
202 * or nonzero to reset it. */
203#endif
204 int (*jit_trust_query)(struct lws_context *cx, const uint8_t *skid,
205 size_t skid_len, void *got_opaque);
206 /**< user defined trust store search, if we do trust a cert with SKID
207 * matching skid / skid_len, then it should get hold of the DER for the
208 * matching root CA and call
209 * lws_tls_jit_trust_got_cert_cb(..., got_opaque) before cleaning up and
210 * returning. The DER should be destroyed if in heap before returning.
211 */
212
213#if defined(LWS_WITH_OTA)
215 /**< Platform OTA interface to lws_ota, see lws-ota.h */
216#endif
217
219 /**< time taken for this device to wake from suspend, in us
220 */
221} lws_system_ops_t;
222
223#if defined(LWS_WITH_SYS_STATE)
224
225/**
226 * lws_system_get_state_manager() - return the state mgr object for system state
227 *
228 * \param context: the lws_context
229 *
230 * The returned pointer can be used with the lws_state_ apis
231 */
232
233LWS_EXTERN LWS_VISIBLE lws_state_manager_t *
234lws_system_get_state_manager(struct lws_context *context);
235
236#endif
237
238/* wrappers handle NULL members or no ops struct set at all cleanly */
239
240#define LWSSYSGAUTH_HEX (1 << 0)
241
242/**
243 * lws_system_get_ops() - get ahold of the system ops struct from the context
244 *
245 * \param context: the lws_context
246 *
247 * Returns the system ops struct. It may return NULL and if not, anything in
248 * there may be NULL.
249 */
250LWS_EXTERN LWS_VISIBLE const lws_system_ops_t *
251lws_system_get_ops(struct lws_context *context);
252
253#if defined(LWS_WITH_SYS_STATE)
254
255/**
256 * lws_system_context_from_system_mgr() - return context from system state mgr
257 *
258 * \param mgr: pointer to specifically the system state mgr
259 *
260 * Returns the context from the system state mgr. Helper since the lws_context
261 * is opaque.
262 */
263LWS_EXTERN LWS_VISIBLE struct lws_context *
264lws_system_context_from_system_mgr(lws_state_manager_t *mgr);
265
266#endif
267
268/**
269 * __lws_system_attach() - get and set items on context attach list
270 *
271 * \param context: context to get or set attach items to
272 * \param tsi: thread service index (normally 0)
273 * \param cb: callback to call from context event loop thread
274 * \param state: the lws_system state we have to be in or have passed through
275 * \param opaque: optional pointer to user specific info given to callback
276 * \param get: NULL, or pointer to pointer to take detached tail item on exit
277 *
278 * This allows other threads to enqueue callback requests to happen from a pt's
279 * event loop thread safely. The callback gets the context pointer and a user
280 * opaque pointer that can be optionally given when the item is added to the
281 * attach list.
282 *
283 * This api is the no-locking core function for getting and setting items on the
284 * pt's attach list. The lws_system operation (*attach) is the actual
285 * api that user and internal code calls for this feature, it should perform
286 * system-specific locking, call this helper, release the locking and then
287 * return the result. This api is public only so it can be used in the locked
288 * implementation of (*attach).
289 *
290 * If get is NULL, then the call adds to the head of the pt attach list using
291 * cb, state, and opaque; if get is non-NULL, then *get is set to the first
292 * waiting attached item that meets the state criteria and that item is removed
293 * from the list.
294 *
295 * This is a non-threadsafe helper only designed to be called from
296 * implementations of struct lws_system's (*attach) operation where system-
297 * specific locking has been applied around it, making it threadsafe.
298 */
299LWS_EXTERN LWS_VISIBLE int
300__lws_system_attach(struct lws_context *context, int tsi, lws_attach_cb_t cb,
301 lws_system_states_t state, void *opaque,
302 struct lws_attach_item **get);
303
304
305enum {
311
313
322
324};
325
326#if defined(LWS_WITH_NETWORK)
327typedef struct lws_dhcpc_ifstate {
328 char ifname[16];
329 char domain[64];
330 uint8_t mac[6];
331 uint32_t nums[_LWSDH_NUMS_COUNT];
332 lws_sockaddr46 sa46[_LWSDH_SA46_COUNT];
333} lws_dhcpc_ifstate_t;
334
335typedef int (*dhcpc_cb_t)(void *opaque, lws_dhcpc_ifstate_t *is);
336
337/**
338 * lws_dhcpc_request() - add a network interface to dhcpc management
339 *
340 * \param c: the lws_context
341 * \param i: the interface name, like "eth0"
342 * \param af: address family
343 * \param cb: the change callback
344 * \param opaque: opaque pointer given to the callback
345 *
346 * Register a network interface as being managed by DHCP. lws will proceed to
347 * try to acquire an IP. Requires LWS_WITH_SYS_DHCP_CLIENT at cmake.
348 */
349LWS_EXTERN LWS_VISIBLE int
350lws_dhcpc_request(struct lws_context *c, const char *i, int af, dhcpc_cb_t cb,
351 void *opaque);
352
353/**
354 * lws_dhcpc_remove() - remove a network interface to dhcpc management
355 *
356 * \param context: the lws_context
357 * \param iface: the interface name, like "eth0"
358 *
359 * Remove handling of the network interface from dhcp.
360 */
361LWS_EXTERN LWS_VISIBLE int
362lws_dhcpc_remove(struct lws_context *context, const char *iface);
363
364/**
365 * lws_dhcpc_status() - has any interface reached BOUND state
366 *
367 * \param context: the lws_context
368 * \param sa46: set to a DNS server from a bound interface, or NULL
369 *
370 * Returns 1 if any network interface managed by dhcpc has reached the BOUND
371 * state (has acquired an IP, gateway and DNS server), otherwise 0.
372 */
373LWS_EXTERN LWS_VISIBLE int
374lws_dhcpc_status(struct lws_context *context, lws_sockaddr46 *sa46);
375
376/**
377 * lws_system_cpd_start() - helper to initiate captive portal detection
378 *
379 * \param context: the lws_context
380 *
381 * Resets the context's captive portal state to LWS_CPD_UNKNOWN and calls the
382 * lws_system_ops_t captive_portal_detect_request() implementation to begin
383 * testing the captive portal state.
384 */
385LWS_EXTERN LWS_VISIBLE int
386lws_system_cpd_start(struct lws_context *context);
387
388LWS_EXTERN LWS_VISIBLE void
389lws_system_cpd_start_defer(struct lws_context *cx, lws_usec_t defer_us);
390
391
392/**
393 * lws_system_cpd_set() - report the result of the captive portal detection
394 *
395 * \param context: the lws_context
396 * \param result: one of the LWS_CPD_ constants representing captive portal state
397 *
398 * Sets the context's captive portal detection state to result. User captive
399 * portal detection code would call this once it had a result from its test.
400 */
401LWS_EXTERN LWS_VISIBLE void
402lws_system_cpd_set(struct lws_context *context, lws_cpd_result_t result);
403
404
405/**
406 * lws_system_cpd_state_get() - returns the last tested captive portal state
407 *
408 * \param context: the lws_context
409 *
410 * Returns one of the LWS_CPD_ constants indicating the system's understanding
411 * of the current captive portal situation.
412 */
413LWS_EXTERN LWS_VISIBLE lws_cpd_result_t
414lws_system_cpd_state_get(struct lws_context *context);
415
416#endif
LWS_EXTERN LWS_VISIBLE int lws_system_blob_get_single_ptr(lws_system_blob_t *b, const uint8_t **ptr)
@ LWS_CPD_UNKNOWN
Definition: lws-system.h:156
@ LWS_CPD_CAPTIVE_PORTAL
Definition: lws-system.h:159
@ LWS_CPD_NO_INTERNET
Definition: lws-system.h:160
@ LWS_CPD_INTERNET_OK
Definition: lws-system.h:157
@ LWS_SYSTATE_POLICY_VALID
Definition: lws-system.h:131
@ LWS_SYSTATE_AUTH1
Definition: lws-system.h:133
@ LWS_SYSTATE_MODAL_UPDATING
Definition: lws-system.h:150
@ LWS_SYSTATE_AUTH2
Definition: lws-system.h:134
@ LWS_SYSTATE_CONTEXT_DESTROYING
Definition: lws-system.h:147
@ LWS_SYSTATE_CPD_PRE_TIME
Definition: lws-system.h:113
@ LWS_SYSTATE_AWAITING_MODAL_UPDATING
Definition: lws-system.h:148
@ LWS_SYSTATE_UNKNOWN
Definition: lws-system.h:106
@ LWS_SYSTATE_IFACE_COLDPLUG
Definition: lws-system.h:111
@ LWS_SYSTATE_DHCP
Definition: lws-system.h:112
@ LWS_SYSTATE_REGISTERED
Definition: lws-system.h:132
@ LWS_SYSTATE_OPERATIONAL
Definition: lws-system.h:141
@ LWS_SYSTATE_INITIALIZED
Definition: lws-system.h:109
@ LWS_SYSTATE_ONE_TIME_UPDATES
Definition: lws-system.h:136
@ LWS_SYSTATE_TIME_VALID
Definition: lws-system.h:120
@ LWS_SYSTATE_CONTEXT_CREATED
Definition: lws-system.h:108
@ LWS_SYSTATE_POLICY_INVALID
Definition: lws-system.h:143
@ LWS_SYSTATE_CPD_POST_TIME
Definition: lws-system.h:123
LWS_EXTERN LWS_VISIBLE int __lws_system_attach(struct lws_context *context, int tsi, lws_attach_cb_t cb, lws_system_states_t state, void *opaque, struct lws_attach_item **get)
LWS_EXTERN LWS_VISIBLE void lws_system_blob_destroy(lws_system_blob_t *b)
LWS_EXTERN LWS_VISIBLE int lws_system_blob_heap_append(lws_system_blob_t *b, const uint8_t *ptr, size_t len)
LWS_EXTERN LWS_VISIBLE void lws_system_blob_heap_empty(lws_system_blob_t *b)
LWS_EXTERN LWS_VISIBLE int lws_system_blob_get(lws_system_blob_t *b, uint8_t *ptr, size_t *len, size_t ofs)
struct lws_system_blob lws_system_blob_t
Definition: lws-system.h:63
void(* lws_attach_cb_t)(struct lws_context *context, int tsi, void *opaque)
Definition: lws-system.h:163
LWS_EXTERN LWS_VISIBLE void lws_system_blob_direct_set(lws_system_blob_t *b, const uint8_t *ptr, size_t len)
LWS_EXTERN LWS_VISIBLE lws_system_blob_t * lws_system_get_blob(struct lws_context *context, lws_system_blob_item_t type, int idx)
LWS_EXTERN LWS_VISIBLE const lws_system_ops_t * lws_system_get_ops(struct lws_context *context)
LWS_EXTERN LWS_VISIBLE int lws_tls_jit_trust_got_cert_cb(struct lws_context *cx, void *got_opaque, const uint8_t *skid, size_t skid_len, const uint8_t *der, size_t der_len)
@ LWS_SYSBLOB_TYPE_NTP_SERVER
Definition: lws-system.h:40
@ LWS_SYSBLOB_TYPE_MQTT_USERNAME
Definition: lws-system.h:42
@ LWS_SYSBLOB_TYPE_MQTT_PASSWORD
Definition: lws-system.h:43
@ LWS_SYSBLOB_TYPE_MQTT_CLIENT_ID
Definition: lws-system.h:41
@ LWS_SYSBLOB_TYPE_CLIENT_CERT_DER
Definition: lws-system.h:35
@ LWS_SYSBLOB_TYPE_COUNT
Definition: lws-system.h:54
@ LWS_SYSBLOB_TYPE_DEVICE_SERIAL
Definition: lws-system.h:37
@ LWS_SYSBLOB_TYPE_DEVICE_FW_VERSION
Definition: lws-system.h:38
@ LWS_SYSBLOB_TYPE_AUTH
Definition: lws-system.h:34
@ LWS_SYSBLOB_TYPE_DEVICE_TYPE
Definition: lws-system.h:39
@ LWS_SYSBLOB_TYPE_CLIENT_KEY_DER
Definition: lws-system.h:36
@ LWSDH_REBINDING_SECS
Definition: lws-system.h:309
@ LWSDH_SA46_DNS_SRV_4
Definition: lws-system.h:318
@ LWSDH_SA46_IPV4_ROUTER
Definition: lws-system.h:319
@ LWSDH_IPV4_BROADCAST
Definition: lws-system.h:307
@ LWSDH_SA46_NTP_SERVER
Definition: lws-system.h:320
@ _LWSDH_NUMS_COUNT
Definition: lws-system.h:312
@ LWSDH_SA46_IP
Definition: lws-system.h:314
@ LWSDH_SA46_DHCP_SERVER
Definition: lws-system.h:321
@ LWSDH_SA46_DNS_SRV_3
Definition: lws-system.h:317
@ LWSDH_IPV4_SUBNET_MASK
Definition: lws-system.h:306
@ LWSDH_RENEWAL_SECS
Definition: lws-system.h:310
@ LWSDH_SA46_DNS_SRV_1
Definition: lws-system.h:315
@ LWSDH_LEASE_SECS
Definition: lws-system.h:308
@ LWSDH_SA46_DNS_SRV_2
Definition: lws-system.h:316
@ _LWSDH_SA46_COUNT
Definition: lws-system.h:323
int(* attach)(struct lws_context *context, int tsi, lws_attach_cb_t cb, lws_system_states_t state, void *opaque, struct lws_attach_item **get)
Definition: lws-system.h:174
int(* jit_trust_query)(struct lws_context *cx, const uint8_t *skid, size_t skid_len, void *got_opaque)
Definition: lws-system.h:204
int(* captive_portal_detect_request)(struct lws_context *context)
Definition: lws-system.h:191
uint32_t wake_latency_us
Definition: lws-system.h:218
int(* set_clock)(lws_usec_t us)
Definition: lws-system.h:173
int(* reboot)(void)
Definition: lws-system.h:172