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

Dependencies:   mbed-http

Files at this revision

API Documentation at this revision

Comitter:
ocomeni
Date:
Fri Jul 19 16:49:26 2019 +0000
Branch:
PassingRegression
Parent:
127:a21788227ca6
Commit message:
Implementation of Access token acquisition; 1. make request with credentials - DONE; 2. get response - DONE; 3. extract Id and refresh tokens from response - DONE; 4. integrate with code - DONE; Testing ongoing

Changed in this revision

mbed_app.json Show annotated file Show diff for this revision Revisions of this file
source/ATCmdManager.cpp Show annotated file Show diff for this revision Revisions of this file
source/WiFiManager.cpp Show annotated file Show diff for this revision Revisions of this file
source/WiFiManager.h Show annotated file Show diff for this revision Revisions of this file
source/common_config.h Show annotated file Show diff for this revision Revisions of this file
source/common_types.h Show annotated file Show diff for this revision Revisions of this file
source/debug.h Show annotated file Show diff for this revision Revisions of this file
diff -r a21788227ca6 -r 590bdc2dcf5b mbed_app.json
--- a/mbed_app.json	Mon Jul 15 21:37:22 2019 +0000
+++ b/mbed_app.json	Fri Jul 19 16:49:26 2019 +0000
@@ -40,7 +40,7 @@
             "platform.stdio-convert-newlines": true,
             "platform.thread-stats-enabled":1,
             "mbed-trace.enable": 1,
-            "mbed-http.http-buffer-size": 1024
+            "mbed-http.http-buffer-size": 2048
       }
      }
 }
diff -r a21788227ca6 -r 590bdc2dcf5b source/ATCmdManager.cpp
--- a/source/ATCmdManager.cpp	Mon Jul 15 21:37:22 2019 +0000
+++ b/source/ATCmdManager.cpp	Fri Jul 19 16:49:26 2019 +0000
@@ -354,6 +354,22 @@
                 at_resp = AT_RESP_NONE;
                 break;
             }
