diff --git a/lib/context.c b/lib/context.c index 3159b1fb..f0eac398 100644 --- a/lib/context.c +++ b/lib/context.c @@ -76,10 +76,14 @@ libwebsocket_create_context(struct lws_context_creation_info *info) { struct libwebsocket_context *context = NULL; char *p; +#if LWS_POSIX int pid_daemon = get_daemonize_pid(); +#endif lwsl_notice("Initial logging level %d\n", log_level); - lwsl_notice("Library version: %s\n", library_version); + + lwsl_notice("Libwebsockets version: %s\n", library_version); +#if LWS_POSIX #ifdef LWS_USE_IPV6 if (!(info->options & LWS_SERVER_OPTION_DISABLE_IPV6)) lwsl_notice("IPV6 compiled in and enabled\n"); @@ -87,6 +91,7 @@ libwebsocket_create_context(struct lws_context_creation_info *info) lwsl_notice("IPV6 compiled in but disabled\n"); #else lwsl_notice("IPV6 not compiled in\n"); +#endif #endif lws_feature_status_libev(info); lwsl_info(" LWS_MAX_HEADER_LEN: %u\n", LWS_MAX_HEADER_LEN); @@ -96,7 +101,7 @@ libwebsocket_create_context(struct lws_context_creation_info *info) lwsl_info(" AWAITING_TIMEOUT: %u\n", AWAITING_TIMEOUT); lwsl_info(" SYSTEM_RANDOM_FILEPATH: '%s'\n", SYSTEM_RANDOM_FILEPATH); lwsl_info(" LWS_MAX_ZLIB_CONN_BUFFER: %u\n", LWS_MAX_ZLIB_CONN_BUFFER); - + if (lws_plat_context_early_init()) return NULL; @@ -105,11 +110,13 @@ libwebsocket_create_context(struct lws_context_creation_info *info) lwsl_err("No memory for websocket context\n"); return NULL; } - +#if LWS_POSIX if (pid_daemon) { context->started_with_parent = pid_daemon; lwsl_notice(" Started with daemon pid %d\n", pid_daemon); } +#endif + lwsl_notice(" context: %p\r\n", context); context->listen_service_extraseen = 0; context->protocols = info->protocols; @@ -139,7 +146,7 @@ libwebsocket_create_context(struct lws_context_creation_info *info) context->lws_ev_sigint_cb = &libwebsocket_sigint_cb; #endif /* LWS_USE_LIBEV */ - +#if LWS_POSIX /* to reduce this allocation, */ context->max_fds = getdtablesize(); lwsl_notice(" static allocation: %u + (%u x %u fds) = %u bytes\n", @@ -167,7 +174,7 @@ libwebsocket_create_context(struct lws_context_creation_info *info) if (lws_plat_init_fd_tables(context)) { goto bail; } - +#endif lws_context_init_extensions(info, context); context->user_space = info->user; @@ -218,7 +225,7 @@ libwebsocket_create_context(struct lws_context_creation_info *info) info->protocols[context->count_protocols].callback; context->count_protocols++) { - lwsl_parser(" Protocol: %s\n", + lwsl_notice(" Protocol: %s\n", info->protocols[context->count_protocols].name); info->protocols[context->count_protocols].owning_server = @@ -249,7 +256,7 @@ libwebsocket_create_context(struct lws_context_creation_info *info) LWS_EXT_CALLBACK_CLIENT_CONTEXT_CONSTRUCT, NULL, 0) < 0) goto bail; - + return context; bail: diff --git a/lib/libwebsockets.c b/lib/libwebsockets.c index 28f2c618..ae4478df 100644 --- a/lib/libwebsockets.c +++ b/lib/libwebsockets.c @@ -301,6 +301,7 @@ just_kill_connection: /* lwsl_info("closing fd=%d\n", wsi->sock); */ if (!lws_ssl_close(wsi) && lws_socket_is_valid(wsi->sock)) { +#if LWS_POSIX n = shutdown(wsi->sock, SHUT_RDWR); if (n) lwsl_debug("closing: shutdown ret %d\n", LWS_ERRNO); @@ -308,7 +309,9 @@ just_kill_connection: n = compatible_close(wsi->sock); if (n) lwsl_debug("closing: close ret %d\n", LWS_ERRNO); + wsi->sock = LWS_SOCK_INVALID; +#endif } /* outermost destroy notification for wsi (user_space still intact) */ @@ -323,6 +326,7 @@ libwebsockets_get_addresses(struct libwebsocket_context *context, void *ads, char *name, int name_len, char *rip, int rip_len) { +#if LWS_POSIX struct addrinfo ai, *res; struct sockaddr_in addr4; @@ -387,6 +391,16 @@ libwebsockets_get_addresses(struct libwebsocket_context *context, lws_plat_inet_ntop(AF_INET, &addr4.sin_addr, rip, rip_len); return 0; +#else + (void)context; + (void)ads; + (void)name; + (void)name_len; + (void)rip; + (void)rip_len; + + return -1; +#endif } /** @@ -407,9 +421,10 @@ libwebsockets_get_addresses(struct libwebsocket_context *context, LWS_VISIBLE void libwebsockets_get_peer_addresses(struct libwebsocket_context *context, - struct libwebsocket *wsi, int fd, char *name, int name_len, + struct libwebsocket *wsi, lws_sockfd_type fd, char *name, int name_len, char *rip, int rip_len) { +#if LWS_POSIX socklen_t len; #ifdef LWS_USE_IPV6 struct sockaddr_in6 sin6; @@ -443,6 +458,15 @@ libwebsockets_get_peer_addresses(struct libwebsocket_context *context, bail: lws_latency(context, wsi, "libwebsockets_get_peer_addresses", ret, 1); +#else + (void)context; + (void)wsi; + (void)fd; + (void)name; + (void)name_len; + (void)rip; + (void)rip_len; +#endif } /** @@ -512,6 +536,8 @@ libwebsocket_set_timeout(struct libwebsocket *wsi, } +#if LWS_POSIX + /** * libwebsocket_get_socket_fd() - returns the socket file descriptor * @@ -526,6 +552,8 @@ libwebsocket_get_socket_fd(struct libwebsocket *wsi) return wsi->sock; } +#endif + #ifdef LWS_LATENCY void lws_latency(struct libwebsocket_context *context, struct libwebsocket *wsi, diff --git a/lib/libwebsockets.h b/lib/libwebsockets.h index dfa40c75..a0ca6cfe 100644 --- a/lib/libwebsockets.h +++ b/lib/libwebsockets.h @@ -30,6 +30,55 @@ #include "sal-iface-eth/EthernetInterface.h" #include "sockets/TCPListener.h" #include "sal-stack-lwip/lwipv4_init.h" + +namespace { + const int SERVER_PORT = 80; + const int BUFFER_SIZE = 4096; +} +using namespace mbed::Sockets::v0; + +struct libwebsocket; + +class lws_conn { + public: + lws_conn(): + ts(NULL), + wsi(NULL) + { + } + +public: + void set_wsi(struct libwebsocket *_wsi) { wsi = _wsi; } +public: + TCPStream *ts; + +public: + struct libwebsocket *wsi; + char buffer[BUFFER_SIZE]; +}; + +class lws_conn_listener : lws_conn { +public: + lws_conn_listener(): + srv(SOCKET_STACK_LWIP_IPV4) + { + srv.setOnError(TCPStream::ErrorHandler_t(this, &lws_conn_listener::onError)); + } + + void start(const uint16_t port); + +protected: + void onRX(Socket *s); + void onError(Socket *s, socket_error_t err); + void onIncoming(TCPListener *s, void *impl); + void onDisconnect(TCPStream *s); + void onSent(Socket *s, uint16_t len); + +public: + TCPListener srv; +}; + + #define LWS_POSIX 0 #else #define LWS_POSIX 1 @@ -79,6 +128,8 @@ extern "C" { #ifndef MBED_OPERATORS #include #include +#else +#define getdtablesize() (10) #endif #if defined(__GNUC__) @@ -250,6 +301,7 @@ enum libwebsocket_callback_reasons { #if defined(_WIN32) && (_WIN32_WINNT < 0x0600) typedef SOCKET lws_sockfd_type; +#define lws_sockfd_valid(sfd) (!!sfd) struct libwebsocket_pollfd { lws_sockfd_type fd; SHORT events; @@ -259,9 +311,10 @@ WINSOCK_API_LINKAGE int WSAAPI WSAPoll(struct libwebsocket_pollfd fdArray[], ULO #else #if defined(MBED_OPERATORS) -typedef int lws_sockfd_type; +typedef void * lws_sockfd_type; +#define lws_sockfd_valid(sfd) (!!sfd) struct pollfd { - lws_sockfd_type *fd; + lws_sockfd_type fd; short events; short revents; }; @@ -271,8 +324,16 @@ struct pollfd { #define POLLERR 0x0008 #define POLLHUP 0x0010 #define POLLNVAL 0x0020 + +struct libwebsocket; + +void * mbed3_create_tcp_stream_socket(void); +void mbed3_delete_tcp_stream_socket(void *sockfd); +void mbed3_tcp_stream_bind(void *sock, int port, struct libwebsocket *); +void mbed3_tcp_stream_accept(void *sock, struct libwebsocket *); #else typedef int lws_fd_type; +#define lws_sockfd_valid(sfd) (sfd >= 0) #endif #define libwebsocket_pollfd pollfd diff --git a/lib/lws-plat-mbed3.c b/lib/lws-plat-mbed3.c new file mode 100644 index 00000000..264ee9c5 --- /dev/null +++ b/lib/lws-plat-mbed3.c @@ -0,0 +1,263 @@ +#include "private-libwebsockets.h" + +/* + * included from libwebsockets.c for MBED3 builds + * MBED3 is an "OS" for very small embedded systems. + * He doesn't have Posix semantics or apis. + * But he has things like TCP sockets. + */ + +unsigned long long time_in_microseconds(void) +{ + return 0; +} + +LWS_VISIBLE int libwebsockets_get_random(struct libwebsocket_context *context, + void *buf, int len) +{ + (void)context; + int n = len; + unsigned char *b = (unsigned char *)buf; + while (n--) + b[n]= rand(); + return len; +} + +/* + * MBED3 does not have a 'kernel' which takes copies of what userland wants + * to send. The user application must hold the tx buffer until it is informed + * that send of the user buffer was complete. + * + * So as soon as you send something the pipe is globally choked. + * + * There is no concept of additional sent things being maybe acceptable. + * You can send one thing up to 64KB at a time and may not try to send + * anything else until that is completed. + * + * You can send things on other sockets, but they cannot complete until they + * get their turn at the network device. + */ + +LWS_VISIBLE int lws_send_pipe_choked(struct libwebsocket *wsi) +{ +#if 0 + struct libwebsocket_pollfd fds; + + /* treat the fact we got a truncated send pending as if we're choked */ + if (wsi->truncated_send_len) + return 1; + + fds.fd = wsi->sock; + fds.events = POLLOUT; + fds.revents = 0; + + if (poll(&fds, 1, 0) != 1) + return 1; + + if ((fds.revents & POLLOUT) == 0) + return 1; + + /* okay to send another packet without blocking */ +#endif + (void)wsi; + return 0; +} + +LWS_VISIBLE int +lws_poll_listen_fd(struct libwebsocket_pollfd *fd) +{ + (void)fd; + return -1; +} + +/** + * libwebsocket_cancel_service() - Cancel servicing of pending websocket activity + * @context: Websocket context + * + * This function let a call to libwebsocket_service() waiting for a timeout + * immediately return. + * + * There is no poll() in MBED3, he will fire callbacks when he feels like + * it. + */ +LWS_VISIBLE void +libwebsocket_cancel_service(struct libwebsocket_context *context) +{ + (void)context; +} + +LWS_VISIBLE void lwsl_emit_syslog(int level, const char *line) +{ + printf("%d: %s", level, line); +} + +LWS_VISIBLE int +lws_plat_service(struct libwebsocket_context *context, int timeout_ms) +{ + (void)context; + (void)timeout_ms; +#if 0 + int n; + int m; + char buf; +#ifdef LWS_OPENSSL_SUPPORT + struct libwebsocket *wsi, *wsi_next; +#endif + + /* stay dead once we are dead */ + + if (!context) + return 1; + + lws_libev_run(context); + + context->service_tid = context->protocols[0].callback(context, NULL, + LWS_CALLBACK_GET_THREAD_ID, NULL, NULL, 0); + +#ifdef LWS_OPENSSL_SUPPORT + /* if we know we have non-network pending data, do not wait in poll */ + if (lws_ssl_anybody_has_buffered_read(context)) + timeout_ms = 0; +#endif + n = poll(context->fds, context->fds_count, timeout_ms); + context->service_tid = 0; + +#ifdef LWS_OPENSSL_SUPPORT + if (!lws_ssl_anybody_has_buffered_read(context) && n == 0) { +#else + if (n == 0) /* poll timeout */ { +#endif + libwebsocket_service_fd(context, NULL); + return 0; + } + + if (n < 0) { + if (LWS_ERRNO != LWS_EINTR) + return -1; + return 0; + } + + /* any socket with events to service? */ + + for (n = 0; n < context->fds_count; n++) { + + if (!context->fds[n].revents) + continue; + + if (context->fds[n].fd == context->dummy_pipe_fds[0]) { + if (read(context->fds[n].fd, &buf, 1) != 1) + lwsl_err("Cannot read from dummy pipe."); + continue; + } + + m = libwebsocket_service_fd(context, &context->fds[n]); + if (m < 0) + return -1; + /* if something closed, retry this slot */ + if (m) + n--; + } +#endif + return 0; +} + +LWS_VISIBLE int +lws_plat_set_socket_options(struct libwebsocket_context *context, lws_sockfd_type fd) +{ + (void)context; + (void)fd; + return 0; +} + +LWS_VISIBLE void +lws_plat_drop_app_privileges(struct lws_context_creation_info *info) +{ + (void)info; +} + +LWS_VISIBLE int +lws_plat_init_lookup(struct libwebsocket_context *context) +{ + (void)context; + return 0; +} + +LWS_VISIBLE int +lws_plat_init_fd_tables(struct libwebsocket_context *context) +{ + (void)context; + return 0; +} + + +LWS_VISIBLE int +lws_plat_context_early_init(void) +{ + return 0; +} + +LWS_VISIBLE void +lws_plat_context_early_destroy(struct libwebsocket_context *context) +{ + (void)context; +} + +LWS_VISIBLE void +lws_plat_context_late_destroy(struct libwebsocket_context *context) +{ + (void)context; +} + + +LWS_VISIBLE void +lws_plat_service_periodic(struct libwebsocket_context *context) +{ + (void)context; +} + +LWS_VISIBLE int +lws_plat_change_pollfd(struct libwebsocket_context *context, + struct libwebsocket *wsi, struct libwebsocket_pollfd *pfd) +{ + (void)context; + (void)wsi; + (void)pfd; + + return 0; +} + +LWS_VISIBLE int +lws_plat_open_file(const char* filename, unsigned long* filelen) +{ + (void)filename; + (void)filelen; + return LWS_INVALID_FILE; +} + +LWS_VISIBLE const char * +lws_plat_inet_ntop(int af, const void *src, char *dst, int cnt) +{ + (void)af; + (void)src; + (void)dst; + (void)cnt; + return "unsupported"; +} + +LWS_VISIBLE int +insert_wsi(struct libwebsocket_context *context, struct libwebsocket *wsi) +{ + (void)context; + (void)wsi; + + return 0; +} + +LWS_VISIBLE int +delete_from_fd(struct libwebsocket_context *context, lws_sockfd_type fd) +{ + (void)context; + (void)fd; + + return 1; +} \ No newline at end of file diff --git a/lib/lws-plat-mbed3.cpp b/lib/lws-plat-mbed3.cpp new file mode 100644 index 00000000..19c957d5 --- /dev/null +++ b/lib/lws-plat-mbed3.cpp @@ -0,0 +1,143 @@ +#include "private-libwebsockets.h" + +extern "C" void *mbed3_create_tcp_stream_socket(void) +{ + lws_conn_listener *srv = new lws_conn_listener; + + printf("%s: %p\r\n", __func__, (void *)srv); + + return (void *)srv; +} + +extern "C" void mbed3_delete_tcp_stream_socket(void *sock) +{ + printf("%s: %p\r\n", __func__, sock); + delete (lws_conn *)sock; +} + +extern "C" void mbed3_tcp_stream_bind(void *sock, int port, struct libwebsocket *wsi) +{ + lws_conn_listener *srv = (lws_conn_listener *)sock; + + lwsl_notice("%s\r\n", __func__); + /* associate us with the listening wsi */ + ((lws_conn *)srv)->set_wsi(wsi); + + mbed::util::FunctionPointer1 fp(srv, &lws_conn_listener::start); + minar::Scheduler::postCallback(fp.bind(port)); +} + +extern "C" void mbed3_tcp_stream_accept(void *sock, struct libwebsocket *wsi) +{ + lws_conn *conn = (lws_conn *)sock; + + lwsl_notice("%s\r\n", __func__); + conn->set_wsi(wsi); +} + +/* + * 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); +} + +/* + * 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) +{ + lws_conn *conn; + + printf("%s\r\n", __func__); + if (!impl) { + onError(tl, SOCKET_ERROR_NULL_PTR); + return; + } + + conn = new(lws_conn); + conn->ts = srv.accept(impl); + + conn->ts->setOnReadable(TCPStream::ReadableHandler_t(this, + &lws_conn_listener::onRX)); + + if (!conn->ts) { + onError(tl, SOCKET_ERROR_BAD_ALLOC); + return; + } + + conn->ts->setOnError(TCPStream::ErrorHandler_t(this, + &lws_conn_listener::onError)); + conn->ts->setOnDisconnect(TCPStream::DisconnectHandler_t(this, + &lws_conn_listener::onDisconnect)); + conn->ts->setOnSent(Socket::SentHandler_t(this, &lws_conn_listener::onSent)); + + /* + * we use the listen socket wsi to get started, but a new wsi is + * created. mbed3_tcp_stream_accept() is also called from here to + * bind the ts and wsi together + */ + lws_server_socket_service(wsi->protocol->owning_server, + wsi, (struct pollfd *)conn); +} + +void lws_conn_listener::onRX(Socket *s) +{ + socket_error_t err; + static const char *rsp = + "HTTP/1.1 200 OK\r\n" + "\r\n" + "Ahaha... hello\r\n"; + size_t size = BUFFER_SIZE - 1; + int n; + + lwsl_notice("%s\r\n", __func__); + + err = s->recv(buffer, &size); + n = s->error_check(err); + if (!n) { + buffer[size] = 0; + printf("%d: %s", size, buffer); + + err = s->send(rsp, strlen(rsp)); +// if (err != SOCKET_ERROR_NONE) +// onError(s, err); + } else + printf("%s: error %d\r\n", __func__, n); +} + +void lws_conn_listener::onDisconnect(TCPStream *s) +{ + lwsl_notice("%s\r\n", __func__); + (void)s; + //if (s) + //delete this; +} +void lws_conn_listener::onSent(Socket *s, uint16_t len) +{ + lwsl_notice("%s\r\n", __func__); + (void)s; + (void)len; + ts->close(); +} + +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(); +} diff --git a/lib/output.c b/lib/output.c index 059fbaa0..756616c9 100644 --- a/lib/output.c +++ b/lib/output.c @@ -120,6 +120,7 @@ int lws_issue_raw(struct libwebsocket *wsi, unsigned char *buf, size_t len) n = m; goto handle_truncated_send; } + if (!lws_socket_is_valid(wsi->sock)) lwsl_warn("** error invalid sock but expected to send\n"); @@ -584,7 +585,7 @@ lws_ssl_capable_read_no_ssl(struct libwebsocket_context *context, int n; (void)context; - +#if LWS_POSIX n = recv(wsi->sock, (char *)buf, len, 0); if (n >= 0) return n; @@ -593,7 +594,13 @@ lws_ssl_capable_read_no_ssl(struct libwebsocket_context *context, LWS_ERRNO == LWS_EWOULDBLOCK || LWS_ERRNO == LWS_EINTR) return LWS_SSL_CAPABLE_MORE_SERVICE; - +#else + (void)n; + (void)wsi; + (void)buf; + (void)len; + // !!! +#endif lwsl_warn("error on reading from skt\n"); return LWS_SSL_CAPABLE_ERROR; } @@ -602,7 +609,8 @@ LWS_VISIBLE int lws_ssl_capable_write_no_ssl(struct libwebsocket *wsi, unsigned char *buf, int len) { int n; - + +#if LWS_POSIX n = send(wsi->sock, (char *)buf, len, MSG_NOSIGNAL); if (n >= 0) return n; @@ -615,6 +623,14 @@ lws_ssl_capable_write_no_ssl(struct libwebsocket *wsi, unsigned char *buf, int l return LWS_SSL_CAPABLE_MORE_SERVICE; } +#else + (void)n; + (void)wsi; + (void)buf; + (void)len; + // !!! +#endif + lwsl_debug("ERROR writing len %d to skt %d\n", len, n); return LWS_SSL_CAPABLE_ERROR; } diff --git a/lib/pollfd.c b/lib/pollfd.c index 80cb2eaa..3c4d17c4 100644 --- a/lib/pollfd.c +++ b/lib/pollfd.c @@ -25,6 +25,7 @@ int insert_wsi_socket_into_fds(struct libwebsocket_context *context, struct libwebsocket *wsi) { +#if LWS_POSIX struct libwebsocket_pollargs pa = { wsi->sock, LWS_POLLIN, 0 }; if (context->fds_count >= context->max_fds) { @@ -65,6 +66,9 @@ insert_wsi_socket_into_fds(struct libwebsocket_context *context, if (context->protocols[0].callback(context, wsi, LWS_CALLBACK_UNLOCK_POLL, wsi->user_space, (void *)&pa, 0)) return -1; +#endif + (void)context; + (void)wsi; return 0; } @@ -73,6 +77,7 @@ int remove_wsi_socket_from_fds(struct libwebsocket_context *context, struct libwebsocket *wsi) { +#if LWS_POSIX int m; struct libwebsocket_pollargs pa = { wsi->sock, 0, 0 }; @@ -80,7 +85,7 @@ remove_wsi_socket_from_fds(struct libwebsocket_context *context, --context->fds_count; -#ifndef _WIN32 +#if !defined(_WIN32) && !defined(MBED_OPERATORS) if (wsi->sock > context->max_fds) { lwsl_err("Socket fd %d too high (%d)\n", wsi->sock, context->max_fds); @@ -125,6 +130,10 @@ remove_wsi_socket_from_fds(struct libwebsocket_context *context, LWS_CALLBACK_UNLOCK_POLL, wsi->user_space, (void *) &pa, 0)) return -1; +#endif + + (void)context; + (void)wsi; return 0; } @@ -253,6 +262,7 @@ libwebsocket_callback_on_writable(struct libwebsocket_context *context, network_sock: #endif + (void)context; if (lws_ext_callback_for_each_active(wsi, LWS_EXT_CALLBACK_REQUEST_ON_WRITEABLE, NULL, 0)) return 1; diff --git a/lib/private-libwebsockets.h b/lib/private-libwebsockets.h index 57578f2c..0e1ce72d 100644 --- a/lib/private-libwebsockets.h +++ b/lib/private-libwebsockets.h @@ -91,12 +91,15 @@ #define LWS_INVALID_FILE INVALID_HANDLE_VALUE #else /* not windows --> */ -#include + #include #include #include #include #ifndef MBED_OPERATORS +#ifndef __cplusplus +#include +#endif #include #include #include @@ -189,6 +192,11 @@ #include "libwebsockets.h" +#if defined(MBED_OPERATORS) +#undef compatible_close +#define compatible_close(fd) mbed3_delete_tcp_stream_socket(fd) +#endif + #if defined(WIN32) || defined(_WIN32) #ifndef BIG_ENDIAN @@ -225,6 +233,9 @@ typedef unsigned __int64 u_int64_t; #include #endif +#ifdef __cplusplus +extern "C" { +#endif #include #ifndef container_of @@ -548,8 +559,12 @@ LWS_EXTERN void lws_libev_run(struct libwebsocket_context *context); #else #define LWS_LIBEV_ENABLED(context) (0) +#ifdef LWS_POSIX #define lws_feature_status_libev(_a) \ lwsl_notice("libev support not compiled in\n") +#else +#define lws_feature_status_libev(_a) +#endif #define lws_libev_accept(_a, _b, _c) ((void) 0) #define lws_libev_io(_a, _b, _c) ((void) 0) #define lws_libev_init_fd_table(_a) (0) @@ -618,7 +633,7 @@ struct _lws_http_mode_related { #if defined(WIN32) || defined(_WIN32) HANDLE fd; #else - lws_sockfd_type fd; + int fd; #endif unsigned long filepos; unsigned long filelen; @@ -1279,3 +1294,7 @@ LWS_EXTERN unsigned long long time_in_microseconds(void); LWS_EXTERN const char * lws_plat_inet_ntop(int af, const void *src, char *dst, int cnt); + +#ifdef __cplusplus +}; +#endif diff --git a/lib/server.c b/lib/server.c index 38e19259..0fca0273 100644 --- a/lib/server.c +++ b/lib/server.c @@ -1,7 +1,7 @@ /* * libwebsockets - small server side websockets and web server implementation * - * Copyright (C) 2010-2013 Andy Green + * Copyright (C) 2010-2015 Andy Green * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -25,9 +25,9 @@ int lws_context_init_server(struct lws_context_creation_info *info, struct libwebsocket_context *context) { - int n; lws_sockfd_type sockfd; #if LWS_POSIX + int n; struct sockaddr_in sin; socklen_t len = sizeof(sin); #ifdef LWS_USE_IPV6 @@ -35,8 +35,8 @@ int lws_context_init_server(struct lws_context_creation_info *info, #endif struct sockaddr_in serv_addr4; struct sockaddr *v; -#endif int opt = 1; +#endif struct libwebsocket *wsi; /* set up our external listening socket we serve on */ @@ -44,18 +44,25 @@ int lws_context_init_server(struct lws_context_creation_info *info, if (info->port == CONTEXT_PORT_NO_LISTEN) return 0; +#if LWS_POSIX #ifdef LWS_USE_IPV6 if (LWS_IPV6_ENABLED(context)) sockfd = socket(AF_INET6, SOCK_STREAM, 0); else #endif sockfd = socket(AF_INET, SOCK_STREAM, 0); - + if (sockfd == -1) { +#else + sockfd = mbed3_create_tcp_stream_socket(); + if (!lws_sockfd_valid(sockfd)) { +#endif + lwsl_err("ERROR opening socket\n"); return 1; } +#if LWS_POSIX /* * allow us to restart even if old sockets in TIME_WAIT */ @@ -64,9 +71,10 @@ int lws_context_init_server(struct lws_context_creation_info *info, compatible_close(sockfd); return 1; } - +#endif lws_plat_set_socket_options(context, sockfd); +#if LWS_POSIX #ifdef LWS_USE_IPV6 if (LWS_IPV6_ENABLED(context)) { v = (struct sockaddr *)&serv_addr6; @@ -109,6 +117,7 @@ int lws_context_init_server(struct lws_context_creation_info *info, lwsl_warn("getsockname: %s\n", strerror(LWS_ERRNO)); else info->port = ntohs(sin.sin_port); +#endif context->listen_port = info->port; @@ -120,6 +129,7 @@ int lws_context_init_server(struct lws_context_creation_info *info, } wsi->sock = sockfd; wsi->mode = LWS_CONNMODE_SERVER_LISTENER; + wsi->protocol = context->protocols; if (insert_wsi_socket_into_fds(context, wsi)) { compatible_close(sockfd); @@ -130,7 +140,11 @@ int lws_context_init_server(struct lws_context_creation_info *info, context->listen_service_count = 0; context->listen_service_fd = sockfd; +#if LWS_POSIX listen(sockfd, LWS_SOMAXCONN); +#else + mbed3_tcp_stream_bind(sockfd, info->port, wsi); +#endif lwsl_notice(" Listening on port %d\n", info->port); return 0; @@ -564,12 +578,12 @@ upgrade_ws: return 1; } lwsl_info("Allocating RX buffer %d\n", n); - +#if LWS_POSIX if (setsockopt(wsi->sock, SOL_SOCKET, SO_SNDBUF, (const char *)&n, sizeof n)) { lwsl_warn("Failed to set SNDBUF to %d", n); return 1; } - +#endif lwsl_parser("accepted v%02d connection\n", wsi->ietf_spec_revision); } /* while all chars are handled */ @@ -669,13 +683,16 @@ int lws_http_transaction_completed(struct libwebsocket *wsi) return 0; } +LWS_VISIBLE int lws_server_socket_service(struct libwebsocket_context *context, struct libwebsocket *wsi, struct libwebsocket_pollfd *pollfd) { struct libwebsocket *new_wsi = NULL; - int accept_fd = LWS_SOCK_INVALID; + lws_sockfd_type accept_fd = LWS_SOCK_INVALID; +#if LWS_POSIX socklen_t clilen; struct sockaddr_in cli_addr; +#endif int n; int len; @@ -775,13 +792,14 @@ try_pollout: case LWS_CONNMODE_SERVER_LISTENER: +#if LWS_POSIX /* pollin means a client has connected to us then */ if (!(pollfd->revents & LWS_POLLIN)) break; /* listen socket got an unencrypted connection... */ - + clilen = sizeof(cli_addr); lws_latency_pre(context, wsi); accept_fd = accept(pollfd->fd, (struct sockaddr *)&cli_addr, @@ -799,7 +817,10 @@ try_pollout: } lws_plat_set_socket_options(context, accept_fd); - +#else + /* not very beautiful... */ + accept_fd = (lws_sockfd_type)pollfd; +#endif /* * look at who we connected to and give user code a chance * to reject based on client IP. There's no protocol selected @@ -827,6 +848,10 @@ try_pollout: PENDING_TIMEOUT_ESTABLISH_WITH_SERVER, AWAITING_TIMEOUT); +#if LWS_POSIX == 0 + mbed3_tcp_stream_accept(accept_fd, new_wsi); +#endif + /* * A new connection was accepted. Give the user a chance to * set properties of the newly created wsi. There's no protocol @@ -978,10 +1003,13 @@ lws_server_get_canonical_hostname(struct libwebsocket_context *context, { if (info->options & LWS_SERVER_OPTION_SKIP_SERVER_CANONICAL_NAME) return; - +#if LWS_POSIX /* find canonical hostname */ gethostname((char *)context->canonical_hostname, sizeof(context->canonical_hostname) - 1); lwsl_notice(" canonical_hostname = %s\n", context->canonical_hostname); +#else + (void)context; +#endif } diff --git a/lib/service.c b/lib/service.c index 120d6c52..0c07370c 100644 --- a/lib/service.c +++ b/lib/service.c @@ -1,7 +1,7 @@ /* * libwebsockets - small server side websockets and web server implementation * - * Copyright (C) 2010-2014 Andy Green + * Copyright (C) 2010-2015 Andy Green * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -359,15 +359,15 @@ int lws_rxflow_cache(struct libwebsocket *wsi, unsigned char *buf, int n, int le LWS_VISIBLE int libwebsocket_service_fd(struct libwebsocket_context *context, - struct libwebsocket_pollfd *pollfd) + struct libwebsocket_pollfd *pollfd) { struct libwebsocket *wsi; - int n; - int m; + int n, m; + lws_sockfd_type mfd; int listen_socket_fds_index = 0; time_t now; int timed_out = 0; - int our_fd = 0; + lws_sockfd_type our_fd = 0; char draining_flow = 0; int more; struct lws_tokens eff_buf; @@ -396,14 +396,14 @@ libwebsocket_service_fd(struct libwebsocket_context *context, our_fd = pollfd->fd; for (n = 0; n < context->fds_count; n++) { - m = context->fds[n].fd; - wsi = wsi_from_fd(context,m); + mfd = context->fds[n].fd; + wsi = wsi_from_fd(context, mfd); if (!wsi) continue; if (libwebsocket_service_timeout_check(context, wsi, now)) /* he did time out... */ - if (m == our_fd) { + if (mfd == our_fd) { /* it was the guy we came to service! */ timed_out = 1; /* he's gone, no need to mark as handled */ @@ -420,7 +420,7 @@ libwebsocket_service_fd(struct libwebsocket_context *context, return 0; /* no, here to service a socket descriptor */ - wsi = wsi_from_fd(context,pollfd->fd); + wsi = wsi_from_fd(context, pollfd->fd); if (wsi == NULL) /* not lws connection ... leave revents alone and return */ return 0; diff --git a/module.json b/module.json index faf977da..f2c565ed 100644 --- a/module.json +++ b/module.json @@ -1,14 +1,18 @@ { - "name": "lws", - "version": "0.0.0", + "name": "websockets", + "version": "1.5.0", "description": "Libwebsockets", "keywords": [ + "lws", + "libwebsockets", "websockets", "ws" ], "author": "Andy Green ", "homepage": "https://libwebsockets.org", "license": "LGPL2.1-SLE", + + "extraIncludes": [ "build/frdm-k64f-gcc/generated/include" ], "dependencies": { "mbed-drivers": "^0.11.1", "sockets": "^1.0.0"