NuMaker connection with AWS IoT thru MQTT/HTTPS

Dependencies:   MQTT

Files at this revision

API Documentation at this revision

Comitter:
ccli8
Date:
Fri Mar 27 14:32:06 2020 +0800
Parent:
40:5a813d7ad6d8
Child:
42:fa6f7f79a112
Commit message:
Make code work across mbed-os 5.15/6.x

1. Replace deprecated API
2. Re-implement MyTLSSocket with Mbed OS internal TLSSocket
3. Fix PRNG driver calling code with M480 BSP update

Changed in this revision

main.cpp Show annotated file Show diff for this revision Revisions of this file
my-tlssocket/MyTLSSocket.cpp Show annotated file Show diff for this revision Revisions of this file
my-tlssocket/MyTLSSocket.h Show annotated file Show diff for this revision Revisions of this file
my-tlssocket/mbed_lib.json Show annotated file Show diff for this revision Revisions of this file
pre-main/provision.cpp Show annotated file Show diff for this revision Revisions of this file
targets/TARGET_NUVOTON/platform_entropy.cpp Show annotated file Show diff for this revision Revisions of this file
--- a/main.cpp	Thu Nov 12 16:24:00 2020 +0800
+++ b/main.cpp	Fri Mar 27 14:32:06 2020 +0800
@@ -14,8 +14,6 @@
 #define AWS_IOT_HTTPS_TEST      0
 
 #include "mbed.h"
-
-/* MyTLSSocket = Mbed TLS over TCPSocket */
 #include "MyTLSSocket.h"
 
 #if AWS_IOT_MQTT_TEST
@@ -238,13 +236,8 @@
      * @param[in] net_iface Network interface
      */
     AWS_IoT_MQTT_Test(const char * domain, const uint16_t port, NetworkInterface *net_iface) :
-        _domain(domain), _port(port) {
-        _tlssocket = new MyTLSSocket(net_iface, SSL_CA_CERT_PEM, SSL_USER_CERT_PEM, SSL_USER_PRIV_KEY_PEM);
-        /* Blocking mode */
-        _tlssocket->set_blocking(true);
-        /* Print Mbed TLS handshake log */
-        _tlssocket->set_debug(true);
-
+        _domain(domain), _port(port), _net_iface(net_iface) {
+        _tlssocket = new MyTLSSocket;
         _mqtt_client = new MQTT::Client<MyTLSSocket, Countdown, MAX_MQTT_PACKET_SIZE>(*_tlssocket);
     }
 
@@ -266,21 +259,61 @@
 
         int tls_rc;
         int mqtt_rc;
-        
+
         do {
+            /* Set host name of the remote host, used for certificate checking */
+            _tlssocket->set_hostname(_domain);
+
+            /* Set the certification of Root CA */
+            tls_rc = _tlssocket->set_root_ca_cert(SSL_CA_CERT_PEM);
+            if (tls_rc != NSAPI_ERROR_OK) {
+                printf("TLSSocket::set_root_ca_cert(...) returned %d\n", tls_rc);
+                break;
+            }
+
+            /* Set client certificate and client private key */
+            tls_rc = _tlssocket->set_client_cert_key(SSL_USER_CERT_PEM, SSL_USER_PRIV_KEY_PEM);
+            if (tls_rc != NSAPI_ERROR_OK) {
+                printf("TLSSocket::set_client_cert_key(...) returned %d\n", tls_rc);
+                break;
+            }
+
+            /* Blocking mode */
+            _tlssocket->set_blocking(true);
+
+            /* Open a network socket on the network stack of the given network interface */
+            printf("Opening network socket on network stack\n");
+            tls_rc = _tlssocket->open(_net_iface);
+            if (tls_rc != NSAPI_ERROR_OK) {
+                printf("Opens network socket on network stack failed: %d\n", tls_rc);
+                break;
+            }
+            printf("Opens network socket on network stack OK\n");
+
+            /* DNS resolution */
+            printf("DNS resolution for %s...\n", _domain);
+            SocketAddress sockaddr;
+            tls_rc = _net_iface->gethostbyname(_domain, &sockaddr);
+            if (tls_rc != NSAPI_ERROR_OK) {
+                printf("DNS resolution for %s failed with %d\n", _domain, tls_rc);
+                break;
+            }
+            sockaddr.set_port(_port);
+            printf("DNS resolution for %s: %s:%d\n", _domain, sockaddr.get_ip_address(), sockaddr.get_port());
+
             /* Connect to the server */
             /* Initialize TLS-related stuff */
             printf("Connecting with %s:%d\n", _domain, _port);
-            tls_rc = _tlssocket->connect(_domain, _port);
+            tls_rc = _tlssocket->connect(sockaddr);
             if (tls_rc != NSAPI_ERROR_OK) {
                 printf("Connects with %s:%d failed: %d\n", _domain, _port, tls_rc);
                 break;
             }
             printf("Connects with %s:%d OK\n", _domain, _port);
-            
+
             /* See the link below for AWS IoT support for MQTT:
              * http://docs.aws.amazon.com/iot/latest/developerguide/protocols.html */
-         
+
             /* MQTT connect */
             /* The message broker does not support persistent sessions (connections made with 
              * the cleanSession flag set to false. */
@@ -306,9 +339,9 @@
             conn_data.cleansession = 1;
             //conn_data.username.cstring = "USERNAME";
             //conn_data.password.cstring = "PASSWORD";
-        
+
             MQTT::connackData connack_data;
-        
+
             /* _tlssocket must connect to the network endpoint before calling this. */
             printf("MQTT connecting");
             if ((mqtt_rc = _mqtt_client->connect(conn_data, connack_data)) != 0) {
@@ -316,57 +349,56 @@
                 break;
             }
             printf("\rMQTT connects OK\n\n");
-            
+
             /* Subscribe/publish user topic */
             printf("Subscribing/publishing user topic\n");
             if (! sub_pub_topic(USER_MQTT_TOPIC, USER_MQTT_TOPIC_FILTERS, sizeof (USER_MQTT_TOPIC_FILTERS) / sizeof (USER_MQTT_TOPIC_FILTERS[0]), USER_MQTT_TOPIC_PUBLISH_MESSAGE)) {
                 break;
             }
             printf("Subscribes/publishes user topic OK\n\n");
-            
+
             /* Subscribe/publish UpdateThingShadow topic */
             printf("Subscribing/publishing UpdateThingShadow topic\n");
             if (! sub_pub_topic(UPDATETHINGSHADOW_MQTT_TOPIC, UPDATETHINGSHADOW_MQTT_TOPIC_FILTERS, sizeof (UPDATETHINGSHADOW_MQTT_TOPIC_FILTERS) / sizeof (UPDATETHINGSHADOW_MQTT_TOPIC_FILTERS[0]), UPDATETHINGSHADOW_MQTT_TOPIC_PUBLISH_MESSAGE)) {
                 break;
             }
             printf("Subscribes/publishes UpdateThingShadow topic OK\n\n");
-            
+
             /* Subscribe/publish GetThingShadow topic */
             printf("Subscribing/publishing GetThingShadow topic\n");
             if (! sub_pub_topic(GETTHINGSHADOW_MQTT_TOPIC, GETTHINGSHADOW_MQTT_TOPIC_FILTERS, sizeof (GETTHINGSHADOW_MQTT_TOPIC_FILTERS) / sizeof (GETTHINGSHADOW_MQTT_TOPIC_FILTERS[0]), GETTHINGSHADOW_MQTT_TOPIC_PUBLISH_MESSAGE)) {
                 break;
             }
             printf("Subscribes/publishes GetThingShadow topic OK\n\n");
-            
+
             /* Subscribe/publish DeleteThingShadow topic */
             printf("Subscribing/publishing DeleteThingShadow topic\n");
             if (! sub_pub_topic(DELETETHINGSHADOW_MQTT_TOPIC, DELETETHINGSHADOW_MQTT_TOPIC_FILTERS, sizeof (DELETETHINGSHADOW_MQTT_TOPIC_FILTERS) / sizeof (DELETETHINGSHADOW_MQTT_TOPIC_FILTERS[0]), DELETETHINGSHADOW_MQTT_TOPIC_PUBLISH_MESSAGE)) {
                 break;
             }
             printf("Subscribes/publishes DeleteThingShadow topic OK\n\n");
-            
+
         } while (0);
-        
+
         printf("MQTT disconnecting");
         if ((mqtt_rc = _mqtt_client->disconnect()) != 0) {
             printf("\rMQTT disconnects failed %d\n\n", mqtt_rc);
         }
         printf("\rMQTT disconnects OK\n\n");
-        
+
         _tlssocket->close();
     }
 
