Index: azure_iot_hub_f767zi/trunk/wolfssl-4.7.0/src/wolfio.c
===================================================================
--- azure_iot_hub_f767zi/trunk/wolfssl-4.4.0/src/wolfio.c	(revision 457)
+++ azure_iot_hub_f767zi/trunk/wolfssl-4.7.0/src/wolfio.c	(revision 464)
@@ -89,10 +89,17 @@
 }
 
-static WC_INLINE int wolfSSL_LastError(void)
-{
+static WC_INLINE int wolfSSL_LastError(int err)
+{
+    (void)err; /* Suppress unused arg */
+
 #ifdef USE_WINDOWS_API
     return WSAGetLastError();
 #elif defined(EBSNET)
     return xn_getlasterror();
+#elif defined(WOLFSSL_LINUXKM)
+    return err; /* Return provided error value */
+#elif defined(FUSION_RTOS)
+    #include <fclerrno.h>
+    return FCL_GET_ERRNO;
 #else
     return errno;
@@ -104,4 +111,5 @@
 
 #ifdef OPENSSL_EXTRA
+#ifndef NO_BIO
 /* Use the WOLFSSL read BIO for receiving data. This is set by the function
  * wolfSSL_set_bio and can also be set by wolfSSL_CTX_SetIORecv.
@@ -182,5 +190,5 @@
         WOLFSSL_MSG("Calling custom biowr");
         sent = ssl->biowr->method->writeCb(ssl->biowr, buf, sz);
-        if (sent < 0) {
+        if ((sent < 0) && (sent != WOLFSSL_CBIO_ERR_WANT_WRITE)) {
             return WOLFSSL_CBIO_ERR_GENERAL;
         }
@@ -205,5 +213,6 @@
     return sent;
 }
-#endif
+#endif /* !NO_BIO */
+#endif /* OPENSSL_EXTRA */
 
 
@@ -215,10 +224,14 @@
 int EmbedReceive(WOLFSSL *ssl, char *buf, int sz, void *ctx)
 {
+    int recvd;
+#ifndef WOLFSSL_LINUXKM
     int sd = *(int*)ctx;
-    int recvd;
+#else
+    struct socket *sd = (struct socket*)ctx;
+#endif
 
     recvd = wolfIO_Recv(sd, buf, sz, ssl->rflags);
     if (recvd < 0) {
-        int err = wolfSSL_LastError();
+        int err = wolfSSL_LastError(recvd);
         WOLFSSL_MSG("Embed Receive error");
 
@@ -257,6 +270,10 @@
 int EmbedSend(WOLFSSL* ssl, char *buf, int sz, void *ctx)
 {
+    int sent;
+#ifndef WOLFSSL_LINUXKM
     int sd = *(int*)ctx;
-    int sent;
+#else
+    struct socket *sd = (struct socket*)ctx;
+#endif
 
 #ifdef WOLFSSL_MAX_SEND_SZ
@@ -267,5 +284,5 @@
     sent = wolfIO_Send(sd, buf, sz, ssl->wflags);
     if (sent < 0) {
-        int err = wolfSSL_LastError();
+        int err = wolfSSL_LastError(sent);
         WOLFSSL_MSG("Embed Send error");
 
@@ -319,5 +336,7 @@
     WOLFSSL_ENTER("EmbedReceiveFrom()");
 
-    if (ssl->options.handShakeDone)
+    /* Don't use ssl->options.handShakeDone since it is true even if
+     * we are in the process of renegotiation */
+    if (ssl->options.handShakeState == HANDSHAKE_DONE)
         dtls_timeout = 0;
 
@@ -335,4 +354,16 @@
         }
     }
+#ifndef NO_ASN_TIME
+    else if(IsSCR(ssl)) {
+        if (ssl->dtls_start_timeout &&
+                LowResTimer() - ssl->dtls_start_timeout > (word32)dtls_timeout) {
+            ssl->dtls_start_timeout = 0;
+            return WOLFSSL_CBIO_ERR_TIMEOUT;
+        }
+        else if (!ssl->dtls_start_timeout) {
+            ssl->dtls_start_timeout = LowResTimer();
+        }
+    }
+#endif /* !NO_ASN_TIME */
 
     recvd = (int)RECVFROM_FUNCTION(sd, buf, sz, ssl->rflags,
@@ -342,5 +373,5 @@
 
     if (recvd < 0) {
-        err = wolfSSL_LastError();
+        err = wolfSSL_LastError(recvd);
         WOLFSSL_MSG("Embed Receive From error");
 
@@ -380,4 +411,7 @@
         }
     }
+#ifndef NO_ASN_TIME
+    ssl->dtls_start_timeout = 0;
+#endif /* !NO_ASN_TIME */
 
     return recvd;
@@ -404,5 +438,5 @@
 
     if (sent < 0) {
-        err = wolfSSL_LastError();
+        err = wolfSSL_LastError(sent);
         WOLFSSL_MSG("Embed Send To error");
 
@@ -452,5 +486,5 @@
 
     if (recvd < 0) {
-        err = wolfSSL_LastError();
+        err = wolfSSL_LastError(recvd);
         WOLFSSL_MSG("Embed Receive From error");
 
@@ -636,4 +670,26 @@
 #endif /* WOLFSSL_SESSION_EXPORT */
 #endif /* WOLFSSL_DTLS */
+
+#ifdef WOLFSSL_LINUXKM
+static int linuxkm_send(struct socket *socket, void *buf, int size,
+    unsigned int flags)
+{
+    int ret;
+    struct kvec vec = { .iov_base = buf, .iov_len = size };
+    struct msghdr msg = { .msg_flags = flags };
+    ret = kernel_sendmsg(socket, &msg, &vec, 1, size);
+    return ret;
+}
+
+static int linuxkm_recv(struct socket *socket, void *buf, int size,
+    unsigned int flags)
+{
+    int ret;
+    struct kvec vec = { .iov_base = buf, .iov_len = size };
+    struct msghdr msg = { .msg_flags = flags };
+    ret = kernel_recvmsg(socket, &msg, &vec, 1, size, msg.msg_flags);
+    return ret;
+}
+#endif /* WOLFSSL_LINUXKM */
 
 
@@ -733,4 +789,6 @@
             }
         }
+
+        WOLFSSL_MSG("Select error");
         return SOCKET_ERROR_E;
     }
@@ -780,4 +838,8 @@
 #endif
 
+    if (sockfd == NULL || ip == NULL) {
+        return -1;
+    }
+
     XMEMSET(&addr, 0, sizeof(addr));
 
@@ -822,16 +884,13 @@
 
     *sockfd = (SOCKET_T)socket(addr.ss_family, SOCK_STREAM, 0);
-
 #ifdef USE_WINDOWS_API
-    if (*sockfd == INVALID_SOCKET) {
+    if (*sockfd == SOCKET_INVALID)
+#else
+    if (*sockfd <= SOCKET_INVALID)
+#endif
+    {
         WOLFSSL_MSG("bad socket fd, out of fds?");
         return -1;
     }
-#else
-     if (*sockfd < 0) {
-         WOLFSSL_MSG("bad socket fd, out of fds?");
-         return -1;
-     }
-#endif
 
 #ifdef HAVE_IO_TIMEOUT
@@ -858,4 +917,6 @@
     if (ret != 0) {
         WOLFSSL_MSG("Responder tcp connect failed");
+        CloseSocket(*sockfd);
+        *sockfd = SOCKET_INVALID;
         return -1;
     }
@@ -1074,4 +1135,10 @@
             }
             else {
+                result = TranslateReturnCode(result, sfd);
+                result = wolfSSL_LastError(result);
+                if (result == SOCKET_EWOULDBLOCK || result == SOCKET_EAGAIN) {
+                    return OCSP_WANT_READ;
+                }
+
                 WOLFSSL_MSG("wolfIO_HttpProcessResponse recv http from peer failed");
                 return -1;
@@ -1339,5 +1406,5 @@
                         byte* ocspReqBuf, int ocspReqSz, byte** ocspRespBuf)
 {
-    SOCKET_T sfd = 0;
+    SOCKET_T sfd = SOCKET_INVALID;
     word16   port;
     int      ret = -1;
@@ -1386,5 +1453,5 @@
 
             ret = wolfIO_TcpConnect(&sfd, domainName, port, io_timeout_sec);
-            if ((ret != 0) || ((int)sfd < 0)) {
+            if (ret != 0) {
                 WOLFSSL_MSG("OCSP Responder connection failed");
             }
@@ -1401,6 +1468,6 @@
                                                  HTTP_SCRATCH_BUFFER_SIZE, ctx);
             }
-
-            CloseSocket(sfd);
+            if (sfd != SOCKET_INVALID)
+                CloseSocket(sfd);
             XFREE(httpBuf, ctx, DYNAMIC_TYPE_OCSP);
         }
@@ -1460,5 +1527,5 @@
 int EmbedCrlLookup(WOLFSSL_CRL* crl, const char* url, int urlSz)
 {
-    SOCKET_T sfd = 0;
+    SOCKET_T sfd = SOCKET_INVALID;
     word16   port;
     int      ret = -1;
@@ -1492,5 +1559,5 @@
 
             ret = wolfIO_TcpConnect(&sfd, domainName, port, io_timeout_sec);
-            if ((ret != 0) || (sfd < 0)) {
+            if (ret != 0) {
                 WOLFSSL_MSG("CRL connection failed");
             }
@@ -1503,6 +1570,6 @@
                                                       HTTP_SCRATCH_BUFFER_SIZE);
             }
-
-            CloseSocket(sfd);
+            if (sfd != SOCKET_INVALID)
+                CloseSocket(sfd);
             XFREE(httpBuf, crl->heap, DYNAMIC_TYPE_CRL);
         }
@@ -2031,5 +2098,5 @@
 
     XMEMSET(mynewt_ctx, 0, sizeof(Mynewt_Ctx));
-    mynewt_ctx->mnMemBuffer = XMALLOC(mempool_bytes, 0, 0);
+    mynewt_ctx->mnMemBuffer = (void *)XMALLOC(mempool_bytes, 0, 0);
     if(!mynewt_ctx->mnMemBuffer) {
         mynewt_ctx_clear((void*)mynewt_ctx);
@@ -2082,5 +2149,5 @@
     struct os_mbuf *m;
     int read_sz = 0;
-    uint16_t total;
+    word16 total;
 
     if (mynewt_ctx == NULL || mynewt_ctx->mnSocket == NULL) {
@@ -2325,5 +2392,5 @@
     sock_udp_ep_t ep;
     int ret;
-    uint32_t timeout = wolfSSL_dtls_get_current_timeout(ssl) * 1000000;
+    word32 timeout = wolfSSL_dtls_get_current_timeout(ssl) * 1000000;
     sock_tls_t *ctx = (sock_tls_t *)_ctx;
     if (!ctx)