+            case AT_ACCESS_TOKEN_SUCCESS:  
+            {
+                // AT_ACCESS_TOKEN_SUCCESS response state 
+                dbg_printf(LOG, "\n [ATCMD MAN] AT_ACCESS_TOKEN_SUCCESS RESPONSE RECEIVED!!\r\n");
+                sendAtConfirmation("\r\nAWS ACCESS TOKEN ACQUIRED \r\n");
+                at_resp = AT_RESP_NONE;
+                break;
+            }
+            case AT_ACCESS_TOKEN_FAILED:  
+            {
+                // AT_ACCESS_TOKEN_FAILED response state 
+                dbg_printf(LOG, "\n [ATCMD MAN] AT_ACCESS_TOKEN_FAILED!!\r\n");
+                sendAtConfirmation("\r\nAWS ACCESS TOKEN ACQUISITION FAILURE!!\r\n");
+                at_resp = AT_RESP_NONE;
+                break;
+            }
             default:
             {
                  //UNKNOWN response state
@@ -469,7 +485,7 @@
     char * bodyPtr = p2+4;
     dbg_printf(LOG, "\nstrPtr address= %x",strPtr);
     dbg_printf(LOG, "\np2 address= %x", p2);
-    for(int i = 0; i < 5; i++){
+    for(int i = 0; i < 6; i++){
         if(i == 0)// firstline scan method uri and http_ver
         {
             n = sscanf(nxtPtr,"%s %s %s", s1, s2, s3);
diff -r a21788227ca6 -r 590bdc2dcf5b source/WiFiManager.cpp
--- a/source/WiFiManager.cpp	Mon Jul 15 21:37:22 2019 +0000
+++ b/source/WiFiManager.cpp	Fri Jul 19 16:49:26 2019 +0000
@@ -51,7 +51,8 @@
     //_event_queue.call_every(10000, this, &WiFiManager::callWifiWatchDog);
     //keep_alive_id = _event_queue.call_every(CLOUD_KEEP_ALIVE_INTERVAL, this, &WiFiManager::callInternetKeepAlive);
     keep_alive_id = 0;
-    https_request_succeeded = false;
+    https_token_valid = false;
+    token_refresh_count = 0;
     //watchDogTick.attach(callback(this, &WiFiManager::callWifiWatchDogIsr), 10.0); // call flip function every 10 seconds
 }
 
@@ -121,7 +122,12 @@
     nsapi_size_or_error_t error;
     //serr = socket->send("GET /nudgebox/v1 HTTP/1.0\r\nHost: https://dev2.dnanudge.io\r\n\r\n", 18);
     dbg_printf(LOG, "\n[WIFI MAN] KEEP ALIVE SERVER REQUEST\r\n");
-    error = socket->send(HELLO_MSG, sizeof(HELLO_MSG));
+    char *httpsReq = new char[KEEPALIVE_MSG_SIZE];
+    sprintf(httpsReq,"%s\r\nAuthorization: %s\r\n\r\n", KEEPALIVE_MSG_HDR, aws_id_token);
+    int hdrlen= strlen(httpsReq);
+    dbg_printf(LOG, "\n[WIFI MAN] KEEP ALIVE MSG [len = %d]\r\n%s", hdrlen, httpsReq);
+    memcpy(&httpsReq[hdrlen], KEEPALIVE_MSG_BDY,sizeof(KEEPALIVE_MSG_BDY));
+    error = socket->send(httpsReq, (hdrlen+sizeof(KEEPALIVE_MSG_BDY)));
     
     if(error < 0)
     {
@@ -146,37 +152,48 @@
     {
        queueATresponse(AT_SOCKET_KEEP_ALIVE_FAILED);
        https_connection_active = false;
+       socket->close();
+       delete socket;
+       socket = NULL;
     }
+    delete httpsReq;
 }
 
 void WiFiManager::CreateTokenHttpsRequest(char * httpsReq)
 {
-    
-    sprintf(httpsReq, "%s\r\n\r\n{\r\n\"AuthParameters\" : {\r\n"
+    char *httpsBody = new char[200];
+    sprintf(httpsBody,"{\r\n\"AuthParameters\" : {\r\n"
                      "\"USERNAME\" : \"%s\",\r\n\"PASSWORD\" : \"%s\"\r\n},\r\n"
                      "\"AuthFlow\" : \"%s\",\r\n"
-                     "\"ClientId\" : \"%s\"\r\n}", TOKEN_REQ_HDR, UserName, Password, AuthFlow, ClientId);
+                     "\"ClientId\" : \"%s\"\r\n}", UserName, Password, AuthFlow, ClientId);
+    int bodyLen = strlen(httpsBody);
+    sprintf(httpsReq,"%s\r\ncontent-length: %d"
+                     "\r\n\r\n%s", TOKEN_REQ_HDR, bodyLen, httpsBody);
     dbg_printf(LOG, "\n[WIFI MAN] Cloud Access Token REQUEST:\r\n%s\r\n", httpsReq);
+    delete httpsBody;
 }
 
 void WiFiManager::GetCloudAccessToken()
 {
+    int start = Kernel::get_ms_count();
     // Send data
     nsapi_size_or_error_t error;
     dbg_printf(LOG, "\n[WIFI MAN] Get Cloud Access Token REQUEST\r\n");
+    // first free up access token memory to avoid leak
+    freeAccessTokenMemory();
     char *httpsReq = new char[500];
     httpsReq[0] = NULL;
     CreateTokenHttpsRequest(httpsReq);
     if(strlen(httpsReq) == 0)
     {
-       queueATresponse(AT_SOCKET_KEEP_ALIVE_FAILED);
+       queueATresponse(AT_ACCESS_TOKEN_FAILED);
        return;
     }
     error = socket->send(httpsReq, strlen(httpsReq)+1);
-    
+    delete httpsReq;
     if(error < 0)
     {
-       queueATresponse(AT_SOCKET_KEEP_ALIVE_FAILED);
+       queueATresponse(AT_ACCESS_TOKEN_FAILED);
        return;
     }
     
@@ -187,33 +204,59 @@
     if(error >= 0 && strstr(respBuf, "HTTP/1.1 200")!= NULL) // received HTTP 200 OK status
     {
         dbg_printf(LOG, "\n[WIFI MAN] ACCESS TOKEN RESPONSE: \r\n %s\r\n", respBuf);
-        // reserve memomry on the heap for tokens
-        aws_id_token      = new char[ID_TOKEN_SIZE]; 
-        aws_refresh_token = new char[REFRESH_TOKEN_SIZE];  
         // extract ID TOKEN    
         char *sp1 = strstr(respBuf,ID_TOKEN_STR_START);   
-        char *sp2 = strstr(respBuf,ACCESS_TOKEN_STR_END);  
-        int tokenLen = sp2-sp1;
-        strncpy(aws_id_token, sp1, tokenLen);
-        dbg_printf(LOG, "\n[WIFI MAN] IdToken: \r\n %s\r\n", aws_id_token);
+        char *sp2 = strstr(sp1+strlen(ID_TOKEN_STR_START),ACCESS_TOKEN_STR_END);  
+        int tokenLen = sp2-sp1-(strlen(ID_TOKEN_STR_START));
+        // reserve memomry on the heap for id token
+        aws_id_token      = new char[tokenLen+1]; 
+        strncpy(aws_id_token, sp1+(strlen(ID_TOKEN_STR_START)), tokenLen);
+        dbg_printf(LOG, "\n[WIFI MAN] Token Length: %d \r\n IdToken: \r\n %s\r\n", tokenLen, aws_id_token);
+#ifdef EXTRACT_REFRESH_TOKEN
         // extract Refresh TOKEN    
         sp1 = strstr(respBuf,REFRESH_TOKEN_STR_START);   
-        sp2 = strstr(respBuf,ACCESS_TOKEN_STR_END);  
-        tokenLen = sp2-sp1;
-        strncpy(aws_refresh_token, sp1, tokenLen);
-        dbg_printf(LOG, "\n[WIFI MAN] RefreshToken: \r\n %s\r\n", aws_refresh_token);       
-        queueATresponse(AT_SOCKET_KEEP_ALIVE_OK);
-        https_connection_active = true;
+        sp2 = strstr(sp1+strlen(REFRESH_TOKEN_STR_START),ACCESS_TOKEN_STR_END);  
+        tokenLen = sp2-sp1-(strlen(REFRESH_TOKEN_STR_START));
+        // reserve memomry on the heap for refresh token
+        aws_refresh_token      = new char[tokenLen+1]; 
+        strncpy(aws_refresh_token, sp1+(strlen(REFRESH_TOKEN_STR_START)), tokenLen);
+        dbg_printf(LOG, "\n[WIFI MAN] Token Length: %d \r\nRefreshToken: \r\n %s\r\n", tokenLen, aws_refresh_token);  
+#endif     
+        queueATresponse(AT_ACCESS_TOKEN_SUCCESS);
+        token_refresh_count++;
+        //https_connection_active = true;
+        https_token_valid = true;
+        // schedule the invalidation of the token for 59 minutes time
+        _event_queue.call_in(TOKEN_VALID_PERIOD_MS, this, &WiFiManager::invalidateAccessToken);
     }
     else
     {
-       queueATresponse(AT_SOCKET_KEEP_ALIVE_FAILED);
-       https_connection_active = false;
+        dbg_printf(LOG, "\n[WIFI MAN] Failure Response: \r\n %s\r\n", respBuf);  
+        queueATresponse(AT_ACCESS_TOKEN_FAILED);
+       //https_connection_active = false;
     }
     delete respBuf;
+    int elapsed_ms = Kernel::get_ms_count() - start;
+    dbg_printf(LOG, "\n[WIFI MAN] Access token Acquisition::\r\n Time Elapsed : %ld ms\r\n", elapsed_ms);  
+    socket->close();
+    delete socket;
+    socket = NULL;
 }
 
+void WiFiManager::invalidateAccessToken()
+{
+    https_token_valid = false;
+}
 
+void WiFiManager::freeAccessTokenMemory()
+{
+    free(aws_id_token);
+    aws_id_token = NULL;
+#ifdef EXTRACT_REFRESH_TOKEN
+    free(aws_refresh_token);
+    aws_refresh_token = NULL;
+#endif
+}
 void  WiFiManager::sendThreadATresponseString(const char * buf, at_cmd_resp_t at_cmd)
 {
     if(at_data_resp != NULL) return;
@@ -426,6 +469,7 @@
                 }
                 backgroundTaskCompleted = false;
                 wifiCmd = WIFI_CMD_NONE;
+                //wifiCmd = WIFI_CMD_GET_TOKEN;
                 break;
             }
             case WIFI_CMD_NETWORK_STATUS:
@@ -450,12 +494,20 @@
                 break;
             case WIFI_CMD_SEND_HTTPS_REQ:
             {
+                wifiBusy = 1;
+                if(!https_token_valid) // if this is the first time get token
+                {
+                    wifiCmd = WIFI_CMD_NONE;
+                    fromWiFiCmd = WIFI_CMD_TLS_CONNECT;
+                    nextWiFiCmd = WIFI_CMD_SEND_HTTPS_REQ;
+                    setNextCommand(WIFI_CMD_GET_TOKEN);
+                    break;
+                }
                 // cancel keep alive event as not needed since new request has come in.
                 if(keep_alive_id != 0) // only cancel if it has been activated
                 {
                     _event_queue.cancel(keep_alive_id); 
                 }               
-                wifiBusy = 1;
 #ifdef SEND_DEBUG_MESSAGES
                 if(outputBuffersAvailable())
                 {
@@ -467,25 +519,27 @@
                 dbg_printf(LOG, "before call to send http request \n");
                 dbg_printf(LOG, "\r\n[WIFI-MAN] Received HTTPS request...\r\n");
                 print_memory_info();
-                //network->attach(NULL);
+                // disable network interrupts during https request
+                network->attach(NULL);
 #ifdef USE_EVENTS_FOR_HTTPS_REQUESTS
                 
                 // Events can be cancelled as long as they have not been dispatched. If the
                 // event has already expired, cancel has no side-effects.
                 int event_id = _event_queue.call(this, &WiFiManager::createSendHttpsRequest);
-                backgroundTaskCompleted = false;               
-                int msecCount = 0;
-                int oldChunkNum = chunkNum;
-                while(!backgroundTaskCompleted && msecCount < 6000)
-                {
-                    msecCount+=10;
-                    wait_ms(10);
-                    if(oldChunkNum != chunkNum) // new payload received
-                    {
-                        oldChunkNum = chunkNum;
-                        msecCount = 0;
-                    }
-                }
+                waitForBackgroundTask(6000, 10); // six second timeout
+//                backgroundTaskCompleted = false;               
+//                int msecCount = 0;
+//                int oldChunkNum = chunkNum;
+//                while(!backgroundTaskCompleted && msecCount < 6000)
+//                {
+//                    msecCount+=10;
+//                    wait_ms(10);
+//                    if(oldChunkNum != chunkNum) // new payload received
+//                    {
+//                        oldChunkNum = chunkNum;
+//                        msecCount = 0;
+//                    }
+//                }
                 if(backgroundTaskCompleted)
                 {
                     //queueATresponse(AT_INTERNET_CONFIG_RESP);
@@ -513,46 +567,93 @@
                     }
                     sendATresponseString(AT_COMMAND_FAILED);
                 }
-                if(https_request_succeeded == false)
-                {
-                    https_request_succeeded = result;
-                }
-                
                 dbg_printf(LOG, "after call to send http request \n");
                 print_memory_info();
                 wifiCmd = WIFI_CMD_NONE;
                 wifiBusy = 0;
                 // enable keep alive after https request completes
                 keep_alive_id = _event_queue.call_every(CLOUD_KEEP_ALIVE_INTERVAL, this, &WiFiManager::callInternetKeepAlive);
-                //network->attach(callback(this, &WiFiManager::status_callback));
+                // re-enable network interrupts after https request.
+                network->attach(callback(this, &WiFiManager::status_callback));
                 break;
             }            
             case WIFI_CMD_TLS_CONNECT:
             {
+                dbg_printf(LOG, "\r\n[WIFI-MAN] ATTEMPTING TLS CONNECTION\r\n");
                 char* hostName = strstr(internet_config->url,"//");
                 wifiBusy = 1;
                 if(hostName != NULL)
                 {
                     hostName += 2; 
-                    https_connection_active = createTLSconnection(hostName);
-                    if(https_connection_active == false)
+                    //https_connection_active = createTLSconnection(hostName);
+                    _event_queue.call(this, &WiFiManager::createTLSconnThreadCall, (const char*)hostName);
+                    waitForBackgroundTask(6000, 10); // six second timeout
+                    if(backgroundTaskCompleted == false)
                     {
+                        https_connection_active = false;
                         queueATresponse(AT_SOCKET_KEEP_ALIVE_FAILED);
                         delete socket;
                         socket = NULL;
                     }
+                    else
+                    {
+                        https_connection_active = true;
+                    }
                 }
-                wifiCmd = WIFI_CMD_NONE;
+                if(fromWiFiCmd == WIFI_CMD_TLS_CONNECT)
+                {
+                    wifiCmd = nextWiFiCmd;
+                    fromWiFiCmd = WIFI_CMD_NONE;
+                    nextWiFiCmd = WIFI_CMD_NONE;
+                }
+                else
+                {
+                    wifiCmd = WIFI_CMD_NONE;
+                }
                 wifiBusy = 0;
                 break;
             }
             case WIFI_CMD_INTERNET_KEEP_ALIVE:
+            {
                 wifiBusy = 1;
+                if(!https_token_valid) // if this is the first time get token
+                {
+                    wifiCmd = WIFI_CMD_NONE;
+                    fromWiFiCmd = WIFI_CMD_TLS_CONNECT;
+                    nextWiFiCmd = WIFI_CMD_INTERNET_KEEP_ALIVE;
+                    setNextCommand(WIFI_CMD_GET_TOKEN);
+                    break;
+                }
                 keepSocketAlive();
                 wifiCmd = WIFI_CMD_NONE;
                 wifiBusy = 0;
                 break;
+            }
+            case WIFI_CMD_GET_TOKEN:
+            {
+                wifiBusy = 1;                
+                _event_queue.call(this, &WiFiManager::createTLSconnThreadCall, AWS_HOST_NAME);
+                waitForBackgroundTask(6000, 10); // six second timeout
+                if(backgroundTaskCompleted == false)
+                {
+                    queueATresponse(AT_SOCKET_KEEP_ALIVE_FAILED);
+                    delete socket;
+                    socket = NULL;
+                }
+                else
+                {
+                    https_connection_active = false;
+                    GetCloudAccessToken();
+                    wifiCmd = WIFI_CMD_NONE;
+                    setNextCommand(WIFI_CMD_TLS_CONNECT);
+                    //_event_queue.call_in(ONE_SECOND,this, &WiFiManager::setNextCommand, WIFI_CMD_TLS_CONNECT);
+                    //wifiCmd = WIFI_CMD_TLS_CONNECT;
+                }
+                //wifiBusy = 0;
+                break;
+            }
             case WIFI_CMD_WIFI_MAC_ADDR:
+            {
                 wifiBusy = 1;
                 if(outputBuffersAvailable())
                 {
@@ -562,6 +663,7 @@
                 wifiCmd = WIFI_CMD_NONE;
                 wifiBusy = 0;
                 break;
+            }
             case WIFI_CMD_SEND_HTTP_REQ:
                 break;
             default:
@@ -577,6 +679,38 @@
     backgroundTaskCompleted = createHttpsRequest();
 }
 
+
+void  WiFiManager::createTLSconnThreadCall(const char * hostName)
+{
+    bool result;
+    backgroundTaskCompleted = false;
+    result = createTLSconnection(hostName);
+    if(result)
+    {
+        // update remote peer details after socket connection
+        updateRemotePeerDetails();
+        // send socket connection event before proceeding to send https request
+        // give about 2 ms
+        sendSocketConnectionEvent();
+        backgroundTaskCompleted = true;
+    }
+}
+void  WiFiManager::waitForBackgroundTask(int timeout_ms, int inc_ms)
+{
+    backgroundTaskCompleted = false;               
+    int msecCount = 0;
+    int oldChunkNum = chunkNum;
+    while(!backgroundTaskCompleted && msecCount < timeout_ms)
+    {
+        msecCount+=inc_ms;
+        wait_ms(inc_ms);
+        if(oldChunkNum != chunkNum) // new payload received
+        {
+            oldChunkNum = chunkNum;
+            msecCount = 0;
+        }
+    }
+}
 void  WiFiManager::sendATresponseString(at_cmd_resp_t at_cmd)
 {
     int strLen = strlen(responseString) + 1;
@@ -701,7 +835,7 @@
         dbg_printf(LOG, "\n [WIFI-MAN] Error instantiating WiFi!! \n");
         return 0;
     }
-    nsapi_error_t error;
+    //nsapi_error_t error;
     dbg_printf(LOG, "\n [WIFI-MAN] About to start scan for WiFi networks\n");
     lastScanCount = network->scan(NULL, 0);
     dbg_printf(LOG, "\n [WIFI-MAN] Scan for WiFi networks completed - \n");
@@ -1314,7 +1448,7 @@
     if(responseString == NULL && chunkNum==1)
     {
         responseString = (char *) malloc(100);
-        sprintf(responseString, "\r\nHTTPS BODY CALLBACK RECEIVED\r\n");
+        sprintf(responseString, "\r\nHTTPS BODY CALLBACK RECEIVED:: length= %d\r\n", length);
         sendATresponseString(AT_EVENT);
     }
 #endif
@@ -1346,17 +1480,23 @@
         return false;
     }
     dbg_printf(LOG, "TLS set_root_ca_cert passed!!\n");
-    r = socket->connect(hostName, 443);
-    if(r != NSAPI_ERROR_OK)
-    { 
-        char errstr[100];
-        mbedtls_strerror(r, errstr, 100);
-        dbg_printf(LOG, "TLS connect failed (err = %d) for hostname '%s' -- ERROR = %s !!\n", r, hostName, errstr);
-        socket->close();
-        return false;
-    }
-    dbg_printf(LOG, "TLS connection successful for https site :  %s\n", hostName);
-    return true;
+    int start_ms = _event_queue.tick();
+    int elapsed_ms;
+    do{
+        r = socket->connect(hostName, 443);
+        elapsed_ms = _event_queue.tick() - start_ms;
+        if(r == NSAPI_ERROR_OK)
+        { 
+            dbg_printf(LOG, "TLS connection successful for https site :  %s"
+                            " \r\n[TLS conn elapsed_ms = %d]\n", hostName, elapsed_ms);
+            return true;
+        }
+    }while(elapsed_ms < TLS_RETRY_TIMEOUT_MS);
+    char errstr[100];
+    mbedtls_strerror(r, errstr, 100);
+    dbg_printf(LOG, "TLS connect failed (err = %d) for hostname '%s' -- ERROR = %s !!\n", r, hostName, errstr);
+    socket->close();
+    return false;
 }
 
 