-    
 protected:
 
     /**
      * @brief   Subscribe/publish specific topic
      */
     bool sub_pub_topic(const char *topic, const char **topic_filters, size_t topic_filters_size, const char *publish_message_body) {
-        
+
         bool ret = false;
         int mqtt_rc;
-        
+
         do {
             const char **topic_filter;
             const char **topic_filter_end = topic_filters + topic_filters_size;
@@ -388,7 +420,7 @@
             MQTT::Message message;
 
             int _bpos;
-        
+
             _bpos = snprintf(_buffer, sizeof (_buffer) - 1, publish_message_body);
             if (_bpos < 0 || ((size_t) _bpos) > (sizeof (_buffer) - 1)) {
                 printf("snprintf failed: %d\n", _bpos);
@@ -411,7 +443,7 @@
                 break;
             }
             printf("\rMQTT publishes message to %s OK\n", topic);
-        
+
             /* Receive message with subscribed topic */
             printf("MQTT receives message with subscribed %s...\n", topic);
             Timer timer;
@@ -441,12 +473,12 @@
             }
 
             ret = true;
-        
+
         } while (0);
-        
+
         return ret;
     }
-    
+
 protected:
     MyTLSSocket *                                                           _tlssocket;
     MQTT::Client<MyTLSSocket, Countdown, MAX_MQTT_PACKET_SIZE> *            _mqtt_client;
@@ -454,7 +486,8 @@
     const char *_domain;                    /**< Domain name of the MQTT server */
     const uint16_t _port;                   /**< Port number of the MQTT server */
     char _buffer[MQTT_USER_BUFFER_SIZE];    /**< User buffer */
-    
+    NetworkInterface *_net_iface;
+
 private:
     static volatile uint16_t   _message_arrive_count;
 
@@ -465,7 +498,7 @@
         printf("%.*s\n", message.payloadlen, (char*)message.payload);
         ++ _message_arrive_count;
     }
-    
+
     static void clear_message_arrive_count() {
         _message_arrive_count = 0;
     }
@@ -493,13 +526,8 @@
      * @param[in] net_iface Network interface
      */
     AWS_IoT_HTTPS_Test(const char * domain, const uint16_t port, NetworkInterface *net_iface) :
