1*1c60b9acSAndroid Build Coastguard Worker /*
2*1c60b9acSAndroid Build Coastguard Worker * lws-minimal-dbus-ws-proxy-testclient
3*1c60b9acSAndroid Build Coastguard Worker *
4*1c60b9acSAndroid Build Coastguard Worker * Written in 2010-2019 by Andy Green <[email protected]>
5*1c60b9acSAndroid Build Coastguard Worker *
6*1c60b9acSAndroid Build Coastguard Worker * This file is made available under the Creative Commons CC0 1.0
7*1c60b9acSAndroid Build Coastguard Worker * Universal Public Domain Dedication.
8*1c60b9acSAndroid Build Coastguard Worker *
9*1c60b9acSAndroid Build Coastguard Worker * This acts as a test client over DBUS, opening a session with
10*1c60b9acSAndroid Build Coastguard Worker * minimal-dbus-ws-proxy and sending and receiving data on the libwebsockets
11*1c60b9acSAndroid Build Coastguard Worker * mirror demo page.
12*1c60b9acSAndroid Build Coastguard Worker */
13*1c60b9acSAndroid Build Coastguard Worker
14*1c60b9acSAndroid Build Coastguard Worker #include <stdbool.h>
15*1c60b9acSAndroid Build Coastguard Worker #include <string.h>
16*1c60b9acSAndroid Build Coastguard Worker #include <stdio.h>
17*1c60b9acSAndroid Build Coastguard Worker #include <stdlib.h>
18*1c60b9acSAndroid Build Coastguard Worker #include <unistd.h>
19*1c60b9acSAndroid Build Coastguard Worker #include <signal.h>
20*1c60b9acSAndroid Build Coastguard Worker
21*1c60b9acSAndroid Build Coastguard Worker #include <libwebsockets.h>
22*1c60b9acSAndroid Build Coastguard Worker #include <libwebsockets/lws-dbus.h>
23*1c60b9acSAndroid Build Coastguard Worker
24*1c60b9acSAndroid Build Coastguard Worker /*
25*1c60b9acSAndroid Build Coastguard Worker * These are the various states our connection can be in, both with regards
26*1c60b9acSAndroid Build Coastguard Worker * to the direct connection to the proxy, and the state of the onward ws
27*1c60b9acSAndroid Build Coastguard Worker * connection the proxy opens at our request.
28*1c60b9acSAndroid Build Coastguard Worker */
29*1c60b9acSAndroid Build Coastguard Worker
30*1c60b9acSAndroid Build Coastguard Worker enum lws_dbus_client_state {
31*1c60b9acSAndroid Build Coastguard Worker LDCS_NOTHING, /* no connection yet */
32*1c60b9acSAndroid Build Coastguard Worker LDCS_CONN, /* conn to proxy */
33*1c60b9acSAndroid Build Coastguard Worker LDCS_CONN_WAITING_ONWARD, /* conn to proxy, awaiting proxied conn */
34*1c60b9acSAndroid Build Coastguard Worker LDCS_CONN_ONWARD, /* conn to proxy and onward conn OK */
35*1c60b9acSAndroid Build Coastguard Worker LDCS_CONN_CLOSED, /* conn to proxy but onward conn closed */
36*1c60b9acSAndroid Build Coastguard Worker LDCS_CLOSED, /* connection to proxy is closed */
37*1c60b9acSAndroid Build Coastguard Worker };
38*1c60b9acSAndroid Build Coastguard Worker
39*1c60b9acSAndroid Build Coastguard Worker /*
40*1c60b9acSAndroid Build Coastguard Worker * our expanded dbus context
41*1c60b9acSAndroid Build Coastguard Worker */
42*1c60b9acSAndroid Build Coastguard Worker
43*1c60b9acSAndroid Build Coastguard Worker struct lws_dbus_ctx_wsproxy_client {
44*1c60b9acSAndroid Build Coastguard Worker struct lws_dbus_ctx ctx;
45*1c60b9acSAndroid Build Coastguard Worker
46*1c60b9acSAndroid Build Coastguard Worker lws_sorted_usec_list_t sul;
47*1c60b9acSAndroid Build Coastguard Worker
48*1c60b9acSAndroid Build Coastguard Worker enum lws_dbus_client_state state;
49*1c60b9acSAndroid Build Coastguard Worker };
50*1c60b9acSAndroid Build Coastguard Worker
51*1c60b9acSAndroid Build Coastguard Worker static struct lws_dbus_ctx_wsproxy_client *dbus_ctx;
52*1c60b9acSAndroid Build Coastguard Worker static struct lws_context *context;
53*1c60b9acSAndroid Build Coastguard Worker static int interrupted, autoexit_budget = -1, count_rx, count_tx;
54*1c60b9acSAndroid Build Coastguard Worker
55*1c60b9acSAndroid Build Coastguard Worker #define THIS_INTERFACE "org.libwebsockets.wsclientproxy"
56*1c60b9acSAndroid Build Coastguard Worker #define THIS_OBJECT "/org/libwebsockets/wsclientproxy"
57*1c60b9acSAndroid Build Coastguard Worker #define THIS_BUSNAME "org.libwebsockets.wsclientproxy"
58*1c60b9acSAndroid Build Coastguard Worker
59*1c60b9acSAndroid Build Coastguard Worker #define THIS_LISTEN_PATH "unix:abstract=org.libwebsockets.wsclientproxy"
60*1c60b9acSAndroid Build Coastguard Worker
61*1c60b9acSAndroid Build Coastguard Worker static void
state_transition(struct lws_dbus_ctx_wsproxy_client * dcwc,enum lws_dbus_client_state state)62*1c60b9acSAndroid Build Coastguard Worker state_transition(struct lws_dbus_ctx_wsproxy_client *dcwc,
63*1c60b9acSAndroid Build Coastguard Worker enum lws_dbus_client_state state)
64*1c60b9acSAndroid Build Coastguard Worker {
65*1c60b9acSAndroid Build Coastguard Worker lwsl_notice("%s: %p: from state %d -> %d\n", __func__,
66*1c60b9acSAndroid Build Coastguard Worker dcwc,dcwc->state, state);
67*1c60b9acSAndroid Build Coastguard Worker dcwc->state = state;
68*1c60b9acSAndroid Build Coastguard Worker }
69*1c60b9acSAndroid Build Coastguard Worker
70*1c60b9acSAndroid Build Coastguard Worker static DBusHandlerResult
filter(DBusConnection * conn,DBusMessage * message,void * data)71*1c60b9acSAndroid Build Coastguard Worker filter(DBusConnection *conn, DBusMessage *message, void *data)
72*1c60b9acSAndroid Build Coastguard Worker {
73*1c60b9acSAndroid Build Coastguard Worker struct lws_dbus_ctx_wsproxy_client *dcwc =
74*1c60b9acSAndroid Build Coastguard Worker (struct lws_dbus_ctx_wsproxy_client *)data;
75*1c60b9acSAndroid Build Coastguard Worker const char *str;
76*1c60b9acSAndroid Build Coastguard Worker
77*1c60b9acSAndroid Build Coastguard Worker if (!dbus_message_get_args(message, NULL,
78*1c60b9acSAndroid Build Coastguard Worker DBUS_TYPE_STRING, &str,
79*1c60b9acSAndroid Build Coastguard Worker DBUS_TYPE_INVALID))
80*1c60b9acSAndroid Build Coastguard Worker return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
81*1c60b9acSAndroid Build Coastguard Worker
82*1c60b9acSAndroid Build Coastguard Worker /* received ws data */
83*1c60b9acSAndroid Build Coastguard Worker
84*1c60b9acSAndroid Build Coastguard Worker if (dbus_message_is_signal(message, THIS_INTERFACE, "Receive")) {
85*1c60b9acSAndroid Build Coastguard Worker lwsl_user("%s: Received '%s'\n", __func__, str);
86*1c60b9acSAndroid Build Coastguard Worker count_rx++;
87*1c60b9acSAndroid Build Coastguard Worker }
88*1c60b9acSAndroid Build Coastguard Worker
89*1c60b9acSAndroid Build Coastguard Worker /* proxy ws connection failed */
90*1c60b9acSAndroid Build Coastguard Worker
91*1c60b9acSAndroid Build Coastguard Worker if (dbus_message_is_signal(message, THIS_INTERFACE, "Status") &&
92*1c60b9acSAndroid Build Coastguard Worker !strcmp(str, "ws client connection error"))
93*1c60b9acSAndroid Build Coastguard Worker state_transition(dcwc, LDCS_CONN_CLOSED);
94*1c60b9acSAndroid Build Coastguard Worker
95*1c60b9acSAndroid Build Coastguard Worker /* proxy ws connection succeeded */
96*1c60b9acSAndroid Build Coastguard Worker
97*1c60b9acSAndroid Build Coastguard Worker if (dbus_message_is_signal(message, THIS_INTERFACE, "Status") &&
98*1c60b9acSAndroid Build Coastguard Worker !strcmp(str, "ws client connection established"))
99*1c60b9acSAndroid Build Coastguard Worker state_transition(dcwc, LDCS_CONN_ONWARD);
100*1c60b9acSAndroid Build Coastguard Worker
101*1c60b9acSAndroid Build Coastguard Worker /* proxy ws connection has closed */
102*1c60b9acSAndroid Build Coastguard Worker
103*1c60b9acSAndroid Build Coastguard Worker if (dbus_message_is_signal(message, THIS_INTERFACE, "Status") &&
104*1c60b9acSAndroid Build Coastguard Worker !strcmp(str, "ws client connection closed"))
105*1c60b9acSAndroid Build Coastguard Worker state_transition(dcwc, LDCS_CONN_CLOSED);
106*1c60b9acSAndroid Build Coastguard Worker
107*1c60b9acSAndroid Build Coastguard Worker return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
108*1c60b9acSAndroid Build Coastguard Worker }
109*1c60b9acSAndroid Build Coastguard Worker
110*1c60b9acSAndroid Build Coastguard Worker static void
destroy_dbus_client_conn(struct lws_dbus_ctx_wsproxy_client ** pdcwc)111*1c60b9acSAndroid Build Coastguard Worker destroy_dbus_client_conn(struct lws_dbus_ctx_wsproxy_client **pdcwc)
112*1c60b9acSAndroid Build Coastguard Worker {
113*1c60b9acSAndroid Build Coastguard Worker struct lws_dbus_ctx_wsproxy_client *dcwc = *pdcwc;
114*1c60b9acSAndroid Build Coastguard Worker
115*1c60b9acSAndroid Build Coastguard Worker if (!dcwc || !dcwc->ctx.conn)
116*1c60b9acSAndroid Build Coastguard Worker return;
117*1c60b9acSAndroid Build Coastguard Worker
118*1c60b9acSAndroid Build Coastguard Worker lwsl_notice("%s\n", __func__);
119*1c60b9acSAndroid Build Coastguard Worker
120*1c60b9acSAndroid Build Coastguard Worker dbus_connection_remove_filter(dcwc->ctx.conn, filter, &dcwc->ctx);
121*1c60b9acSAndroid Build Coastguard Worker dbus_connection_close(dcwc->ctx.conn);
122*1c60b9acSAndroid Build Coastguard Worker dbus_connection_unref(dcwc->ctx.conn);
123*1c60b9acSAndroid Build Coastguard Worker
124*1c60b9acSAndroid Build Coastguard Worker free(dcwc);
125*1c60b9acSAndroid Build Coastguard Worker
126*1c60b9acSAndroid Build Coastguard Worker *pdcwc = NULL;
127*1c60b9acSAndroid Build Coastguard Worker }
128*1c60b9acSAndroid Build Coastguard Worker
129*1c60b9acSAndroid Build Coastguard Worker /*
130*1c60b9acSAndroid Build Coastguard Worker * This callback is coming when lws has noticed the fd took a POLLHUP. The
131*1c60b9acSAndroid Build Coastguard Worker * ctx has effectively gone out of scope before this, and the connection can
132*1c60b9acSAndroid Build Coastguard Worker * be cleaned up and the ctx freed.
133*1c60b9acSAndroid Build Coastguard Worker */
134*1c60b9acSAndroid Build Coastguard Worker
135*1c60b9acSAndroid Build Coastguard Worker static void
cb_closing(struct lws_dbus_ctx * ctx)136*1c60b9acSAndroid Build Coastguard Worker cb_closing(struct lws_dbus_ctx *ctx)
137*1c60b9acSAndroid Build Coastguard Worker {
138*1c60b9acSAndroid Build Coastguard Worker struct lws_dbus_ctx_wsproxy_client *dcwc =
139*1c60b9acSAndroid Build Coastguard Worker (struct lws_dbus_ctx_wsproxy_client *)ctx;
140*1c60b9acSAndroid Build Coastguard Worker
141*1c60b9acSAndroid Build Coastguard Worker lwsl_err("%s: closing\n", __func__);
142*1c60b9acSAndroid Build Coastguard Worker
143*1c60b9acSAndroid Build Coastguard Worker if (dcwc == dbus_ctx)
144*1c60b9acSAndroid Build Coastguard Worker dbus_ctx = NULL;
145*1c60b9acSAndroid Build Coastguard Worker
146*1c60b9acSAndroid Build Coastguard Worker destroy_dbus_client_conn(&dcwc);
147*1c60b9acSAndroid Build Coastguard Worker
148*1c60b9acSAndroid Build Coastguard Worker interrupted = 1;
149*1c60b9acSAndroid Build Coastguard Worker }
150*1c60b9acSAndroid Build Coastguard Worker
151*1c60b9acSAndroid Build Coastguard Worker static struct lws_dbus_ctx_wsproxy_client *
create_dbus_client_conn(struct lws_vhost * vh,int tsi,const char * ads)152*1c60b9acSAndroid Build Coastguard Worker create_dbus_client_conn(struct lws_vhost *vh, int tsi, const char *ads)
153*1c60b9acSAndroid Build Coastguard Worker {
154*1c60b9acSAndroid Build Coastguard Worker struct lws_dbus_ctx_wsproxy_client *dcwc;
155*1c60b9acSAndroid Build Coastguard Worker DBusError e;
156*1c60b9acSAndroid Build Coastguard Worker
157*1c60b9acSAndroid Build Coastguard Worker dcwc = malloc(sizeof(*dcwc));
158*1c60b9acSAndroid Build Coastguard Worker if (!dcwc)
159*1c60b9acSAndroid Build Coastguard Worker return NULL;
160*1c60b9acSAndroid Build Coastguard Worker
161*1c60b9acSAndroid Build Coastguard Worker memset(dcwc, 0, sizeof(*dcwc));
162*1c60b9acSAndroid Build Coastguard Worker
163*1c60b9acSAndroid Build Coastguard Worker dcwc->state = LDCS_NOTHING;
164*1c60b9acSAndroid Build Coastguard Worker dcwc->ctx.vh = vh;
165*1c60b9acSAndroid Build Coastguard Worker dcwc->ctx.tsi = tsi;
166*1c60b9acSAndroid Build Coastguard Worker
167*1c60b9acSAndroid Build Coastguard Worker dbus_error_init(&e);
168*1c60b9acSAndroid Build Coastguard Worker
169*1c60b9acSAndroid Build Coastguard Worker lwsl_user("%s: connecting to '%s'\n", __func__, ads);
170*1c60b9acSAndroid Build Coastguard Worker #if 1
171*1c60b9acSAndroid Build Coastguard Worker /* connect to our daemon bus */
172*1c60b9acSAndroid Build Coastguard Worker
173*1c60b9acSAndroid Build Coastguard Worker dcwc->ctx.conn = dbus_connection_open_private(ads, &e);
174*1c60b9acSAndroid Build Coastguard Worker if (!dcwc->ctx.conn) {
175*1c60b9acSAndroid Build Coastguard Worker lwsl_err("%s: Failed to connect: %s\n",
176*1c60b9acSAndroid Build Coastguard Worker __func__, e.message);
177*1c60b9acSAndroid Build Coastguard Worker goto fail;
178*1c60b9acSAndroid Build Coastguard Worker }
179*1c60b9acSAndroid Build Coastguard Worker #else
180*1c60b9acSAndroid Build Coastguard Worker /* connect to the SYSTEM bus */
181*1c60b9acSAndroid Build Coastguard Worker
182*1c60b9acSAndroid Build Coastguard Worker dcwc->ctx.conn = dbus_bus_get(DBUS_BUS_SYSTEM, &e);
183*1c60b9acSAndroid Build Coastguard Worker if (!dcwc->ctx.conn) {
184*1c60b9acSAndroid Build Coastguard Worker lwsl_err("%s: Failed to get a session DBus connection: %s\n",
185*1c60b9acSAndroid Build Coastguard Worker __func__, e.message);
186*1c60b9acSAndroid Build Coastguard Worker goto fail;
187*1c60b9acSAndroid Build Coastguard Worker }
188*1c60b9acSAndroid Build Coastguard Worker #endif
189*1c60b9acSAndroid Build Coastguard Worker dbus_connection_set_exit_on_disconnect(dcwc->ctx.conn, 0);
190*1c60b9acSAndroid Build Coastguard Worker
191*1c60b9acSAndroid Build Coastguard Worker if (!dbus_connection_add_filter(dcwc->ctx.conn, filter,
192*1c60b9acSAndroid Build Coastguard Worker &dcwc->ctx, NULL)) {
193*1c60b9acSAndroid Build Coastguard Worker lwsl_err("%s: Failed to add filter\n", __func__);
194*1c60b9acSAndroid Build Coastguard Worker goto fail;
195*1c60b9acSAndroid Build Coastguard Worker }
196*1c60b9acSAndroid Build Coastguard Worker
197*1c60b9acSAndroid Build Coastguard Worker /*
198*1c60b9acSAndroid Build Coastguard Worker * This is the part that binds the connection to lws watcher and
199*1c60b9acSAndroid Build Coastguard Worker * timeout handling provided by lws
200*1c60b9acSAndroid Build Coastguard Worker */
201*1c60b9acSAndroid Build Coastguard Worker
202*1c60b9acSAndroid Build Coastguard Worker if (lws_dbus_connection_setup(&dcwc->ctx, dcwc->ctx.conn, cb_closing)) {
203*1c60b9acSAndroid Build Coastguard Worker lwsl_err("%s: connection bind to lws failed\n", __func__);
204*1c60b9acSAndroid Build Coastguard Worker goto fail;
205*1c60b9acSAndroid Build Coastguard Worker }
206*1c60b9acSAndroid Build Coastguard Worker
207*1c60b9acSAndroid Build Coastguard Worker state_transition(dcwc, LDCS_CONN);
208*1c60b9acSAndroid Build Coastguard Worker
209*1c60b9acSAndroid Build Coastguard Worker lwsl_notice("%s: created OK\n", __func__);
210*1c60b9acSAndroid Build Coastguard Worker
211*1c60b9acSAndroid Build Coastguard Worker return dcwc;
212*1c60b9acSAndroid Build Coastguard Worker
213*1c60b9acSAndroid Build Coastguard Worker fail:
214*1c60b9acSAndroid Build Coastguard Worker dbus_error_free(&e);
215*1c60b9acSAndroid Build Coastguard Worker
216*1c60b9acSAndroid Build Coastguard Worker free(dcwc);
217*1c60b9acSAndroid Build Coastguard Worker
218*1c60b9acSAndroid Build Coastguard Worker return NULL;
219*1c60b9acSAndroid Build Coastguard Worker }
220*1c60b9acSAndroid Build Coastguard Worker
221*1c60b9acSAndroid Build Coastguard Worker
sigint_handler(int sig)222*1c60b9acSAndroid Build Coastguard Worker void sigint_handler(int sig)
223*1c60b9acSAndroid Build Coastguard Worker {
224*1c60b9acSAndroid Build Coastguard Worker interrupted = 1;
225*1c60b9acSAndroid Build Coastguard Worker }
226*1c60b9acSAndroid Build Coastguard Worker
227*1c60b9acSAndroid Build Coastguard Worker /*
228*1c60b9acSAndroid Build Coastguard Worker * This gets called if we timed out waiting for the dbus server reply, or the
229*1c60b9acSAndroid Build Coastguard Worker * reply arrived.
230*1c60b9acSAndroid Build Coastguard Worker */
231*1c60b9acSAndroid Build Coastguard Worker
232*1c60b9acSAndroid Build Coastguard Worker static void
pending_call_notify(DBusPendingCall * pending,void * data)233*1c60b9acSAndroid Build Coastguard Worker pending_call_notify(DBusPendingCall *pending, void *data)
234*1c60b9acSAndroid Build Coastguard Worker {
235*1c60b9acSAndroid Build Coastguard Worker const char *payload;
236*1c60b9acSAndroid Build Coastguard Worker DBusMessage *msg;
237*1c60b9acSAndroid Build Coastguard Worker
238*1c60b9acSAndroid Build Coastguard Worker if (!dbus_pending_call_get_completed(pending)) {
239*1c60b9acSAndroid Build Coastguard Worker lwsl_err("%s: timed out waiting for reply\n", __func__);
240*1c60b9acSAndroid Build Coastguard Worker
241*1c60b9acSAndroid Build Coastguard Worker goto bail;
242*1c60b9acSAndroid Build Coastguard Worker }
243*1c60b9acSAndroid Build Coastguard Worker
244*1c60b9acSAndroid Build Coastguard Worker msg = dbus_pending_call_steal_reply(pending);
245*1c60b9acSAndroid Build Coastguard Worker if (!msg)
246*1c60b9acSAndroid Build Coastguard Worker goto bail;
247*1c60b9acSAndroid Build Coastguard Worker
248*1c60b9acSAndroid Build Coastguard Worker if (!dbus_message_get_args(msg, NULL, DBUS_TYPE_STRING, &payload,
249*1c60b9acSAndroid Build Coastguard Worker DBUS_TYPE_INVALID)) {
250*1c60b9acSAndroid Build Coastguard Worker goto bail1;
251*1c60b9acSAndroid Build Coastguard Worker }
252*1c60b9acSAndroid Build Coastguard Worker
253*1c60b9acSAndroid Build Coastguard Worker lwsl_user("%s: received '%s'\n", __func__, payload);
254*1c60b9acSAndroid Build Coastguard Worker
255*1c60b9acSAndroid Build Coastguard Worker bail1:
256*1c60b9acSAndroid Build Coastguard Worker dbus_message_unref(msg);
257*1c60b9acSAndroid Build Coastguard Worker bail:
258*1c60b9acSAndroid Build Coastguard Worker dbus_pending_call_unref(pending);
259*1c60b9acSAndroid Build Coastguard Worker }
260*1c60b9acSAndroid Build Coastguard Worker
261*1c60b9acSAndroid Build Coastguard Worker static int
remote_method_call(struct lws_dbus_ctx_wsproxy_client * dcwc)262*1c60b9acSAndroid Build Coastguard Worker remote_method_call(struct lws_dbus_ctx_wsproxy_client *dcwc)
263*1c60b9acSAndroid Build Coastguard Worker {
264*1c60b9acSAndroid Build Coastguard Worker char _uri[96];
265*1c60b9acSAndroid Build Coastguard Worker const char *subprotocol = "lws-mirror-protocol", *uri = _uri;
266*1c60b9acSAndroid Build Coastguard Worker DBusMessage *msg;
267*1c60b9acSAndroid Build Coastguard Worker int ret = 1;
268*1c60b9acSAndroid Build Coastguard Worker
269*1c60b9acSAndroid Build Coastguard Worker /*
270*1c60b9acSAndroid Build Coastguard Worker * make our own private mirror session... because others may run this
271*1c60b9acSAndroid Build Coastguard Worker * at the same time against libwebsockets.org... as happened 2019-03-14
272*1c60b9acSAndroid Build Coastguard Worker * and broke travis tests :-)
273*1c60b9acSAndroid Build Coastguard Worker */
274*1c60b9acSAndroid Build Coastguard Worker
275*1c60b9acSAndroid Build Coastguard Worker lws_snprintf(_uri, sizeof(_uri), "wss://libwebsockets.org/?mirror=dbt-%d",
276*1c60b9acSAndroid Build Coastguard Worker (int)getpid());
277*1c60b9acSAndroid Build Coastguard Worker
278*1c60b9acSAndroid Build Coastguard Worker msg = dbus_message_new_method_call(
279*1c60b9acSAndroid Build Coastguard Worker /* dest */ THIS_BUSNAME,
280*1c60b9acSAndroid Build Coastguard Worker /* object-path */ THIS_OBJECT,
281*1c60b9acSAndroid Build Coastguard Worker /* interface */ THIS_INTERFACE,
282*1c60b9acSAndroid Build Coastguard Worker /* method */ "Connect");
283*1c60b9acSAndroid Build Coastguard Worker if (!msg)
284*1c60b9acSAndroid Build Coastguard Worker return 1;
285*1c60b9acSAndroid Build Coastguard Worker
286*1c60b9acSAndroid Build Coastguard Worker if (!dbus_message_append_args(msg, DBUS_TYPE_STRING, &uri,
287*1c60b9acSAndroid Build Coastguard Worker DBUS_TYPE_STRING, &subprotocol,
288*1c60b9acSAndroid Build Coastguard Worker DBUS_TYPE_INVALID))
289*1c60b9acSAndroid Build Coastguard Worker goto bail;
290*1c60b9acSAndroid Build Coastguard Worker
291*1c60b9acSAndroid Build Coastguard Worker lwsl_user("%s: requesting proxy connection %s %s\n", __func__,
292*1c60b9acSAndroid Build Coastguard Worker uri, subprotocol);
293*1c60b9acSAndroid Build Coastguard Worker
294*1c60b9acSAndroid Build Coastguard Worker if (!dbus_connection_send_with_reply(dcwc->ctx.conn, msg, &dcwc->ctx.pc,
295*1c60b9acSAndroid Build Coastguard Worker DBUS_TIMEOUT_USE_DEFAULT)) {
296*1c60b9acSAndroid Build Coastguard Worker lwsl_err("%s: unable to send\n", __func__);
297*1c60b9acSAndroid Build Coastguard Worker
298*1c60b9acSAndroid Build Coastguard Worker goto bail;
299*1c60b9acSAndroid Build Coastguard Worker }
300*1c60b9acSAndroid Build Coastguard Worker
301*1c60b9acSAndroid Build Coastguard Worker dbus_pending_call_set_notify(dcwc->ctx.pc, pending_call_notify,
302*1c60b9acSAndroid Build Coastguard Worker &dcwc->ctx, NULL);
303*1c60b9acSAndroid Build Coastguard Worker
304*1c60b9acSAndroid Build Coastguard Worker state_transition(dcwc, LDCS_CONN_WAITING_ONWARD);
305*1c60b9acSAndroid Build Coastguard Worker
306*1c60b9acSAndroid Build Coastguard Worker ret = 0;
307*1c60b9acSAndroid Build Coastguard Worker
308*1c60b9acSAndroid Build Coastguard Worker bail:
309*1c60b9acSAndroid Build Coastguard Worker dbus_message_unref(msg);
310*1c60b9acSAndroid Build Coastguard Worker
311*1c60b9acSAndroid Build Coastguard Worker return ret;
312*1c60b9acSAndroid Build Coastguard Worker }
313*1c60b9acSAndroid Build Coastguard Worker
314*1c60b9acSAndroid Build Coastguard Worker static void
sul_timer(struct lws_sorted_usec_list * sul)315*1c60b9acSAndroid Build Coastguard Worker sul_timer(struct lws_sorted_usec_list *sul)
316*1c60b9acSAndroid Build Coastguard Worker {
317*1c60b9acSAndroid Build Coastguard Worker char payload[64];
318*1c60b9acSAndroid Build Coastguard Worker const char *ws_pkt = payload;
319*1c60b9acSAndroid Build Coastguard Worker DBusMessage *msg;
320*1c60b9acSAndroid Build Coastguard Worker
321*1c60b9acSAndroid Build Coastguard Worker if (!dbus_ctx || dbus_ctx->state != LDCS_CONN_ONWARD)
322*1c60b9acSAndroid Build Coastguard Worker goto again;
323*1c60b9acSAndroid Build Coastguard Worker
324*1c60b9acSAndroid Build Coastguard Worker if (autoexit_budget > 0) {
325*1c60b9acSAndroid Build Coastguard Worker if (!--autoexit_budget) {
326*1c60b9acSAndroid Build Coastguard Worker lwsl_notice("reached autoexit budget\n");
327*1c60b9acSAndroid Build Coastguard Worker interrupted = 1;
328*1c60b9acSAndroid Build Coastguard Worker return;
329*1c60b9acSAndroid Build Coastguard Worker }
330*1c60b9acSAndroid Build Coastguard Worker }
331*1c60b9acSAndroid Build Coastguard Worker
332*1c60b9acSAndroid Build Coastguard Worker msg = dbus_message_new_method_call(THIS_BUSNAME, THIS_OBJECT,
333*1c60b9acSAndroid Build Coastguard Worker THIS_INTERFACE, "Send");
334*1c60b9acSAndroid Build Coastguard Worker if (!msg)
335*1c60b9acSAndroid Build Coastguard Worker goto again;
336*1c60b9acSAndroid Build Coastguard Worker
337*1c60b9acSAndroid Build Coastguard Worker lws_snprintf(payload, sizeof(payload), "d #%06X %d %d %d %d;",
338*1c60b9acSAndroid Build Coastguard Worker rand() & 0xffffff, rand() % 480, rand() % 300,
339*1c60b9acSAndroid Build Coastguard Worker rand() % 480, rand() % 300);
340*1c60b9acSAndroid Build Coastguard Worker
341*1c60b9acSAndroid Build Coastguard Worker if (!dbus_message_append_args(msg, DBUS_TYPE_STRING, &ws_pkt,
342*1c60b9acSAndroid Build Coastguard Worker DBUS_TYPE_INVALID)) {
343*1c60b9acSAndroid Build Coastguard Worker dbus_message_unref(msg);
344*1c60b9acSAndroid Build Coastguard Worker goto again;
345*1c60b9acSAndroid Build Coastguard Worker }
346*1c60b9acSAndroid Build Coastguard Worker
347*1c60b9acSAndroid Build Coastguard Worker if (!dbus_connection_send_with_reply(dbus_ctx->ctx.conn, msg,
348*1c60b9acSAndroid Build Coastguard Worker &dbus_ctx->ctx.pc,
349*1c60b9acSAndroid Build Coastguard Worker DBUS_TIMEOUT_USE_DEFAULT)) {
350*1c60b9acSAndroid Build Coastguard Worker lwsl_err("%s: unable to send\n", __func__);
351*1c60b9acSAndroid Build Coastguard Worker dbus_message_unref(msg);
352*1c60b9acSAndroid Build Coastguard Worker goto again;
353*1c60b9acSAndroid Build Coastguard Worker }
354*1c60b9acSAndroid Build Coastguard Worker
355*1c60b9acSAndroid Build Coastguard Worker dbus_message_unref(msg);
356*1c60b9acSAndroid Build Coastguard Worker dbus_pending_call_set_notify(dbus_ctx->ctx.pc,
357*1c60b9acSAndroid Build Coastguard Worker pending_call_notify,
358*1c60b9acSAndroid Build Coastguard Worker &dbus_ctx->ctx, NULL);
359*1c60b9acSAndroid Build Coastguard Worker count_tx++;
360*1c60b9acSAndroid Build Coastguard Worker
361*1c60b9acSAndroid Build Coastguard Worker again:
362*1c60b9acSAndroid Build Coastguard Worker lws_sul_schedule(context, 0, &dbus_ctx->sul, sul_timer, 2 * LWS_US_PER_SEC);
363*1c60b9acSAndroid Build Coastguard Worker }
364*1c60b9acSAndroid Build Coastguard Worker
main(int argc,const char ** argv)365*1c60b9acSAndroid Build Coastguard Worker int main(int argc, const char **argv)
366*1c60b9acSAndroid Build Coastguard Worker {
367*1c60b9acSAndroid Build Coastguard Worker struct lws_vhost *vh;
368*1c60b9acSAndroid Build Coastguard Worker struct lws_context_creation_info info;
369*1c60b9acSAndroid Build Coastguard Worker const char *p;
370*1c60b9acSAndroid Build Coastguard Worker int n = 0, logs = LLL_USER | LLL_ERR | LLL_WARN | LLL_NOTICE
371*1c60b9acSAndroid Build Coastguard Worker /* for LLL_ verbosity above NOTICE to be built into lws,
372*1c60b9acSAndroid Build Coastguard Worker * lws must have been configured and built with
373*1c60b9acSAndroid Build Coastguard Worker * -DCMAKE_BUILD_TYPE=DEBUG instead of =RELEASE */
374*1c60b9acSAndroid Build Coastguard Worker /* | LLL_INFO */ /* | LLL_PARSER */ /* | LLL_HEADER */
375*1c60b9acSAndroid Build Coastguard Worker /* | LLL_EXT */ /* | LLL_CLIENT */ /* | LLL_LATENCY */
376*1c60b9acSAndroid Build Coastguard Worker /* | LLL_DEBUG */ /* | LLL_THREAD */;
377*1c60b9acSAndroid Build Coastguard Worker
378*1c60b9acSAndroid Build Coastguard Worker signal(SIGINT, sigint_handler);
379*1c60b9acSAndroid Build Coastguard Worker
380*1c60b9acSAndroid Build Coastguard Worker if ((p = lws_cmdline_option(argc, argv, "-d")))
381*1c60b9acSAndroid Build Coastguard Worker logs = atoi(p);
382*1c60b9acSAndroid Build Coastguard Worker
383*1c60b9acSAndroid Build Coastguard Worker if ((p = lws_cmdline_option(argc, argv, "-x")))
384*1c60b9acSAndroid Build Coastguard Worker autoexit_budget = atoi(p);
385*1c60b9acSAndroid Build Coastguard Worker
386*1c60b9acSAndroid Build Coastguard Worker lws_set_log_level(logs, NULL);
387*1c60b9acSAndroid Build Coastguard Worker lwsl_user("LWS minimal DBUS ws proxy testclient\n");
388*1c60b9acSAndroid Build Coastguard Worker
389*1c60b9acSAndroid Build Coastguard Worker memset(&info, 0, sizeof info); /* otherwise uninitialized garbage */
390*1c60b9acSAndroid Build Coastguard Worker info.options = LWS_SERVER_OPTION_EXPLICIT_VHOSTS;
391*1c60b9acSAndroid Build Coastguard Worker context = lws_create_context(&info);
392*1c60b9acSAndroid Build Coastguard Worker if (!context) {
393*1c60b9acSAndroid Build Coastguard Worker lwsl_err("lws init failed\n");
394*1c60b9acSAndroid Build Coastguard Worker return 1;
395*1c60b9acSAndroid Build Coastguard Worker }
396*1c60b9acSAndroid Build Coastguard Worker
397*1c60b9acSAndroid Build Coastguard Worker info.options |=
398*1c60b9acSAndroid Build Coastguard Worker LWS_SERVER_OPTION_HTTP_HEADERS_SECURITY_BEST_PRACTICES_ENFORCE;
399*1c60b9acSAndroid Build Coastguard Worker
400*1c60b9acSAndroid Build Coastguard Worker vh = lws_create_vhost(context, &info);
401*1c60b9acSAndroid Build Coastguard Worker if (!vh)
402*1c60b9acSAndroid Build Coastguard Worker goto bail;
403*1c60b9acSAndroid Build Coastguard Worker
404*1c60b9acSAndroid Build Coastguard Worker dbus_ctx = create_dbus_client_conn(vh, 0, THIS_LISTEN_PATH);
405*1c60b9acSAndroid Build Coastguard Worker if (!dbus_ctx)
406*1c60b9acSAndroid Build Coastguard Worker goto bail1;
407*1c60b9acSAndroid Build Coastguard Worker
408*1c60b9acSAndroid Build Coastguard Worker lws_sul_schedule(context, 0, &dbus_ctx->sul, sul_timer, LWS_US_PER_SEC);
409*1c60b9acSAndroid Build Coastguard Worker
410*1c60b9acSAndroid Build Coastguard Worker
411*1c60b9acSAndroid Build Coastguard Worker if (remote_method_call(dbus_ctx))
412*1c60b9acSAndroid Build Coastguard Worker goto bail2;
413*1c60b9acSAndroid Build Coastguard Worker
414*1c60b9acSAndroid Build Coastguard Worker /* lws event loop (default poll one) */
415*1c60b9acSAndroid Build Coastguard Worker
416*1c60b9acSAndroid Build Coastguard Worker while (n >= 0 && !interrupted)
417*1c60b9acSAndroid Build Coastguard Worker n = lws_service(context, 0);
418*1c60b9acSAndroid Build Coastguard Worker
419*1c60b9acSAndroid Build Coastguard Worker bail2:
420*1c60b9acSAndroid Build Coastguard Worker destroy_dbus_client_conn(&dbus_ctx);
421*1c60b9acSAndroid Build Coastguard Worker
422*1c60b9acSAndroid Build Coastguard Worker bail1:
423*1c60b9acSAndroid Build Coastguard Worker /* this is required for valgrind-cleanliness */
424*1c60b9acSAndroid Build Coastguard Worker dbus_shutdown();
425*1c60b9acSAndroid Build Coastguard Worker lws_context_destroy(context);
426*1c60b9acSAndroid Build Coastguard Worker
427*1c60b9acSAndroid Build Coastguard Worker lwsl_notice("Exiting cleanly, rx: %d, tx: %d\n", count_rx, count_tx);
428*1c60b9acSAndroid Build Coastguard Worker
429*1c60b9acSAndroid Build Coastguard Worker return 0;
430*1c60b9acSAndroid Build Coastguard Worker
431*1c60b9acSAndroid Build Coastguard Worker bail:
432*1c60b9acSAndroid Build Coastguard Worker lwsl_err("%s: failed to start\n", __func__);
433*1c60b9acSAndroid Build Coastguard Worker lws_context_destroy(context);
434*1c60b9acSAndroid Build Coastguard Worker
435*1c60b9acSAndroid Build Coastguard Worker return 1;
436*1c60b9acSAndroid Build Coastguard Worker }
437