1*1c60b9acSAndroid Build Coastguard Worker /*
2*1c60b9acSAndroid Build Coastguard Worker * libwebsockets - small server side websockets and web server implementation
3*1c60b9acSAndroid Build Coastguard Worker *
4*1c60b9acSAndroid Build Coastguard Worker * Copyright (C) 2010 - 2019 Andy Green <[email protected]>
5*1c60b9acSAndroid Build Coastguard Worker *
6*1c60b9acSAndroid Build Coastguard Worker * Permission is hereby granted, free of charge, to any person obtaining a copy
7*1c60b9acSAndroid Build Coastguard Worker * of this software and associated documentation files (the "Software"), to
8*1c60b9acSAndroid Build Coastguard Worker * deal in the Software without restriction, including without limitation the
9*1c60b9acSAndroid Build Coastguard Worker * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
10*1c60b9acSAndroid Build Coastguard Worker * sell copies of the Software, and to permit persons to whom the Software is
11*1c60b9acSAndroid Build Coastguard Worker * furnished to do so, subject to the following conditions:
12*1c60b9acSAndroid Build Coastguard Worker *
13*1c60b9acSAndroid Build Coastguard Worker * The above copyright notice and this permission notice shall be included in
14*1c60b9acSAndroid Build Coastguard Worker * all copies or substantial portions of the Software.
15*1c60b9acSAndroid Build Coastguard Worker *
16*1c60b9acSAndroid Build Coastguard Worker * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17*1c60b9acSAndroid Build Coastguard Worker * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18*1c60b9acSAndroid Build Coastguard Worker * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19*1c60b9acSAndroid Build Coastguard Worker * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20*1c60b9acSAndroid Build Coastguard Worker * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
21*1c60b9acSAndroid Build Coastguard Worker * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
22*1c60b9acSAndroid Build Coastguard Worker * IN THE SOFTWARE.
23*1c60b9acSAndroid Build Coastguard Worker *
24*1c60b9acSAndroid Build Coastguard Worker * This role for wrapping dbus fds in a wsi + role is unusual in that the
25*1c60b9acSAndroid Build Coastguard Worker * wsi it creates and binds to the role do not have control over the related fd
26*1c60b9acSAndroid Build Coastguard Worker * lifecycle. In fact dbus doesn't inform us directly about the lifecycle of
27*1c60b9acSAndroid Build Coastguard Worker * the fds it wants to be managed by the lws event loop.
28*1c60b9acSAndroid Build Coastguard Worker *
29*1c60b9acSAndroid Build Coastguard Worker * What it does tell us is when it wants to wait on POLLOUT and / or POLLIN,
30*1c60b9acSAndroid Build Coastguard Worker * and since it should stop any watchers before close, we take the approach to
31*1c60b9acSAndroid Build Coastguard Worker * create a lightweight "shadow" wsi for any fd from dbus that has a POLLIN or
32*1c60b9acSAndroid Build Coastguard Worker * POLLOUT wait active. When the dbus fd asks to have no wait active, we
33*1c60b9acSAndroid Build Coastguard Worker * destroy the wsi, since this is indistinguishable from dbus close path
34*1c60b9acSAndroid Build Coastguard Worker * behaviour. If it actually stays alive and later asks to wait again, well no
35*1c60b9acSAndroid Build Coastguard Worker * worries we create a new shadow wsi until it looks like it is closing again.
36*1c60b9acSAndroid Build Coastguard Worker */
37*1c60b9acSAndroid Build Coastguard Worker
38*1c60b9acSAndroid Build Coastguard Worker #include <private-lib-core.h>
39*1c60b9acSAndroid Build Coastguard Worker
40*1c60b9acSAndroid Build Coastguard Worker #include <libwebsockets/lws-dbus.h>
41*1c60b9acSAndroid Build Coastguard Worker
42*1c60b9acSAndroid Build Coastguard Worker /*
43*1c60b9acSAndroid Build Coastguard Worker * retreives existing or creates new shadow wsi for fd owned by dbus stuff.
44*1c60b9acSAndroid Build Coastguard Worker *
45*1c60b9acSAndroid Build Coastguard Worker * Requires context + vhost lock
46*1c60b9acSAndroid Build Coastguard Worker */
47*1c60b9acSAndroid Build Coastguard Worker
48*1c60b9acSAndroid Build Coastguard Worker static struct lws *
__lws_shadow_wsi(struct lws_dbus_ctx * ctx,DBusWatch * w,int fd,int create_ok)49*1c60b9acSAndroid Build Coastguard Worker __lws_shadow_wsi(struct lws_dbus_ctx *ctx, DBusWatch *w, int fd, int create_ok)
50*1c60b9acSAndroid Build Coastguard Worker {
51*1c60b9acSAndroid Build Coastguard Worker struct lws *wsi;
52*1c60b9acSAndroid Build Coastguard Worker
53*1c60b9acSAndroid Build Coastguard Worker if (fd < 0 || fd >= (int)ctx->vh->context->fd_limit_per_thread) {
54*1c60b9acSAndroid Build Coastguard Worker lwsl_err("%s: fd %d vs fds_count %d\n", __func__, fd,
55*1c60b9acSAndroid Build Coastguard Worker (int)ctx->vh->context->fd_limit_per_thread);
56*1c60b9acSAndroid Build Coastguard Worker assert(0);
57*1c60b9acSAndroid Build Coastguard Worker
58*1c60b9acSAndroid Build Coastguard Worker return NULL;
59*1c60b9acSAndroid Build Coastguard Worker }
60*1c60b9acSAndroid Build Coastguard Worker
61*1c60b9acSAndroid Build Coastguard Worker wsi = wsi_from_fd(ctx->vh->context, fd);
62*1c60b9acSAndroid Build Coastguard Worker if (wsi) {
63*1c60b9acSAndroid Build Coastguard Worker assert(wsi->opaque_parent_data == ctx);
64*1c60b9acSAndroid Build Coastguard Worker
65*1c60b9acSAndroid Build Coastguard Worker return wsi;
66*1c60b9acSAndroid Build Coastguard Worker }
67*1c60b9acSAndroid Build Coastguard Worker
68*1c60b9acSAndroid Build Coastguard Worker if (!create_ok)
69*1c60b9acSAndroid Build Coastguard Worker return NULL;
70*1c60b9acSAndroid Build Coastguard Worker
71*1c60b9acSAndroid Build Coastguard Worker lws_context_assert_lock_held(wsi->a.context);
72*1c60b9acSAndroid Build Coastguard Worker lws_vhost_assert_lock_held(wsi->a.vhost);
73*1c60b9acSAndroid Build Coastguard Worker
74*1c60b9acSAndroid Build Coastguard Worker /* requires context lock */
75*1c60b9acSAndroid Build Coastguard Worker wsi = __lws_wsi_create_with_role(ctx->vh->context, ctx->tsi, NULL,
76*1c60b9acSAndroid Build Coastguard Worker ctx->vh->lc.log_cx);
77*1c60b9acSAndroid Build Coastguard Worker if (wsi == NULL) {
78*1c60b9acSAndroid Build Coastguard Worker lwsl_err("Out of mem\n");
79*1c60b9acSAndroid Build Coastguard Worker return NULL;
80*1c60b9acSAndroid Build Coastguard Worker }
81*1c60b9acSAndroid Build Coastguard Worker
82*1c60b9acSAndroid Build Coastguard Worker lwsl_info("%s: creating shadow wsi\n", __func__);
83*1c60b9acSAndroid Build Coastguard Worker
84*1c60b9acSAndroid Build Coastguard Worker wsi->desc.sockfd = fd;
85*1c60b9acSAndroid Build Coastguard Worker lws_role_transition(wsi, 0, LRS_ESTABLISHED, &role_ops_dbus);
86*1c60b9acSAndroid Build Coastguard Worker wsi->a.protocol = ctx->vh->protocols;
87*1c60b9acSAndroid Build Coastguard Worker wsi->shadow = 1;
88*1c60b9acSAndroid Build Coastguard Worker wsi->opaque_parent_data = ctx;
89*1c60b9acSAndroid Build Coastguard Worker ctx->w[0] = w;
90*1c60b9acSAndroid Build Coastguard Worker
91*1c60b9acSAndroid Build Coastguard Worker __lws_lc_tag(ctx->vh->context, &ctx->vh->context->lcg[LWSLCG_WSI],
92*1c60b9acSAndroid Build Coastguard Worker &wsi->lc, "dbus|%s", ctx->vh->name);
93*1c60b9acSAndroid Build Coastguard Worker
94*1c60b9acSAndroid Build Coastguard Worker lws_vhost_bind_wsi(ctx->vh, wsi);
95*1c60b9acSAndroid Build Coastguard Worker if (__insert_wsi_socket_into_fds(ctx->vh->context, wsi)) {
96*1c60b9acSAndroid Build Coastguard Worker lwsl_err("inserting wsi socket into fds failed\n");
97*1c60b9acSAndroid Build Coastguard Worker __lws_vhost_unbind_wsi(wsi); /* cx + vh lock */
98*1c60b9acSAndroid Build Coastguard Worker lws_free(wsi);
99*1c60b9acSAndroid Build Coastguard Worker return NULL;
100*1c60b9acSAndroid Build Coastguard Worker }
101*1c60b9acSAndroid Build Coastguard Worker
102*1c60b9acSAndroid Build Coastguard Worker return wsi;
103*1c60b9acSAndroid Build Coastguard Worker }
104*1c60b9acSAndroid Build Coastguard Worker
105*1c60b9acSAndroid Build Coastguard Worker /*
106*1c60b9acSAndroid Build Coastguard Worker * Requires cx + vhost lock
107*1c60b9acSAndroid Build Coastguard Worker */
108*1c60b9acSAndroid Build Coastguard Worker
109*1c60b9acSAndroid Build Coastguard Worker static int
__lws_shadow_wsi_destroy(struct lws_dbus_ctx * ctx,struct lws * wsi)110*1c60b9acSAndroid Build Coastguard Worker __lws_shadow_wsi_destroy(struct lws_dbus_ctx *ctx, struct lws *wsi)
111*1c60b9acSAndroid Build Coastguard Worker {
112*1c60b9acSAndroid Build Coastguard Worker lwsl_info("%s: destroying shadow wsi\n", __func__);
113*1c60b9acSAndroid Build Coastguard Worker
114*1c60b9acSAndroid Build Coastguard Worker lws_context_assert_lock_held(wsi->a.context);
115*1c60b9acSAndroid Build Coastguard Worker lws_vhost_assert_lock_held(wsi->a.vhost);
116*1c60b9acSAndroid Build Coastguard Worker
117*1c60b9acSAndroid Build Coastguard Worker if (__remove_wsi_socket_from_fds(wsi)) {
118*1c60b9acSAndroid Build Coastguard Worker lwsl_err("%s: unable to remove %d from fds\n", __func__,
119*1c60b9acSAndroid Build Coastguard Worker wsi->desc.sockfd);
120*1c60b9acSAndroid Build Coastguard Worker
121*1c60b9acSAndroid Build Coastguard Worker return 1;
122*1c60b9acSAndroid Build Coastguard Worker }
123*1c60b9acSAndroid Build Coastguard Worker
124*1c60b9acSAndroid Build Coastguard Worker __lws_vhost_unbind_wsi(wsi);
125*1c60b9acSAndroid Build Coastguard Worker
126*1c60b9acSAndroid Build Coastguard Worker lws_free(wsi);
127*1c60b9acSAndroid Build Coastguard Worker
128*1c60b9acSAndroid Build Coastguard Worker return 0;
129*1c60b9acSAndroid Build Coastguard Worker }
130*1c60b9acSAndroid Build Coastguard Worker
131*1c60b9acSAndroid Build Coastguard Worker
132*1c60b9acSAndroid Build Coastguard Worker static void
handle_dispatch_status(DBusConnection * c,DBusDispatchStatus s,void * data)133*1c60b9acSAndroid Build Coastguard Worker handle_dispatch_status(DBusConnection *c, DBusDispatchStatus s, void *data)
134*1c60b9acSAndroid Build Coastguard Worker {
135*1c60b9acSAndroid Build Coastguard Worker lwsl_info("%s: new dbus dispatch status: %d\n", __func__, s);
136*1c60b9acSAndroid Build Coastguard Worker }
137*1c60b9acSAndroid Build Coastguard Worker
138*1c60b9acSAndroid Build Coastguard Worker /*
139*1c60b9acSAndroid Build Coastguard Worker * These are complicated by the fact libdbus can have two separate DBusWatch
140*1c60b9acSAndroid Build Coastguard Worker * objects for the same fd, to control watching POLLIN and POLLOUT individually.
141*1c60b9acSAndroid Build Coastguard Worker *
142*1c60b9acSAndroid Build Coastguard Worker * However we will actually watch using poll(), where the unit is the fd, and
143*1c60b9acSAndroid Build Coastguard Worker * it has a unified events field with just POLLIN / POLLOUT flags.
144*1c60b9acSAndroid Build Coastguard Worker *
145*1c60b9acSAndroid Build Coastguard Worker * So we have to be prepared for one or two watchers coming in any order.
146*1c60b9acSAndroid Build Coastguard Worker */
147*1c60b9acSAndroid Build Coastguard Worker
148*1c60b9acSAndroid Build Coastguard Worker static dbus_bool_t
lws_dbus_add_watch(DBusWatch * w,void * data)149*1c60b9acSAndroid Build Coastguard Worker lws_dbus_add_watch(DBusWatch *w, void *data)
150*1c60b9acSAndroid Build Coastguard Worker {
151*1c60b9acSAndroid Build Coastguard Worker struct lws_dbus_ctx *ctx = (struct lws_dbus_ctx *)data;
152*1c60b9acSAndroid Build Coastguard Worker struct lws_context_per_thread *pt = &ctx->vh->context->pt[ctx->tsi];
153*1c60b9acSAndroid Build Coastguard Worker unsigned int flags = 0, lws_flags = 0;
154*1c60b9acSAndroid Build Coastguard Worker struct lws *wsi;
155*1c60b9acSAndroid Build Coastguard Worker int n;
156*1c60b9acSAndroid Build Coastguard Worker
157*1c60b9acSAndroid Build Coastguard Worker lws_context_lock(pt->context, __func__);
158*1c60b9acSAndroid Build Coastguard Worker lws_pt_lock(pt, __func__);
159*1c60b9acSAndroid Build Coastguard Worker
160*1c60b9acSAndroid Build Coastguard Worker wsi = __lws_shadow_wsi(ctx, w, dbus_watch_get_unix_fd(w), 1);
161*1c60b9acSAndroid Build Coastguard Worker if (!wsi) {
162*1c60b9acSAndroid Build Coastguard Worker lws_pt_unlock(pt);
163*1c60b9acSAndroid Build Coastguard Worker lws_context_unlock(pt->context);
164*1c60b9acSAndroid Build Coastguard Worker lwsl_err("%s: unable to get wsi\n", __func__);
165*1c60b9acSAndroid Build Coastguard Worker
166*1c60b9acSAndroid Build Coastguard Worker return FALSE;
167*1c60b9acSAndroid Build Coastguard Worker }
168*1c60b9acSAndroid Build Coastguard Worker
169*1c60b9acSAndroid Build Coastguard Worker for (n = 0; n < (int)LWS_ARRAY_SIZE(ctx->w); n++)
170*1c60b9acSAndroid Build Coastguard Worker if (w == ctx->w[n])
171*1c60b9acSAndroid Build Coastguard Worker break;
172*1c60b9acSAndroid Build Coastguard Worker
173*1c60b9acSAndroid Build Coastguard Worker if (n == (int)LWS_ARRAY_SIZE(ctx->w))
174*1c60b9acSAndroid Build Coastguard Worker for (n = 0; n < (int)LWS_ARRAY_SIZE(ctx->w); n++)
175*1c60b9acSAndroid Build Coastguard Worker if (!ctx->w[n]) {
176*1c60b9acSAndroid Build Coastguard Worker ctx->w[n] = w;
177*1c60b9acSAndroid Build Coastguard Worker break;
178*1c60b9acSAndroid Build Coastguard Worker }
179*1c60b9acSAndroid Build Coastguard Worker
180*1c60b9acSAndroid Build Coastguard Worker for (n = 0; n < (int)LWS_ARRAY_SIZE(ctx->w); n++)
181*1c60b9acSAndroid Build Coastguard Worker if (ctx->w[n] && dbus_watch_get_enabled(ctx->w[n]))
182*1c60b9acSAndroid Build Coastguard Worker flags |= dbus_watch_get_flags(ctx->w[n]);
183*1c60b9acSAndroid Build Coastguard Worker
184*1c60b9acSAndroid Build Coastguard Worker if (flags & DBUS_WATCH_READABLE)
185*1c60b9acSAndroid Build Coastguard Worker lws_flags |= LWS_POLLIN;
186*1c60b9acSAndroid Build Coastguard Worker if (flags & DBUS_WATCH_WRITABLE)
187*1c60b9acSAndroid Build Coastguard Worker lws_flags |= LWS_POLLOUT;
188*1c60b9acSAndroid Build Coastguard Worker
189*1c60b9acSAndroid Build Coastguard Worker lwsl_info("%s: %s: %p, fd %d, data %p, fl %d\n", __func__,
190*1c60b9acSAndroid Build Coastguard Worker lws_wsi_tag(wsi), w, dbus_watch_get_unix_fd(w),
191*1c60b9acSAndroid Build Coastguard Worker data, lws_flags);
192*1c60b9acSAndroid Build Coastguard Worker
193*1c60b9acSAndroid Build Coastguard Worker if (lws_flags)
194*1c60b9acSAndroid Build Coastguard Worker __lws_change_pollfd(wsi, 0, (int)lws_flags);
195*1c60b9acSAndroid Build Coastguard Worker
196*1c60b9acSAndroid Build Coastguard Worker lws_pt_unlock(pt);
197*1c60b9acSAndroid Build Coastguard Worker lws_context_unlock(pt->context);
198*1c60b9acSAndroid Build Coastguard Worker
199*1c60b9acSAndroid Build Coastguard Worker return TRUE;
200*1c60b9acSAndroid Build Coastguard Worker }
201*1c60b9acSAndroid Build Coastguard Worker
202*1c60b9acSAndroid Build Coastguard Worker /* cx + vh lock */
203*1c60b9acSAndroid Build Coastguard Worker static int
__check_destroy_shadow_wsi(struct lws_dbus_ctx * ctx,struct lws * wsi)204*1c60b9acSAndroid Build Coastguard Worker __check_destroy_shadow_wsi(struct lws_dbus_ctx *ctx, struct lws *wsi)
205*1c60b9acSAndroid Build Coastguard Worker {
206*1c60b9acSAndroid Build Coastguard Worker int n;
207*1c60b9acSAndroid Build Coastguard Worker
208*1c60b9acSAndroid Build Coastguard Worker if (!wsi)
209*1c60b9acSAndroid Build Coastguard Worker return 0;
210*1c60b9acSAndroid Build Coastguard Worker
211*1c60b9acSAndroid Build Coastguard Worker for (n = 0; n < (int)LWS_ARRAY_SIZE(ctx->w); n++)
212*1c60b9acSAndroid Build Coastguard Worker if (ctx->w[n])
213*1c60b9acSAndroid Build Coastguard Worker return 0;
214*1c60b9acSAndroid Build Coastguard Worker
215*1c60b9acSAndroid Build Coastguard Worker __lws_shadow_wsi_destroy(ctx, wsi);
216*1c60b9acSAndroid Build Coastguard Worker
217*1c60b9acSAndroid Build Coastguard Worker if (!ctx->conn || !ctx->hup || ctx->timeouts)
218*1c60b9acSAndroid Build Coastguard Worker return 0;
219*1c60b9acSAndroid Build Coastguard Worker
220*1c60b9acSAndroid Build Coastguard Worker if (dbus_connection_get_dispatch_status(ctx->conn) ==
221*1c60b9acSAndroid Build Coastguard Worker DBUS_DISPATCH_DATA_REMAINS)
222*1c60b9acSAndroid Build Coastguard Worker return 0;
223*1c60b9acSAndroid Build Coastguard Worker
224*1c60b9acSAndroid Build Coastguard Worker if (ctx->cb_closing)
225*1c60b9acSAndroid Build Coastguard Worker ctx->cb_closing(ctx);
226*1c60b9acSAndroid Build Coastguard Worker
227*1c60b9acSAndroid Build Coastguard Worker return 1;
228*1c60b9acSAndroid Build Coastguard Worker }
229*1c60b9acSAndroid Build Coastguard Worker
230*1c60b9acSAndroid Build Coastguard Worker static void
lws_dbus_remove_watch(DBusWatch * w,void * data)231*1c60b9acSAndroid Build Coastguard Worker lws_dbus_remove_watch(DBusWatch *w, void *data)
232*1c60b9acSAndroid Build Coastguard Worker {
233*1c60b9acSAndroid Build Coastguard Worker struct lws_dbus_ctx *ctx = (struct lws_dbus_ctx *)data;
234*1c60b9acSAndroid Build Coastguard Worker struct lws_context_per_thread *pt = &ctx->vh->context->pt[ctx->tsi];
235*1c60b9acSAndroid Build Coastguard Worker unsigned int flags = 0, lws_flags = 0;
236*1c60b9acSAndroid Build Coastguard Worker struct lws *wsi;
237*1c60b9acSAndroid Build Coastguard Worker int n;
238*1c60b9acSAndroid Build Coastguard Worker
239*1c60b9acSAndroid Build Coastguard Worker lws_context_lock(pt->context, __func__);
240*1c60b9acSAndroid Build Coastguard Worker lws_pt_lock(pt, __func__);
241*1c60b9acSAndroid Build Coastguard Worker
242*1c60b9acSAndroid Build Coastguard Worker wsi = __lws_shadow_wsi(ctx, w, dbus_watch_get_unix_fd(w), 0);
243*1c60b9acSAndroid Build Coastguard Worker if (!wsi)
244*1c60b9acSAndroid Build Coastguard Worker goto bail;
245*1c60b9acSAndroid Build Coastguard Worker
246*1c60b9acSAndroid Build Coastguard Worker for (n = 0; n < (int)LWS_ARRAY_SIZE(ctx->w); n++)
247*1c60b9acSAndroid Build Coastguard Worker if (w == ctx->w[n]) {
248*1c60b9acSAndroid Build Coastguard Worker ctx->w[n] = NULL;
249*1c60b9acSAndroid Build Coastguard Worker break;
250*1c60b9acSAndroid Build Coastguard Worker }
251*1c60b9acSAndroid Build Coastguard Worker
252*1c60b9acSAndroid Build Coastguard Worker for (n = 0; n < (int)LWS_ARRAY_SIZE(ctx->w); n++)
253*1c60b9acSAndroid Build Coastguard Worker if (ctx->w[n])
254*1c60b9acSAndroid Build Coastguard Worker flags |= dbus_watch_get_flags(ctx->w[n]);
255*1c60b9acSAndroid Build Coastguard Worker
256*1c60b9acSAndroid Build Coastguard Worker if ((~flags) & DBUS_WATCH_READABLE)
257*1c60b9acSAndroid Build Coastguard Worker lws_flags |= LWS_POLLIN;
258*1c60b9acSAndroid Build Coastguard Worker if ((~flags) & DBUS_WATCH_WRITABLE)
259*1c60b9acSAndroid Build Coastguard Worker lws_flags |= LWS_POLLOUT;
260*1c60b9acSAndroid Build Coastguard Worker
261*1c60b9acSAndroid Build Coastguard Worker lwsl_info("%s: %p, fd %d, data %p, clearing lws flags %d\n",
262*1c60b9acSAndroid Build Coastguard Worker __func__, w, dbus_watch_get_unix_fd(w),
263*1c60b9acSAndroid Build Coastguard Worker data, lws_flags);
264*1c60b9acSAndroid Build Coastguard Worker
265*1c60b9acSAndroid Build Coastguard Worker __lws_change_pollfd(wsi, (int)lws_flags, 0);
266*1c60b9acSAndroid Build Coastguard Worker
267*1c60b9acSAndroid Build Coastguard Worker bail:
268*1c60b9acSAndroid Build Coastguard Worker lws_pt_unlock(pt);
269*1c60b9acSAndroid Build Coastguard Worker lws_context_unlock(pt->context);
270*1c60b9acSAndroid Build Coastguard Worker }
271*1c60b9acSAndroid Build Coastguard Worker
272*1c60b9acSAndroid Build Coastguard Worker static void
lws_dbus_toggle_watch(DBusWatch * w,void * data)273*1c60b9acSAndroid Build Coastguard Worker lws_dbus_toggle_watch(DBusWatch *w, void *data)
274*1c60b9acSAndroid Build Coastguard Worker {
275*1c60b9acSAndroid Build Coastguard Worker if (dbus_watch_get_enabled(w))
276*1c60b9acSAndroid Build Coastguard Worker lws_dbus_add_watch(w, data);
277*1c60b9acSAndroid Build Coastguard Worker else
278*1c60b9acSAndroid Build Coastguard Worker lws_dbus_remove_watch(w, data);
279*1c60b9acSAndroid Build Coastguard Worker }
280*1c60b9acSAndroid Build Coastguard Worker
281*1c60b9acSAndroid Build Coastguard Worker static void
lws_dbus_sul_cb(lws_sorted_usec_list_t * sul)282*1c60b9acSAndroid Build Coastguard Worker lws_dbus_sul_cb(lws_sorted_usec_list_t *sul)
283*1c60b9acSAndroid Build Coastguard Worker {
284*1c60b9acSAndroid Build Coastguard Worker struct lws_context_per_thread *pt = lws_container_of(sul,
285*1c60b9acSAndroid Build Coastguard Worker struct lws_context_per_thread, dbus.sul);
286*1c60b9acSAndroid Build Coastguard Worker
287*1c60b9acSAndroid Build Coastguard Worker lws_start_foreach_dll_safe(struct lws_dll2 *, rdt, nx,
288*1c60b9acSAndroid Build Coastguard Worker lws_dll2_get_head(&pt->dbus.timer_list_owner)) {
289*1c60b9acSAndroid Build Coastguard Worker struct lws_role_dbus_timer *r = lws_container_of(rdt,
290*1c60b9acSAndroid Build Coastguard Worker struct lws_role_dbus_timer, timer_list);
291*1c60b9acSAndroid Build Coastguard Worker
292*1c60b9acSAndroid Build Coastguard Worker if (time(NULL) > r->fire) {
293*1c60b9acSAndroid Build Coastguard Worker lwsl_notice("%s: firing timer\n", __func__);
294*1c60b9acSAndroid Build Coastguard Worker dbus_timeout_handle(r->data);
295*1c60b9acSAndroid Build Coastguard Worker lws_dll2_remove(rdt);
296*1c60b9acSAndroid Build Coastguard Worker lws_free(rdt);
297*1c60b9acSAndroid Build Coastguard Worker }
298*1c60b9acSAndroid Build Coastguard Worker } lws_end_foreach_dll_safe(rdt, nx);
299*1c60b9acSAndroid Build Coastguard Worker
300*1c60b9acSAndroid Build Coastguard Worker if (pt->dbus.timer_list_owner.count)
301*1c60b9acSAndroid Build Coastguard Worker lws_sul_schedule(pt->context, pt->tid, &pt->dbus.sul,
302*1c60b9acSAndroid Build Coastguard Worker lws_dbus_sul_cb, 3 * LWS_US_PER_SEC);
303*1c60b9acSAndroid Build Coastguard Worker }
304*1c60b9acSAndroid Build Coastguard Worker
305*1c60b9acSAndroid Build Coastguard Worker static dbus_bool_t
lws_dbus_add_timeout(DBusTimeout * t,void * data)306*1c60b9acSAndroid Build Coastguard Worker lws_dbus_add_timeout(DBusTimeout *t, void *data)
307*1c60b9acSAndroid Build Coastguard Worker {
308*1c60b9acSAndroid Build Coastguard Worker struct lws_dbus_ctx *ctx = (struct lws_dbus_ctx *)data;
309*1c60b9acSAndroid Build Coastguard Worker struct lws_context_per_thread *pt = &ctx->vh->context->pt[ctx->tsi];
310*1c60b9acSAndroid Build Coastguard Worker int ms = dbus_timeout_get_interval(t);
311*1c60b9acSAndroid Build Coastguard Worker struct lws_role_dbus_timer *dbt;
312*1c60b9acSAndroid Build Coastguard Worker time_t ti = time(NULL);
313*1c60b9acSAndroid Build Coastguard Worker
314*1c60b9acSAndroid Build Coastguard Worker if (!dbus_timeout_get_enabled(t))
315*1c60b9acSAndroid Build Coastguard Worker return TRUE;
316*1c60b9acSAndroid Build Coastguard Worker
317*1c60b9acSAndroid Build Coastguard Worker if (ms < 1000)
318*1c60b9acSAndroid Build Coastguard Worker ms = 1000;
319*1c60b9acSAndroid Build Coastguard Worker
320*1c60b9acSAndroid Build Coastguard Worker dbt = lws_malloc(sizeof(*dbt), "dbus timer");
321*1c60b9acSAndroid Build Coastguard Worker if (!dbt)
322*1c60b9acSAndroid Build Coastguard Worker return FALSE;
323*1c60b9acSAndroid Build Coastguard Worker
324*1c60b9acSAndroid Build Coastguard Worker lwsl_info("%s: adding timeout %dms\n", __func__,
325*1c60b9acSAndroid Build Coastguard Worker dbus_timeout_get_interval(t));
326*1c60b9acSAndroid Build Coastguard Worker
327*1c60b9acSAndroid Build Coastguard Worker dbt->data = t;
328*1c60b9acSAndroid Build Coastguard Worker dbt->fire = ti + (ms < 1000);
329*1c60b9acSAndroid Build Coastguard Worker dbt->timer_list.prev = NULL;
330*1c60b9acSAndroid Build Coastguard Worker dbt->timer_list.next = NULL;
331*1c60b9acSAndroid Build Coastguard Worker dbt->timer_list.owner = NULL;
332*1c60b9acSAndroid Build Coastguard Worker lws_dll2_add_head(&dbt->timer_list, &pt->dbus.timer_list_owner);
333*1c60b9acSAndroid Build Coastguard Worker
334*1c60b9acSAndroid Build Coastguard Worker if (!pt->dbus.sul.list.owner)
335*1c60b9acSAndroid Build Coastguard Worker lws_sul_schedule(pt->context, pt->tid, &pt->dbus.sul,
336*1c60b9acSAndroid Build Coastguard Worker lws_dbus_sul_cb, 3 * LWS_US_PER_SEC);
337*1c60b9acSAndroid Build Coastguard Worker
338*1c60b9acSAndroid Build Coastguard Worker ctx->timeouts++;
339*1c60b9acSAndroid Build Coastguard Worker
340*1c60b9acSAndroid Build Coastguard Worker return TRUE;
341*1c60b9acSAndroid Build Coastguard Worker }
342*1c60b9acSAndroid Build Coastguard Worker
343*1c60b9acSAndroid Build Coastguard Worker static void
lws_dbus_remove_timeout(DBusTimeout * t,void * data)344*1c60b9acSAndroid Build Coastguard Worker lws_dbus_remove_timeout(DBusTimeout *t, void *data)
345*1c60b9acSAndroid Build Coastguard Worker {
346*1c60b9acSAndroid Build Coastguard Worker struct lws_dbus_ctx *ctx = (struct lws_dbus_ctx *)data;
347*1c60b9acSAndroid Build Coastguard Worker struct lws_context_per_thread *pt = &ctx->vh->context->pt[ctx->tsi];
348*1c60b9acSAndroid Build Coastguard Worker
349*1c60b9acSAndroid Build Coastguard Worker lwsl_info("%s: t %p, data %p\n", __func__, t, data);
350*1c60b9acSAndroid Build Coastguard Worker
351*1c60b9acSAndroid Build Coastguard Worker lws_start_foreach_dll_safe(struct lws_dll2 *, rdt, nx,
352*1c60b9acSAndroid Build Coastguard Worker lws_dll2_get_head(&pt->dbus.timer_list_owner)) {
353*1c60b9acSAndroid Build Coastguard Worker struct lws_role_dbus_timer *r = lws_container_of(rdt,
354*1c60b9acSAndroid Build Coastguard Worker struct lws_role_dbus_timer, timer_list);
355*1c60b9acSAndroid Build Coastguard Worker if (t == r->data) {
356*1c60b9acSAndroid Build Coastguard Worker lws_dll2_remove(rdt);
357*1c60b9acSAndroid Build Coastguard Worker lws_free(rdt);
358*1c60b9acSAndroid Build Coastguard Worker ctx->timeouts--;
359*1c60b9acSAndroid Build Coastguard Worker break;
360*1c60b9acSAndroid Build Coastguard Worker }
361*1c60b9acSAndroid Build Coastguard Worker } lws_end_foreach_dll_safe(rdt, nx);
362*1c60b9acSAndroid Build Coastguard Worker
363*1c60b9acSAndroid Build Coastguard Worker if (!pt->dbus.timer_list_owner.count)
364*1c60b9acSAndroid Build Coastguard Worker lws_sul_cancel(&pt->dbus.sul);
365*1c60b9acSAndroid Build Coastguard Worker }
366*1c60b9acSAndroid Build Coastguard Worker
367*1c60b9acSAndroid Build Coastguard Worker static void
lws_dbus_toggle_timeout(DBusTimeout * t,void * data)368*1c60b9acSAndroid Build Coastguard Worker lws_dbus_toggle_timeout(DBusTimeout *t, void *data)
369*1c60b9acSAndroid Build Coastguard Worker {
370*1c60b9acSAndroid Build Coastguard Worker if (dbus_timeout_get_enabled(t))
371*1c60b9acSAndroid Build Coastguard Worker lws_dbus_add_timeout(t, data);
372*1c60b9acSAndroid Build Coastguard Worker else
373*1c60b9acSAndroid Build Coastguard Worker lws_dbus_remove_timeout(t, data);
374*1c60b9acSAndroid Build Coastguard Worker }
375*1c60b9acSAndroid Build Coastguard Worker
376*1c60b9acSAndroid Build Coastguard Worker /*
377*1c60b9acSAndroid Build Coastguard Worker * This sets up a connection along the same lines as
378*1c60b9acSAndroid Build Coastguard Worker * dbus_connection_setup_with_g_main(), but for using the lws event loop.
379*1c60b9acSAndroid Build Coastguard Worker */
380*1c60b9acSAndroid Build Coastguard Worker
381*1c60b9acSAndroid Build Coastguard Worker int
lws_dbus_connection_setup(struct lws_dbus_ctx * ctx,DBusConnection * conn,lws_dbus_closing_t cb_closing)382*1c60b9acSAndroid Build Coastguard Worker lws_dbus_connection_setup(struct lws_dbus_ctx *ctx, DBusConnection *conn,
383*1c60b9acSAndroid Build Coastguard Worker lws_dbus_closing_t cb_closing)
384*1c60b9acSAndroid Build Coastguard Worker {
385*1c60b9acSAndroid Build Coastguard Worker int n;
386*1c60b9acSAndroid Build Coastguard Worker
387*1c60b9acSAndroid Build Coastguard Worker ctx->conn = conn;
388*1c60b9acSAndroid Build Coastguard Worker ctx->cb_closing = cb_closing;
389*1c60b9acSAndroid Build Coastguard Worker ctx->hup = 0;
390*1c60b9acSAndroid Build Coastguard Worker ctx->timeouts = 0;
391*1c60b9acSAndroid Build Coastguard Worker for (n = 0; n < (int)LWS_ARRAY_SIZE(ctx->w); n++)
392*1c60b9acSAndroid Build Coastguard Worker ctx->w[n] = NULL;
393*1c60b9acSAndroid Build Coastguard Worker
394*1c60b9acSAndroid Build Coastguard Worker if (!dbus_connection_set_watch_functions(conn, lws_dbus_add_watch,
395*1c60b9acSAndroid Build Coastguard Worker lws_dbus_remove_watch,
396*1c60b9acSAndroid Build Coastguard Worker lws_dbus_toggle_watch,
397*1c60b9acSAndroid Build Coastguard Worker ctx, NULL)) {
398*1c60b9acSAndroid Build Coastguard Worker lwsl_err("%s: dbus_connection_set_watch_functions fail\n",
399*1c60b9acSAndroid Build Coastguard Worker __func__);
400*1c60b9acSAndroid Build Coastguard Worker return 1;
401*1c60b9acSAndroid Build Coastguard Worker }
402*1c60b9acSAndroid Build Coastguard Worker
403*1c60b9acSAndroid Build Coastguard Worker if (!dbus_connection_set_timeout_functions(conn,
404*1c60b9acSAndroid Build Coastguard Worker lws_dbus_add_timeout,
405*1c60b9acSAndroid Build Coastguard Worker lws_dbus_remove_timeout,
406*1c60b9acSAndroid Build Coastguard Worker lws_dbus_toggle_timeout,
407*1c60b9acSAndroid Build Coastguard Worker ctx, NULL)) {
408*1c60b9acSAndroid Build Coastguard Worker lwsl_err("%s: dbus_connection_set_timeout_functions fail\n",
409*1c60b9acSAndroid Build Coastguard Worker __func__);
410*1c60b9acSAndroid Build Coastguard Worker return 1;
411*1c60b9acSAndroid Build Coastguard Worker }
412*1c60b9acSAndroid Build Coastguard Worker
413*1c60b9acSAndroid Build Coastguard Worker dbus_connection_set_dispatch_status_function(conn,
414*1c60b9acSAndroid Build Coastguard Worker handle_dispatch_status,
415*1c60b9acSAndroid Build Coastguard Worker ctx, NULL);
416*1c60b9acSAndroid Build Coastguard Worker
417*1c60b9acSAndroid Build Coastguard Worker return 0;
418*1c60b9acSAndroid Build Coastguard Worker }
419*1c60b9acSAndroid Build Coastguard Worker
420*1c60b9acSAndroid Build Coastguard Worker /*
421*1c60b9acSAndroid Build Coastguard Worker * This wraps dbus_server_listen(), additionally taking care of the event loop
422*1c60b9acSAndroid Build Coastguard Worker * -related setups.
423*1c60b9acSAndroid Build Coastguard Worker */
424*1c60b9acSAndroid Build Coastguard Worker
425*1c60b9acSAndroid Build Coastguard Worker DBusServer *
lws_dbus_server_listen(struct lws_dbus_ctx * ctx,const char * ads,DBusError * e,DBusNewConnectionFunction new_conn)426*1c60b9acSAndroid Build Coastguard Worker lws_dbus_server_listen(struct lws_dbus_ctx *ctx, const char *ads, DBusError *e,
427*1c60b9acSAndroid Build Coastguard Worker DBusNewConnectionFunction new_conn)
428*1c60b9acSAndroid Build Coastguard Worker {
429*1c60b9acSAndroid Build Coastguard Worker ctx->cb_closing = NULL;
430*1c60b9acSAndroid Build Coastguard Worker ctx->hup = 0;
431*1c60b9acSAndroid Build Coastguard Worker ctx->timeouts = 0;
432*1c60b9acSAndroid Build Coastguard Worker
433*1c60b9acSAndroid Build Coastguard Worker ctx->dbs = dbus_server_listen(ads, e);
434*1c60b9acSAndroid Build Coastguard Worker if (!ctx->dbs)
435*1c60b9acSAndroid Build Coastguard Worker return NULL;
436*1c60b9acSAndroid Build Coastguard Worker
437*1c60b9acSAndroid Build Coastguard Worker dbus_server_set_new_connection_function(ctx->dbs, new_conn, ctx, NULL);
438*1c60b9acSAndroid Build Coastguard Worker
439*1c60b9acSAndroid Build Coastguard Worker if (!dbus_server_set_watch_functions(ctx->dbs, lws_dbus_add_watch,
440*1c60b9acSAndroid Build Coastguard Worker lws_dbus_remove_watch,
441*1c60b9acSAndroid Build Coastguard Worker lws_dbus_toggle_watch,
442*1c60b9acSAndroid Build Coastguard Worker ctx, NULL)) {
443*1c60b9acSAndroid Build Coastguard Worker lwsl_err("%s: dbus_connection_set_watch_functions fail\n",
444*1c60b9acSAndroid Build Coastguard Worker __func__);
445*1c60b9acSAndroid Build Coastguard Worker goto bail;
446*1c60b9acSAndroid Build Coastguard Worker }
447*1c60b9acSAndroid Build Coastguard Worker
448*1c60b9acSAndroid Build Coastguard Worker if (!dbus_server_set_timeout_functions(ctx->dbs, lws_dbus_add_timeout,
449*1c60b9acSAndroid Build Coastguard Worker lws_dbus_remove_timeout,
450*1c60b9acSAndroid Build Coastguard Worker lws_dbus_toggle_timeout,
451*1c60b9acSAndroid Build Coastguard Worker ctx, NULL)) {
452*1c60b9acSAndroid Build Coastguard Worker lwsl_err("%s: dbus_connection_set_timeout_functions fail\n",
453*1c60b9acSAndroid Build Coastguard Worker __func__);
454*1c60b9acSAndroid Build Coastguard Worker goto bail;
455*1c60b9acSAndroid Build Coastguard Worker }
456*1c60b9acSAndroid Build Coastguard Worker
457*1c60b9acSAndroid Build Coastguard Worker return ctx->dbs;
458*1c60b9acSAndroid Build Coastguard Worker
459*1c60b9acSAndroid Build Coastguard Worker bail:
460*1c60b9acSAndroid Build Coastguard Worker dbus_server_disconnect(ctx->dbs);
461*1c60b9acSAndroid Build Coastguard Worker dbus_server_unref(ctx->dbs);
462*1c60b9acSAndroid Build Coastguard Worker
463*1c60b9acSAndroid Build Coastguard Worker return NULL;
464*1c60b9acSAndroid Build Coastguard Worker }
465*1c60b9acSAndroid Build Coastguard Worker
466*1c60b9acSAndroid Build Coastguard Worker
467*1c60b9acSAndroid Build Coastguard Worker /*
468*1c60b9acSAndroid Build Coastguard Worker * There shouldn't be a race here with watcher removal and poll wait, because
469*1c60b9acSAndroid Build Coastguard Worker * everything including the dbus activity is serialized in one event loop.
470*1c60b9acSAndroid Build Coastguard Worker *
471*1c60b9acSAndroid Build Coastguard Worker * If it removes the watcher and we remove the wsi and fd entry before this,
472*1c60b9acSAndroid Build Coastguard Worker * actually we can no longer map the fd to this invalidated wsi pointer to call
473*1c60b9acSAndroid Build Coastguard Worker * this.
474*1c60b9acSAndroid Build Coastguard Worker */
475*1c60b9acSAndroid Build Coastguard Worker
476*1c60b9acSAndroid Build Coastguard Worker static int
rops_handle_POLLIN_dbus(struct lws_context_per_thread * pt,struct lws * wsi,struct lws_pollfd * pollfd)477*1c60b9acSAndroid Build Coastguard Worker rops_handle_POLLIN_dbus(struct lws_context_per_thread *pt, struct lws *wsi,
478*1c60b9acSAndroid Build Coastguard Worker struct lws_pollfd *pollfd)
479*1c60b9acSAndroid Build Coastguard Worker {
480*1c60b9acSAndroid Build Coastguard Worker struct lws_dbus_ctx *ctx =
481*1c60b9acSAndroid Build Coastguard Worker (struct lws_dbus_ctx *)wsi->opaque_parent_data;
482*1c60b9acSAndroid Build Coastguard Worker unsigned int flags = 0;
483*1c60b9acSAndroid Build Coastguard Worker int n;
484*1c60b9acSAndroid Build Coastguard Worker
485*1c60b9acSAndroid Build Coastguard Worker if (pollfd->revents & LWS_POLLIN)
486*1c60b9acSAndroid Build Coastguard Worker flags |= DBUS_WATCH_READABLE;
487*1c60b9acSAndroid Build Coastguard Worker if (pollfd->revents & LWS_POLLOUT)
488*1c60b9acSAndroid Build Coastguard Worker flags |= DBUS_WATCH_WRITABLE;
489*1c60b9acSAndroid Build Coastguard Worker
490*1c60b9acSAndroid Build Coastguard Worker if (pollfd->revents & (LWS_POLLHUP))
491*1c60b9acSAndroid Build Coastguard Worker ctx->hup = 1;
492*1c60b9acSAndroid Build Coastguard Worker
493*1c60b9acSAndroid Build Coastguard Worker /*
494*1c60b9acSAndroid Build Coastguard Worker * POLLIN + POLLOUT gets us called here on the corresponding shadow
495*1c60b9acSAndroid Build Coastguard Worker * wsi. wsi->opaque_parent_data is the watcher handle bound to the wsi
496*1c60b9acSAndroid Build Coastguard Worker */
497*1c60b9acSAndroid Build Coastguard Worker
498*1c60b9acSAndroid Build Coastguard Worker for (n = 0; n < (int)LWS_ARRAY_SIZE(ctx->w); n++)
499*1c60b9acSAndroid Build Coastguard Worker if (ctx->w[n] && !dbus_watch_handle(ctx->w[n], flags))
500*1c60b9acSAndroid Build Coastguard Worker lwsl_err("%s: dbus_watch_handle failed\n", __func__);
501*1c60b9acSAndroid Build Coastguard Worker
502*1c60b9acSAndroid Build Coastguard Worker if (ctx->conn) {
503*1c60b9acSAndroid Build Coastguard Worker lwsl_info("%s: conn: flags %d\n", __func__, flags);
504*1c60b9acSAndroid Build Coastguard Worker
505*1c60b9acSAndroid Build Coastguard Worker while (dbus_connection_get_dispatch_status(ctx->conn) ==
506*1c60b9acSAndroid Build Coastguard Worker DBUS_DISPATCH_DATA_REMAINS)
507*1c60b9acSAndroid Build Coastguard Worker dbus_connection_dispatch(ctx->conn);
508*1c60b9acSAndroid Build Coastguard Worker
509*1c60b9acSAndroid Build Coastguard Worker handle_dispatch_status(NULL, DBUS_DISPATCH_DATA_REMAINS, NULL);
510*1c60b9acSAndroid Build Coastguard Worker
511*1c60b9acSAndroid Build Coastguard Worker __check_destroy_shadow_wsi(ctx, wsi);
512*1c60b9acSAndroid Build Coastguard Worker } else
513*1c60b9acSAndroid Build Coastguard Worker if (ctx->dbs)
514*1c60b9acSAndroid Build Coastguard Worker /* ??? */
515*1c60b9acSAndroid Build Coastguard Worker lwsl_debug("%s: dbs: %d\n", __func__, flags);
516*1c60b9acSAndroid Build Coastguard Worker
517*1c60b9acSAndroid Build Coastguard Worker return LWS_HPI_RET_HANDLED;
518*1c60b9acSAndroid Build Coastguard Worker }
519*1c60b9acSAndroid Build Coastguard Worker
520*1c60b9acSAndroid Build Coastguard Worker static int
rops_pt_init_destroy_dbus(struct lws_context * context,const struct lws_context_creation_info * info,struct lws_context_per_thread * pt,int destroy)521*1c60b9acSAndroid Build Coastguard Worker rops_pt_init_destroy_dbus(struct lws_context *context,
522*1c60b9acSAndroid Build Coastguard Worker const struct lws_context_creation_info *info,
523*1c60b9acSAndroid Build Coastguard Worker struct lws_context_per_thread *pt, int destroy)
524*1c60b9acSAndroid Build Coastguard Worker {
525*1c60b9acSAndroid Build Coastguard Worker if (destroy)
526*1c60b9acSAndroid Build Coastguard Worker lws_sul_cancel(&pt->dbus.sul);
527*1c60b9acSAndroid Build Coastguard Worker
528*1c60b9acSAndroid Build Coastguard Worker return 0;
529*1c60b9acSAndroid Build Coastguard Worker }
530*1c60b9acSAndroid Build Coastguard Worker
531*1c60b9acSAndroid Build Coastguard Worker static const lws_rops_t rops_table_dbus[] = {
532*1c60b9acSAndroid Build Coastguard Worker /* 1 */ { .pt_init_destroy = rops_pt_init_destroy_dbus },
533*1c60b9acSAndroid Build Coastguard Worker /* 2 */ { .handle_POLLIN = rops_handle_POLLIN_dbus },
534*1c60b9acSAndroid Build Coastguard Worker };
535*1c60b9acSAndroid Build Coastguard Worker
536*1c60b9acSAndroid Build Coastguard Worker const struct lws_role_ops role_ops_dbus = {
537*1c60b9acSAndroid Build Coastguard Worker /* role name */ "dbus",
538*1c60b9acSAndroid Build Coastguard Worker /* alpn id */ NULL,
539*1c60b9acSAndroid Build Coastguard Worker
540*1c60b9acSAndroid Build Coastguard Worker /* rops_table */ rops_table_dbus,
541*1c60b9acSAndroid Build Coastguard Worker /* rops_idx */ {
542*1c60b9acSAndroid Build Coastguard Worker /* LWS_ROPS_check_upgrades */
543*1c60b9acSAndroid Build Coastguard Worker /* LWS_ROPS_pt_init_destroy */ 0x01,
544*1c60b9acSAndroid Build Coastguard Worker /* LWS_ROPS_init_vhost */
545*1c60b9acSAndroid Build Coastguard Worker /* LWS_ROPS_destroy_vhost */ 0x00,
546*1c60b9acSAndroid Build Coastguard Worker /* LWS_ROPS_service_flag_pending */
547*1c60b9acSAndroid Build Coastguard Worker /* LWS_ROPS_handle_POLLIN */ 0x02,
548*1c60b9acSAndroid Build Coastguard Worker /* LWS_ROPS_handle_POLLOUT */
549*1c60b9acSAndroid Build Coastguard Worker /* LWS_ROPS_perform_user_POLLOUT */ 0x00,
550*1c60b9acSAndroid Build Coastguard Worker /* LWS_ROPS_callback_on_writable */
551*1c60b9acSAndroid Build Coastguard Worker /* LWS_ROPS_tx_credit */ 0x00,
552*1c60b9acSAndroid Build Coastguard Worker /* LWS_ROPS_write_role_protocol */
553*1c60b9acSAndroid Build Coastguard Worker /* LWS_ROPS_encapsulation_parent */ 0x00,
554*1c60b9acSAndroid Build Coastguard Worker /* LWS_ROPS_alpn_negotiated */
555*1c60b9acSAndroid Build Coastguard Worker /* LWS_ROPS_close_via_role_protocol */ 0x00,
556*1c60b9acSAndroid Build Coastguard Worker /* LWS_ROPS_close_role */
557*1c60b9acSAndroid Build Coastguard Worker /* LWS_ROPS_close_kill_connection */ 0x00,
558*1c60b9acSAndroid Build Coastguard Worker /* LWS_ROPS_destroy_role */
559*1c60b9acSAndroid Build Coastguard Worker /* LWS_ROPS_adoption_bind */ 0x00,
560*1c60b9acSAndroid Build Coastguard Worker /* LWS_ROPS_client_bind */
561*1c60b9acSAndroid Build Coastguard Worker /* LWS_ROPS_issue_keepalive */ 0x00,
562*1c60b9acSAndroid Build Coastguard Worker },
563*1c60b9acSAndroid Build Coastguard Worker
564*1c60b9acSAndroid Build Coastguard Worker /* adoption_cb clnt, srv */ { 0, 0 },
565*1c60b9acSAndroid Build Coastguard Worker /* rx_cb clnt, srv */ { 0, 0 },
566*1c60b9acSAndroid Build Coastguard Worker /* writeable cb clnt, srv */ { 0, 0 },
567*1c60b9acSAndroid Build Coastguard Worker /* close cb clnt, srv */ { 0, 0 },
568*1c60b9acSAndroid Build Coastguard Worker /* protocol_bind_cb c,s */ { 0, 0 },
569*1c60b9acSAndroid Build Coastguard Worker /* protocol_unbind_cb c,s */ { 0, 0 },
570*1c60b9acSAndroid Build Coastguard Worker /* file_handle */ 0,
571*1c60b9acSAndroid Build Coastguard Worker };
572