-            _domain(domain), _port(port) {
-
-        _tlssocket = new MyTLSSocket(net_iface, SSL_CA_CERT_PEM, SSL_USER_CERT_PEM, SSL_USER_PRIV_KEY_PEM);
-        /* Non-blocking mode */
-        _tlssocket->set_blocking(false);
-        /* Print Mbed TLS handshake log */
-        _tlssocket->set_debug(true);
+        _domain(domain), _port(port), _net_iface(net_iface) {
+        _tlssocket = new MyTLSSocket;
     }
     /**
      * @brief AWS_IoT_HTTPS_Test Destructor
@@ -515,19 +543,62 @@
      * @param[in] path  The path of the file to fetch from the HTTPS server
      */
     void start_test() {
-        
+
         int tls_rc;
-         
+
         do {
+            /* Set host name of the remote host, used for certificate checking */
+            _tlssocket->set_hostname(_domain);
+
+            /* Set the certification of Root CA */
+            tls_rc = _tlssocket->set_root_ca_cert(SSL_CA_CERT_PEM);
+            if (tls_rc != NSAPI_ERROR_OK) {
+                printf("TLSSocket::set_root_ca_cert(...) returned %d\n", tls_rc);
+                break;
+            }
+
+            /* Set client certificate and client private key */
+            tls_rc = _tlssocket->set_client_cert_key(SSL_USER_CERT_PEM, SSL_USER_PRIV_KEY_PEM);
+            if (tls_rc != NSAPI_ERROR_OK) {
+                printf("TLSSocket::set_client_cert_key(...) returned %d\n", tls_rc);
+                break;
+            }
+
+            /* Open a network socket on the network stack of the given network interface */
+            printf("Opening network socket on network stack\n");
+            tls_rc = _tlssocket->open(_net_iface);
+            if (tls_rc != NSAPI_ERROR_OK) {
+                printf("Opens network socket on network stack failed: %d\n", tls_rc);
+                break;
+            }
+            printf("Opens network socket on network stack OK\n");
+
+            /* DNS resolution */
+            printf("DNS resolution for %s...\n", _domain);
+            SocketAddress sockaddr;
+            tls_rc = _net_iface->gethostbyname(_domain, &sockaddr);
+            if (tls_rc != NSAPI_ERROR_OK) {
+                printf("DNS resolution for %s failed with %d\n", _domain, tls_rc);
+                break;
+            }
+            sockaddr.set_port(_port);
+            printf("DNS resolution for %s: %s:%d\n", _domain, sockaddr.get_ip_address(), sockaddr.get_port());
+
             /* Connect to the server */
             /* Initialize TLS-related stuff */
             printf("Connecting with %s:%d\n", _domain, _port);
-            tls_rc = _tlssocket->connect(_domain, _port);
+            tls_rc = _tlssocket->connect(sockaddr);
             if (tls_rc != NSAPI_ERROR_OK) {
                 printf("Connects with %s:%d failed: %d\n", _domain, _port, tls_rc);
                 break;
             }
-            printf("Connects with %s:%d OK\n\n", _domain, _port);
+            printf("Connects with %s:%d OK\n", _domain, _port);
+
+            /* Non-blocking mode
+             *
+             * Don't change to non-blocking mode before connect; otherwise, we may meet NSAPI_ERROR_IN_PROGRESS.
+             */
+            _tlssocket->set_blocking(false);
 
             /* Publish to user topic through HTTPS/POST */
             printf("Publishing to user topic through HTTPS/POST\n");
@@ -535,42 +606,42 @@
                 break;
             }
             printf("Publishes to user topic through HTTPS/POST OK\n\n");
-        
+
             /* Update thing shadow by publishing to UpdateThingShadow topic through HTTPS/POST */
             printf("Updating thing shadow by publishing to Update Thing Shadow topic through HTTPS/POST\n");
             if (! run_req_resp(UPDATETHINGSHADOW_TOPIC_HTTPS_PATH, UPDATETHINGSHADOW_TOPIC_HTTPS_REQUEST_METHOD, UPDATETHINGSHADOW_TOPIC_HTTPS_REQUEST_MESSAGE_BODY)) {
                 break;
             }
             printf("Update thing shadow by publishing to Update Thing Shadow topic through HTTPS/POST OK\n\n");
-            
+
             /* Get thing shadow by publishing to GetThingShadow topic through HTTPS/POST */
             printf("Getting thing shadow by publishing to GetThingShadow topic through HTTPS/POST\n");
             if (! run_req_resp(GETTHINGSHADOW_TOPIC_HTTPS_PATH, GETTHINGSHADOW_TOPIC_HTTPS_REQUEST_METHOD, GETTHINGSHADOW_TOPIC_HTTPS_REQUEST_MESSAGE_BODY)) {
                 break;
             }
             printf("Get thing shadow by publishing to GetThingShadow topic through HTTPS/POST OK\n\n");
-            
+
             /* Delete thing shadow by publishing to DeleteThingShadow topic through HTTPS/POST */
             printf("Deleting thing shadow by publishing to DeleteThingShadow topic through HTTPS/POST\n");
             if (! run_req_resp(DELETETHINGSHADOW_TOPIC_HTTPS_PATH, DELETETHINGSHADOW_TOPIC_HTTPS_REQUEST_METHOD, DELETETHINGSHADOW_TOPIC_HTTPS_REQUEST_MESSAGE_BODY)) {
                 break;
             }
             printf("Delete thing shadow by publishing to DeleteThingShadow topic through HTTPS/POST OK\n\n");
-            
+
             /* Update thing shadow RESTfully through HTTPS/POST */
             printf("Updating thing shadow RESTfully through HTTPS/POST\n");
             if (! run_req_resp(UPDATETHINGSHADOW_THING_HTTPS_PATH, UPDATETHINGSHADOW_THING_HTTPS_REQUEST_METHOD, UPDATETHINGSHADOW_THING_HTTPS_REQUEST_MESSAGE_BODY)) {
                 break;
             }
             printf("Update thing shadow RESTfully through HTTPS/POST OK\n\n");
-            
+
             /* Get thing shadow RESTfully through HTTPS/GET */
             printf("Getting thing shadow RESTfully through HTTPS/GET\n");
             if (! run_req_resp(GETTHINGSHADOW_THING_HTTPS_PATH, GETTHINGSHADOW_THING_HTTPS_REQUEST_METHOD, GETTHINGSHADOW_THING_HTTPS_REQUEST_MESSAGE_BODY)) {
                 break;
             }
             printf("Get thing shadow RESTfully through HTTPS/GET OK\n\n");
-            
+
             /* Delete thing shadow RESTfully through HTTPS/DELETE */
             printf("Deleting thing shadow RESTfully through HTTPS/DELETE\n");
             if (! run_req_resp(DELETETHINGSHADOW_THING_HTTPS_PATH, DELETETHINGSHADOW_THING_HTTPS_REQUEST_METHOD, DELETETHINGSHADOW_THING_HTTPS_REQUEST_MESSAGE_BODY)) {
@@ -590,9 +661,9 @@
      * @brief   Run request/response through HTTPS
      */
     bool run_req_resp(const char *https_path, const char *https_request_method, const char *https_request_message_body) {
-        
+
         bool ret = false;
-        
+
         do {
             int tls_rc;
             bool _got200 = false;
@@ -611,7 +682,7 @@
             /* Print request message */
             printf("HTTPS: Request message:\n");
             printf("%s\n", _buffer);
-        
+
             int offset = 0;
             do {
                 tls_rc = _tlssocket->send((const unsigned char *) _buffer + offset, _bpos - offset);
@@ -619,8 +690,9 @@
                     offset += tls_rc;
                 }
             } while (offset < _bpos && 
-                    (tls_rc > 0 || tls_rc == MBEDTLS_ERR_SSL_WANT_READ || tls_rc == MBEDTLS_ERR_SSL_WANT_WRITE));
-            if (tls_rc < 0) {
+                    (tls_rc > 0 || tls_rc == NSAPI_ERROR_WOULD_BLOCK));
+            if (tls_rc < 0 &&
+                tls_rc != NSAPI_ERROR_WOULD_BLOCK) {
                 print_mbedtls_error("_tlssocket->send", tls_rc);
                 break;
             }
@@ -675,10 +747,9 @@
                     }
                 }
             } while ((offset_end == 0 || offset < offset_end) &&
-                    (tls_rc > 0 || tls_rc == MBEDTLS_ERR_SSL_WANT_READ || tls_rc == MBEDTLS_ERR_SSL_WANT_WRITE));
+                    (tls_rc > 0 || tls_rc == NSAPI_ERROR_WOULD_BLOCK));
             if (tls_rc < 0 && 
-                tls_rc != MBEDTLS_ERR_SSL_WANT_READ && 
-                tls_rc != MBEDTLS_ERR_SSL_WANT_WRITE) {
+                tls_rc != NSAPI_ERROR_WOULD_BLOCK) {
                 print_mbedtls_error("_tlssocket->read", tls_rc);
                 break;
             }