@@ -1409,9 +1549,20 @@
     char full_url[100];
     char host[60] ;
     strncpy(full_url,internet_config->url, strlen(internet_config->url)+1);
-    strncpy(host,http_req_cfg->hostName, strlen(http_req_cfg->hostName)+1);
+    //strncpy(host,http_req_cfg->hostName, strlen(http_req_cfg->hostName)+1);
+    char *eu = strstr(internet_config->url,HTTPS_URL_PREFIX);
+    if(eu == NULL)
+        eu = internet_config->url;
+    else
+        eu += strlen(HTTPS_URL_PREFIX);
+    char *eu2 = strstr(eu, "/"); // find the api path
+    int hLen = eu2 != NULL ? eu2-eu-1:  strlen(eu);
+        
+    
+    strncpy(host,eu, hLen+1);
     strncat(full_url, http_req_cfg->request_URI, strlen(http_req_cfg->request_URI)+1);
 #ifdef FULL_DEBUG_ENABLED
+    dbg_printf(LOG, "\n[WIFI MAN] server host name = %s\n", host);
     dbg_printf(LOG, "\n[WIFI MAN] server url+uri = %s\n", full_url);
     dbg_printf(LOG, "\n[WIFI MAN] Host = %s\n", http_req_cfg->hostName);
     dbg_printf(LOG, "\n[WIFI MAN] Accept = %s\n", http_req_cfg->AcceptVal);
