mbed3 working examples
authorAndy Green <andy.green@linaro.org>
Wed, 25 Nov 2015 00:22:08 +0000 (08:22 +0800)
committerAndy Green <andy.green@linaro.org>
Wed, 25 Nov 2015 00:22:08 +0000 (08:22 +0800)
You need sal-stack-lwip > 1.0.4 with the listen fix

Signed-off-by: Andy Green <andy.green@linaro.org>
lib/libwebsockets.h
lib/lws-plat-mbed3.c
lib/lws-plat-mbed3.cpp
lib/pollfd.c
module.json

index ec17571..851c38d 100644 (file)
@@ -38,12 +38,15 @@ namespace {
 using namespace mbed::Sockets::v0;
 
 struct libwebsocket;
+struct libwebsocket_context;
 
 class lws_conn {
        public:
        lws_conn():
                ts(NULL),
-               wsi(NULL)
+               wsi(NULL),
+               writeable(1),
+               awaiting_on_writeable(0)
        {
        }
 
@@ -54,14 +57,16 @@ public:
        void onError(Socket *s, socket_error_t err);
        void onDisconnect(TCPStream *s);
        void onSent(Socket *s, uint16_t len);
+       void serialized_writeable(struct libwebsocket *wsi);
 
 public:
        TCPStream *ts;
-       Socket *s_HACK;
        
 public:
        struct libwebsocket *wsi;
        char buffer[BUFFER_SIZE];
+       char writeable;
+       char awaiting_on_writeable;
 };
 
 class lws_conn_listener : lws_conn {
@@ -137,7 +142,7 @@ extern "C" {
 #include <poll.h>
 #include <netdb.h>
 #else
-#define getdtablesize() (10)
+#define getdtablesize() (20)
 #endif
 
 #if defined(__GNUC__)
index 264ee9c..d11bfee 100644 (file)
@@ -92,76 +92,6 @@ LWS_VISIBLE void lwsl_emit_syslog(int level, const char *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;
@@ -216,17 +146,6 @@ lws_plat_service_periodic(struct libwebsocket_context *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;
index 1c9a049..ca0a1a3 100644 (file)
@@ -21,11 +21,28 @@ extern "C" void mbed3_delete_tcp_stream_socket(void *sock)
        delete conn;
 }
 
+void lws_conn::serialized_writeable(struct libwebsocket *_wsi)
+{
+       struct libwebsocket *wsi = (struct libwebsocket *)_wsi;
+       struct libwebsocket_pollfd pollfd;
+       lws_conn *conn = (lws_conn *)wsi->sock;
+       
+       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);
+
+       libwebsocket_service_fd(wsi->protocol->owning_server, &pollfd);
+}
+
 extern "C" void mbed3_tcp_stream_bind(void *sock, int port, struct libwebsocket *wsi)
 {
        lws_conn_listener *srv = (lws_conn_listener *)sock;
        
-       lwsl_info("%s\r\n", __func__);
+       lwsl_debug("%s\r\n", __func__);
        /* associate us with the listening wsi */
        ((lws_conn *)srv)->set_wsi(wsi);
 
@@ -37,22 +54,44 @@ extern "C" void mbed3_tcp_stream_accept(void *sock, struct libwebsocket *wsi)
 {
        lws_conn *conn = (lws_conn *)sock;
 
-       lwsl_info("%s\r\n", __func__);
+       lwsl_debug("%s\r\n", __func__);
        conn->set_wsi(wsi);
 }
 
 extern "C" LWS_VISIBLE int
+lws_plat_change_pollfd(struct libwebsocket_context *context,
+                     struct libwebsocket *wsi, struct libwebsocket_pollfd *pfd)
+{
+       lws_conn *conn = (lws_conn *)wsi->sock;
+       
+       (void)context;
+       if (pfd->events & POLLOUT) {
+               conn->awaiting_on_writeable = 1;
+               if (conn->writeable) {
+                       mbed::util::FunctionPointer1<void, struct libwebsocket *> book(conn, &lws_conn::serialized_writeable);
+                       minar::Scheduler::postCallback(book.bind(wsi));
+                       lwsl_debug("%s: wsi %p (booked callback)\r\n", __func__, (void *)wsi);
+               } else {
+                       
+                       lwsl_debug("%s: wsi %p (set awaiting_on_writeable)\r\n", __func__, (void *)wsi);
+               }
+       } else
+               conn->awaiting_on_writeable = 0;
+       
+       return 0;
+}
+
+extern "C" LWS_VISIBLE int
 lws_ssl_capable_read_no_ssl(struct libwebsocket_context *context,
                            struct libwebsocket *wsi, unsigned char *buf, int len)
 {
        socket_error_t err;
        size_t _len = len;
-
        lwsl_debug("%s\r\n", __func__);
        
        (void)context;
-       /* s/s_HACK/ts/g when mbed3 listen payload bug fixed */
-       err = ((lws_conn *)wsi->sock)->s_HACK->recv((char *)buf, &_len);
+       err = ((lws_conn *)wsi->sock)->ts->recv((char *)buf, &_len);
        if (err == SOCKET_ERROR_NONE) {
                lwsl_info("%s: got %d bytes\n", __func__, _len);
                return _len;
@@ -66,10 +105,6 @@ lws_ssl_capable_read_no_ssl(struct libwebsocket_context *context,
 #endif
                return LWS_SSL_CAPABLE_MORE_SERVICE;
 
-       // !!! while listen payload mbed3 bug, don't error out if nothing */    
-//     if (((lws_conn *)wsi->sock)->s_HACK != ((Socket *)((lws_conn *)wsi->sock)->ts))
-//             return 0;
-
        lwsl_warn("error on reading from skt: %d\n", err);
        return LWS_SSL_CAPABLE_ERROR;
 }
@@ -78,10 +113,14 @@ extern "C" LWS_VISIBLE int
 lws_ssl_capable_write_no_ssl(struct libwebsocket *wsi, unsigned char *buf, int len)
 {
        socket_error_t err;
+       lws_conn *conn = (lws_conn *)wsi->sock;
 
        lwsl_debug("%s: wsi %p: write %d (from %p)\n", __func__, (void *)wsi, len, (void *)buf);
        
-       err = ((lws_conn *)wsi->sock)->ts->send((char *)buf, len);
+       lwsl_debug("%s: wsi %p: clear writeable\n", __func__, (void *)wsi);
+       conn->writeable = 0;
+       
+       err = conn->ts->send((char *)buf, len);
        if (err == SOCKET_ERROR_NONE)
                return len;
 
@@ -121,6 +160,8 @@ void lws_conn_listener::start(const uint16_t port)
 int lws_conn::actual_onRX(Socket *s)
 {
        struct libwebsocket_pollfd pollfd;
+       
+       (void)s;
 
        pollfd.fd = this;
        pollfd.events = POLLIN;
@@ -128,8 +169,6 @@ int lws_conn::actual_onRX(Socket *s)
        
        lwsl_debug("%s: lws %p\n", __func__, wsi);
        
-       s_HACK = s;
-       
        return libwebsocket_service_fd(wsi->protocol->owning_server, &pollfd);
 }
 
@@ -215,20 +254,36 @@ void lws_conn_listener::onDisconnect(TCPStream *s)
        //if (s)
        //delete this;
 }
+
+extern "C" LWS_VISIBLE int
+lws_plat_service(struct libwebsocket_context *context, int timeout_ms)
+{
+       (void)context;
+       (void)timeout_ms;
+
+       return 0;
+}
+
 void lws_conn::onSent(Socket *s, uint16_t len)
 {
        struct libwebsocket_pollfd pollfd;
 
        (void)s;
        (void)len;
+       
+       if (!awaiting_on_writeable) {
+               lwsl_debug("%s: wsi %p (setting writable=1)\r\n", __func__, (void *)wsi);
+               writeable = 1;
+               return;
+       }
+       
+       writeable = 1;
 
-       pollfd.fd = this;
+       pollfd.fd = wsi->sock;
        pollfd.events = POLLOUT;
        pollfd.revents = POLLOUT;
-       
-       s_HACK = s;
 
-       lwsl_debug("%s: wsi %p\r\n", __func__, (void *)wsi);
+       lwsl_debug("%s: wsi %p (servicing now)\r\n", __func__, (void *)wsi);
        
        libwebsocket_service_fd(wsi->protocol->owning_server, &pollfd);
 }
index b38df3d..bdf0172 100644 (file)
@@ -167,7 +167,10 @@ lws_change_pollfd(struct libwebsocket *wsi, int _and, int _or)
         *       ... and the service thread is waiting ...
         *         then cancel it to force a restart with our changed events
         */
-       if (pa.prev_events != pa.events) {
+#if LWS_POSIX
+       if (pa.prev_events != pa.events)
+#endif
+       {
                
                if (lws_plat_change_pollfd(context, wsi, pfd)) {
                        lwsl_info("%s failed\n", __func__);
index f2c565e..221e299 100644 (file)
@@ -15,6 +15,7 @@
   "extraIncludes": [ "build/frdm-k64f-gcc/generated/include" ],
   "dependencies": {
     "mbed-drivers": "^0.11.1",
+    "sal-stack-lwip": "^1.0.4",
     "sockets": "^1.0.0"
   }
 }