@@ -691,26 +762,27 @@
             printf("HTTPS: Received 200 OK status ... %s\n", _got200 ? "[OK]" : "[FAIL]");
             printf("HTTPS: Received message:\n");
             printf("%s\n", _buffer);
-        
+
             ret = true;
-            
+
         } while (0);
-        
+
         return ret;
     }
-     
+
 protected:
     MyTLSSocket *     _tlssocket;
 
     const char *_domain;                    /**< Domain name of the HTTPS server */
     const uint16_t _port;                   /**< Port number of the HTTPS server */
     char _buffer[HTTPS_USER_BUFFER_SIZE];   /**< User buffer */
+    NetworkInterface *_net_iface;
 };
 
 #endif  // End of AWS_IOT_HTTPS_TEST
 
 int main() {
-    
+
     /* The default 9600 bps is too slow to print full TLS debug info and could
      * cause the other party to time out. */
 
@@ -732,14 +804,20 @@
         printf("Connecting to the network failed %d!\n", status);
         return -1;
     }
-    printf("Connected to the network successfully. IP address: %s\n", net->get_ip_address());
-    
+    SocketAddress sockaddr;
+    status = net->get_ip_address(&sockaddr);
+    if (status != NSAPI_ERROR_OK) {
+        printf("Network interface get_ip_address(...) failed with %d", status);
+        return -1;
+    }
+    printf("Connected to the network successfully. IP address: %s\n", sockaddr.get_ip_address());
+
 #if AWS_IOT_MQTT_TEST
     AWS_IoT_MQTT_Test *mqtt_test = new AWS_IoT_MQTT_Test(AWS_IOT_MQTT_SERVER_NAME, AWS_IOT_MQTT_SERVER_PORT, net);
     mqtt_test->start_test();
     delete mqtt_test;
 #endif  // End of AWS_IOT_MQTT_TEST
-    
+
 #if AWS_IOT_HTTPS_TEST
     AWS_IoT_HTTPS_Test *https_test = new AWS_IoT_HTTPS_Test(AWS_IOT_HTTPS_SERVER_NAME, AWS_IOT_HTTPS_SERVER_PORT, net);
     https_test->start_test();
--- a/my-tlssocket/MyTLSSocket.cpp	Thu Nov 12 16:24:00 2020 +0800
+++ b/my-tlssocket/MyTLSSocket.cpp	Fri Mar 27 14:32:06 2020 +0800
@@ -1,243 +1,53 @@
 #include "mbed.h"
 #include "MyTLSSocket.h"
 
