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