blob: a96cbb7b1ee795c82fa2c2439bef4b004f51c6b6 [file] [log] [blame]
Andy Green8c0d3c02015-11-02 20:34:12 +08001#include "private-libwebsockets.h"
Andy Green11f27342015-11-08 12:10:26 +08002#include "core-util/CriticalSectionLock.h"
Andy Green8c0d3c02015-11-02 20:34:12 +08003
4extern "C" void *mbed3_create_tcp_stream_socket(void)
5{
6 lws_conn_listener *srv = new lws_conn_listener;
7
Andy Green11f27342015-11-08 12:10:26 +08008 //lwsl_notice("%s: %p\r\n", __func__, (void *)srv);
Andy Green8c0d3c02015-11-02 20:34:12 +08009
10 return (void *)srv;
11}
12
Andy Green11f27342015-11-08 12:10:26 +080013/* this is called by compatible_close() */
Andy Green8c0d3c02015-11-02 20:34:12 +080014extern "C" void mbed3_delete_tcp_stream_socket(void *sock)
15{
Andy Green11f27342015-11-08 12:10:26 +080016 lws_conn *conn = (lws_conn *)sock;
17
18 conn->ts->close();
19
20 lwsl_notice("%s: wsi %p: conn %p\r\n", __func__, (void *)conn->wsi, sock);
21 delete conn;
Andy Green8c0d3c02015-11-02 20:34:12 +080022}
23
Andy Green4b85c1d2015-12-04 11:08:32 +080024void lws_conn::serialized_writeable(struct lws *_wsi)
Andy Green87eeb0a2015-11-25 08:22:08 +080025{
Andy Green4b85c1d2015-12-04 11:08:32 +080026 struct lws *wsi = (struct lws *)_wsi;
27 struct lws_pollfd pollfd;
Andy Green87eeb0a2015-11-25 08:22:08 +080028 lws_conn *conn = (lws_conn *)wsi->sock;
29
30 conn->awaiting_on_writeable = 0;
31
32 pollfd.fd = wsi->sock;
33 pollfd.events = POLLOUT;
34 pollfd.revents = POLLOUT;
35
36 lwsl_debug("%s: wsi %p\r\n", __func__, (void *)wsi);
37
Andy Green62304762015-12-04 08:43:54 +080038 lws_service_fd(wsi->protocol->owning_server, &pollfd);
Andy Green87eeb0a2015-11-25 08:22:08 +080039}
40
Andy Green4b85c1d2015-12-04 11:08:32 +080041extern "C" void mbed3_tcp_stream_bind(void *sock, int port, struct lws *wsi)
Andy Green8c0d3c02015-11-02 20:34:12 +080042{
43 lws_conn_listener *srv = (lws_conn_listener *)sock;
44
Andy Green87eeb0a2015-11-25 08:22:08 +080045 lwsl_debug("%s\r\n", __func__);
Andy Green8c0d3c02015-11-02 20:34:12 +080046 /* associate us with the listening wsi */
47 ((lws_conn *)srv)->set_wsi(wsi);
48
49 mbed::util::FunctionPointer1<void, uint16_t> fp(srv, &lws_conn_listener::start);
50 minar::Scheduler::postCallback(fp.bind(port));
51}
52
Andy Green4b85c1d2015-12-04 11:08:32 +080053extern "C" void mbed3_tcp_stream_accept(void *sock, struct lws *wsi)
Andy Green8c0d3c02015-11-02 20:34:12 +080054{
55 lws_conn *conn = (lws_conn *)sock;
56
Andy Green87eeb0a2015-11-25 08:22:08 +080057 lwsl_debug("%s\r\n", __func__);
Andy Green8c0d3c02015-11-02 20:34:12 +080058 conn->set_wsi(wsi);
59}
60
Andy Green11f27342015-11-08 12:10:26 +080061extern "C" LWS_VISIBLE int
Andy Green4b85c1d2015-12-04 11:08:32 +080062lws_plat_change_pollfd(struct lws_context *context,
63 struct lws *wsi, struct lws_pollfd *pfd)
Andy Green87eeb0a2015-11-25 08:22:08 +080064{
65 lws_conn *conn = (lws_conn *)wsi->sock;
66
67 (void)context;
68 if (pfd->events & POLLOUT) {
69 conn->awaiting_on_writeable = 1;
70 if (conn->writeable) {
Andy Green4b85c1d2015-12-04 11:08:32 +080071 mbed::util::FunctionPointer1<void, struct lws *> book(conn, &lws_conn::serialized_writeable);
Andy Green87eeb0a2015-11-25 08:22:08 +080072 minar::Scheduler::postCallback(book.bind(wsi));
73 lwsl_debug("%s: wsi %p (booked callback)\r\n", __func__, (void *)wsi);
74 } else {
75
76 lwsl_debug("%s: wsi %p (set awaiting_on_writeable)\r\n", __func__, (void *)wsi);
77 }
78 } else
79 conn->awaiting_on_writeable = 0;
80
81 return 0;
82}
83
84extern "C" LWS_VISIBLE int
Andy Green4b85c1d2015-12-04 11:08:32 +080085lws_ssl_capable_read_no_ssl(struct lws_context *context,
86 struct lws *wsi, unsigned char *buf, int len)
Andy Green11f27342015-11-08 12:10:26 +080087{
88 socket_error_t err;
89 size_t _len = len;
Andy Green87eeb0a2015-11-25 08:22:08 +080090
Andy Green11f27342015-11-08 12:10:26 +080091 lwsl_debug("%s\r\n", __func__);
92
93 (void)context;
Andy Green87eeb0a2015-11-25 08:22:08 +080094 err = ((lws_conn *)wsi->sock)->ts->recv((char *)buf, &_len);
Andy Green11f27342015-11-08 12:10:26 +080095 if (err == SOCKET_ERROR_NONE) {
96 lwsl_info("%s: got %d bytes\n", __func__, _len);
97 return _len;
98 }
99#if LWS_POSIX
100 if (LWS_ERRNO == LWS_EAGAIN ||
101 LWS_ERRNO == LWS_EWOULDBLOCK ||
102 LWS_ERRNO == LWS_EINTR)
103#else
104 if (err == SOCKET_ERROR_WOULD_BLOCK)
105#endif
106 return LWS_SSL_CAPABLE_MORE_SERVICE;
107
Andy Green11f27342015-11-08 12:10:26 +0800108 lwsl_warn("error on reading from skt: %d\n", err);
109 return LWS_SSL_CAPABLE_ERROR;
110}
111
112extern "C" LWS_VISIBLE int
Andy Green4b85c1d2015-12-04 11:08:32 +0800113lws_ssl_capable_write_no_ssl(struct lws *wsi, unsigned char *buf, int len)
Andy Green11f27342015-11-08 12:10:26 +0800114{
115 socket_error_t err;
Andy Green87eeb0a2015-11-25 08:22:08 +0800116 lws_conn *conn = (lws_conn *)wsi->sock;
Andy Green11f27342015-11-08 12:10:26 +0800117
118 lwsl_debug("%s: wsi %p: write %d (from %p)\n", __func__, (void *)wsi, len, (void *)buf);
119
Andy Green87eeb0a2015-11-25 08:22:08 +0800120 lwsl_debug("%s: wsi %p: clear writeable\n", __func__, (void *)wsi);
121 conn->writeable = 0;
122
123 err = conn->ts->send((char *)buf, len);
Andy Green11f27342015-11-08 12:10:26 +0800124 if (err == SOCKET_ERROR_NONE)
125 return len;
126
127#if LWS_POSIX
128 if (LWS_ERRNO == LWS_EAGAIN ||
129 LWS_ERRNO == LWS_EWOULDBLOCK ||
130 LWS_ERRNO == LWS_EINTR) {
131 if (LWS_ERRNO == LWS_EWOULDBLOCK)
132 lws_set_blocking_send(wsi);
133#else
134 if (err == SOCKET_ERROR_WOULD_BLOCK)
135 return LWS_SSL_CAPABLE_MORE_SERVICE;
136#endif
137
138 lwsl_warn("%s: wsi %p: ERROR %d writing len %d to skt\n", __func__, (void *)wsi, err, len);
139 return LWS_SSL_CAPABLE_ERROR;
140}
141
Andy Green8c0d3c02015-11-02 20:34:12 +0800142/*
143 * Set the listening socket to listen.
144 */
145
146void lws_conn_listener::start(const uint16_t port)
147{
148 socket_error_t err = srv.open(SOCKET_AF_INET4);
149
150 if (srv.error_check(err))
151 return;
152 err = srv.bind("0.0.0.0", port);
153 if (srv.error_check(err))
154 return;
155 err = srv.start_listening(TCPListener::IncomingHandler_t(this,
156 &lws_conn_listener::onIncoming));
157 srv.error_check(err);
158}
159
Andy Green11f27342015-11-08 12:10:26 +0800160int lws_conn::actual_onRX(Socket *s)
161{
Andy Green4b85c1d2015-12-04 11:08:32 +0800162 struct lws_pollfd pollfd;
Andy Green87eeb0a2015-11-25 08:22:08 +0800163
164 (void)s;
Andy Green11f27342015-11-08 12:10:26 +0800165
166 pollfd.fd = this;
167 pollfd.events = POLLIN;
168 pollfd.revents = POLLIN;
169
170 lwsl_debug("%s: lws %p\n", __func__, wsi);
171
Andy Green62304762015-12-04 08:43:54 +0800172 return lws_service_fd(wsi->protocol->owning_server, &pollfd);
Andy Green11f27342015-11-08 12:10:26 +0800173}
174
Andy Green8c0d3c02015-11-02 20:34:12 +0800175/*
176 * this gets called from the OS when the TCPListener gets a connection that
177 * needs accept()-ing. LWS needs to run the associated flow.
178 */
179
180void lws_conn_listener::onIncoming(TCPListener *tl, void *impl)
181{
Andy Green11f27342015-11-08 12:10:26 +0800182 mbed::util::CriticalSectionLock lock;
Andy Green8c0d3c02015-11-02 20:34:12 +0800183 lws_conn *conn;
Andy Green11f27342015-11-08 12:10:26 +0800184
Andy Greenae7b27c2015-11-24 16:06:22 +0800185 if (!impl) {
Andy Green8c0d3c02015-11-02 20:34:12 +0800186 onError(tl, SOCKET_ERROR_NULL_PTR);
187 return;
188 }
189
190 conn = new(lws_conn);
Andy Green11f27342015-11-08 12:10:26 +0800191 if (!conn) {
192 lwsl_err("OOM\n");
Andy Green8c0d3c02015-11-02 20:34:12 +0800193 return;
194 }
Andy Greenae7b27c2015-11-24 16:06:22 +0800195 conn->ts = srv.accept(impl);
196 if (!conn->ts)
197 return;
Andy Green8c0d3c02015-11-02 20:34:12 +0800198
199 /*
200 * we use the listen socket wsi to get started, but a new wsi is
Andy Green11f27342015-11-08 12:10:26 +0800201 * created. mbed3_tcp_stream_accept() is also called from
202 * here to bind the conn and new wsi together
Andy Green8c0d3c02015-11-02 20:34:12 +0800203 */
204 lws_server_socket_service(wsi->protocol->owning_server,
205 wsi, (struct pollfd *)conn);
Andy Green11f27342015-11-08 12:10:26 +0800206
Andy Greenae7b27c2015-11-24 16:06:22 +0800207 conn->ts->setOnSent(Socket::SentHandler_t(conn, &lws_conn::onSent));
208 conn->ts->setOnReadable(TCPStream::ReadableHandler_t(conn, &lws_conn::onRX));
209 conn->ts->setOnError(TCPStream::ErrorHandler_t(conn, &lws_conn::onError));
210 conn->ts->setOnDisconnect(TCPStream::DisconnectHandler_t(conn,
Andy Green11f27342015-11-08 12:10:26 +0800211 &lws_conn::onDisconnect));
Andy Greenae7b27c2015-11-24 16:06:22 +0800212
Andy Green11f27342015-11-08 12:10:26 +0800213 conn->actual_onRX((Socket *)conn->ts);
214
215 lwsl_debug("%s: exit\n", __func__);
Andy Green8c0d3c02015-11-02 20:34:12 +0800216}
217
Andy Green4b85c1d2015-12-04 11:08:32 +0800218extern "C" LWS_VISIBLE struct lws *
219wsi_from_fd(struct lws_context *context, lws_sockfd_type fd)
Andy Green8c0d3c02015-11-02 20:34:12 +0800220{
Andy Green11f27342015-11-08 12:10:26 +0800221 lws_conn *conn = (lws_conn *)fd;
222 (void)context;
Andy Green8c0d3c02015-11-02 20:34:12 +0800223
Andy Green11f27342015-11-08 12:10:26 +0800224 return conn->wsi;
225}
226
227extern "C" LWS_VISIBLE void
Andy Green4b85c1d2015-12-04 11:08:32 +0800228lws_plat_insert_socket_into_fds(struct lws_context *context,
229 struct lws *wsi)
Andy Green11f27342015-11-08 12:10:26 +0800230{
231 (void)wsi;
232 lws_libev_io(context, wsi, LWS_EV_START | LWS_EV_READ);
233 context->fds[context->fds_count++].revents = 0;
234}
235
236extern "C" LWS_VISIBLE void
Andy Green4b85c1d2015-12-04 11:08:32 +0800237lws_plat_delete_socket_from_fds(struct lws_context *context,
238 struct lws *wsi, int m)
Andy Green11f27342015-11-08 12:10:26 +0800239{
240 (void)context;
241 (void)wsi;
242 (void)m;
243}
244
245void lws_conn::onRX(Socket *s)
246{
247 actual_onRX(s);
Andy Green8c0d3c02015-11-02 20:34:12 +0800248}
249
250void lws_conn_listener::onDisconnect(TCPStream *s)
251{
Andy Green11f27342015-11-08 12:10:26 +0800252 lwsl_info("%s\r\n", __func__);
Andy Green8c0d3c02015-11-02 20:34:12 +0800253 (void)s;
254 //if (s)
255 //delete this;
256}
Andy Green87eeb0a2015-11-25 08:22:08 +0800257
258extern "C" LWS_VISIBLE int
Andy Green4b85c1d2015-12-04 11:08:32 +0800259lws_plat_service(struct lws_context *context, int timeout_ms)
Andy Green87eeb0a2015-11-25 08:22:08 +0800260{
261 (void)context;
262 (void)timeout_ms;
263
264 return 0;
265}
266
Andy Green11f27342015-11-08 12:10:26 +0800267void lws_conn::onSent(Socket *s, uint16_t len)
Andy Green8c0d3c02015-11-02 20:34:12 +0800268{
Andy Green4b85c1d2015-12-04 11:08:32 +0800269 struct lws_pollfd pollfd;
Andy Green11f27342015-11-08 12:10:26 +0800270
Andy Green8c0d3c02015-11-02 20:34:12 +0800271 (void)s;
272 (void)len;
Andy Green87eeb0a2015-11-25 08:22:08 +0800273
274 if (!awaiting_on_writeable) {
275 lwsl_debug("%s: wsi %p (setting writable=1)\r\n", __func__, (void *)wsi);
276 writeable = 1;
277 return;
278 }
279
280 writeable = 1;
Andy Green11f27342015-11-08 12:10:26 +0800281
Andy Green87eeb0a2015-11-25 08:22:08 +0800282 pollfd.fd = wsi->sock;
Andy Green11f27342015-11-08 12:10:26 +0800283 pollfd.events = POLLOUT;
284 pollfd.revents = POLLOUT;
Andy Green11f27342015-11-08 12:10:26 +0800285
Andy Green87eeb0a2015-11-25 08:22:08 +0800286 lwsl_debug("%s: wsi %p (servicing now)\r\n", __func__, (void *)wsi);
Andy Green11f27342015-11-08 12:10:26 +0800287
Andy Green62304762015-12-04 08:43:54 +0800288 lws_service_fd(wsi->protocol->owning_server, &pollfd);
Andy Green8c0d3c02015-11-02 20:34:12 +0800289}
290
291void lws_conn_listener::onError(Socket *s, socket_error_t err)
292{
293 (void) s;
294 lwsl_notice("Socket Error: %s (%d)\r\n", socket_strerror(err), err);
295 if (ts)
296 ts->close();
297}
Andy Green11f27342015-11-08 12:10:26 +0800298
299void lws_conn::onDisconnect(TCPStream *s)
300{
301 (void)s;
Andy Green3ef579b2015-12-04 09:23:56 +0800302 lws_close_and_free_session(wsi->protocol->owning_server, wsi,
Andy Green11f27342015-11-08 12:10:26 +0800303 LWS_CLOSE_STATUS_NOSTATUS);
304}
305
306
307void lws_conn::onError(Socket *s, socket_error_t err)
308{
309 (void) s;
310 lwsl_notice("Socket Error: %s (%d)\r\n", socket_strerror(err), err);
311 if (ts)
312 ts->close();
313}