-
-MyTLSSocket::MyTLSSocket(NetworkInterface* net_iface, const char* ssl_ca_pem, const char* ssl_owncert_pem, const char* ssl_own_priv_key_pem)
+MyTLSSocket::MyTLSSocket()
 {
-    _tcpsocket = new TCPSocket(net_iface);
-    _ssl_ca_pem = ssl_ca_pem;
-    _ssl_owncert_pem = ssl_owncert_pem;
-    _ssl_own_priv_key_pem = ssl_own_priv_key_pem;
-    _is_connected = false;
-    _debug = false;
-    _hostname = NULL;
-    _port = 0;
-    _error = 0;
+    /* TLSSocket prints debug message thru mbed-trace. We override it and print thru STDIO. */
+#if MBED_CONF_MY_TLSSOCKET_TLS_DEBUG_LEVEL > 0
+    mbedtls_ssl_conf_verify(get_ssl_config(), my_verify, this);
+    mbedtls_ssl_conf_dbg(get_ssl_config(), my_debug, this);
+    mbedtls_debug_set_threshold(MBED_CONF_MY_TLSSOCKET_TLS_DEBUG_LEVEL);
+#endif
 
-    DRBG_PERS = "mbed TLS helloword client";
-
-    mbedtls_entropy_init(&_entropy);
-    mbedtls_ctr_drbg_init(&_ctr_drbg);
-    mbedtls_x509_crt_init(&_cacert);
-    mbedtls_x509_crt_init(&_owncert);
-    mbedtls_pk_init(&_own_priv_key);
-    mbedtls_ssl_init(&_ssl);
-    mbedtls_ssl_config_init(&_ssl_conf);
+    /* Enable RFC 6066 max_fragment_length extension in SSL */
+#if defined(MBEDTLS_SSL_MAX_FRAGMENT_LENGTH) && (MBED_CONF_MY_TLSSOCKET_TLS_MAX_FRAG_LEN > 0)
+    mbedtls_ssl_conf_max_frag_len(get_ssl_config(), MBED_CONF_MY_TLSSOCKET_TLS_MAX_FRAG_LEN);
+#endif
 }
 
 MyTLSSocket::~MyTLSSocket()
 {
-    mbedtls_entropy_free(&_entropy);
-    mbedtls_ctr_drbg_free(&_ctr_drbg);
-    mbedtls_x509_crt_free(&_cacert);
-    mbedtls_x509_crt_free(&_owncert);
-    mbedtls_pk_free(&_own_priv_key);
-    mbedtls_ssl_free(&_ssl);
-    mbedtls_ssl_config_free(&_ssl_conf);
-
-    if (_tcpsocket) {
-        _tcpsocket->close();
-        delete _tcpsocket;
-    }
 }
 
