Andy Green | 8c0d3c0 | 2015-11-02 20:34:12 +0800 | [diff] [blame] | 1 | #include "private-libwebsockets.h" |
Andy Green | 11f2734 | 2015-11-08 12:10:26 +0800 | [diff] [blame] | 2 | #include "core-util/CriticalSectionLock.h" |
Andy Green | 8c0d3c0 | 2015-11-02 20:34:12 +0800 | [diff] [blame] | 3 | |
| 4 | extern "C" void *mbed3_create_tcp_stream_socket(void) |
| 5 | { |
| 6 | lws_conn_listener *srv = new lws_conn_listener; |
| 7 | |
Andy Green | 11f2734 | 2015-11-08 12:10:26 +0800 | [diff] [blame] | 8 | //lwsl_notice("%s: %p\r\n", __func__, (void *)srv); |
Andy Green | 8c0d3c0 | 2015-11-02 20:34:12 +0800 | [diff] [blame] | 9 | |
| 10 | return (void *)srv; |
| 11 | } |
| 12 | |
Andy Green | 11f2734 | 2015-11-08 12:10:26 +0800 | [diff] [blame] | 13 | /* this is called by compatible_close() */ |
Andy Green | 8c0d3c0 | 2015-11-02 20:34:12 +0800 | [diff] [blame] | 14 | extern "C" void mbed3_delete_tcp_stream_socket(void *sock) |
| 15 | { |
Andy Green | 11f2734 | 2015-11-08 12:10:26 +0800 | [diff] [blame] | 16 | 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 Green | 8c0d3c0 | 2015-11-02 20:34:12 +0800 | [diff] [blame] | 22 | } |
| 23 | |
Andy Green | 4b85c1d | 2015-12-04 11:08:32 +0800 | [diff] [blame^] | 24 | void lws_conn::serialized_writeable(struct lws *_wsi) |
Andy Green | 87eeb0a | 2015-11-25 08:22:08 +0800 | [diff] [blame] | 25 | { |
Andy Green | 4b85c1d | 2015-12-04 11:08:32 +0800 | [diff] [blame^] | 26 | struct lws *wsi = (struct lws *)_wsi; |
| 27 | struct lws_pollfd pollfd; |
Andy Green | 87eeb0a | 2015-11-25 08:22:08 +0800 | [diff] [blame] | 28 | 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 Green | 6230476 | 2015-12-04 08:43:54 +0800 | [diff] [blame] | 38 | lws_service_fd(wsi->protocol->owning_server, &pollfd); |
Andy Green | 87eeb0a | 2015-11-25 08:22:08 +0800 | [diff] [blame] | 39 | } |
| 40 | |
Andy Green | 4b85c1d | 2015-12-04 11:08:32 +0800 | [diff] [blame^] | 41 | extern "C" void mbed3_tcp_stream_bind(void *sock, int port, struct lws *wsi) |
Andy Green | 8c0d3c0 | 2015-11-02 20:34:12 +0800 | [diff] [blame] | 42 | { |
| 43 | lws_conn_listener *srv = (lws_conn_listener *)sock; |
| 44 | |
Andy Green | 87eeb0a | 2015-11-25 08:22:08 +0800 | [diff] [blame] | 45 | lwsl_debug("%s\r\n", __func__); |
Andy Green | 8c0d3c0 | 2015-11-02 20:34:12 +0800 | [diff] [blame] | 46 | /* 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 Green | 4b85c1d | 2015-12-04 11:08:32 +0800 | [diff] [blame^] | 53 | extern "C" void mbed3_tcp_stream_accept(void *sock, struct lws *wsi) |
Andy Green | 8c0d3c0 | 2015-11-02 20:34:12 +0800 | [diff] [blame] | 54 | { |
| 55 | lws_conn *conn = (lws_conn *)sock; |
| 56 | |
Andy Green | 87eeb0a | 2015-11-25 08:22:08 +0800 | [diff] [blame] | 57 | lwsl_debug("%s\r\n", __func__); |
Andy Green | 8c0d3c0 | 2015-11-02 20:34:12 +0800 | [diff] [blame] | 58 | conn->set_wsi(wsi); |
| 59 | } |
| 60 | |
Andy Green | 11f2734 | 2015-11-08 12:10:26 +0800 | [diff] [blame] | 61 | extern "C" LWS_VISIBLE int |
Andy Green | 4b85c1d | 2015-12-04 11:08:32 +0800 | [diff] [blame^] | 62 | lws_plat_change_pollfd(struct lws_context *context, |
| 63 | struct lws *wsi, struct lws_pollfd *pfd) |
Andy Green | 87eeb0a | 2015-11-25 08:22:08 +0800 | [diff] [blame] | 64 | { |
| 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 Green | 4b85c1d | 2015-12-04 11:08:32 +0800 | [diff] [blame^] | 71 | mbed::util::FunctionPointer1<void, struct lws *> book(conn, &lws_conn::serialized_writeable); |
Andy Green | 87eeb0a | 2015-11-25 08:22:08 +0800 | [diff] [blame] | 72 | 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 | |
| 84 | extern "C" LWS_VISIBLE int |
Andy Green | 4b85c1d | 2015-12-04 11:08:32 +0800 | [diff] [blame^] | 85 | lws_ssl_capable_read_no_ssl(struct lws_context *context, |
| 86 | struct lws *wsi, unsigned char *buf, int len) |
Andy Green | 11f2734 | 2015-11-08 12:10:26 +0800 | [diff] [blame] | 87 | { |
| 88 | socket_error_t err; |
| 89 | size_t _len = len; |
Andy Green | 87eeb0a | 2015-11-25 08:22:08 +0800 | [diff] [blame] | 90 | |
Andy Green | 11f2734 | 2015-11-08 12:10:26 +0800 | [diff] [blame] | 91 | lwsl_debug("%s\r\n", __func__); |
| 92 | |
| 93 | (void)context; |
Andy Green | 87eeb0a | 2015-11-25 08:22:08 +0800 | [diff] [blame] | 94 | err = ((lws_conn *)wsi->sock)->ts->recv((char *)buf, &_len); |
Andy Green | 11f2734 | 2015-11-08 12:10:26 +0800 | [diff] [blame] | 95 | 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 Green | 11f2734 | 2015-11-08 12:10:26 +0800 | [diff] [blame] | 108 | lwsl_warn("error on reading from skt: %d\n", err); |
| 109 | return LWS_SSL_CAPABLE_ERROR; |
| 110 | } |
| 111 | |
| 112 | extern "C" LWS_VISIBLE int |
Andy Green | 4b85c1d | 2015-12-04 11:08:32 +0800 | [diff] [blame^] | 113 | lws_ssl_capable_write_no_ssl(struct lws *wsi, unsigned char *buf, int len) |
Andy Green | 11f2734 | 2015-11-08 12:10:26 +0800 | [diff] [blame] | 114 | { |
| 115 | socket_error_t err; |
Andy Green | 87eeb0a | 2015-11-25 08:22:08 +0800 | [diff] [blame] | 116 | lws_conn *conn = (lws_conn *)wsi->sock; |
Andy Green | 11f2734 | 2015-11-08 12:10:26 +0800 | [diff] [blame] | 117 | |
| 118 | lwsl_debug("%s: wsi %p: write %d (from %p)\n", __func__, (void *)wsi, len, (void *)buf); |
| 119 | |
Andy Green | 87eeb0a | 2015-11-25 08:22:08 +0800 | [diff] [blame] | 120 | 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 Green | 11f2734 | 2015-11-08 12:10:26 +0800 | [diff] [blame] | 124 | 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 Green | 8c0d3c0 | 2015-11-02 20:34:12 +0800 | [diff] [blame] | 142 | /* |
| 143 | * Set the listening socket to listen. |
| 144 | */ |
| 145 | |
| 146 | void 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 Green | 11f2734 | 2015-11-08 12:10:26 +0800 | [diff] [blame] | 160 | int lws_conn::actual_onRX(Socket *s) |
| 161 | { |
Andy Green | 4b85c1d | 2015-12-04 11:08:32 +0800 | [diff] [blame^] | 162 | struct lws_pollfd pollfd; |
Andy Green | 87eeb0a | 2015-11-25 08:22:08 +0800 | [diff] [blame] | 163 | |
| 164 | (void)s; |
Andy Green | 11f2734 | 2015-11-08 12:10:26 +0800 | [diff] [blame] | 165 | |
| 166 | pollfd.fd = this; |
| 167 | pollfd.events = POLLIN; |
| 168 | pollfd.revents = POLLIN; |
| 169 | |
| 170 | lwsl_debug("%s: lws %p\n", __func__, wsi); |
| 171 | |
Andy Green | 6230476 | 2015-12-04 08:43:54 +0800 | [diff] [blame] | 172 | return lws_service_fd(wsi->protocol->owning_server, &pollfd); |
Andy Green | 11f2734 | 2015-11-08 12:10:26 +0800 | [diff] [blame] | 173 | } |
| 174 | |
Andy Green | 8c0d3c0 | 2015-11-02 20:34:12 +0800 | [diff] [blame] | 175 | /* |
| 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 | |
| 180 | void lws_conn_listener::onIncoming(TCPListener *tl, void *impl) |
| 181 | { |
Andy Green | 11f2734 | 2015-11-08 12:10:26 +0800 | [diff] [blame] | 182 | mbed::util::CriticalSectionLock lock; |
Andy Green | 8c0d3c0 | 2015-11-02 20:34:12 +0800 | [diff] [blame] | 183 | lws_conn *conn; |
Andy Green | 11f2734 | 2015-11-08 12:10:26 +0800 | [diff] [blame] | 184 | |
Andy Green | ae7b27c | 2015-11-24 16:06:22 +0800 | [diff] [blame] | 185 | if (!impl) { |
Andy Green | 8c0d3c0 | 2015-11-02 20:34:12 +0800 | [diff] [blame] | 186 | onError(tl, SOCKET_ERROR_NULL_PTR); |
| 187 | return; |
| 188 | } |
| 189 | |
| 190 | conn = new(lws_conn); |
Andy Green | 11f2734 | 2015-11-08 12:10:26 +0800 | [diff] [blame] | 191 | if (!conn) { |
| 192 | lwsl_err("OOM\n"); |
Andy Green | 8c0d3c0 | 2015-11-02 20:34:12 +0800 | [diff] [blame] | 193 | return; |
| 194 | } |
Andy Green | ae7b27c | 2015-11-24 16:06:22 +0800 | [diff] [blame] | 195 | conn->ts = srv.accept(impl); |
| 196 | if (!conn->ts) |
| 197 | return; |
Andy Green | 8c0d3c0 | 2015-11-02 20:34:12 +0800 | [diff] [blame] | 198 | |
| 199 | /* |
| 200 | * we use the listen socket wsi to get started, but a new wsi is |
Andy Green | 11f2734 | 2015-11-08 12:10:26 +0800 | [diff] [blame] | 201 | * created. mbed3_tcp_stream_accept() is also called from |
| 202 | * here to bind the conn and new wsi together |
Andy Green | 8c0d3c0 | 2015-11-02 20:34:12 +0800 | [diff] [blame] | 203 | */ |
| 204 | lws_server_socket_service(wsi->protocol->owning_server, |
| 205 | wsi, (struct pollfd *)conn); |
Andy Green | 11f2734 | 2015-11-08 12:10:26 +0800 | [diff] [blame] | 206 | |
Andy Green | ae7b27c | 2015-11-24 16:06:22 +0800 | [diff] [blame] | 207 | 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 Green | 11f2734 | 2015-11-08 12:10:26 +0800 | [diff] [blame] | 211 | &lws_conn::onDisconnect)); |
Andy Green | ae7b27c | 2015-11-24 16:06:22 +0800 | [diff] [blame] | 212 | |
Andy Green | 11f2734 | 2015-11-08 12:10:26 +0800 | [diff] [blame] | 213 | conn->actual_onRX((Socket *)conn->ts); |
| 214 | |
| 215 | lwsl_debug("%s: exit\n", __func__); |
Andy Green | 8c0d3c0 | 2015-11-02 20:34:12 +0800 | [diff] [blame] | 216 | } |
| 217 | |
Andy Green | 4b85c1d | 2015-12-04 11:08:32 +0800 | [diff] [blame^] | 218 | extern "C" LWS_VISIBLE struct lws * |
| 219 | wsi_from_fd(struct lws_context *context, lws_sockfd_type fd) |
Andy Green | 8c0d3c0 | 2015-11-02 20:34:12 +0800 | [diff] [blame] | 220 | { |
Andy Green | 11f2734 | 2015-11-08 12:10:26 +0800 | [diff] [blame] | 221 | lws_conn *conn = (lws_conn *)fd; |
| 222 | (void)context; |
Andy Green | 8c0d3c0 | 2015-11-02 20:34:12 +0800 | [diff] [blame] | 223 | |
Andy Green | 11f2734 | 2015-11-08 12:10:26 +0800 | [diff] [blame] | 224 | return conn->wsi; |
| 225 | } |
| 226 | |
| 227 | extern "C" LWS_VISIBLE void |
Andy Green | 4b85c1d | 2015-12-04 11:08:32 +0800 | [diff] [blame^] | 228 | lws_plat_insert_socket_into_fds(struct lws_context *context, |
| 229 | struct lws *wsi) |
Andy Green | 11f2734 | 2015-11-08 12:10:26 +0800 | [diff] [blame] | 230 | { |
| 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 | |
| 236 | extern "C" LWS_VISIBLE void |
Andy Green | 4b85c1d | 2015-12-04 11:08:32 +0800 | [diff] [blame^] | 237 | lws_plat_delete_socket_from_fds(struct lws_context *context, |
| 238 | struct lws *wsi, int m) |
Andy Green | 11f2734 | 2015-11-08 12:10:26 +0800 | [diff] [blame] | 239 | { |
| 240 | (void)context; |
| 241 | (void)wsi; |
| 242 | (void)m; |
| 243 | } |
| 244 | |
| 245 | void lws_conn::onRX(Socket *s) |
| 246 | { |
| 247 | actual_onRX(s); |
Andy Green | 8c0d3c0 | 2015-11-02 20:34:12 +0800 | [diff] [blame] | 248 | } |
| 249 | |
| 250 | void lws_conn_listener::onDisconnect(TCPStream *s) |
| 251 | { |
Andy Green | 11f2734 | 2015-11-08 12:10:26 +0800 | [diff] [blame] | 252 | lwsl_info("%s\r\n", __func__); |
Andy Green | 8c0d3c0 | 2015-11-02 20:34:12 +0800 | [diff] [blame] | 253 | (void)s; |
| 254 | //if (s) |
| 255 | //delete this; |
| 256 | } |
Andy Green | 87eeb0a | 2015-11-25 08:22:08 +0800 | [diff] [blame] | 257 | |
| 258 | extern "C" LWS_VISIBLE int |
Andy Green | 4b85c1d | 2015-12-04 11:08:32 +0800 | [diff] [blame^] | 259 | lws_plat_service(struct lws_context *context, int timeout_ms) |
Andy Green | 87eeb0a | 2015-11-25 08:22:08 +0800 | [diff] [blame] | 260 | { |
| 261 | (void)context; |
| 262 | (void)timeout_ms; |
| 263 | |
| 264 | return 0; |
| 265 | } |
| 266 | |
Andy Green | 11f2734 | 2015-11-08 12:10:26 +0800 | [diff] [blame] | 267 | void lws_conn::onSent(Socket *s, uint16_t len) |
Andy Green | 8c0d3c0 | 2015-11-02 20:34:12 +0800 | [diff] [blame] | 268 | { |
Andy Green | 4b85c1d | 2015-12-04 11:08:32 +0800 | [diff] [blame^] | 269 | struct lws_pollfd pollfd; |
Andy Green | 11f2734 | 2015-11-08 12:10:26 +0800 | [diff] [blame] | 270 | |
Andy Green | 8c0d3c0 | 2015-11-02 20:34:12 +0800 | [diff] [blame] | 271 | (void)s; |
| 272 | (void)len; |
Andy Green | 87eeb0a | 2015-11-25 08:22:08 +0800 | [diff] [blame] | 273 | |
| 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 Green | 11f2734 | 2015-11-08 12:10:26 +0800 | [diff] [blame] | 281 | |
Andy Green | 87eeb0a | 2015-11-25 08:22:08 +0800 | [diff] [blame] | 282 | pollfd.fd = wsi->sock; |
Andy Green | 11f2734 | 2015-11-08 12:10:26 +0800 | [diff] [blame] | 283 | pollfd.events = POLLOUT; |
| 284 | pollfd.revents = POLLOUT; |
Andy Green | 11f2734 | 2015-11-08 12:10:26 +0800 | [diff] [blame] | 285 | |
Andy Green | 87eeb0a | 2015-11-25 08:22:08 +0800 | [diff] [blame] | 286 | lwsl_debug("%s: wsi %p (servicing now)\r\n", __func__, (void *)wsi); |
Andy Green | 11f2734 | 2015-11-08 12:10:26 +0800 | [diff] [blame] | 287 | |
Andy Green | 6230476 | 2015-12-04 08:43:54 +0800 | [diff] [blame] | 288 | lws_service_fd(wsi->protocol->owning_server, &pollfd); |
Andy Green | 8c0d3c0 | 2015-11-02 20:34:12 +0800 | [diff] [blame] | 289 | } |
| 290 | |
| 291 | void 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 Green | 11f2734 | 2015-11-08 12:10:26 +0800 | [diff] [blame] | 298 | |
| 299 | void lws_conn::onDisconnect(TCPStream *s) |
| 300 | { |
| 301 | (void)s; |
Andy Green | 3ef579b | 2015-12-04 09:23:56 +0800 | [diff] [blame] | 302 | lws_close_and_free_session(wsi->protocol->owning_server, wsi, |
Andy Green | 11f2734 | 2015-11-08 12:10:26 +0800 | [diff] [blame] | 303 | LWS_CLOSE_STATUS_NOSTATUS); |
| 304 | } |
| 305 | |
| 306 | |
| 307 | void 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 | } |