this is using the mbed os version 5-13-1

Dependencies:   mbed-http

Revision:
88:7ffa053be662
Parent:
87:99b37d26ff2a
Child:
89:45f6db09a76d
--- a/source/WiFiManager.cpp	Fri Mar 29 22:18:33 2019 +0000
+++ b/source/WiFiManager.cpp	Sun Mar 31 22:09:45 2019 +0000
@@ -32,6 +32,8 @@
  internet_config.connectionScheme = ALWAYS_CONNECTED; // set default connection scheme
  is_connected = false;
  chunkNum = 0;
+ socket = NULL;
+ https_connection_active = false;
 }
 
 WiFiManager::~WiFiManager()
@@ -40,6 +42,7 @@
   
 bool WiFiManager::queueATresponse(at_cmd_resp_t resp){
     at_resp_message_t *atResp  = _wiFi2ATmPool->alloc();
+    if(atResp == NULL) return false; // queue full;
     atResp->at_resp            = resp;
     _wiFi2ATCmdQueue->put(atResp);
     return true;
@@ -48,6 +51,7 @@
 
 bool WiFiManager::queueWiFiDataResponse(at_data_msg_t at_resp){
     at_data_msg_t *atData = _wiFi2ATDatamPool->alloc();
+    if(atData == NULL) return false; // queue full;
     atData->at_resp        = at_resp.at_resp;
     atData->dataLen        = at_resp.dataLen;
     memcpy(atData->buffer, at_resp.buffer, at_resp.dataLen);
@@ -100,7 +104,11 @@
                 queueATresponse(AT_INTERNET_CONFIG_RESP);
                 break;
             case WIFI_CMD_SEND_HTTPS_REQ:
+                printf("before call to send http request \n");
+                print_memory_info();
                 createHttpsRequest();
+                printf("after call to send http request \n");
+                print_memory_info();
                 wifiCmd = WIFI_CMD_NONE;
                 break;
             case WIFI_CMD_SEND_HTTP_REQ:
@@ -225,7 +233,7 @@
 {
     strcpy(wifi_config.ssid, wifi_ssid);
     printf("[WIFI-MAN]  wifi_ssid set to %s\n", wifi_config.ssid);
-
+    https_connection_active = false; // reset whenever any of the security credentials change
 }
 
 
@@ -233,6 +241,7 @@
 {
     strcpy(wifi_config.pass, wifi_pass);
     printf("[WIFI-MAN]  wifi_pass set to %s\n", wifi_config.pass);
+    https_connection_active = false; // reset whenever any of the security credentials change
 }
 
 
@@ -240,6 +249,7 @@
 {
     wifi_config.security = wifi_security;
     printf("[WIFI-MAN]  wifi_security set to %s\n", sec2str(wifi_config.security));
+    https_connection_active = false; // reset whenever any of the security credentials change
 }
 
 
@@ -255,6 +265,7 @@
     printf("peer_id = %1d, url = %s, connScheme = %1d\n", internet_config.peer_id, 
                                                       internet_config.url, 
                                                       internet_config.connectionScheme);
+    https_connection_active = false; // reset whenever any of the security credentials change
 }
 
 void WiFiManager::free_DataMsg()
@@ -264,6 +275,7 @@
 }
 
 
+
 void WiFiManager::status_callback(nsapi_event_t status, intptr_t param)
 {
     //if (status == NSAPI_EVENT_CONNECTION_STATUS_CHANGE) {
@@ -335,21 +347,37 @@
     return error;
 }
 