-nsapi_error_t MyTLSSocket::close()
-{
-    return _tcpsocket->close();
-}
-    
-nsapi_error_t MyTLSSocket::connect(const char *hostname, uint16_t port)
-{
-    _hostname = hostname;
-    _port = port;
-        
-    /* Initialize the flags */
-    /*
-     * Initialize TLS-related stuf.
-     */
-    int ret;
-    if ((ret = mbedtls_ctr_drbg_seed(&_ctr_drbg, mbedtls_entropy_func, &_entropy,
-                                    (const unsigned char *) DRBG_PERS,
-                                    sizeof (DRBG_PERS))) != 0) {
-        print_mbedtls_error("mbedtls_crt_drbg_init", ret);
-        _error = ret;
-        return _error;
-    }
-
-    if ((ret = mbedtls_x509_crt_parse(&_cacert, (const unsigned char *)_ssl_ca_pem,
-                                      strlen(_ssl_ca_pem) + 1)) != 0) {
-        print_mbedtls_error("mbedtls_x509_crt_parse", ret);
-        _error = ret;
-        return _error;
-    }
-
-    if ((ret = mbedtls_x509_crt_parse(&_owncert, (const unsigned char *) _ssl_owncert_pem,
-                                      strlen(_ssl_owncert_pem) + 1)) != 0) {
-        print_mbedtls_error("mbedtls_x509_crt_parse", ret);
-        _error = ret;
-        return _error;
-    }
-        
-    if ((ret = mbedtls_pk_parse_key(&_own_priv_key, (const unsigned char *) _ssl_own_priv_key_pem,
-                                    strlen(_ssl_own_priv_key_pem) + 1, NULL, 0)) != 0) {
-        print_mbedtls_error("mbedtls_pk_parse_key", ret);
-        _error = ret;
-        return _error;
-    }
-        
-    if ((ret = mbedtls_ssl_config_defaults(&_ssl_conf,
-                                           MBEDTLS_SSL_IS_CLIENT,
-                                           MBEDTLS_SSL_TRANSPORT_STREAM,
-                                           MBEDTLS_SSL_PRESET_DEFAULT)) != 0) {
-        print_mbedtls_error("mbedtls_ssl_config_defaults", ret);
-        _error = ret;
-        return _error;
-    }
-
-    mbedtls_ssl_conf_ca_chain(&_ssl_conf, &_cacert, NULL);
-    mbedtls_ssl_conf_own_cert(&_ssl_conf, &_owncert, &_own_priv_key);
-    mbedtls_ssl_conf_rng(&_ssl_conf, mbedtls_ctr_drbg_random, &_ctr_drbg);
-
-    /* It is possible to disable authentication by passing
-     * MBEDTLS_SSL_VERIFY_NONE in the call to mbedtls_ssl_conf_authmode()
-     */
-    mbedtls_ssl_conf_authmode(&_ssl_conf, MBEDTLS_SSL_VERIFY_REQUIRED);
-
-    /* Enable RFC 6066 max_fragment_length extension in SSL */
-#if defined(MBEDTLS_SSL_MAX_FRAGMENT_LENGTH) && (MBED_CONF_MY_TLSSOCKET_TLS_MAX_FRAG_LEN > 0)
-    mbedtls_ssl_conf_max_frag_len(&_ssl_conf, MBED_CONF_MY_TLSSOCKET_TLS_MAX_FRAG_LEN);
-#endif
-
-#if MBED_CONF_MY_TLSSOCKET_TLS_DEBUG_LEVEL > 0
-    mbedtls_ssl_conf_verify(&_ssl_conf, my_verify, this);
-    mbedtls_ssl_conf_dbg(&_ssl_conf, my_debug, this);
-    mbedtls_debug_set_threshold(MBED_CONF_MY_TLSSOCKET_TLS_DEBUG_LEVEL);
-#endif
-
-    if ((ret = mbedtls_ssl_setup(&_ssl, &_ssl_conf)) != 0) {
-        print_mbedtls_error("mbedtls_ssl_setup", ret);
-        _error = ret;
-        return _error;
-    }
-
-    mbedtls_ssl_set_hostname(&_ssl, _hostname);
-
-    mbedtls_ssl_set_bio(&_ssl, static_cast<void *>(_tcpsocket),
-                        ssl_send, ssl_recv, NULL );
-
-    /* Connect to the server */
-    if (_debug) {
-        mbedtls_printf("Connecting to %s:%d\r\n", _hostname, _port);
-    }
-    ret = _tcpsocket->connect(_hostname, _port);
-    if (ret != NSAPI_ERROR_OK) {
-        if (_debug) {
-            mbedtls_printf("Failed to connect\r\n");
-        }
-        onError(_tcpsocket, -1);
-        return _error;
-    }
-
-    /* Start the handshake, the rest will be done in onReceive() */
-    if (_debug) {
-        mbedtls_printf("Starting the TLS handshake...\r\n");
-    }
-    do {
-        ret = mbedtls_ssl_handshake(&_ssl);
-    } while (ret == MBEDTLS_ERR_SSL_WANT_READ || ret == MBEDTLS_ERR_SSL_WANT_WRITE);
-    if (ret < 0) {
-        print_mbedtls_error("mbedtls_ssl_handshake", ret);
-        onError(_tcpsocket, ret);
-        return ret;
-    }
-            
-    /* It also means the handshake is done, time to print info */
-    if (_debug) {
-        mbedtls_printf("TLS connection to %s:%d established\r\n", _hostname, _port);
-    }
-
-    const uint32_t buf_size = 1024;
-    char *buf = new char[buf_size];
-    mbedtls_x509_crt_info(buf, buf_size, "\r    ", mbedtls_ssl_get_peer_cert(&_ssl));
-    if (_debug) {
-        mbedtls_printf("Server certificate:\r\n%s\r", buf);
-    }
-
-    uint32_t flags = mbedtls_ssl_get_verify_result(&_ssl);
-    if (flags != 0) {
-        mbedtls_x509_crt_verify_info(buf, buf_size, "\r  ! ", flags);
-        if (_debug) {
-            mbedtls_printf("Certificate verification failed:\r\n%s\r\r\n", buf);
-        }
-    }
-    else {
-        if (_debug) mbedtls_printf("Certificate verification passed\r\n\r\n");
-    }
-    delete [] buf;
-    buf = NULL;
-
-    _is_connected = true;
-
-    return 0;
-}
-
-nsapi_size_or_error_t MyTLSSocket::send(const void *data, nsapi_size_t size)
-{
-    return mbedtls_ssl_write(&_ssl, (const uint8_t *) data, size);
-}
-    
-nsapi_size_or_error_t MyTLSSocket::recv(void *data, nsapi_size_t size)
-{
-    return mbedtls_ssl_read(&_ssl, (uint8_t *) data, size);
-}
-
-void MyTLSSocket::set_blocking(bool blocking)
-{
-    _tcpsocket->set_blocking(blocking);
-}
-
-void MyTLSSocket::set_timeout(int timeout)
-{
-    _tcpsocket->set_timeout(timeout);
-}
-    
-bool MyTLSSocket::connected()
-{
-    return _is_connected;
-}
-
-nsapi_error_t MyTLSSocket::error()
-{
-    return _error;
-}
-
-TCPSocket* MyTLSSocket::get_tcp_socket()
-{
-    return _tcpsocket;
-}
-
-mbedtls_ssl_context *MyTLSSocket::get_ssl_context()
-{
-    return &_ssl;
-}
-
-void MyTLSSocket::set_debug(bool debug)
-{
-    _debug = debug;
-}
-    
 int MyTLSSocket::read(unsigned char* buffer, int len, int timeout)
 {
     set_timeout(timeout);
+
     int rc = recv(buffer, len);
-    return (rc == MBEDTLS_ERR_SSL_WANT_READ || rc == MBEDTLS_ERR_SSL_WANT_WRITE) ? 0 : rc;
+    if (rc >= 0) {
+        return rc;
+    } else if (rc == NSAPI_ERROR_WOULD_BLOCK) {
+        return 0;
+    } else {
+        printf("TLSSocket recv(%d) failed with %d\n", len, rc);
+        return -1;
+    }
 }
 
 int MyTLSSocket::write(unsigned char* buffer, int len, int timeout)
 {
     set_timeout(timeout);
+
     int rc = send(buffer, len);
-    return (rc == MBEDTLS_ERR_SSL_WANT_READ || rc == MBEDTLS_ERR_SSL_WANT_WRITE) ? 0 : rc;
+    if (rc >= 0) {
+        return rc;
+    } else if (rc == NSAPI_ERROR_WOULD_BLOCK) {
+        return 0;
+    } else {
+        printf("TLSSocket send(%d) failed with %d\n", len, rc);
+        return -1;
+    }
 }
 
 #if MBED_CONF_MY_TLSSOCKET_TLS_DEBUG_LEVEL > 0
@@ -254,9 +64,7 @@
         }
     }
 
-    if (tlssocket->_debug) {
-        mbedtls_printf("%s:%04d: |%d| %s", basename, line, level, str);
-    }
+    mbedtls_printf("%s:%04d: |%d| %s", basename, line, level, str);
 }
 
 int MyTLSSocket::my_verify(void *data, mbedtls_x509_crt *crt, int depth, uint32_t *flags)
@@ -265,65 +73,19 @@
     char *buf = new char[buf_size];
     MyTLSSocket *tlssocket = static_cast<MyTLSSocket *>(data);
 
-    if (tlssocket->_debug) {
-        mbedtls_printf("\nVerifying certificate at depth %d:\n", depth);
-    }
+    printf("\nVerifying certificate at depth %d:\n", depth);
     mbedtls_x509_crt_info(buf, buf_size - 1, "  ", crt);
-    if (tlssocket->_debug) {
-        mbedtls_printf("%s", buf);
-    }
-    
+    printf("%s", buf);
+
     if (*flags == 0) {
-        if (tlssocket->_debug) {
-            mbedtls_printf("No verification issue for this certificate\n");
-        }
-    }
-    else {
+        printf("No verification issue for this certificate\n");
+    } else {
         mbedtls_x509_crt_verify_info(buf, buf_size, "  ! ", *flags);
-        if (tlssocket->_debug) mbedtls_printf("%s\n", buf);
+        printf("%s\n", buf);
     }
 
     delete[] buf;