@@ -1509,27 +1660,38 @@
         dbg_printf(LOG, "http_req_cfg->method = %d\n", http_req_cfg->method);
         if(http_req_cfg->method == HTTP_GET){
             dbg_printf(LOG, "HTTP_GET -- ignoring body\n");
-            setHttpsHeader("Host", http_req_cfg->hostName);
+            setHttpsHeader("Host", host);
             setHttpsHeader("Accept", http_req_cfg->AcceptVal);
             http_response = https_request->send(NULL, 0);
         }
         else{
-            setHttpsHeader("Host", http_req_cfg->hostName);
+            setHttpsHeader("Host", host);
+            setHttpsHeader("Authorization", aws_id_token);
             setHttpsHeader("Accept", http_req_cfg->AcceptVal);
             setHttpsHeader("Content-Type", http_req_cfg->contentType);
             setHttpsHeader("Content-Length", http_req_cfg->contentLen);
             dbg_printf(LOG, "https headers setup - about to send request\r\n");
             // Grab the heap statistics
             dbg_printf(LOG, "Heap size: %lu / %lu bytes\r\n", heap_stats.current_size, heap_stats.reserved_size);
+            dbg_printf(LOG, "\n[WIFI MAN] Token Length: %d \r\n IdToken: \r\n %s\r\n", strlen(aws_id_token), aws_id_token);
+            
+#ifdef PRINT_REQUEST_LOGS  
+            uint8_t *http_req_log_buf = (uint8_t*)calloc(2048, 1);
+            https_request->set_request_log_buffer(http_req_log_buf, 2048);
+#endif
             http_response = https_request->send(http_req_cfg->body, bodyLen);
         }
 #else
