lws-plat-mbed3.cpp 7.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314
  1. #include "private-libwebsockets.h"
  2. #include "core-util/CriticalSectionLock.h"
  3. extern "C" void *mbed3_create_tcp_stream_socket(void)
  4. {
  5. lws_conn_listener *srv = new lws_conn_listener;
  6. //lwsl_notice("%s: %p\r\n", __func__, (void *)srv);
  7. return (void *)srv;
  8. }
  9. /* this is called by compatible_close() */
  10. extern "C" void mbed3_delete_tcp_stream_socket(void *sock)
  11. {
  12. lws_conn *conn = (lws_conn *)sock;
  13. conn->ts->close();
  14. lwsl_notice("%s: wsi %p: conn %p\r\n", __func__, (void *)conn->wsi, sock);
  15. delete conn;
  16. }
  17. void lws_conn::serialized_writeable(struct lws *_wsi)
  18. {
  19. struct lws *wsi = (struct lws *)_wsi;
  20. struct lws_pollfd pollfd;
  21. lws_conn *conn = (lws_conn *)wsi->sock;
  22. conn->awaiting_on_writeable = 0;
  23. pollfd.fd = wsi->sock;
  24. pollfd.events = POLLOUT;
  25. pollfd.revents = POLLOUT;
  26. lwsl_debug("%s: wsi %p\r\n", __func__, (void *)wsi);
  27. lws_service_fd(lws_get_context(wsi), &pollfd);
  28. }
  29. extern "C" void mbed3_tcp_stream_bind(void *sock, int port, struct lws *wsi)
  30. {
  31. lws_conn_listener *srv = (lws_conn_listener *)sock;
  32. lwsl_debug("%s\r\n", __func__);
  33. /* associate us with the listening wsi */
  34. ((lws_conn *)srv)->set_wsi(wsi);
  35. mbed::util::FunctionPointer1<void, uint16_t> fp(srv, &lws_conn_listener::start);
  36. minar::Scheduler::postCallback(fp.bind(port));
  37. }
  38. extern "C" void mbed3_tcp_stream_accept(void *sock, struct lws *wsi)
  39. {
  40. lws_conn *conn = (lws_conn *)sock;
  41. lwsl_debug("%s\r\n", __func__);
  42. conn->set_wsi(wsi);
  43. }
  44. extern "C" LWS_VISIBLE int
  45. lws_plat_change_pollfd(struct lws_context *context,
  46. struct lws *wsi, struct lws_pollfd *pfd)
  47. {
  48. lws_conn *conn = (lws_conn *)wsi->sock;
  49. (void)context;
  50. if (pfd->events & POLLOUT) {
  51. conn->awaiting_on_writeable = 1;
  52. if (conn->writeable) {
  53. mbed::util::FunctionPointer1<void, struct lws *> book(conn, &lws_conn::serialized_writeable);
  54. minar::Scheduler::postCallback(book.bind(wsi));
  55. lwsl_debug("%s: wsi %p (booked callback)\r\n", __func__, (void *)wsi);
  56. } else {
  57. lwsl_debug("%s: wsi %p (set awaiting_on_writeable)\r\n", __func__, (void *)wsi);
  58. }
  59. } else
  60. conn->awaiting_on_writeable = 0;
  61. return 0;
  62. }
  63. extern "C" LWS_VISIBLE int
  64. lws_plat_check_connection_error(struct lws *wsi)
  65. {
  66. return 0;
  67. }
  68. extern "C" LWS_VISIBLE int
  69. lws_ssl_capable_read_no_ssl(struct lws *wsi, unsigned char *buf, int len)
  70. {
  71. socket_error_t err;
  72. size_t _len = len;
  73. lwsl_debug("%s\r\n", __func__);
  74. err = ((lws_conn *)wsi->sock)->ts->recv((char *)buf, &_len);
  75. if (err == SOCKET_ERROR_NONE) {
  76. lwsl_info("%s: got %d bytes\n", __func__, _len);
  77. return _len;
  78. }
  79. #if LWS_POSIX
  80. if (LWS_ERRNO == LWS_EAGAIN ||
  81. LWS_ERRNO == LWS_EWOULDBLOCK ||
  82. LWS_ERRNO == LWS_EINTR)
  83. #else
  84. if (err == SOCKET_ERROR_WOULD_BLOCK)
  85. #endif
  86. return LWS_SSL_CAPABLE_MORE_SERVICE;
  87. lwsl_warn("error on reading from skt: %d\n", err);
  88. return LWS_SSL_CAPABLE_ERROR;
  89. }
  90. extern "C" LWS_VISIBLE int
  91. lws_ssl_capable_write_no_ssl(struct lws *wsi, unsigned char *buf, int len)
  92. {
  93. socket_error_t err;
  94. lws_conn *conn = (lws_conn *)wsi->sock;
  95. lwsl_debug("%s: wsi %p: write %d (from %p)\n", __func__, (void *)wsi, len, (void *)buf);
  96. lwsl_debug("%s: wsi %p: clear writeable\n", __func__, (void *)wsi);
  97. conn->writeable = 0;
  98. err = conn->ts->send((char *)buf, len);
  99. if (err == SOCKET_ERROR_NONE)
  100. return len;
  101. #if LWS_POSIX
  102. if (LWS_ERRNO == LWS_EAGAIN ||
  103. LWS_ERRNO == LWS_EWOULDBLOCK ||
  104. LWS_ERRNO == LWS_EINTR) {
  105. if (LWS_ERRNO == LWS_EWOULDBLOCK)
  106. lws_set_blocking_send(wsi);
  107. #else
  108. if (err == SOCKET_ERROR_WOULD_BLOCK)
  109. return LWS_SSL_CAPABLE_MORE_SERVICE;
  110. #endif
  111. lwsl_warn("%s: wsi %p: ERROR %d writing len %d to skt\n", __func__, (void *)wsi, err, len);
  112. return LWS_SSL_CAPABLE_ERROR;
  113. }
  114. /*
  115. * Set the listening socket to listen.
  116. */
  117. void lws_conn_listener::start(const uint16_t port)
  118. {
  119. socket_error_t err = srv.open(SOCKET_AF_INET4);
  120. if (srv.error_check(err))
  121. return;
  122. err = srv.bind("0.0.0.0", port);
  123. if (srv.error_check(err))
  124. return;
  125. err = srv.start_listening(TCPListener::IncomingHandler_t(this,
  126. &lws_conn_listener::onIncoming));
  127. srv.error_check(err);
  128. }
  129. void lws_conn::onRX(Socket *s)
  130. {
  131. struct lws_pollfd pollfd;
  132. (void)s;
  133. pollfd.fd = this;
  134. pollfd.events = POLLIN;
  135. pollfd.revents = POLLIN;
  136. lwsl_debug("%s: lws %p\n", __func__, wsi);
  137. lws_service_fd(lws_get_context(wsi), &pollfd);
  138. }
  139. /*
  140. * this gets called from the OS when the TCPListener gets a connection that
  141. * needs accept()-ing. LWS needs to run the associated flow.
  142. */
  143. void lws_conn_listener::onIncoming(TCPListener *tl, void *impl)
  144. {
  145. mbed::util::CriticalSectionLock lock;
  146. lws_conn *conn;
  147. if (!impl) {
  148. onError(tl, SOCKET_ERROR_NULL_PTR);
  149. return;
  150. }
  151. conn = new(lws_conn);
  152. if (!conn) {
  153. lwsl_err("OOM\n");
  154. return;
  155. }
  156. conn->ts = srv.accept(impl);
  157. if (!conn->ts)
  158. return;
  159. conn->ts->setNagle(0);
  160. /*
  161. * we use the listen socket wsi to get started, but a new wsi is
  162. * created. mbed3_tcp_stream_accept() is also called from
  163. * here to bind the conn and new wsi together
  164. */
  165. lws_server_socket_service(lws_get_context(wsi),
  166. wsi, (struct pollfd *)conn);
  167. conn->ts->setOnError(TCPStream::ErrorHandler_t(conn, &lws_conn::onError));
  168. conn->ts->setOnDisconnect(TCPStream::DisconnectHandler_t(conn,
  169. &lws_conn::onDisconnect));
  170. conn->ts->setOnSent(Socket::SentHandler_t(conn, &lws_conn::onSent));
  171. conn->ts->setOnReadable(TCPStream::ReadableHandler_t(conn, &lws_conn::onRX));
  172. conn->onRX((Socket *)conn->ts);
  173. lwsl_debug("%s: exit\n", __func__);
  174. }
  175. extern "C" LWS_VISIBLE struct lws *
  176. wsi_from_fd(const struct lws_context *context, lws_sockfd_type fd)
  177. {
  178. lws_conn *conn = (lws_conn *)fd;
  179. (void)context;
  180. return conn->wsi;
  181. }
  182. extern "C" LWS_VISIBLE void
  183. lws_plat_insert_socket_into_fds(struct lws_context *context,
  184. struct lws *wsi)
  185. {
  186. (void)wsi;
  187. lws_libev_io(wsi, LWS_EV_START | LWS_EV_READ);
  188. context->pt[0].fds[context->pt[0].fds_count++].revents = 0;
  189. }
  190. extern "C" LWS_VISIBLE void
  191. lws_plat_delete_socket_from_fds(struct lws_context *context,
  192. struct lws *wsi, int m)
  193. {
  194. (void)context;
  195. (void)wsi;
  196. (void)m;
  197. }
  198. void lws_conn_listener::onDisconnect(TCPStream *s)
  199. {
  200. lwsl_info("%s\r\n", __func__);
  201. (void)s;
  202. //if (s)
  203. //delete this;
  204. }
  205. extern "C" LWS_VISIBLE int
  206. lws_plat_service(struct lws_context *context, int timeout_ms)
  207. {
  208. (void)context;
  209. (void)timeout_ms;
  210. return 0;
  211. }
  212. void lws_conn::onSent(Socket *s, uint16_t len)
  213. {
  214. struct lws_pollfd pollfd;
  215. (void)s;
  216. (void)len;
  217. if (!awaiting_on_writeable) {
  218. lwsl_debug("%s: wsi %p (setting writable=1)\r\n",
  219. __func__, (void *)wsi);
  220. writeable = 1;
  221. return;
  222. }
  223. writeable = 1;
  224. pollfd.fd = wsi->sock;
  225. pollfd.events = POLLOUT;
  226. pollfd.revents = POLLOUT;
  227. lwsl_debug("%s: wsi %p (servicing now)\r\n", __func__, (void *)wsi);
  228. lws_service_fd(lws_get_context(wsi), &pollfd);
  229. }
  230. void lws_conn_listener::onError(Socket *s, socket_error_t err)
  231. {
  232. (void) s;
  233. lwsl_notice("Socket Error: %s (%d)\r\n", socket_strerror(err), err);
  234. if (ts)
  235. ts->close();
  236. }
  237. void lws_conn::onDisconnect(TCPStream *s)
  238. {
  239. lwsl_notice("%s:\r\n", __func__);
  240. (void)s;
  241. lws_close_free_wsi(wsi, LWS_CLOSE_STATUS_NOSTATUS);
  242. }
  243. void lws_conn::onError(Socket *s, socket_error_t err)
  244. {
  245. (void) s;
  246. lwsl_notice("Socket Error: %s (%d)\r\n", socket_strerror(err), err);
  247. s->close();
  248. }