Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Revision 129:590bdc2dcf5b, committed 2019-07-19
- 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
--- 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
       }
      }
 }
--- 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);
--- 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)
 {
 }
--- 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);
 
 
 
--- 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
--- 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
--- 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 -------------------------------------------------// /**