-        setHttpsHeader("Host", http_req_cfg->hostName);
+        setHttpsHeader("Host", host);
+        setHttpsHeader("Authorization", aws_id_token);
         setHttpsHeader("Accept", http_req_cfg->AcceptVal);
         setHttpsHeader("Content-Type", http_req_cfg->contentType);
         setHttpsHeader("Content-Length", http_req_cfg->contentLen);
         http_response = https_request->send(http_req_cfg->body, bodyLen);
-#endif        
+#endif      
+#ifdef PRINT_REQUEST_LOGS  
+        printHttpRequestLogBuffer();
+#endif
         nsapi_error_t error = https_request->get_error();
         if(error < 0)
         {
@@ -1589,6 +1751,22 @@
     https_request->set_header(key, value);
 }
 
+void WiFiManager::printHttpRequestLogBuffer()
+{   
+    
+    // after the request is done:
+#ifdef PRINT_BUFFER_IN_HEX
+    dbg_printf(LOG, "\n----- Request buffer Hex-----\n");
+    for (size_t ix = 0; ix < https_request->get_request_log_buffer_length(); ix++) {
+        if(ix%16 == 0)dbg_printf(LOG, "\n[%04x] ", ix);
+        dbg_printf(LOG, "%02x ", http_req_log_buf[ix]);
+    }
+#endif
+    dbg_printf(LOG, "\n[ request size = %d bytes]\r\n", https_request->get_request_log_buffer_length());
+    dbg_printf(LOG, "----- Request buffer string -----\r\n%s ", (char *)http_req_log_buf);
+    //wait_ms(100);
+    free(http_req_log_buf);
+}
 void WiFiManager::sendHttpsRequest(const char * body, int bodyLen)
 {
 }
