mirror of
https://github.com/warmcat/libwebsockets.git
synced 2025-03-09 00:00:04 +01:00
mbed3 plat
Signed-off-by: Andy Green <andy.green@linaro.org>
This commit is contained in:
parent
2cd3074746
commit
8c0d3c035c
11 changed files with 617 additions and 38 deletions
|
@ -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:
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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 <poll.h>
|
||||
#include <netdb.h>
|
||||
#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
|
||||
|
|
263
lib/lws-plat-mbed3.c
Normal file
263
lib/lws-plat-mbed3.c
Normal file
|
@ -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;
|
||||
}
|
143
lib/lws-plat-mbed3.cpp
Normal file
143
lib/lws-plat-mbed3.cpp
Normal file
|
@ -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<void, uint16_t> 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();
|
||||
}
|
22
lib/output.c
22
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;
|
||||
}
|
||||
|
|
12
lib/pollfd.c
12
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;
|
||||
|
|
|
@ -91,12 +91,15 @@
|
|||
|
||||
#define LWS_INVALID_FILE INVALID_HANDLE_VALUE
|
||||
#else /* not windows --> */
|
||||
#include <errno.h>
|
||||
|
||||
#include <fcntl.h>
|
||||
#include <strings.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/types.h>
|
||||
#ifndef MBED_OPERATORS
|
||||
#ifndef __cplusplus
|
||||
#include <errno.h>
|
||||
#endif
|
||||
#include <netdb.h>
|
||||
#include <signal.h>
|
||||
#include <sys/socket.h>
|
||||
|
@ -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 <endian.h>
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
#include <stddef.h>
|
||||
|
||||
#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
|
||||
|
|
50
lib/server.c
50
lib/server.c
|
@ -1,7 +1,7 @@
|
|||
/*
|
||||
* libwebsockets - small server side websockets and web server implementation
|
||||
*
|
||||
* Copyright (C) 2010-2013 Andy Green <andy@warmcat.com>
|
||||
* Copyright (C) 2010-2015 Andy Green <andy@warmcat.com>
|
||||
*
|
||||
* 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
|
||||
}
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/*
|
||||
* libwebsockets - small server side websockets and web server implementation
|
||||
*
|
||||
* Copyright (C) 2010-2014 Andy Green <andy@warmcat.com>
|
||||
* Copyright (C) 2010-2015 Andy Green <andy@warmcat.com>
|
||||
*
|
||||
* 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;
|
||||
|
|
|
@ -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 <andy@warmcat.com>",
|
||||
"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"
|
||||
|
|
Loading…
Add table
Reference in a new issue