Imported Upstream version 3.2.0
[platform/upstream/libwebsockets.git] / minimal-examples / ws-client / minimal-ws-client-rx / minimal-ws-client.c
1 /*
2  * lws-minimal-ws-client
3  *
4  * Written in 2010-2019 by Andy Green <andy@warmcat.com>
5  *
6  * This file is made available under the Creative Commons CC0 1.0
7  * Universal Public Domain Dedication.
8  *
9  * This demonstrates the a minimal ws client using lws.
10  *
11  * It connects to https://libwebsockets.org/ and makes a
12  * wss connection to the dumb-increment protocol there.  While
13  * connected, it prints the numbers it is being sent by
14  * dumb-increment protocol.
15  */
16
17 #include <libwebsockets.h>
18 #include <string.h>
19 #include <signal.h>
20
21 static int interrupted, rx_seen, test;
22 static struct lws *client_wsi;
23
24 static int
25 callback_dumb_increment(struct lws *wsi, enum lws_callback_reasons reason,
26               void *user, void *in, size_t len)
27 {
28         switch (reason) {
29
30         /* because we are protocols[0] ... */
31         case LWS_CALLBACK_CLIENT_CONNECTION_ERROR:
32                 lwsl_err("CLIENT_CONNECTION_ERROR: %s\n",
33                          in ? (char *)in : "(null)");
34                 client_wsi = NULL;
35                 break;
36
37         case LWS_CALLBACK_CLIENT_ESTABLISHED:
38                 lwsl_user("%s: established\n", __func__);
39                 break;
40
41         case LWS_CALLBACK_CLIENT_RECEIVE:
42                 lwsl_user("RX: %s\n", (const char *)in);
43                 rx_seen++;
44                 if (test && rx_seen == 10)
45                         interrupted = 1;
46                 break;
47
48         case LWS_CALLBACK_CLIENT_CLOSED:
49                 client_wsi = NULL;
50                 break;
51
52         default:
53                 break;
54         }
55
56         return lws_callback_http_dummy(wsi, reason, user, in, len);
57 }
58
59 static const struct lws_protocols protocols[] = {
60         {
61                 "dumb-increment-protocol",
62                 callback_dumb_increment,
63                 0,
64                 0,
65         },
66         { NULL, NULL, 0, 0 }
67 };
68
69 static void
70 sigint_handler(int sig)
71 {
72         interrupted = 1;
73 }
74
75 int main(int argc, const char **argv)
76 {
77         struct lws_context_creation_info info;
78         struct lws_client_connect_info i;
79         struct lws_context *context;
80         const char *p;
81         int n = 0, logs = LLL_USER | LLL_ERR | LLL_WARN | LLL_NOTICE
82                 /* for LLL_ verbosity above NOTICE to be built into lws, lws
83                  * must have been configured with -DCMAKE_BUILD_TYPE=DEBUG
84                  * instead of =RELEASE */
85                 /* | LLL_INFO */ /* | LLL_PARSER */ /* | LLL_HEADER */
86                 /* | LLL_EXT */ /* | LLL_CLIENT */ /* | LLL_LATENCY */
87                 /* | LLL_DEBUG */;
88
89         signal(SIGINT, sigint_handler);
90         if ((p = lws_cmdline_option(argc, argv, "-d")))
91                 logs = atoi(p);
92
93         test = !!lws_cmdline_option(argc, argv, "-t");
94
95         lws_set_log_level(logs, NULL);
96         lwsl_user("LWS minimal ws client rx [-d <logs>] [--h2] [-t (test)]\n");
97
98         memset(&info, 0, sizeof info); /* otherwise uninitialized garbage */
99         info.options = LWS_SERVER_OPTION_DO_SSL_GLOBAL_INIT;
100         info.port = CONTEXT_PORT_NO_LISTEN; /* we do not run any server */
101         info.protocols = protocols;
102 #if defined(LWS_WITH_MBEDTLS)
103         /*
104          * OpenSSL uses the system trust store.  mbedTLS has to be told which
105          * CA to trust explicitly.
106          */
107         info.client_ssl_ca_filepath = "./libwebsockets.org.cer";
108 #endif
109
110         /*
111          * since we know this lws context is only ever going to be used with
112          * one client wsis / fds / sockets at a time, let lws know it doesn't
113          * have to use the default allocations for fd tables up to ulimit -n.
114          * It will just allocate for 1 internal and 1 (+ 1 http2 nwsi) that we
115          * will use.
116          */
117         info.fd_limit_per_thread = 1 + 1 + 1;
118
119         context = lws_create_context(&info);
120         if (!context) {
121                 lwsl_err("lws init failed\n");
122                 return 1;
123         }
124
125         memset(&i, 0, sizeof i); /* otherwise uninitialized garbage */
126         i.context = context;
127         i.port = 443;
128         i.address = "libwebsockets.org";
129         i.path = "/";
130         i.host = i.address;
131         i.origin = i.address;
132         i.ssl_connection = LCCSCF_USE_SSL;
133         i.protocol = protocols[0].name; /* "dumb-increment-protocol" */
134         i.pwsi = &client_wsi;
135
136         if (lws_cmdline_option(argc, argv, "--h2"))
137                 i.alpn = "h2";
138
139         lws_client_connect_via_info(&i);
140
141         while (n >= 0 && client_wsi && !interrupted)
142                 n = lws_service(context, 0);
143
144         lws_context_destroy(context);
145
146         lwsl_user("Completed %s\n", rx_seen > 10 ? "OK" : "Failed");
147
148         return rx_seen > 10;
149 }