diff -r a21788227ca6 -r 590bdc2dcf5b source/WiFiManager.h
--- a/source/WiFiManager.h	Mon Jul 15 21:37:22 2019 +0000
+++ b/source/WiFiManager.h	Fri Jul 19 16:49:26 2019 +0000
@@ -19,11 +19,16 @@
 #define TOKEN_RESPONSE_SIZE             5*1024
 #define ID_TOKEN_SIZE                   1024
 #define REFRESH_TOKEN_SIZE              2*1024
+#define KEEPALIVE_MSG_SIZE              1280
+#define SECS_PER_HOUR                   3600   
+#define MSECS_PER_SEC                   1000  
+#define SECS_IN_MIN                     60               
+#define TOKEN_VALID_PERIOD_MS           (SECS_PER_HOUR-SECS_IN_MIN)*MSECS_PER_SEC // 1 hour less 1 minute 
 #define ID_TOKEN_STR_START              "\"IdToken\":\""
 #define REFRESH_TOKEN_STR_START         "\"RefreshToken\":\""
 #define ACCESS_TOKEN_STR_END            "\",\""
 
-const char    TOKEN_REQ_HDR[] = "POST / HTTP1.1\r\n"
+const char    TOKEN_REQ_HDR[] = "POST / HTTP/1.1\r\n"
                                 "Host: cognito-idp.eu-west-2.amazonaws.com\r\n"
                                 "X-Amz-Target: AWSCognitoIdentityProviderService.InitiateAuth\r\n"
                                 "Content-Type: application/x-amz-json-1.1";
