1d4afb5ceSopenharmony_ci/*
2d4afb5ceSopenharmony_ci * libwebsockets - small server side websockets and web server implementation
3d4afb5ceSopenharmony_ci *
4d4afb5ceSopenharmony_ci * Copyright (C) 2010 - 2020 Andy Green <andy@warmcat.com>
5d4afb5ceSopenharmony_ci *
6d4afb5ceSopenharmony_ci * Permission is hereby granted, free of charge, to any person obtaining a copy
7d4afb5ceSopenharmony_ci * of this software and associated documentation files (the "Software"), to
8d4afb5ceSopenharmony_ci * deal in the Software without restriction, including without limitation the
9d4afb5ceSopenharmony_ci * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
10d4afb5ceSopenharmony_ci * sell copies of the Software, and to permit persons to whom the Software is
11d4afb5ceSopenharmony_ci * furnished to do so, subject to the following conditions:
12d4afb5ceSopenharmony_ci *
13d4afb5ceSopenharmony_ci * The above copyright notice and this permission notice shall be included in
14d4afb5ceSopenharmony_ci * all copies or substantial portions of the Software.
15d4afb5ceSopenharmony_ci *
16d4afb5ceSopenharmony_ci * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17d4afb5ceSopenharmony_ci * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18d4afb5ceSopenharmony_ci * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19d4afb5ceSopenharmony_ci * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20d4afb5ceSopenharmony_ci * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
21d4afb5ceSopenharmony_ci * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
22d4afb5ceSopenharmony_ci * IN THE SOFTWARE.
23d4afb5ceSopenharmony_ci */
24d4afb5ceSopenharmony_ci
25d4afb5ceSopenharmony_ci#include "private-lib-core.h"
26d4afb5ceSopenharmony_ci
27d4afb5ceSopenharmony_civoid
28d4afb5ceSopenharmony_cilws_state_reg_notifier(lws_state_manager_t *mgr,
29d4afb5ceSopenharmony_ci		       lws_state_notify_link_t *notify_link)
30d4afb5ceSopenharmony_ci{
31d4afb5ceSopenharmony_ci	lws_dll2_add_head(&notify_link->list, &mgr->notify_list);
32d4afb5ceSopenharmony_ci}
33d4afb5ceSopenharmony_ci
34d4afb5ceSopenharmony_civoid
35d4afb5ceSopenharmony_cilws_state_reg_deregister(lws_state_notify_link_t *nl)
36d4afb5ceSopenharmony_ci{
37d4afb5ceSopenharmony_ci	lws_dll2_remove(&nl->list);
38d4afb5ceSopenharmony_ci}
39d4afb5ceSopenharmony_ci
40d4afb5ceSopenharmony_civoid
41d4afb5ceSopenharmony_cilws_state_reg_notifier_list(lws_state_manager_t *mgr,
42d4afb5ceSopenharmony_ci			    lws_state_notify_link_t * const *notify_link_array)
43d4afb5ceSopenharmony_ci{
44d4afb5ceSopenharmony_ci	if (notify_link_array)
45d4afb5ceSopenharmony_ci		while (*notify_link_array)
46d4afb5ceSopenharmony_ci			lws_state_reg_notifier(mgr, *notify_link_array++);
47d4afb5ceSopenharmony_ci}
48d4afb5ceSopenharmony_ci
49d4afb5ceSopenharmony_ci#if (_LWS_ENABLED_LOGS & (LLL_INFO | LLL_DEBUG))
50d4afb5ceSopenharmony_cistatic const char *
51d4afb5ceSopenharmony_ci_systnm(lws_state_manager_t *mgr, int state, char *temp8)
52d4afb5ceSopenharmony_ci{
53d4afb5ceSopenharmony_ci	if (!mgr->state_names) {
54d4afb5ceSopenharmony_ci		lws_snprintf(temp8, 8, "%d", state);
55d4afb5ceSopenharmony_ci		return temp8;
56d4afb5ceSopenharmony_ci	}
57d4afb5ceSopenharmony_ci
58d4afb5ceSopenharmony_ci	return mgr->state_names[state];
59d4afb5ceSopenharmony_ci}
60d4afb5ceSopenharmony_ci#endif
61d4afb5ceSopenharmony_ci
62d4afb5ceSopenharmony_cistatic int
63d4afb5ceSopenharmony_ci_report(lws_state_manager_t *mgr, int a, int b)
64d4afb5ceSopenharmony_ci{
65d4afb5ceSopenharmony_ci#if (_LWS_ENABLED_LOGS & LLL_INFO)
66d4afb5ceSopenharmony_ci	char temp8[8];
67d4afb5ceSopenharmony_ci#endif
68d4afb5ceSopenharmony_ci
69d4afb5ceSopenharmony_ci	lws_start_foreach_dll(struct lws_dll2 *, d, mgr->notify_list.head) {
70d4afb5ceSopenharmony_ci		lws_state_notify_link_t *l =
71d4afb5ceSopenharmony_ci			lws_container_of(d, lws_state_notify_link_t, list);
72d4afb5ceSopenharmony_ci
73d4afb5ceSopenharmony_ci		if (l->notify_cb(mgr, l, a, b)) {
74d4afb5ceSopenharmony_ci			/* a dependency took responsibility for retry */
75d4afb5ceSopenharmony_ci
76d4afb5ceSopenharmony_ci#if (_LWS_ENABLED_LOGS & LLL_INFO)
77d4afb5ceSopenharmony_ci			lwsl_cx_info(mgr->context, "%s: %s: rejected '%s' -> '%s'",
78d4afb5ceSopenharmony_ci				     mgr->name, l->name,
79d4afb5ceSopenharmony_ci				     _systnm(mgr, a, temp8),
80d4afb5ceSopenharmony_ci				     _systnm(mgr, b, temp8));
81d4afb5ceSopenharmony_ci#endif
82d4afb5ceSopenharmony_ci
83d4afb5ceSopenharmony_ci			return 1;
84d4afb5ceSopenharmony_ci		}
85d4afb5ceSopenharmony_ci
86d4afb5ceSopenharmony_ci	} lws_end_foreach_dll(d);
87d4afb5ceSopenharmony_ci
88d4afb5ceSopenharmony_ci	return 0;
89d4afb5ceSopenharmony_ci}
90d4afb5ceSopenharmony_ci
91d4afb5ceSopenharmony_cistatic int
92d4afb5ceSopenharmony_ci_lws_state_transition(lws_state_manager_t *mgr, int target)
93d4afb5ceSopenharmony_ci{
94d4afb5ceSopenharmony_ci#if (_LWS_ENABLED_LOGS & LLL_DEBUG)
95d4afb5ceSopenharmony_ci	char temp8[8];
96d4afb5ceSopenharmony_ci#endif
97d4afb5ceSopenharmony_ci
98d4afb5ceSopenharmony_ci	if (_report(mgr, mgr->state, target))
99d4afb5ceSopenharmony_ci		return 1;
100d4afb5ceSopenharmony_ci
101d4afb5ceSopenharmony_ci#if (_LWS_ENABLED_LOGS & LLL_DEBUG)
102d4afb5ceSopenharmony_ci	if (mgr->context)
103d4afb5ceSopenharmony_ci	lwsl_cx_debug(mgr->context, "%s: changed %d '%s' -> %d '%s'", mgr->name,
104d4afb5ceSopenharmony_ci		   mgr->state, _systnm(mgr, mgr->state, temp8), target,
105d4afb5ceSopenharmony_ci		   _systnm(mgr, target, temp8));
106d4afb5ceSopenharmony_ci#endif
107d4afb5ceSopenharmony_ci
108d4afb5ceSopenharmony_ci	mgr->state = target;
109d4afb5ceSopenharmony_ci
110d4afb5ceSopenharmony_ci	/* Indicate success by calling the notifers again with both args same */
111d4afb5ceSopenharmony_ci	_report(mgr, target, target);
112d4afb5ceSopenharmony_ci
113d4afb5ceSopenharmony_ci#if defined(LWS_WITH_SYS_SMD)
114d4afb5ceSopenharmony_ci	if (mgr->smd_class && mgr->context)
115d4afb5ceSopenharmony_ci		(void)lws_smd_msg_printf(mgr->context,
116d4afb5ceSopenharmony_ci				   mgr->smd_class, "{\"state\":\"%s\"}",
117d4afb5ceSopenharmony_ci				   mgr->state_names[target]);
118d4afb5ceSopenharmony_ci#endif
119d4afb5ceSopenharmony_ci
120d4afb5ceSopenharmony_ci	return 0;
121d4afb5ceSopenharmony_ci}
122d4afb5ceSopenharmony_ci
123d4afb5ceSopenharmony_ciint
124d4afb5ceSopenharmony_cilws_state_transition_steps(lws_state_manager_t *mgr, int target)
125d4afb5ceSopenharmony_ci{
126d4afb5ceSopenharmony_ci	int n = 0;
127d4afb5ceSopenharmony_ci#if (_LWS_ENABLED_LOGS & LLL_INFO)
128d4afb5ceSopenharmony_ci	int i = mgr->state;
129d4afb5ceSopenharmony_ci	char temp8[8];
130d4afb5ceSopenharmony_ci#endif
131d4afb5ceSopenharmony_ci
132d4afb5ceSopenharmony_ci	if (mgr->state > target)
133d4afb5ceSopenharmony_ci		return 0;
134d4afb5ceSopenharmony_ci
135d4afb5ceSopenharmony_ci	while (!n && mgr->state != target)
136d4afb5ceSopenharmony_ci		n = _lws_state_transition(mgr, mgr->state + 1);
137d4afb5ceSopenharmony_ci
138d4afb5ceSopenharmony_ci#if (_LWS_ENABLED_LOGS & LLL_INFO)
139d4afb5ceSopenharmony_ci	lwsl_cx_info(mgr->context, "%s -> %s", _systnm(mgr, i, temp8),
140d4afb5ceSopenharmony_ci			_systnm(mgr, mgr->state, temp8));
141d4afb5ceSopenharmony_ci#endif
142d4afb5ceSopenharmony_ci
143d4afb5ceSopenharmony_ci	return 0;
144d4afb5ceSopenharmony_ci}
145d4afb5ceSopenharmony_ci
146d4afb5ceSopenharmony_ciint
147d4afb5ceSopenharmony_cilws_state_transition(lws_state_manager_t *mgr, int target)
148d4afb5ceSopenharmony_ci{
149d4afb5ceSopenharmony_ci	if (mgr->state != target)
150d4afb5ceSopenharmony_ci		_lws_state_transition(mgr, target);
151d4afb5ceSopenharmony_ci
152d4afb5ceSopenharmony_ci	return 0;
153d4afb5ceSopenharmony_ci}
154