+
     return 0;
 }
 #endif
-
-int MyTLSSocket::ssl_recv(void *ctx, unsigned char *buf, size_t len)
-{
-    int recv = -1;
-    TCPSocket *socket = static_cast<TCPSocket *>(ctx);
-    recv = socket->recv(buf, len);
-
-    if (NSAPI_ERROR_WOULD_BLOCK == recv) {
-        return MBEDTLS_ERR_SSL_WANT_READ;
-    }
-    else if (recv < 0) {
-        return -1;
-    }
-    else {
-        return recv;
-    }
-}
-
-int MyTLSSocket::ssl_send(void *ctx, const unsigned char *buf, size_t len)
-{
-    int size = -1;
-    TCPSocket *socket = static_cast<TCPSocket *>(ctx);
-    size = socket->send(buf, len);
-
-    if (NSAPI_ERROR_WOULD_BLOCK == size) {
-        return MBEDTLS_ERR_SSL_WANT_WRITE;
-    }
-    else if (size < 0) {
-        return -1;
-    }
-    else {
-        return size;
-    }
-}
-
-void MyTLSSocket::onError(TCPSocket *s, int error)
-{
-    s->close();
-    _error = error;
-}
--- a/my-tlssocket/MyTLSSocket.h	Thu Nov 12 16:24:00 2020 +0800
+++ b/my-tlssocket/MyTLSSocket.h	Fri Mar 27 14:32:06 2020 +0800
@@ -1,111 +1,21 @@
 #ifndef _MY_TLS_SOCKET_H_
 #define _MY_TLS_SOCKET_H_
 
-#include "mbedtls/platform.h"
-#include "mbedtls/ssl.h"
-#include "mbedtls/entropy.h"
-#include "mbedtls/ctr_drbg.h"
-#include "mbedtls/error.h"
+#include "mbed.h"
+#include "TLSSocket.h"
+#include "mbedtls_utils.h"
 
 #if MBED_CONF_MY_TLSSOCKET_TLS_DEBUG_LEVEL > 0
 #include "mbedtls/debug.h"
 #endif
 