@@ -31,7 +36,7 @@
 const char    Password[] = "DnaN2dg3B4x!";
 const char    AuthFlow[] = "USER_PASSWORD_AUTH";
 const char    ClientId[] = "3el1h42i52p0e1gkb0l86ougdv";
-
+const char    AWS_HOST_NAME[] = "cognito-idp.eu-west-2.amazonaws.com";
 const uint8_t HELLO_MSG[] = {0x50,0x4f
                             ,0x53,0x54,0x20,0x2f,0x6e,0x75,0x64,0x67
                             ,0x65,0x62,0x6f,0x78,0x2f,0x76,0x31,0x20
@@ -52,7 +57,15 @@
                             ,0xca,0x6e,0x79,0x05,0x4e,0x01,0x68,0x65
                             ,0x6c,0x6c,0x6f,0x00,0x00,0x91,0xb5,0xa4
                             ,0x10};
+const char KEEPALIVE_MSG_HDR[] =   "POST /nudgebox/v1 HTTP/1.1\r\n"
+                                   "Host: dev-box.dnanudge.io\r\n"
+                                   "Content-Type: application/octet-stream\r\n"
+                                   "Content-Length: 20"
+                                   "";
 
+const uint8_t KEEPALIVE_MSG_BDY[] = {0x00,0x08,0xd4, 0xca,0x6e,0x79,0x05,0x4e,
+                                 0x01,0x68,0x65, 0x6c,0x6c,0x6f,0x00,0x00,
+                                 0x91,0xb5,0xa4,0x10};
 extern void print_memory_info();
 #define  CLOUD_KEEP_ALIVE_INTERVAL  9000
 class WiFiManager {
@@ -91,6 +104,8 @@
     char*                 responseString; // response string formated for Box
     uint8_t*              responseBytes; // response bytes formated for Box
     wifi_cmd_t  wifiCmd;
+    wifi_cmd_t  fromWiFiCmd; 
+    wifi_cmd_t  nextWiFiCmd;
     bool        backgroundTaskCompleted;
     //at_data_msg_t *at_data_resp;
     int         chunkNum;
@@ -121,9 +136,11 @@
     http_result_t http_result;
     bool     use_full_hostname;
     int      keep_alive_id;
-    bool     https_request_succeeded;
+    bool     https_token_valid;
     char *   aws_id_token;
     char *   aws_refresh_token;
+    int      token_refresh_count;
+    uint8_t *http_req_log_buf;
     
 #ifdef DNANUDGE_DEBUG
     rtos::Semaphore callback_semaphore;
@@ -183,6 +200,11 @@
     void                  keepSocketAlive();
     void                  CreateTokenHttpsRequest(char * httpsReq);
     void                  GetCloudAccessToken();
+    void                  printHttpRequestLogBuffer();
+    void                  invalidateAccessToken();
+    void                  freeAccessTokenMemory();
+    void                  createTLSconnThreadCall(const char * hostName);
+    void                  waitForBackgroundTask(int timeout_ms, int inc_ms);
 
 
 
diff -r a21788227ca6 -r 590bdc2dcf5b source/common_config.h
--- a/source/common_config.h	Mon Jul 15 21:37:22 2019 +0000
+++ b/source/common_config.h	Fri Jul 19 16:49:26 2019 +0000
@@ -57,9 +57,12 @@
 #define WIFI_IF_ID                      2
 #define LOCAL_ADDRESS_RESP              "+UMLA:"
 #define BLE_DEVICE_NAME_RESP            "+UBTLN:"
-#define ATCMD_MGR_FULL_DEBUG_ENA        0x80
-#define WIFI_MGR_FULL_DEBUG_ENA         0x8000
-#define BTLE_MGR_FULL_DEBUG_ENA         0x800000
+#define ATCMD_MGR_FULL_DEBUG_ENA        0x01
+#define WIFI_MGR_FULL_DEBUG_ENA         0x02
+#define BTLE_MGR_FULL_DEBUG_ENA         0x04
+#define ONE_SECOND                      1000 // 1000 ms
+#define HTTPS_URL_PREFIX                "https://"
+#define TLS_RETRY_TIMEOUT_MS            2000
 //#define ENABLE_MEMORY_CHECKS
 //#define SEND_DEBUG_MESSAGES
 
diff -r a21788227ca6 -r 590bdc2dcf5b source/common_types.h
--- a/source/common_types.h	Mon Jul 15 21:37:22 2019 +0000
+++ b/source/common_types.h	Fri Jul 19 16:49:26 2019 +0000
@@ -89,7 +89,8 @@
   WIFI_CMD_SEND_HTTPS_REQ,
   WIFI_CMD_SEND_HTTP_REQ,
   WIFI_CMD_TLS_CONNECT,
-  WIFI_CMD_INTERNET_KEEP_ALIVE
+  WIFI_CMD_INTERNET_KEEP_ALIVE,
+  WIFI_CMD_GET_TOKEN
 }wifi_cmd_t;
 
 typedef enum
@@ -122,7 +123,9 @@
   BLE_DISCONNECT_EVENT = 25,
   AT_WIFI_MAC_RESP = 26,
   AT_BLE_MAC_RESP = 27,
-  AT_BLE_NAME_RESP = 28
+  AT_BLE_NAME_RESP = 28,
+  AT_ACCESS_TOKEN_SUCCESS = 29,
+  AT_ACCESS_TOKEN_FAILED = 30
 }at_cmd_resp_t;
 
 typedef enum edm_msg_id
diff -r a21788227ca6 -r 590bdc2dcf5b source/debug.h
--- a/source/debug.h	Mon Jul 15 21:37:22 2019 +0000
+++ b/source/debug.h	Fri Jul 19 16:49:26 2019 +0000
@@ -33,7 +33,7 @@
 #define DBG_RX_CMDDATA_SIZE_BYTES       32   
 
 #define dbg_printf(debug_level, ...) dbg_print(FILE_CODE, __LINE__, debug_level, __VA_ARGS__)
-
+//#define FULL_DEBUG_ENABLED
 //-------- Constants & enums -------------------------------------------------//
 
 /**