-
+void WiFiManager::sendResponseDownloadData(at_cmd_resp_t at_cmd, const uint8_t * buf, int bufLen)
+{
+    at_data_msg_t *at_data_resp;     
+    at_data_resp = new at_data_msg_t;
+    at_data_resp->at_resp = at_cmd;
+    size_t bufSize = sizeof(at_data_resp->buffer);
+    int pos = 0;
+    at_data_resp->dataLen = 0;
+    bool queueResult = true;
+    do {
+        if(!queueResult) wait_ms(10); // wait 10 ms to allow data to be transferred
+        at_data_resp->dataLen = (bufLen - pos) > bufSize? bufSize : (bufLen - pos) ;
+        memcpy(at_data_resp->buffer, &buf[pos], bufLen);
+        queueResult = queueWiFiDataResponse(*at_data_resp);
+        if(queueResult) pos+= at_data_resp->dataLen;
+    }while(queueResult ==  false || pos < bufLen);
+    delete at_data_resp;
+}
 
 void WiFiManager::return_response(HttpResponse* res) {
     
     //queueWiFiDataResponse(at_data_msg_t at_data_resp);
     
-    at_data_msg_t at_data_resp; 
+    at_data_msg_t *at_data_resp;
+    at_data_resp = new at_data_msg_t;
     int numChars = 0;
     // create message pointer for response header generation
-    char * msgPtr = (char *)at_data_resp.buffer;
+    char * msgPtr = (char *)at_data_resp->buffer;
     // do status line
     numChars = sprintf(msgPtr, "HTTP/1.1 %d %s\r\n", res->get_status_code(), res->get_status_message().c_str());
     msgPtr += numChars;
-    //at_data_resp = &at_data;
-    at_data_resp.dataLen = sizeof(*res); // start with minimum size of response
     for (size_t ix = 0; ix < res->get_headers_length(); ix++) {
         numChars = sprintf(msgPtr, "%s: %s\r\n", 
                            res->get_headers_fields()[ix]->c_str(), 
@@ -361,21 +389,19 @@
     strncpy(msgPtr, res->get_body_as_string().c_str(), res->get_body_length()+1);
     // print out generated header
     printf("generated response:\n");
-    printf("%s\r\n", (char *)at_data_resp.buffer);
+    printf("%s\r\n", (char *)at_data_resp->buffer);
     //printf("\nBody (%lu bytes):\n\n%s\n", res->get_body_length(), res->get_body_as_string().c_str());
-    at_data_resp.dataLen = (msgPtr - (char *)at_data_resp.buffer) + res->get_body_length();
+    at_data_resp->dataLen = (msgPtr - (char *)at_data_resp->buffer) + res->get_body_length();
     //printf("WIFI MAN]: wifi_cfg.security = %s\n", sec2str(wifi_cfg.security));
     // package and send on wifi data queue
     
-    at_data_resp.at_resp = AT_HTTPS_RESP;
+    at_data_resp->at_resp = AT_HTTPS_RESP;
     //at_data_resp.at_data_resp = sizeof(wifi_config_t);
     //memcpy(at_data_resp.buffer, res, at_data_resp.dataLen);
-    queueWiFiDataResponse(at_data_resp);
-    
-    delete res;
-
+    queueWiFiDataResponse(*at_data_resp);
+    delete at_data_resp;
 }
-#define TRY_PRINTF
+//#define TRY_PRINTF
 
 void WiFiManager::body_callback(const char *at, uint32_t length) {
     
@@ -390,22 +416,70 @@
         //int resp = write( (const uint8_t *)at, (int) length, &completed, SERIAL_EVENT_TX_COMPLETE);
     //}
     //if(false)
+#ifdef DUMP_BODY_BYTES
     if(chunkNum < 2)
     for (size_t ix = 0; ix < length; ix++) {
         printf("%02X: ", (uint8_t)at[ix]);
         if((ix % 32) == 0 and ix)
         printf("\n");
     }
+#endif
 #ifdef TRY_PRINTF
     printf("%s\n", at);
 #endif    
 
     printf("\n\n");
     chunkNum++;
+    sendResponseDownloadData(AT_HTTPS_RESP, (uint8_t *)at, length);
 }
 
+
+bool WiFiManager::createTLSconnection(const char * hostName)
+{
+    printf("\n\nbefore TLS socket creation\n");
+    print_memory_info();
+    socket = new TLSSocket();
+    printf("\n\nafter TLS socket creation\n");
+    print_memory_info();
+    //printf("\n[WIFI MAN] TLS Host = %s\n", hostName);
+
+    nsapi_error_t r;
+    // make sure to check the return values for the calls below (should return NSAPI_ERROR_OK)
+    r = socket->open(network);
+    if(r != NSAPI_ERROR_OK)
+    { 
+        //printf("TLS open failed!!");
+        return false;
+    }
+    printf("\n\nafter TLS socket opened\n");
+    print_memory_info();
+    printf("TLS open passed!!\n");
+    r = socket->set_root_ca_cert(SSL_CA_PEM);
+    if(r != NSAPI_ERROR_OK)
+    { 
+        printf("TLS set_root_ca_cert failed!!\n");
+        return false;
+    }
+    printf("\n\nbefore set root passed\n");
+    print_memory_info();
+    printf("TLS set_root_ca_cert passed!!\n");
+    r = socket->connect(hostName, 443);
+    if(r != NSAPI_ERROR_OK)
+    { 
+        printf("TLS connect failed for hostname %s!!\n", hostName);
+        return false;
+    }
+
+    printf("\n\nafter connection passed\n");
+    print_memory_info();
+    printf("TLS connection successful for https site :  %s\n", hostName);
+    return true;
+}
+#define TESTING_HTTPS
 void WiFiManager::createHttpsRequest()
 {
+    //printf("start of https request \n");
+    //print_memory_info();
     // reset chunk #;
     chunkNum = 0;
     printf("\n[WIFI MAN] Http Request received:");
@@ -413,7 +487,9 @@
     printf("\n[WIFI MAN] uri = %s", http_req_cfg->request_URI.c_str());
     printf("\n[WIFI MAN] internet cfg url = %s", internet_config.url);
     char full_url[100];
+    char host[60] ;
     strncpy(full_url,internet_config.url, strlen(internet_config.url)+1);
+    strncpy(host,http_req_cfg->hostName.c_str(), http_req_cfg->hostName.size());
     printf("\n[WIFI MAN] server url = %s\n", full_url);
     //strncat(internet_config.url, http_req_cfg->request_URI.c_str(), http_req_cfg->request_URI.size());
     strncat(full_url, http_req_cfg->request_URI.c_str(), http_req_cfg->request_URI.size());
@@ -426,7 +502,8 @@
     //printf("\n[WIFI MAN] server url = %s\n", internet_config.url.c_str());
     //const char* url = internet_config.url;
                                            
-    print_memory_info();
+    //printf("after http config processing\n");
+    //print_memory_info();
     //    http_request = new HttpRequest(network, 
     //   http_request = new HttpRequest(network, 
     int bodyLen;
@@ -437,13 +514,22 @@
         http_request = new HttpRequest(network,  
                                          //SSL_CA_PEM, 
                                          http_req_cfg->method, 
-                                         internet_config.url,
+                                         full_url,
                                          callback(this, &WiFiManager::body_callback));
         setHttpHeader("Host", http_req_cfg->hostName);
         setHttpHeader("Accept", http_req_cfg->AcceptVal);
-        setHttpHeader("Content-Type", http_req_cfg->contentType);
-        setHttpHeader("Content-Length", http_req_cfg->contentLen);
-        http_response = http_request->send(http_req_cfg->body, bodyLen);
+        printf("http_req_cfg->method = %d\n");
+        if(http_req_cfg->method == HTTP_GET){
+            printf("HTTP_GET -- ignoring body\n");
+            //setHttpHeader("Content-Type", http_req_cfg->contentType);
+            //setHttpHeader("Content-Length", http_req_cfg->contentLen);
+            http_response = http_request->send(NULL, 0);
+        }
+        else{
+            setHttpHeader("Content-Type", http_req_cfg->contentType);
+            setHttpHeader("Content-Length", http_req_cfg->contentLen);
+            http_response = http_request->send(http_req_cfg->body, bodyLen);
+        }
         free_DataMsg();
         if (!http_response) {
             char buf[100];
@@ -453,33 +539,74 @@
             delete http_request; // free the memory
             return;
         }
+        delete http_request; // free the memory
         printf("\n----- HTTP POST response -----\n");
     }
     else
     {
-        https_request = new HttpsRequest(network, 
-                                         SSL_CA_PEM, 
+        if(https_connection_active == false){
+            bool tlsResult;
+            tlsResult = createTLSconnection(host);
+            if(tlsResult == false){
+                 delete socket;
+                 free_DataMsg();
+                 return;
+            }
+            printf("[create https] TLS connection successful for https site :  %s\n", host);
+        }        
+        // Pass in `socket`, instead of `network` as first argument, and omit the `SSL_CA_PEM` argument
+        //HttpsRequest* get_req = new HttpsRequest(socket, HTTP_GET, "https://httpbin.org/status/418");
+        //_wmutex.lock();
+        https_request = new HttpsRequest(socket, 
                                          http_req_cfg->method, 
-                                         internet_config.url,
+                                         full_url,
                                          callback(this, &WiFiManager::body_callback));
         
         setHttpsHeader("Host", http_req_cfg->hostName);
         setHttpsHeader("Accept", http_req_cfg->AcceptVal);
-        setHttpsHeader("Content-Type", http_req_cfg->contentType);
-        setHttpsHeader("Content-Length", http_req_cfg->contentLen);
+#ifdef TESTING_HTTPS
+        printf("http_req_cfg->method = %d\n");
+        if(http_req_cfg->method == HTTP_GET){
+            printf("HTTP_GET -- ignoring body\n");
+            //setHttpHeader("Content-Type", http_req_cfg->contentType);
+            //setHttpHeader("Content-Length", http_req_cfg->contentLen);
+            http_response = https_request->send(NULL, 0);
+        }
+        else{
+            setHttpHeader("Content-Type", http_req_cfg->contentType);
+            setHttpHeader("Content-Length", http_req_cfg->contentLen);
+            http_response = https_request->send(http_req_cfg->body, bodyLen);
+        }
+#else
+        setHttpHeader("Content-Type", http_req_cfg->contentType);
+        setHttpHeader("Content-Length", http_req_cfg->contentLen);
         http_response = https_request->send(http_req_cfg->body, bodyLen);
+#endif        
+        
+        //_wmutex.unlock();
+        printf("after https request creation\n");
+        print_memory_info();
         free_DataMsg();
+        //printf("after https response and freeData alloc\n");
+        //print_memory_info();
         if (!http_response) {
             char buf[100];
             mbedtls_strerror(https_request->get_error(), buf, 100);
-            printf("HttpRequest failed (error code %s)\n", buf);
+            printf("HttpsRequest failed (error code %s)\n", buf);
             //printf("HttpsRequest failed (error code %d)\n", https_request->get_error());
             delete https_request; // free the memory
+            https_connection_active = false; // reset true whenever connection fails
+            delete socket;
             return;
         }
+        https_connection_active = true; // set true whenever connection succeeds
+        //delete https_request; // free the memory
+        //printf("after https request deletion\n");
+        //print_memory_info();
         printf("\n----- HTTPS POST response -----\r\n");
    }
     return_response(http_response);
+    delete http_response;
 }
 
 void WiFiManager::createHttpRequest(http_method method,