-#include "mbedtls_utils.h"
-    
-/**
- * \brief MyTLSSocket a wrapper around TCPSocket for interacting with TLS servers
- */
-class MyTLSSocket {
+/* MyTLSSocket = TLSSocket + MQTT lib required timed read/write + debug thru console */
+class MyTLSSocket : public TLSSocket
+{
 public:
-    MyTLSSocket(NetworkInterface* net_iface, const char* ssl_ca_pem, const char* ssl_owncert_pem, const char* ssl_own_priv_key_pem);
+    MyTLSSocket();
     ~MyTLSSocket();
 
-    /** Close the socket
-     *
-     *  Closes any open connection and deallocates any memory associated
-     *  with the socket. Called from destructor if socket is not closed.
-     *
-     *  @return         0 on success, negative error code on failure
-     */
-    nsapi_error_t close();
-    
-    nsapi_error_t connect(const char *hostname, uint16_t port);
-
-    /** Send data over a TCP socket
-     *
-     *  The socket must be connected to a remote host. Returns the number of
-     *  bytes sent from the buffer.
-     *
-     *  By default, send blocks until all data is sent. If socket is set to
-     *  non-blocking or times out, a partial amount can be written.
-     *  NSAPI_ERROR_WOULD_BLOCK is returned if no data was written.
-     *
-     *  @param data     Buffer of data to send to the host
-     *  @param size     Size of the buffer in bytes
-     *  @return         Number of sent bytes on success, negative error
-     *                  code on failure
-     */
-    nsapi_size_or_error_t send(const void *data, nsapi_size_t size);
-    
-    /** Receive data over a TCP socket
-     *
-     *  The socket must be connected to a remote host. Returns the number of
-     *  bytes received into the buffer.
-     *
-     *  By default, recv blocks until some data is received. If socket is set to
-     *  non-blocking or times out, NSAPI_ERROR_WOULD_BLOCK can be returned to
-     *  indicate no data.
-     *
-     *  @param data     Destination buffer for data received from the host
-     *  @param size     Size of the buffer in bytes
-     *  @return         Number of received bytes on success, negative error
-     *                  code on failure
-     */
-    nsapi_size_or_error_t recv(void *data, nsapi_size_t size);
-    
-    /** Set blocking or non-blocking mode of the socket
-     *
-     *  Initially all sockets are in blocking mode. In non-blocking mode
-     *  blocking operations such as send/recv/accept return
-     *  NSAPI_ERROR_WOULD_BLOCK if they can not continue.
-     *
-     *  set_blocking(false) is equivalent to set_timeout(-1)
-     *  set_blocking(true) is equivalent to set_timeout(0)
-     *
-     *  @param blocking true for blocking mode, false for non-blocking mode.
-     */
-    void set_blocking(bool blocking);
-    
-    /** Set timeout on blocking socket operations
-     *
-     *  Initially all sockets have unbounded timeouts. NSAPI_ERROR_WOULD_BLOCK
-     *  is returned if a blocking operation takes longer than the specified
-     *  timeout. A timeout of 0 removes the timeout from the socket. A negative
-     *  value give the socket an unbounded timeout.
-     *
-     *  set_timeout(0) is equivalent to set_blocking(false)
-     *  set_timeout(-1) is equivalent to set_blocking(true)
-     *
-     *  @param timeout  Timeout in milliseconds
-     */
-    void set_timeout(int timeout);
-    
-    bool connected();
-
-    nsapi_error_t error();
-
-    TCPSocket* get_tcp_socket();
-
-    mbedtls_ssl_context* get_ssl_context();
-
-    /**
-     * Set the debug flag.
-     *
-     * If this flag is set, debug information from mbed TLS will be logged to stdout.
-     */
-    void set_debug(bool debug);
-    
     /**
      * Timed recv for MQTT lib
      */
@@ -117,56 +27,20 @@
     int write(unsigned char* buffer, int len, int timeout);
     
 protected:
-
 #if MBED_CONF_MY_TLSSOCKET_TLS_DEBUG_LEVEL > 0
     /**
-     * Debug callback for mbed TLS
+     * Debug callback for Mbed TLS
      * Just prints on the USB serial port
      */
     static void my_debug(void *ctx, int level, const char *file, int line,
                          const char *str);
 
     /**
-     * Certificate verification callback for mbed TLS
+     * Certificate verification callback for Mbed TLS
      * Here we only use it to display information on each cert in the chain
      */
     static int my_verify(void *data, mbedtls_x509_crt *crt, int depth, uint32_t *flags);
 #endif
-
-    /**
-     * Receive callback for mbed TLS
-     */
-    static int ssl_recv(void *ctx, unsigned char *buf, size_t len);
-
-    /**
-     * Send callback for mbed TLS
-     */
-    static int ssl_send(void *ctx, const unsigned char *buf, size_t len);
-
-private:
-    void onError(TCPSocket *s, int error);
-
-    TCPSocket* _tcpsocket;
-
-    const char* DRBG_PERS;
-    const char* _ssl_ca_pem;
-    const char* _ssl_owncert_pem;
-    const char* _ssl_own_priv_key_pem;
-    const char* _hostname;
-    uint16_t _port;
-
-    bool _debug;
-    bool _is_connected;
-
-    nsapi_error_t _error;
-
-    mbedtls_entropy_context _entropy;
-    mbedtls_ctr_drbg_context _ctr_drbg;
-    mbedtls_x509_crt _cacert;
-    mbedtls_x509_crt _owncert;
-    mbedtls_pk_context _own_priv_key;
-    mbedtls_ssl_context _ssl;
-    mbedtls_ssl_config _ssl_conf;
 };
 
 #endif // _MY_TLS_SOCKET_H_
--- a/my-tlssocket/mbed_lib.json	Thu Nov 12 16:24:00 2020 +0800
+++ b/my-tlssocket/mbed_lib.json	Fri Mar 27 14:32:06 2020 +0800
@@ -3,7 +3,7 @@
     "config": {
         "tls-debug-level": {
             "help": "Debug level for TLS. Larger value for more verbose message. Its value can be 0, 1, 2, 3, or 4",
-            "value": 1
+            "value": 0
         },
         "tls-max-frag-len": {
             "help": "Maximum fragment length value for the payload in one packet, doesn't include TLS header and encryption overhead. Is needed for constrainted devices having low MTU sizes, Value 0 = disabled, 1 = MBEDTLS_SSL_MAX_FRAG_LEN_512, 2= MBEDTLS_SSL_MAX_FRAG_LEN_1024, 3 = MBEDTLS_SSL_MAX_FRAG_LEN_2048, 4 = MBEDTLS_SSL_MAX_FRAG_LEN_4096",
--- a/pre-main/provision.cpp	Thu Nov 12 16:24:00 2020 +0800
+++ b/pre-main/provision.cpp	Fri Mar 27 14:32:06 2020 +0800
@@ -19,7 +19,7 @@
 #include "mbed.h"
 #include "mbedtls/config.h"
 #include "entropy_poll.h"
-#include "psa/crypto.h"
+//#include "psa/crypto.h"
 #include "kvstore_global_api.h"
 #include "KVStore.h"
 #include "TDBStore.h"
--- a/targets/TARGET_NUVOTON/platform_entropy.cpp	Thu Nov 12 16:24:00 2020 +0800
+++ b/targets/TARGET_NUVOTON/platform_entropy.cpp	Fri Mar 27 14:32:06 2020 +0800
@@ -180,7 +180,11 @@
 {
 #if NU_CRYPTO_PRNG_PRESENT
     crypto_init();
+#if TARGET_NUC472 || (MBED_MAJOR_VERSION < 6)
     PRNG_ENABLE_INT();
+#else
+    PRNG_ENABLE_INT(CRPT);
+#endif
 #endif
 
     uint32_t seed = 0;
@@ -194,8 +198,12 @@
 
 #if NU_CRYPTO_PRNG_PRESENT
     /* PRNG reload seed */
+#if TARGET_NUC472 || (MBED_MAJOR_VERSION < 6)
     PRNG_Open(PRNG_KEYSIZE_ID, 1, seed);
 #else
+    PRNG_Open(CRPT, PRNG_KEYSIZE_ID, 1, seed);
+#endif
+#else
     srand(seed);
 #endif  /* #if NU_CRYPTO_PRNG_PRESENT */
 }
@@ -203,7 +211,11 @@
 NuEADCSeedRandom::~NuEADCSeedRandom()
 {
 #if NU_CRYPTO_PRNG_PRESENT
+#if TARGET_NUC472 || (MBED_MAJOR_VERSION < 6)
     PRNG_DISABLE_INT();
+#else
+    PRNG_DISABLE_INT(CRPT);
+#endif
     crypto_uninit();
 #endif /* #if NU_CRYPTO_PRNG_PRESENT */
 }
@@ -221,11 +233,18 @@
     uint32_t rand_data[PRNG_KEYSIZE / sizeof(uint32_t)];
     while (rmn) {
         crypto_prng_prestart();
+#if TARGET_NUC472 || (MBED_MAJOR_VERSION < 6)
         PRNG_Start();
+#else
+        PRNG_Start(CRPT);
+#endif
         crypto_prng_wait();
 
+#if TARGET_NUC472 || (MBED_MAJOR_VERSION < 6)
         PRNG_Read(rand_data);
-
+#else
+        PRNG_Read(CRPT, rand_data);
+#endif
         size_t n = (rmn >= PRNG_KEYSIZE) ? PRNG_KEYSIZE : rmn;
         memcpy(output_ind, rand_data, n);