Coverage Report

Created: 2025-07-18 06:43

/src/libwebsockets/lib/core-net/state.c
Line
Count
Source (jump to first uncovered line)
1
/*
2
 * libwebsockets - small server side websockets and web server implementation
3
 *
4
 * Copyright (C) 2010 - 2020 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
25
#include "private-lib-core.h"
26
27
void
28
lws_state_reg_notifier(lws_state_manager_t *mgr,
29
           lws_state_notify_link_t *notify_link)
30
0
{
31
0
  lws_dll2_add_head(&notify_link->list, &mgr->notify_list);
32
0
}
33
34
void
35
lws_state_reg_deregister(lws_state_notify_link_t *nl)
36
0
{
37
0
  lws_dll2_remove(&nl->list);
38
0
}
39
40
void
41
lws_state_reg_notifier_list(lws_state_manager_t *mgr,
42
          lws_state_notify_link_t * const *notify_link_array)
43
0
{
44
0
  if (notify_link_array)
45
0
    while (*notify_link_array)
46
0
      lws_state_reg_notifier(mgr, *notify_link_array++);
47
0
}
48
49
#if (_LWS_ENABLED_LOGS & (LLL_INFO | LLL_DEBUG))
50
static const char *
51
_systnm(lws_state_manager_t *mgr, int state, char *temp8)
52
0
{
53
0
  if (!mgr->state_names) {
54
0
    lws_snprintf(temp8, 8, "%d", state);
55
0
    return temp8;
56
0
  }
57
58
0
  return mgr->state_names[state];
59
0
}
60
#endif
61
62
static int
63
_report(lws_state_manager_t *mgr, int a, int b)
64
0
{
65
0
#if (_LWS_ENABLED_LOGS & LLL_INFO)
66
0
  char temp8[8];
67
0
#endif
68
69
0
  lws_start_foreach_dll(struct lws_dll2 *, d, mgr->notify_list.head) {
70
0
    lws_state_notify_link_t *l =
71
0
      lws_container_of(d, lws_state_notify_link_t, list);
72
73
0
    if (l->notify_cb(mgr, l, a, b)) {
74
      /* a dependency took responsibility for retry */
75
76
0
#if (_LWS_ENABLED_LOGS & LLL_INFO)
77
0
      lwsl_cx_info(mgr->context, "%s: %s: rejected '%s' -> '%s'",
78
0
             mgr->name, l->name,
79
0
             _systnm(mgr, a, temp8),
80
0
             _systnm(mgr, b, temp8));
81
0
#endif
82
83
0
      return 1;
84
0
    }
85
86
0
  } lws_end_foreach_dll(d);
87
88
0
  return 0;
89
0
}
90
91
static int
92
_lws_state_transition(lws_state_manager_t *mgr, int target)
93
0
{
94
0
#if (_LWS_ENABLED_LOGS & LLL_DEBUG)
95
0
  char temp8[8];
96
0
#endif
97
98
0
  if (_report(mgr, mgr->state, target))
99
0
    return 1;
100
101
0
#if (_LWS_ENABLED_LOGS & LLL_DEBUG)
102
0
  if (mgr->context)
103
0
  lwsl_cx_debug(mgr->context, "%s: changed %d '%s' -> %d '%s'", mgr->name,
104
0
       mgr->state, _systnm(mgr, mgr->state, temp8), target,
105
0
       _systnm(mgr, target, temp8));
106
0
#endif
107
108
0
  mgr->state = target;
109
110
  /* Indicate success by calling the notifers again with both args same */
111
0
  _report(mgr, target, target);
112
113
0
#if defined(LWS_WITH_SYS_SMD)
114
0
  if (mgr->smd_class && mgr->context)
115
0
    (void)lws_smd_msg_printf(mgr->context,
116
0
           mgr->smd_class, "{\"state\":\"%s\"}",
117
0
           mgr->state_names[target]);
118
0
#endif
119
120
0
  return 0;
121
0
}
122
123
int
124
lws_state_transition_steps(lws_state_manager_t *mgr, int target)
125
0
{
126
0
  int n = 0;
127
0
#if (_LWS_ENABLED_LOGS & LLL_INFO)
128
0
  int i = mgr->state;
129
0
  char temp8[8];
130
0
#endif
131
132
0
  if (mgr->state > target)
133
0
    return 0;
134
135
0
  while (!n && mgr->state != target)
136
0
    n = _lws_state_transition(mgr, mgr->state + 1);
137
138
0
#if (_LWS_ENABLED_LOGS & LLL_INFO)
139
0
  lwsl_cx_info(mgr->context, "%s -> %s", _systnm(mgr, i, temp8),
140
0
      _systnm(mgr, mgr->state, temp8));
141
0
#endif
142
143
0
  return 0;
144
0
}
145
146
int
147
lws_state_transition(lws_state_manager_t *mgr, int target)
148
0
{
149
0
  if (mgr->state != target)
150
0
    _lws_state_transition(mgr, target);
151
152
0
  return 0;
153
0
}