2015-11-02 20:34:12 +08:00
|
|
|
#include "private-libwebsockets.h"
|
2015-11-08 12:10:26 +08:00
|
|
|
#include "core-util/CriticalSectionLock.h"
|
2015-11-02 20:34:12 +08:00
|
|
|
|
|
|
|
extern "C" void *mbed3_create_tcp_stream_socket(void)
|
|
|
|
{
|
|
|
|
lws_conn_listener *srv = new lws_conn_listener;
|
2015-12-14 08:52:03 +08:00
|
|
|
|
2015-11-08 12:10:26 +08:00
|
|
|
//lwsl_notice("%s: %p\r\n", __func__, (void *)srv);
|
2015-12-14 08:52:03 +08:00
|
|
|
|
2015-11-02 20:34:12 +08:00
|
|
|
return (void *)srv;
|
|
|
|
}
|
|
|
|
|
2015-11-08 12:10:26 +08:00
|
|
|
/* this is called by compatible_close() */
|
2015-11-02 20:34:12 +08:00
|
|
|
extern "C" void mbed3_delete_tcp_stream_socket(void *sock)
|
|
|
|
{
|
2015-11-08 12:10:26 +08:00
|
|
|
lws_conn *conn = (lws_conn *)sock;
|
2015-12-14 08:52:03 +08:00
|
|
|
|
2015-11-08 12:10:26 +08:00
|
|
|
conn->ts->close();
|
2015-12-14 08:52:03 +08:00
|
|
|
|
2015-11-08 12:10:26 +08:00
|
|
|
lwsl_notice("%s: wsi %p: conn %p\r\n", __func__, (void *)conn->wsi, sock);
|
|
|
|
delete conn;
|
2015-11-02 20:34:12 +08:00
|
|
|
}
|
|
|
|
|
2015-12-04 11:08:32 +08:00
|
|
|
void lws_conn::serialized_writeable(struct lws *_wsi)
|
2015-11-25 08:22:08 +08:00
|
|
|
{
|
2015-12-04 11:08:32 +08:00
|
|
|
struct lws *wsi = (struct lws *)_wsi;
|
|
|
|
struct lws_pollfd pollfd;
|
2015-11-25 08:22:08 +08:00
|
|
|
lws_conn *conn = (lws_conn *)wsi->sock;
|
2015-12-14 08:52:03 +08:00
|
|
|
|
2015-11-25 08:22:08 +08:00
|
|
|
conn->awaiting_on_writeable = 0;
|
|
|
|
|
|
|
|
pollfd.fd = wsi->sock;
|
|
|
|
pollfd.events = POLLOUT;
|
|
|
|
pollfd.revents = POLLOUT;
|
|
|
|
|
|
|
|
lwsl_debug("%s: wsi %p\r\n", __func__, (void *)wsi);
|
|
|
|
|
2015-12-17 18:25:25 +08:00
|
|
|
lws_service_fd(lws_get_context(wsi), &pollfd);
|
2015-11-25 08:22:08 +08:00
|
|
|
}
|
|
|
|
|
2015-12-04 11:08:32 +08:00
|
|
|
extern "C" void mbed3_tcp_stream_bind(void *sock, int port, struct lws *wsi)
|
2015-11-02 20:34:12 +08:00
|
|
|
{
|
|
|
|
lws_conn_listener *srv = (lws_conn_listener *)sock;
|
2015-12-14 08:52:03 +08:00
|
|
|
|
2015-11-25 08:22:08 +08:00
|
|
|
lwsl_debug("%s\r\n", __func__);
|
2015-11-02 20:34:12 +08:00
|
|
|
/* associate us with the listening wsi */
|
|
|
|
((lws_conn *)srv)->set_wsi(wsi);
|
|
|
|
|
|
|
|
mbed::util::FunctionPointer1<void, uint16_t> fp(srv, &lws_conn_listener::start);
|
|
|
|
minar::Scheduler::postCallback(fp.bind(port));
|
|
|
|
}
|
|
|
|
|
2015-12-04 11:08:32 +08:00
|
|
|
extern "C" void mbed3_tcp_stream_accept(void *sock, struct lws *wsi)
|
2015-11-02 20:34:12 +08:00
|
|
|
{
|
|
|
|
lws_conn *conn = (lws_conn *)sock;
|
|
|
|
|
2015-11-25 08:22:08 +08:00
|
|
|
lwsl_debug("%s\r\n", __func__);
|
2015-11-02 20:34:12 +08:00
|
|
|
conn->set_wsi(wsi);
|
|
|
|
}
|
|
|
|
|
2015-11-25 08:22:08 +08:00
|
|
|
extern "C" LWS_VISIBLE int
|
2015-12-04 11:08:32 +08:00
|
|
|
lws_plat_change_pollfd(struct lws_context *context,
|
|
|
|
struct lws *wsi, struct lws_pollfd *pfd)
|
2015-11-25 08:22:08 +08:00
|
|
|
{
|
|
|
|
lws_conn *conn = (lws_conn *)wsi->sock;
|
2015-12-14 08:52:03 +08:00
|
|
|
|
2015-11-25 08:22:08 +08:00
|
|
|
(void)context;
|
|
|
|
if (pfd->events & POLLOUT) {
|
|
|
|
conn->awaiting_on_writeable = 1;
|
|
|
|
if (conn->writeable) {
|
2015-12-04 11:08:32 +08:00
|
|
|
mbed::util::FunctionPointer1<void, struct lws *> book(conn, &lws_conn::serialized_writeable);
|
2015-11-25 08:22:08 +08:00
|
|
|
minar::Scheduler::postCallback(book.bind(wsi));
|
|
|
|
lwsl_debug("%s: wsi %p (booked callback)\r\n", __func__, (void *)wsi);
|
|
|
|
} else {
|
2015-12-14 08:52:03 +08:00
|
|
|
|
2015-11-25 08:22:08 +08:00
|
|
|
lwsl_debug("%s: wsi %p (set awaiting_on_writeable)\r\n", __func__, (void *)wsi);
|
|
|
|
}
|
|
|
|
} else
|
|
|
|
conn->awaiting_on_writeable = 0;
|
2015-12-14 08:52:03 +08:00
|
|
|
|
2015-11-25 08:22:08 +08:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2015-11-08 12:10:26 +08:00
|
|
|
extern "C" LWS_VISIBLE int
|
2015-12-15 21:15:58 +08:00
|
|
|
lws_ssl_capable_read_no_ssl(struct lws *wsi, unsigned char *buf, int len)
|
2015-11-08 12:10:26 +08:00
|
|
|
{
|
|
|
|
socket_error_t err;
|
|
|
|
size_t _len = len;
|
2015-12-14 08:52:03 +08:00
|
|
|
|
2015-11-08 12:10:26 +08:00
|
|
|
lwsl_debug("%s\r\n", __func__);
|
2015-12-14 08:52:03 +08:00
|
|
|
|
2015-11-25 08:22:08 +08:00
|
|
|
err = ((lws_conn *)wsi->sock)->ts->recv((char *)buf, &_len);
|
2015-11-08 12:10:26 +08:00
|
|
|
if (err == SOCKET_ERROR_NONE) {
|
|
|
|
lwsl_info("%s: got %d bytes\n", __func__, _len);
|
|
|
|
return _len;
|
|
|
|
}
|
|
|
|
#if LWS_POSIX
|
|
|
|
if (LWS_ERRNO == LWS_EAGAIN ||
|
|
|
|
LWS_ERRNO == LWS_EWOULDBLOCK ||
|
|
|
|
LWS_ERRNO == LWS_EINTR)
|
|
|
|
#else
|
|
|
|
if (err == SOCKET_ERROR_WOULD_BLOCK)
|
|
|
|
#endif
|
|
|
|
return LWS_SSL_CAPABLE_MORE_SERVICE;
|
|
|
|
|
|
|
|
lwsl_warn("error on reading from skt: %d\n", err);
|
|
|
|
return LWS_SSL_CAPABLE_ERROR;
|
|
|
|
}
|
|
|
|
|
|
|
|
extern "C" LWS_VISIBLE int
|
2015-12-04 11:08:32 +08:00
|
|
|
lws_ssl_capable_write_no_ssl(struct lws *wsi, unsigned char *buf, int len)
|
2015-11-08 12:10:26 +08:00
|
|
|
{
|
|
|
|
socket_error_t err;
|
2015-11-25 08:22:08 +08:00
|
|
|
lws_conn *conn = (lws_conn *)wsi->sock;
|
2015-11-08 12:10:26 +08:00
|
|
|
|
|
|
|
lwsl_debug("%s: wsi %p: write %d (from %p)\n", __func__, (void *)wsi, len, (void *)buf);
|
2015-12-14 08:52:03 +08:00
|
|
|
|
2015-11-25 08:22:08 +08:00
|
|
|
lwsl_debug("%s: wsi %p: clear writeable\n", __func__, (void *)wsi);
|
|
|
|
conn->writeable = 0;
|
2015-12-14 08:52:03 +08:00
|
|
|
|
2015-11-25 08:22:08 +08:00
|
|
|
err = conn->ts->send((char *)buf, len);
|
2015-11-08 12:10:26 +08:00
|
|
|
if (err == SOCKET_ERROR_NONE)
|
|
|
|
return len;
|
|
|
|
|
|
|
|
#if LWS_POSIX
|
|
|
|
if (LWS_ERRNO == LWS_EAGAIN ||
|
|
|
|
LWS_ERRNO == LWS_EWOULDBLOCK ||
|
|
|
|
LWS_ERRNO == LWS_EINTR) {
|
|
|
|
if (LWS_ERRNO == LWS_EWOULDBLOCK)
|
|
|
|
lws_set_blocking_send(wsi);
|
|
|
|
#else
|
|
|
|
if (err == SOCKET_ERROR_WOULD_BLOCK)
|
|
|
|
return LWS_SSL_CAPABLE_MORE_SERVICE;
|
|
|
|
#endif
|
|
|
|
|
|
|
|
lwsl_warn("%s: wsi %p: ERROR %d writing len %d to skt\n", __func__, (void *)wsi, err, len);
|
|
|
|
return LWS_SSL_CAPABLE_ERROR;
|
|
|
|
}
|
|
|
|
|
2015-11-02 20:34:12 +08:00
|
|
|
/*
|
|
|
|
* Set the listening socket to listen.
|
|
|
|
*/
|
|
|
|
|
|
|
|
void lws_conn_listener::start(const uint16_t port)
|
|
|
|
{
|
|
|
|
socket_error_t err = srv.open(SOCKET_AF_INET4);
|
|
|
|
|
|
|
|
if (srv.error_check(err))
|
|
|
|
return;
|
|
|
|
err = srv.bind("0.0.0.0", port);
|
|
|
|
if (srv.error_check(err))
|
|
|
|
return;
|
|
|
|
err = srv.start_listening(TCPListener::IncomingHandler_t(this,
|
|
|
|
&lws_conn_listener::onIncoming));
|
|
|
|
srv.error_check(err);
|
|
|
|
}
|
|
|
|
|
2015-12-04 16:54:12 +08:00
|
|
|
void lws_conn::onRX(Socket *s)
|
2015-11-08 12:10:26 +08:00
|
|
|
{
|
2015-12-04 11:08:32 +08:00
|
|
|
struct lws_pollfd pollfd;
|
2015-12-14 08:52:03 +08:00
|
|
|
|
2015-11-25 08:22:08 +08:00
|
|
|
(void)s;
|
2015-11-08 12:10:26 +08:00
|
|
|
|
|
|
|
pollfd.fd = this;
|
|
|
|
pollfd.events = POLLIN;
|
|
|
|
pollfd.revents = POLLIN;
|
2015-12-14 08:52:03 +08:00
|
|
|
|
2015-11-08 12:10:26 +08:00
|
|
|
lwsl_debug("%s: lws %p\n", __func__, wsi);
|
2015-12-14 08:52:03 +08:00
|
|
|
|
2015-12-17 18:25:25 +08:00
|
|
|
lws_service_fd(lws_get_context(wsi), &pollfd);
|
2015-11-08 12:10:26 +08:00
|
|
|
}
|
|
|
|
|
2015-12-14 08:52:03 +08:00
|
|
|
/*
|
2015-11-02 20:34:12 +08:00
|
|
|
* this gets called from the OS when the TCPListener gets a connection that
|
|
|
|
* needs accept()-ing. LWS needs to run the associated flow.
|
|
|
|
*/
|
|
|
|
|
|
|
|
void lws_conn_listener::onIncoming(TCPListener *tl, void *impl)
|
|
|
|
{
|
2015-11-08 12:10:26 +08:00
|
|
|
mbed::util::CriticalSectionLock lock;
|
2015-11-02 20:34:12 +08:00
|
|
|
lws_conn *conn;
|
2015-11-08 12:10:26 +08:00
|
|
|
|
2015-11-24 16:06:22 +08:00
|
|
|
if (!impl) {
|
2015-11-02 20:34:12 +08:00
|
|
|
onError(tl, SOCKET_ERROR_NULL_PTR);
|
|
|
|
return;
|
|
|
|
}
|
2015-12-14 08:52:03 +08:00
|
|
|
|
2015-11-02 20:34:12 +08:00
|
|
|
conn = new(lws_conn);
|
2015-11-08 12:10:26 +08:00
|
|
|
if (!conn) {
|
|
|
|
lwsl_err("OOM\n");
|
2015-11-02 20:34:12 +08:00
|
|
|
return;
|
|
|
|
}
|
2015-11-24 16:06:22 +08:00
|
|
|
conn->ts = srv.accept(impl);
|
|
|
|
if (!conn->ts)
|
|
|
|
return;
|
2015-11-02 20:34:12 +08:00
|
|
|
|
2015-12-15 19:46:28 +08:00
|
|
|
conn->ts->setNagle(0);
|
|
|
|
|
2015-12-14 08:52:03 +08:00
|
|
|
/*
|
2015-11-02 20:34:12 +08:00
|
|
|
* we use the listen socket wsi to get started, but a new wsi is
|
2015-11-08 12:10:26 +08:00
|
|
|
* created. mbed3_tcp_stream_accept() is also called from
|
|
|
|
* here to bind the conn and new wsi together
|
2015-11-02 20:34:12 +08:00
|
|
|
*/
|
2015-12-17 18:25:25 +08:00
|
|
|
lws_server_socket_service(lws_get_context(wsi),
|
2015-11-02 20:34:12 +08:00
|
|
|
wsi, (struct pollfd *)conn);
|
2015-11-08 12:10:26 +08:00
|
|
|
|
2015-11-24 16:06:22 +08:00
|
|
|
conn->ts->setOnError(TCPStream::ErrorHandler_t(conn, &lws_conn::onError));
|
|
|
|
conn->ts->setOnDisconnect(TCPStream::DisconnectHandler_t(conn,
|
2015-11-08 12:10:26 +08:00
|
|
|
&lws_conn::onDisconnect));
|
2015-12-04 16:54:12 +08:00
|
|
|
conn->ts->setOnSent(Socket::SentHandler_t(conn, &lws_conn::onSent));
|
|
|
|
conn->ts->setOnReadable(TCPStream::ReadableHandler_t(conn, &lws_conn::onRX));
|
2015-11-24 16:06:22 +08:00
|
|
|
|
2015-12-04 16:54:12 +08:00
|
|
|
conn->onRX((Socket *)conn->ts);
|
2015-11-08 12:10:26 +08:00
|
|
|
|
|
|
|
lwsl_debug("%s: exit\n", __func__);
|
2015-11-02 20:34:12 +08:00
|
|
|
}
|
|
|
|
|
2015-12-04 11:08:32 +08:00
|
|
|
extern "C" LWS_VISIBLE struct lws *
|
2015-12-14 11:17:16 +08:00
|
|
|
wsi_from_fd(const struct lws_context *context, lws_sockfd_type fd)
|
2015-11-02 20:34:12 +08:00
|
|
|
{
|
2015-11-08 12:10:26 +08:00
|
|
|
lws_conn *conn = (lws_conn *)fd;
|
|
|
|
(void)context;
|
|
|
|
|
|
|
|
return conn->wsi;
|
|
|
|
}
|
2015-11-02 20:34:12 +08:00
|
|
|
|
2015-11-08 12:10:26 +08:00
|
|
|
extern "C" LWS_VISIBLE void
|
2015-12-04 11:08:32 +08:00
|
|
|
lws_plat_insert_socket_into_fds(struct lws_context *context,
|
|
|
|
struct lws *wsi)
|
2015-11-08 12:10:26 +08:00
|
|
|
{
|
|
|
|
(void)wsi;
|
2015-12-16 18:19:08 +08:00
|
|
|
lws_libev_io(wsi, LWS_EV_START | LWS_EV_READ);
|
2015-11-08 12:10:26 +08:00
|
|
|
context->fds[context->fds_count++].revents = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
extern "C" LWS_VISIBLE void
|
2015-12-04 11:08:32 +08:00
|
|
|
lws_plat_delete_socket_from_fds(struct lws_context *context,
|
|
|
|
struct lws *wsi, int m)
|
2015-11-08 12:10:26 +08:00
|
|
|
{
|
|
|
|
(void)context;
|
|
|
|
(void)wsi;
|
|
|
|
(void)m;
|
|
|
|
}
|
|
|
|
|
2015-11-02 20:34:12 +08:00
|
|
|
void lws_conn_listener::onDisconnect(TCPStream *s)
|
|
|
|
{
|
2015-11-08 12:10:26 +08:00
|
|
|
lwsl_info("%s\r\n", __func__);
|
2015-11-02 20:34:12 +08:00
|
|
|
(void)s;
|
|
|
|
//if (s)
|
|
|
|
//delete this;
|
|
|
|
}
|
2015-11-25 08:22:08 +08:00
|
|
|
|
|
|
|
extern "C" LWS_VISIBLE int
|
2015-12-04 11:08:32 +08:00
|
|
|
lws_plat_service(struct lws_context *context, int timeout_ms)
|
2015-11-25 08:22:08 +08:00
|
|
|
{
|
|
|
|
(void)context;
|
|
|
|
(void)timeout_ms;
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2015-11-08 12:10:26 +08:00
|
|
|
void lws_conn::onSent(Socket *s, uint16_t len)
|
2015-11-02 20:34:12 +08:00
|
|
|
{
|
2015-12-04 11:08:32 +08:00
|
|
|
struct lws_pollfd pollfd;
|
2015-11-08 12:10:26 +08:00
|
|
|
|
2015-11-02 20:34:12 +08:00
|
|
|
(void)s;
|
|
|
|
(void)len;
|
2015-12-14 08:52:03 +08:00
|
|
|
|
2015-11-25 08:22:08 +08:00
|
|
|
if (!awaiting_on_writeable) {
|
2015-12-04 16:54:12 +08:00
|
|
|
lwsl_debug("%s: wsi %p (setting writable=1)\r\n",
|
|
|
|
__func__, (void *)wsi);
|
2015-11-25 08:22:08 +08:00
|
|
|
writeable = 1;
|
|
|
|
return;
|
|
|
|
}
|
2015-12-14 08:52:03 +08:00
|
|
|
|
2015-11-25 08:22:08 +08:00
|
|
|
writeable = 1;
|
2015-11-08 12:10:26 +08:00
|
|
|
|
2015-11-25 08:22:08 +08:00
|
|
|
pollfd.fd = wsi->sock;
|
2015-11-08 12:10:26 +08:00
|
|
|
pollfd.events = POLLOUT;
|
|
|
|
pollfd.revents = POLLOUT;
|
|
|
|
|
2015-11-25 08:22:08 +08:00
|
|
|
lwsl_debug("%s: wsi %p (servicing now)\r\n", __func__, (void *)wsi);
|
2015-12-14 08:52:03 +08:00
|
|
|
|
2015-12-17 18:25:25 +08:00
|
|
|
lws_service_fd(lws_get_context(wsi), &pollfd);
|
2015-11-02 20:34:12 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
void lws_conn_listener::onError(Socket *s, socket_error_t err)
|
|
|
|
{
|
|
|
|
(void) s;
|
|
|
|
lwsl_notice("Socket Error: %s (%d)\r\n", socket_strerror(err), err);
|
|
|
|
if (ts)
|
|
|
|
ts->close();
|
|
|
|
}
|
2015-11-08 12:10:26 +08:00
|
|
|
|
|
|
|
void lws_conn::onDisconnect(TCPStream *s)
|
|
|
|
{
|
2015-12-04 16:54:12 +08:00
|
|
|
lwsl_notice("%s:\r\n", __func__);
|
2015-11-08 12:10:26 +08:00
|
|
|
(void)s;
|
2015-12-15 21:15:58 +08:00
|
|
|
lws_close_free_wsi(wsi, LWS_CLOSE_STATUS_NOSTATUS);
|
2015-11-08 12:10:26 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void lws_conn::onError(Socket *s, socket_error_t err)
|
|
|
|
{
|
|
|
|
(void) s;
|
|
|
|
lwsl_notice("Socket Error: %s (%d)\r\n", socket_strerror(err), err);
|
2015-12-04 16:54:12 +08:00
|
|
|
s->close();
|
|
|
|
}
|