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

Dependencies:   mbed-http

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers WiFiManager.cpp Source File

WiFiManager.cpp

00001 #include "debug.h"
00002 #include "WiFiManager.h"
00003 #include "common_config.h"
00004 #define FILE_CODE       "wifi"
00005 #define USE_EVENTS_FOR_HTTPS_REQUESTS
00006 
00007 WiFiManager::WiFiManager(wifi_config_t *wifi_config, WiFiInterface *wifi, 
00008                          internet_config_t *internet_config, 
00009                          events::EventQueue &event_queue, 
00010                          MemoryPool<wifi_cmd_message_t, 16> *aT2WiFimPool, 
00011                          Queue<wifi_cmd_message_t, 16> *aT2WiFiCmdQueue, 
00012                          MemoryPool<at_resp_message_t, 16> *wiFi2ATmPool, 
00013                          Queue<at_resp_message_t, 16> *wiFi2ATCmdQueue, 
00014                          MemoryPool<wifi_data_msg_t, PQDSZ> *aT2WiFiDatamPool, 
00015                          Queue<wifi_data_msg_t, PQDSZ> *aT2WiFiDataQueue, 
00016                          MemoryPool<at_data_msg_t, PQDSZ> *wiFi2ATDatamPool, 
00017                          Queue<at_data_msg_t, PQDSZ> *wiFi2ATDataQueue) 
00018 :
00019      wifi_config(wifi_config),
00020      network(wifi),
00021      internet_config(internet_config),
00022     _event_queue(event_queue),
00023     _aT2WiFimPool(aT2WiFimPool),
00024     _aT2WiFiCmdQueue(aT2WiFiCmdQueue),
00025     
00026     _wiFi2ATmPool(wiFi2ATmPool),
00027     _wiFi2ATCmdQueue(wiFi2ATCmdQueue),
00028     
00029     _aT2WiFiDatamPool(aT2WiFiDatamPool),
00030     _aT2WiFiDataQueue(aT2WiFiDataQueue),
00031     
00032     _wiFi2ATDatamPool(wiFi2ATDatamPool),
00033     _wiFi2ATDataQueue(wiFi2ATDataQueue)
00034 
00035 {
00036     lastScanCount = 0;
00037     wifiCmd = WIFI_CMD_NONE;
00038     //internet_config.connectionScheme = ALWAYS_CONNECTED; // set default connection scheme
00039     is_connected = false;
00040     http_response = NULL;
00041     chunkNum = 0;
00042     socket = NULL;
00043     responseString = NULL;
00044     responseBytes = NULL;
00045     at_data_resp = NULL;
00046     https_connection_active = false;
00047     use_full_hostname       = false;
00048     wifiBusy = 0;
00049     wifiWatchdogTimer.start();
00050     watchdogCnt = 0;
00051     //_event_queue.call_every(10000, this, &WiFiManager::callWifiWatchDog);
00052     //keep_alive_id = _event_queue.call_every(CLOUD_KEEP_ALIVE_INTERVAL, this, &WiFiManager::callInternetKeepAlive);
00053     keep_alive_id = 0;
00054     https_token_valid = false;
00055     token_refresh_count = 0;
00056     //watchDogTick.attach(callback(this, &WiFiManager::callWifiWatchDogIsr), 10.0); // call flip function every 10 seconds
00057 }
00058 
00059 WiFiManager::~WiFiManager()
00060 {
00061     delete network;
00062     wifiWatchdogTimer.stop();
00063     socket->close();
00064     delete socket;
00065     free(aws_id_token);
00066     free(aws_refresh_token);    
00067 }
00068 //#define DISABLE_WATCHDOG
00069 
00070 void WiFiManager::callWifiWatchDogIsr()
00071 {
00072     _event_queue.call_in(10, this, &WiFiManager::callWifiWatchDog);    
00073 }
00074 void WiFiManager::callWifiWatchDog()
00075 {
00076 #ifdef DISABLE_WATCHDOG
00077     return;
00078 #else
00079     static int inactivity_monitor = 0;
00080     watchdogCnt++;
00081     if(watchdogCnt >= 6 && outputBuffersAvailable()) // every minute
00082     {
00083         char * respStr = (char *) malloc(120);
00084         sprintf(responseString, "\r\n[WiFi-MAN] WiFi Manager Alive : state = %d busy = %d httpsConnActive = %d\r\n",
00085                                 wifiCmd, wifiBusy, https_connection_active);
00086         sendThreadATresponseString(respStr, WIFI_WATCH_DOG);
00087         watchdogCnt = 0;
00088     }
00089     else if(wifiWatchdogTimer.read() > 30 && responseString==NULL)
00090     {
00091         if(wifiCmd == WIFI_CMD_NONE)
00092             inactivity_monitor++;
00093         char * respStr = (char *) malloc(120);
00094         sprintf(responseString, "\r\n[WiFi-MAN] Main Loop InActive : state = %d busy = %d httpsConnActive = %d\r\n", 
00095                                  wifiCmd, wifiBusy, https_connection_active);
00096         sendThreadATresponseString(respStr, WIFI_WATCH_DOG);
00097         if(inactivity_monitor >= 3)
00098         {
00099             free_DataMsg();
00100             inactivity_monitor = 0;
00101         }
00102     }
00103 #endif    
00104 }
00105 
00106 void WiFiManager::callInternetKeepAlive()
00107 {
00108     if(https_connection_active)
00109     {
00110         setNextCommand(WIFI_CMD_INTERNET_KEEP_ALIVE);
00111     }
00112     else
00113     {
00114         setNextCommand(WIFI_CMD_TLS_CONNECT);
00115     }
00116 }
00117 
00118 
00119 void WiFiManager::keepSocketAlive()
00120 {
00121     // Send data
00122     nsapi_size_or_error_t error;
00123     //serr = socket->send("GET /nudgebox/v1 HTTP/1.0\r\nHost: https://dev2.dnanudge.io\r\n\r\n", 18);
00124     dbg_printf(LOG, "\n[WIFI MAN] KEEP ALIVE SERVER REQUEST\r\n");
00125     char *httpsReq = new char[KEEPALIVE_MSG_SIZE];
00126     sprintf(httpsReq,"%s\r\nAuthorization: %s\r\n\r\n", KEEPALIVE_MSG_HDR, aws_id_token);
00127     int hdrlen= strlen(httpsReq);
00128     dbg_printf(LOG, "\n[WIFI MAN] KEEP ALIVE MSG [len = %d]\r\n%s", hdrlen, httpsReq);
00129     memcpy(&httpsReq[hdrlen], KEEPALIVE_MSG_BDY,sizeof(KEEPALIVE_MSG_BDY));
00130     error = socket->send(httpsReq, (hdrlen+sizeof(KEEPALIVE_MSG_BDY)));
00131     
00132     if(error < 0)
00133     {
00134        queueATresponse(AT_SOCKET_KEEP_ALIVE_FAILED);
00135        https_connection_active = false;
00136        socket->close();
00137        delete socket;
00138        socket = NULL;
00139        return;
00140     }
00141     
00142     // Receive data
00143     char buf[500];
00144     error = socket->recv(buf, 500);
00145     if(error >= 0 && strstr(buf, "HTTP/1.1 200")!= NULL) // received HTTP 200 OK status
00146     {
00147         dbg_printf(LOG, "\n[WIFI MAN] KEEP ALIVE SERVER RESPONSE: \r\n %s\r\n", buf);
00148         queueATresponse(AT_SOCKET_KEEP_ALIVE_OK);
00149         https_connection_active = true;
00150     }
00151     else
00152     {
00153        queueATresponse(AT_SOCKET_KEEP_ALIVE_FAILED);
00154        https_connection_active = false;
00155        socket->close();
00156        delete socket;
00157        socket = NULL;
00158     }
00159     delete httpsReq;
00160 }
00161 
00162 void WiFiManager::CreateTokenHttpsRequest(char * httpsReq)
00163 {
00164     char *httpsBody = new char[200];
00165     sprintf(httpsBody,"{\r\n\"AuthParameters\" : {\r\n"
00166                      "\"USERNAME\" : \"%s\",\r\n\"PASSWORD\" : \"%s\"\r\n},\r\n"
00167                      "\"AuthFlow\" : \"%s\",\r\n"
00168                      "\"ClientId\" : \"%s\"\r\n}", UserName, Password, AuthFlow, ClientId);
00169     int bodyLen = strlen(httpsBody);
00170     sprintf(httpsReq,"%s\r\ncontent-length: %d"
00171                      "\r\n\r\n%s", TOKEN_REQ_HDR, bodyLen, httpsBody);
00172     dbg_printf(LOG, "\n[WIFI MAN] Cloud Access Token REQUEST:\r\n%s\r\n", httpsReq);
00173     delete httpsBody;
00174 }
00175 
00176 void WiFiManager::GetCloudAccessToken()
00177 {
00178     int start = Kernel::get_ms_count();
00179     // Send data
00180     nsapi_size_or_error_t error;
00181     dbg_printf(LOG, "\n[WIFI MAN] Get Cloud Access Token REQUEST\r\n");
00182     // first free up access token memory to avoid leak
00183     freeAccessTokenMemory();
00184     char *httpsReq = new char[500];
00185     httpsReq[0] = NULL;
00186     CreateTokenHttpsRequest(httpsReq);
00187     if(strlen(httpsReq) == 0)
00188     {
00189        queueATresponse(AT_ACCESS_TOKEN_FAILED);
00190        return;
00191     }
00192     error = socket->send(httpsReq, strlen(httpsReq)+1);
00193     delete httpsReq;
00194     if(error < 0)
00195     {
00196        queueATresponse(AT_ACCESS_TOKEN_FAILED);
00197        return;
00198     }
00199     
00200     // Receive data
00201     // reserve large buffer from heap to hold response
00202     char *respBuf = new char[TOKEN_RESPONSE_SIZE]; 
00203     error = socket->recv(respBuf, TOKEN_RESPONSE_SIZE);
00204     if(error >= 0 && strstr(respBuf, "HTTP/1.1 200")!= NULL) // received HTTP 200 OK status
00205     {
00206         dbg_printf(LOG, "\n[WIFI MAN] ACCESS TOKEN RESPONSE: \r\n %s\r\n", respBuf);
00207         // extract ID TOKEN    
00208         char *sp1 = strstr(respBuf,ID_TOKEN_STR_START);   
00209         char *sp2 = strstr(sp1+strlen(ID_TOKEN_STR_START),ACCESS_TOKEN_STR_END);  
00210         int tokenLen = sp2-sp1-(strlen(ID_TOKEN_STR_START));
00211         // reserve memomry on the heap for id token
00212         aws_id_token      = new char[tokenLen+1]; 
00213         strncpy(aws_id_token, sp1+(strlen(ID_TOKEN_STR_START)), tokenLen);
00214         dbg_printf(LOG, "\n[WIFI MAN] Token Length: %d \r\n IdToken: \r\n %s\r\n", tokenLen, aws_id_token);
00215 #ifdef EXTRACT_REFRESH_TOKEN
00216         // extract Refresh TOKEN    
00217         sp1 = strstr(respBuf,REFRESH_TOKEN_STR_START);   
00218         sp2 = strstr(sp1+strlen(REFRESH_TOKEN_STR_START),ACCESS_TOKEN_STR_END);  
00219         tokenLen = sp2-sp1-(strlen(REFRESH_TOKEN_STR_START));
00220         // reserve memomry on the heap for refresh token
00221         aws_refresh_token      = new char[tokenLen+1]; 
00222         strncpy(aws_refresh_token, sp1+(strlen(REFRESH_TOKEN_STR_START)), tokenLen);
00223         dbg_printf(LOG, "\n[WIFI MAN] Token Length: %d \r\nRefreshToken: \r\n %s\r\n", tokenLen, aws_refresh_token);  
00224 #endif     
00225         queueATresponse(AT_ACCESS_TOKEN_SUCCESS);
00226         token_refresh_count++;
00227         //https_connection_active = true;
00228         https_token_valid = true;
00229         // schedule the invalidation of the token for 59 minutes time
00230         _event_queue.call_in(TOKEN_VALID_PERIOD_MS, this, &WiFiManager::invalidateAccessToken);
00231     }
00232     else
00233     {
00234         dbg_printf(LOG, "\n[WIFI MAN] Failure Response: \r\n %s\r\n", respBuf);  
00235         queueATresponse(AT_ACCESS_TOKEN_FAILED);
00236        //https_connection_active = false;
00237     }
00238     delete respBuf;
00239     int elapsed_ms = Kernel::get_ms_count() - start;
00240     dbg_printf(LOG, "\n[WIFI MAN] Access token Acquisition::\r\n Time Elapsed : %ld ms\r\n", elapsed_ms);  
00241     socket->close();
00242     delete socket;
00243     socket = NULL;
00244 }
00245 
00246 void WiFiManager::invalidateAccessToken()
00247 {
00248     https_token_valid = false;
00249 }
00250 
00251 void WiFiManager::freeAccessTokenMemory()
00252 {
00253     free(aws_id_token);
00254     aws_id_token = NULL;
00255 #ifdef EXTRACT_REFRESH_TOKEN
00256     free(aws_refresh_token);
00257     aws_refresh_token = NULL;
00258 #endif
00259 }
00260 void  WiFiManager::sendThreadATresponseString(const char * buf, at_cmd_resp_t at_cmd)
00261 {
00262     if(at_data_resp != NULL) return;
00263     int strLen = strlen(buf) + 1;
00264     at_data_resp = new at_data_msg_t;
00265     // set string length 
00266     at_data_resp->dataLen = strLen;
00267     memcpy(at_data_resp->buffer, buf, strLen);
00268     // package and send on wifi data queue    
00269     at_data_resp->at_resp = at_cmd;
00270     bool queueResult = true;
00271     int wait_count = 0;
00272     do
00273     {
00274         if(!queueResult){
00275             wait_count+=10;
00276             dbg_printf(LOG, "ATCMD Queue full waiting %d ms so far...\n", wait_count);
00277             wait_ms(10);
00278         }
00279         queueResult = queueWiFiDataResponse(*at_data_resp);
00280     }while(queueResult == false && wait_count<QUEUE_WAIT_TIMEOUT_MS);
00281     delete at_data_resp;
00282     at_data_resp = NULL;
00283 }
00284 
00285 
00286 bool WiFiManager::outputBuffersAvailable()
00287 {
00288     int timeout = 0;
00289     while(timeout < 100)
00290     {
00291         if(responseBytes==NULL && responseString==NULL && at_data_resp==NULL)
00292         {
00293             return true;
00294         }
00295         else
00296         {
00297             timeout += 10;
00298             wait_ms(10);
00299         }
00300     }
00301     if(responseBytes==NULL && responseString==NULL && at_data_resp==NULL)
00302     {
00303         return true;
00304     }
00305     else
00306     {
00307         return false;
00308     }
00309 }
00310 
00311 
00312 bool WiFiManager::queueATresponse(at_cmd_resp_t resp){
00313 #ifndef USE_MALLOC_FOR_COMMAND_MEMORY_POOL
00314     at_resp_message_t *atResp  = _wiFi2ATmPool->alloc();
00315 #else
00316     at_resp_message_t *atResp  = (at_resp_message_t *) malloc(sizeof(at_resp_message_t));
00317 #endif
00318     if(atResp == NULL) return false; // queue full;
00319     atResp->at_resp            = resp;
00320     _wiFi2ATCmdQueue->put(atResp);
00321     return true;
00322 }
00323 
00324 
00325 bool WiFiManager::queueWiFiDataResponse(at_data_msg_t at_resp){
00326     at_data_msg_t *atData = _wiFi2ATDatamPool->alloc();
00327     if(atData == NULL) return false; // queue full;
00328     atData->at_resp        = at_resp.at_resp;
00329     atData->dataLen        = at_resp.dataLen;
00330     memcpy(atData->buffer, at_resp.buffer, at_resp.dataLen);
00331     _wiFi2ATDataQueue->put(atData);
00332     dbg_printf(LOG, "[WIFI MAN] queued data size = %d : at_resp = %d\n", at_resp.dataLen, at_resp.at_resp);
00333     return true;
00334 }
00335 
00336 void WiFiManager::getWiFiInstance()
00337 {
00338     network = WiFiInterface::get_default_instance();
00339     if (!network) {
00340         dbg_printf(LOG, "ERROR: No WiFiInterface found.\n");
00341     }
00342 }
00343 
00344 void WiFiManager::runMain(){
00345     nsapi_error_t error;
00346     bool result;
00347     dbg_printf(LOG, "\r\n [WIFI MAN]  Thread Id = %X\r\n", (uint32_t)ThisThread::get_id());
00348     while(true){
00349         dequeueWiFiCommands();
00350         dequeueATdataResponse();
00351         wifiWatchdogTimer.reset();
00352         switch(wifiCmd){
00353             case WIFI_CMD_NONE:
00354                 // IDLE STATE
00355                 break;
00356             case WIFI_CMD_SCAN:
00357                 wifiBusy = 1;
00358                 error = scanNetworks();
00359                 wifiCmd = WIFI_CMD_NONE;
00360                 queueATresponse(AT_SCAN_RESP);
00361                 wifiBusy = 0;
00362                 break;
00363             case WIFI_CMD_DETAILED_SCAN:
00364             {
00365                 wifiBusy = 1;
00366                 nsapi_size_or_error_t cnt_err;
00367                 cnt_err = getAvailableAPs(lastScanCount);
00368                 wifiCmd = WIFI_CMD_NONE;
00369                 if(cnt_err >= 0)
00370                 {
00371                     queueATresponse(AT_DETAILED_SCAN_RESP);
00372                 }
00373                 wifiBusy = 0;
00374                 break;
00375             }
00376             case WIFI_CMD_CONNECT:
00377             {
00378                 if(is_connected) // already connected
00379                 {
00380                     wifiCmd = WIFI_CMD_NONE;
00381                     break;
00382                 }
00383                 wifiBusy = 1;
00384                 error = connect();
00385                 int secCount = 0;
00386                 while(secCount++ < WIFI_CONNECT_TIMEOUT_SECS && is_connected==false){
00387                     wait(1); // wait 1 sec
00388                 }
00389                 wifiCmd = WIFI_CMD_NONE;
00390                 if(is_connected==false){
00391                     if(outputBuffersAvailable() == false) // first free it
00392                     {
00393                         free(responseString);
00394                     }
00395                     dbg_printf(LOG, "[WIFI MAN] +++ WIFI CONNECTION TIMEOUT +++ \r\n");
00396                     //queueATresponse(AT_COMMAND_FAILED);
00397                     responseString = (char *) malloc(100);
00398                     sprintf(responseString, "\r\n+UUTIMEOUT\r\n");
00399                     sendATresponseString(AT_COMMAND_FAILED);
00400                 }
00401                 else {
00402                     sendATresponseString(AT_CONNECT_RESP);
00403                 }
00404                 wifiBusy = 0;
00405                 break;
00406             }
00407             case WIFI_CMD_DISCONNECT:
00408             {
00409                 if(!is_connected) // already disconnected
00410                 {
00411                     wifiCmd = WIFI_CMD_NONE;
00412                     break;
00413                 }
00414                 wifiBusy = 1;
00415                 error = disconnect();
00416                 wifiCmd = WIFI_CMD_NONE;
00417                 if(error >= 0)
00418                 {
00419                     int secCount = 0;
00420                     while(secCount++ < WIFI_CONNECT_TIMEOUT_SECS && is_connected==true){
00421                         wait(1); // wait 1 sec
00422                     }
00423                     if(!is_connected)
00424                     {
00425                         sendATresponseString(AT_DISCONNECT_RESP);
00426                     }
00427                     else
00428                     {
00429                         dbg_printf(LOG, "[WIFI MAN] +++ WIFI DISCONNECTION TIMEOUT +++ \r\n");
00430                         //queueATresponse(AT_COMMAND_FAILED);
00431                         responseString = (char *) malloc(100);
00432                         sprintf(responseString, "\r\n+UUTIMEOUT\r\n");
00433                         sendATresponseString(AT_COMMAND_FAILED);
00434                     }
00435                     // attempt reconnection if always connected scheme is set
00436                     if(internet_config->connectionScheme == ALWAYS_CONNECTED)
00437                     {
00438                         setNextCommand(WIFI_CMD_CONNECT);
00439                     }
00440                 }
00441                 wifiBusy = 0;
00442                 break;
00443             }
00444             case WIFI_CMD_CONFIG:
00445                 wifiBusy = 1;
00446                 set_WIFI_CONFIG();
00447                 wifiCmd = WIFI_CMD_NONE;
00448                 queueATresponse(AT_CONFIG_RESP);
00449                 wifiBusy = 0;
00450                 break;
00451             case WIFI_CMD_INTERNET_CONFIG:
00452             {
00453                 wifiBusy = 1;
00454                 backgroundTaskCompleted = false;
00455                 set_internet_config();
00456                 // Wait for callback semaphore
00457 #ifdef DNANUDGE_DEBUG
00458                 callback_semaphore.wait();
00459 #endif
00460                 int msecCount = 0;
00461                 while(!backgroundTaskCompleted && msecCount < 1000)
00462                 {
00463                     msecCount++;
00464                     wait_ms(10);
00465                 }
00466                 if(backgroundTaskCompleted)
00467                 {
00468                     queueATresponse(AT_INTERNET_CONFIG_RESP);
00469                 }
00470                 backgroundTaskCompleted = false;
00471                 wifiCmd = WIFI_CMD_NONE;
00472                 //wifiCmd = WIFI_CMD_GET_TOKEN;
00473                 break;
00474             }
00475             case WIFI_CMD_NETWORK_STATUS:
00476                 wifiBusy = 1;
00477                 if(outputBuffersAvailable())
00478                 {
00479                     getNetworkStatus();
00480                 }
00481                 sendATresponseString(AT_NETWORK_STATUS_RESP);
00482                 wifiCmd = WIFI_CMD_NONE;
00483                 wifiBusy = 0;
00484                 break;
00485             case WIFI_CMD_WIFI_STATUS:
00486                 wifiBusy = 1;
00487                 if(outputBuffersAvailable())
00488                 {
00489                     getWiFiStatus();
00490                 }
00491                 sendATresponseString(AT_WIFI_STATUS_RESP);
00492                 wifiCmd = WIFI_CMD_NONE;
00493                 wifiBusy = 0;
00494                 break;
00495             case WIFI_CMD_SEND_HTTPS_REQ:
00496             {
00497                 wifiBusy = 1;
00498                 if(!https_token_valid) // if this is the first time get token
00499                 {
00500                     wifiCmd = WIFI_CMD_NONE;
00501                     fromWiFiCmd = WIFI_CMD_TLS_CONNECT;
00502                     nextWiFiCmd = WIFI_CMD_SEND_HTTPS_REQ;
00503                     setNextCommand(WIFI_CMD_GET_TOKEN);
00504                     break;
00505                 }
00506                 // cancel keep alive event as not needed since new request has come in.
00507                 if(keep_alive_id != 0) // only cancel if it has been activated
00508                 {
00509                     _event_queue.cancel(keep_alive_id); 
00510                 }               
00511 #ifdef SEND_DEBUG_MESSAGES
00512                 if(outputBuffersAvailable())
00513                 {
00514                     responseString = (char *) malloc(100);
00515                     sprintf(responseString, "\r\nHTTP REQUEST RECEIVED\r\n");
00516                     sendATresponseString(AT_EVENT);
00517                 }
00518 #endif
00519                 dbg_printf(LOG, "before call to send http request \n");
00520                 dbg_printf(LOG, "\r\n[WIFI-MAN] Received HTTPS request...\r\n");
00521                 print_memory_info();
00522                 // disable network interrupts during https request
00523                 network->attach(NULL);
00524 #ifdef USE_EVENTS_FOR_HTTPS_REQUESTS
00525                 
00526                 // Events can be cancelled as long as they have not been dispatched. If the
00527                 // event has already expired, cancel has no side-effects.
00528                 int event_id = _event_queue.call(this, &WiFiManager::createSendHttpsRequest);
00529                 waitForBackgroundTask(6000, 10); // six second timeout
00530 //                backgroundTaskCompleted = false;               
00531 //                int msecCount = 0;
00532 //                int oldChunkNum = chunkNum;
00533 //                while(!backgroundTaskCompleted && msecCount < 6000)
00534 //                {
00535 //                    msecCount+=10;
00536 //                    wait_ms(10);
00537 //                    if(oldChunkNum != chunkNum) // new payload received
00538 //                    {
00539 //                        oldChunkNum = chunkNum;
00540 //                        msecCount = 0;
00541 //                    }
00542 //                }
00543                 if(backgroundTaskCompleted)
00544                 {
00545                     //queueATresponse(AT_INTERNET_CONFIG_RESP);
00546                     result = true;
00547                 }
00548                 else
00549                 {
00550                     //_event_queue.cancel(event_id); 
00551                     result = false;
00552                 }
00553                 backgroundTaskCompleted = false;
00554 #else
00555                 result = createHttpsRequest();
00556 #endif
00557                 if(result == false && outputBuffersAvailable())
00558                 {
00559                     responseString = (char *) malloc(100);
00560                     if(http_result==TLS_CONNECTION_FAILED)
00561                     {
00562                         sprintf(responseString, "\r\nTLS CONNECTION FAILURE\r\n");
00563                     }
00564                     else
00565                     {
00566                         sprintf(responseString, "\r\nHTTP REQUEST FAILED\r\n");
00567                     }
00568                     sendATresponseString(AT_COMMAND_FAILED);
00569                 }
00570                 dbg_printf(LOG, "after call to send http request \n");
00571                 print_memory_info();
00572                 wifiCmd = WIFI_CMD_NONE;
00573                 wifiBusy = 0;
00574                 // enable keep alive after https request completes
00575                 keep_alive_id = _event_queue.call_every(CLOUD_KEEP_ALIVE_INTERVAL, this, &WiFiManager::callInternetKeepAlive);
00576                 // re-enable network interrupts after https request.
00577                 network->attach(callback(this, &WiFiManager::status_callback));
00578                 break;
00579             }            
00580             case WIFI_CMD_TLS_CONNECT:
00581             {
00582                 dbg_printf(LOG, "\r\n[WIFI-MAN] ATTEMPTING TLS CONNECTION\r\n");
00583                 char* hostName = strstr(internet_config->url,"//");
00584                 wifiBusy = 1;
00585                 if(hostName != NULL)
00586                 {
00587                     hostName += 2; 
00588                     //https_connection_active = createTLSconnection(hostName);
00589                     _event_queue.call(this, &WiFiManager::createTLSconnThreadCall, (const char*)hostName);
00590                     waitForBackgroundTask(6000, 10); // six second timeout
00591                     if(backgroundTaskCompleted == false)
00592                     {
00593                         https_connection_active = false;
00594                         queueATresponse(AT_SOCKET_KEEP_ALIVE_FAILED);
00595                         delete socket;
00596                         socket = NULL;
00597                     }
00598                     else
00599                     {
00600                         https_connection_active = true;
00601                     }
00602                 }
00603                 if(fromWiFiCmd == WIFI_CMD_TLS_CONNECT)
00604                 {
00605                     wifiCmd = nextWiFiCmd;
00606                     fromWiFiCmd = WIFI_CMD_NONE;
00607                     nextWiFiCmd = WIFI_CMD_NONE;
00608                 }
00609                 else
00610                 {
00611                     wifiCmd = WIFI_CMD_NONE;
00612                 }
00613                 wifiBusy = 0;
00614                 break;
00615             }
00616             case WIFI_CMD_INTERNET_KEEP_ALIVE:
00617             {
00618                 wifiBusy = 1;
00619                 if(!https_token_valid) // if this is the first time get token
00620                 {
00621                     wifiCmd = WIFI_CMD_NONE;
00622                     fromWiFiCmd = WIFI_CMD_TLS_CONNECT;
00623                     nextWiFiCmd = WIFI_CMD_INTERNET_KEEP_ALIVE;
00624                     setNextCommand(WIFI_CMD_GET_TOKEN);
00625                     break;
00626                 }
00627                 keepSocketAlive();
00628                 wifiCmd = WIFI_CMD_NONE;
00629                 wifiBusy = 0;
00630                 break;
00631             }
00632             case WIFI_CMD_GET_TOKEN:
00633             {
00634                 wifiBusy = 1;                
00635                 _event_queue.call(this, &WiFiManager::createTLSconnThreadCall, AWS_HOST_NAME);
00636                 waitForBackgroundTask(6000, 10); // six second timeout
00637                 if(backgroundTaskCompleted == false)
00638                 {
00639                     queueATresponse(AT_SOCKET_KEEP_ALIVE_FAILED);
00640                     delete socket;
00641                     socket = NULL;
00642                 }
00643                 else
00644                 {
00645                     https_connection_active = false;
00646                     GetCloudAccessToken();
00647                     wifiCmd = WIFI_CMD_NONE;
00648                     setNextCommand(WIFI_CMD_TLS_CONNECT);
00649                     //_event_queue.call_in(ONE_SECOND,this, &WiFiManager::setNextCommand, WIFI_CMD_TLS_CONNECT);
00650                     //wifiCmd = WIFI_CMD_TLS_CONNECT;
00651                 }
00652                 //wifiBusy = 0;
00653                 break;
00654             }
00655             case WIFI_CMD_WIFI_MAC_ADDR:
00656             {
00657                 wifiBusy = 1;
00658                 if(outputBuffersAvailable())
00659                 {
00660                     getWiFiMACaddress();
00661                     sendATresponseString(AT_WIFI_MAC_RESP);
00662                 }
00663                 wifiCmd = WIFI_CMD_NONE;
00664                 wifiBusy = 0;
00665                 break;
00666             }
00667             case WIFI_CMD_SEND_HTTP_REQ:
00668                 break;
00669             default:
00670                 break;
00671         }
00672         wait_ms(WIFI_MAIN_LOOP_WAIT_TIME_MS); // 
00673     }
00674     
00675 }
00676 
00677 void  WiFiManager::createSendHttpsRequest()
00678 {
00679     backgroundTaskCompleted = createHttpsRequest();
00680 }
00681 
00682 
00683 void  WiFiManager::createTLSconnThreadCall(const char * hostName)
00684 {
00685     bool result;
00686     backgroundTaskCompleted = false;
00687     result = createTLSconnection(hostName);
00688     if(result)
00689     {
00690         // update remote peer details after socket connection
00691         updateRemotePeerDetails();
00692         // send socket connection event before proceeding to send https request
00693         // give about 2 ms
00694         sendSocketConnectionEvent();
00695         backgroundTaskCompleted = true;
00696     }
00697 }
00698 void  WiFiManager::waitForBackgroundTask(int timeout_ms, int inc_ms)
00699 {
00700     backgroundTaskCompleted = false;               
00701     int msecCount = 0;
00702     int oldChunkNum = chunkNum;
00703     while(!backgroundTaskCompleted && msecCount < timeout_ms)
00704     {
00705         msecCount+=inc_ms;
00706         wait_ms(inc_ms);
00707         if(oldChunkNum != chunkNum) // new payload received
00708         {
00709             oldChunkNum = chunkNum;
00710             msecCount = 0;
00711         }
00712     }
00713 }
00714 void  WiFiManager::sendATresponseString(at_cmd_resp_t at_cmd)
00715 {
00716     int strLen = strlen(responseString) + 1;
00717     at_data_resp = new at_data_msg_t;
00718     // set string length 
00719     at_data_resp->dataLen = strLen;
00720     memcpy(at_data_resp->buffer, responseString, strLen);
00721     free(responseString);
00722     responseString = NULL;
00723     // package and send on wifi data queue    
00724     at_data_resp->at_resp = at_cmd;
00725     bool queueResult = true;
00726     int wait_count = 0;
00727     do
00728     {
00729         if(!queueResult){
00730             wait_count+=10;
00731             dbg_printf(LOG, "ATCMD Queue full waiting %d ms so far...\n", wait_count);
00732             wait_ms(10);
00733         }
00734         queueResult = queueWiFiDataResponse(*at_data_resp);
00735     }while(queueResult == false && wait_count<QUEUE_WAIT_TIMEOUT_MS);
00736     delete at_data_resp;
00737     at_data_resp = NULL;
00738 }                                            
00739 
00740 
00741 void  WiFiManager::sendATresponseBytes(at_cmd_resp_t at_cmd, int len)
00742 {
00743     at_data_resp = new at_data_msg_t;
00744     // set string length 
00745     at_data_resp->dataLen = len;
00746     memcpy(at_data_resp->buffer, responseBytes, len);
00747     delete responseBytes;
00748     responseBytes = NULL;
00749     // package and send on wifi data queue    
00750     at_data_resp->at_resp = at_cmd;
00751     bool queueResult = true;
00752     int wait_count = 0;
00753     do
00754     {
00755         if(!queueResult){
00756             wait_count+=10;
00757             wait_ms(10);
00758             dbg_printf(LOG, "ATCMD Queue full waited %d ms so far...\n", wait_count);
00759         }
00760         queueResult = queueWiFiDataResponse(*at_data_resp);
00761     }while(queueResult == false && wait_count<QUEUE_WAIT_TIMEOUT_MS);
00762     delete at_data_resp;
00763     at_data_resp = NULL;
00764     dbg_printf(LOG, "[WIFI-MAN] sendATresponseBytes completed successfully\r\n");
00765 }                                            
00766 
00767 
00768 
00769 bool  WiFiManager::dequeueWiFiCommands(){
00770     if(wifiCmd != WIFI_CMD_NONE || wifiBusy!=0) return false; // busy
00771     osEvent evt = _aT2WiFiCmdQueue->get(0);
00772     if(evt.status == osEventMessage){
00773         wifi_cmd_message_t *cmd = (wifi_cmd_message_t*)evt.value.p;
00774         setNextCommand(cmd->wifi_cmd);
00775 #ifndef USE_MALLOC_FOR_COMMAND_MEMORY_POOL
00776         _aT2WiFimPool->free(cmd);
00777         cmd = NULL;
00778 #else
00779         free(cmd);
00780         cmd = NULL;
00781 #endif
00782     }
00783     return true;
00784 }
00785 
00786 
00787 bool WiFiManager::dequeueATdataResponse(){
00788     if(wifiCmd != WIFI_CMD_NONE || wifiBusy!=0) return false; // busy
00789     osEvent evt = _aT2WiFiDataQueue->get(0);
00790     if(evt.status == osEventMessage){
00791         data_msg = (wifi_data_msg_t*)evt.value.p;
00792         setNextCommand(data_msg->wifi_cmd);
00793         //_wiFi2ATDatamPool->free(data_msg);
00794     }
00795     return true;
00796 }
00797 
00798 
00799 bool WiFiManager::setNextCommand(wifi_cmd_t cmd)
00800 {
00801     dbg_printf(LOG, "\n [WIFI-MAN] About to set next WiFi manager command to %d\n", cmd);
00802     if(wifiCmd == WIFI_CMD_NONE){
00803         wifiCmd = cmd;
00804         return true; // success
00805     }
00806     dbg_printf(LOG, "\n [WIFI-MAN] Busy : current state = %d \n", wifiCmd);
00807     return false; // wiFiManager busy
00808 }
00809 
00810 const char * WiFiManager::sec2str(nsapi_security_t sec)
00811 {
00812     switch (sec) {
00813         case NSAPI_SECURITY_NONE:
00814             return "None";
00815         case NSAPI_SECURITY_WEP:
00816             return "WEP";
00817         case NSAPI_SECURITY_WPA:
00818             return "WPA";
00819         case NSAPI_SECURITY_WPA2:
00820             return "WPA2";
00821         case NSAPI_SECURITY_WPA_WPA2:
00822             return "WPA/WPA2";
00823         case NSAPI_SECURITY_UNKNOWN:
00824         default:
00825             return "Unknown";
00826     }
00827 }
00828 
00829 
00830 nsapi_size_or_error_t WiFiManager::scanNetworks()
00831 {
00832     getWiFiInstance();
00833     if(network == NULL)
00834     {
00835         dbg_printf(LOG, "\n [WIFI-MAN] Error instantiating WiFi!! \n");
00836         return 0;
00837     }
00838     //nsapi_error_t error;
00839     dbg_printf(LOG, "\n [WIFI-MAN] About to start scan for WiFi networks\n");
00840     lastScanCount = network->scan(NULL, 0);
00841     dbg_printf(LOG, "\n [WIFI-MAN] Scan for WiFi networks completed - \n");
00842     return lastScanCount;
00843 }
00844 
00845 
00846 //nsapi_size_or_error_t WiFiManager::getAvailableAPs(WiFiAccessPoint * res, 
00847 //                                                   nsapi_size_t ncount)
00848 nsapi_size_or_error_t WiFiManager::getAvailableAPs(nsapi_size_t ncount)
00849 {
00850     getWiFiInstance();
00851     if(network == NULL)
00852     {
00853         dbg_printf(LOG, "\n [WIFI-MAN] Error instantiating WiFi!! \n");
00854         return 0;
00855     }
00856     WiFiAccessPoint       *ap;
00857     nsapi_size_or_error_t count;
00858     count = ncount;
00859     if (count <= 0) {
00860         dbg_printf(LOG, "[WIFI-MAN] scan() failed with return value: %d\n", count);
00861         return 0;
00862     }
00863     /* Limit number of network arbitrary to 15 */
00864     count = count < 15 ? count : 15;
00865     ap = new WiFiAccessPoint[count];
00866     count = network->scan(ap, count);
00867     if (count <= 0) {
00868         dbg_printf(LOG, "[WIFI-MAN] scan() failed with return value: %d\n", count);
00869         return 0;
00870     }
00871 
00872     for (int i = 0; i < count; i++) {
00873         dbg_printf(LOG, "[WIFI-MAN]: %s secured: %s BSSID: %hhX:%hhX:%hhX:%hhx:%hhx:%hhx RSSI: %hhd Ch: %hhd\n", ap[i].get_ssid(),
00874                sec2str(ap[i].get_security()), ap[i].get_bssid()[0], ap[i].get_bssid()[1], ap[i].get_bssid()[2],
00875                ap[i].get_bssid()[3], ap[i].get_bssid()[4], ap[i].get_bssid()[5], ap[i].get_rssi(), ap[i].get_channel());
00876     }
00877     dbg_printf(LOG, "[WIFI-MAN]  %d networks available.\n", count);
00878 
00879     delete[] ap;
00880     return count;
00881 }
00882 
00883 
00884 void WiFiManager::set_WIFI_CONFIG()
00885 {
00886     wifi_config_t *wifi_cfg= (wifi_config_t *) data_msg->buffer;
00887     if(wifi_cfg->ssid[0] != NULL)set_WIFI_SSID(wifi_cfg->ssid);
00888     if(wifi_cfg->pass[0] != NULL)set_WIFI_PASSWORD(wifi_cfg->pass);
00889     if(wifi_cfg->security != NSAPI_SECURITY_UNKNOWN)set_WIFI_SECURITY(wifi_cfg->security);
00890     free_DataMsg();
00891 }
00892 
00893 void WiFiManager::set_WIFI_SSID(char * wifi_ssid)
00894 {
00895     strcpy(wifi_config->ssid, wifi_ssid);
00896     dbg_printf(LOG, "[WIFI-MAN]  wifi_ssid set to %s\n", wifi_config->ssid);
00897     https_connection_active = false; // reset whenever any of the security credentials change
00898     delete socket;
00899 }
00900 
00901 
00902 void WiFiManager::set_WIFI_PASSWORD(char * wifi_pass)
00903 {
00904     strcpy(wifi_config->pass, wifi_pass);
00905     dbg_printf(LOG, "[WIFI-MAN]  wifi_pass set to %s\n", "****************");
00906     https_connection_active = false; // reset whenever any of the security credentials change
00907     delete socket;
00908 }
00909 
00910 
00911 void WiFiManager::set_WIFI_SECURITY(nsapi_security_t wifi_security)
00912 {
00913     wifi_config->security = wifi_security;
00914     dbg_printf(LOG, "[WIFI-MAN]  wifi_security set to %s\n", sec2str(wifi_config->security));
00915     https_connection_active = false; // reset whenever any of the security credentials change
00916     delete socket;
00917 }
00918 
00919 void WiFiManager::gethostbyname()
00920 {
00921     nsapi_value_or_error_t value_or_error;
00922 #ifdef DNANUDGE_DEBUG
00923     SocketAddress * addr = new SocketAddress;
00924     bool res;
00925     res = addr->set_ip_address("8.8.8.8");
00926     if(res)
00927     {
00928         dbg_printf(LOG, "[WIFI-MAN] added ip address %s\r\n", addr->get_ip_address());
00929     }
00930     else
00931     {
00932         dbg_printf(LOG, "[WIFI-MAN] Error adding ip address \r\n");
00933     }
00934     network->add_dns_server(*addr);
00935 #endif
00936     char * serverAddress = new char[100];
00937     char *p = strstr(internet_config->url, "//");
00938     if(p != NULL && use_full_hostname == false)
00939     {
00940         strcpy(serverAddress,p+2);
00941     }
00942     else
00943     {
00944         strcpy(serverAddress,internet_config->url);
00945     }
00946     value_or_error = network->gethostbyname_async(serverAddress, 
00947                                          callback(this, &WiFiManager::gethostbyname_callback), 
00948                                          NSAPI_UNSPEC);
00949                                                                                   
00950     if(value_or_error >= NSAPI_ERROR_OK) // success
00951     {
00952         dbg_printf(LOG, "[WIFI-MAN] hostname translation successful value_or_error = %d\r\n", value_or_error);
00953         //strcpy(responseString, UDDRP_WRITE_OK);
00954         //printBufferInHex(responseBytes, HOSTNAME_RESPONSE_LEN);
00955         //sendATresponseBytes(CONNECT_EVENT, HOSTNAME_RESPONSE_LEN);
00956     }
00957     else if(outputBuffersAvailable()) // -ve number means error
00958     {
00959         responseString = (char *) malloc(20);
00960         dbg_printf(LOG, "[WIFI-MAN] hostname translation failed\r\n");
00961         strcpy(responseString, UDDRP_ERROR);
00962         sendATresponseString(AT_COMMAND_FAILED);
00963     }
00964 
00965 }
00966 
00967 void WiFiManager::set_internet_config()
00968 {
00969     internet_config_t *internet_cfg  = (internet_config_t *) data_msg->buffer;
00970     internet_config->peer_id          = internet_cfg->peer_id;
00971     strncpy(internet_config->url,internet_cfg->url, strlen(internet_cfg->url)+1);
00972     internet_config->connectionScheme = internet_cfg->connectionScheme;
00973     free_DataMsg();
00974     dbg_printf(LOG, "[WIFI MAN] Internet configuration setup completed\n"); 
00975     dbg_printf(LOG, "peer_id = %1d, url = %s, connScheme = %1d\n", internet_config->peer_id, 
00976                                                       internet_config->url, 
00977                                                       internet_config->connectionScheme);
00978     if(https_connection_active)
00979     {
00980         https_connection_active = false; // reset whenever any of the security credentials change
00981         socket->close();    // close socket before deleting memory    
00982         delete socket;
00983         socket = NULL;
00984     }
00985     _event_queue.call_in(10, this, &WiFiManager::gethostbyname);
00986 }
00987 
00988 
00989 
00990 void WiFiManager::getNetworkStatus(){
00991     
00992     responseString = (char *) malloc(MAX_RESPONSE_STRING_LEN);
00993     net_stat_id_t status_id;
00994     char * nextStrPtr = responseString;
00995     for(int i=0; i< NumNetworkStatus;i++){
00996         status_id = netStatusIds[i]; // get current status id
00997         switch(status_id){
00998             case IF_HW_ADDRESS:
00999                 sprintf(nextStrPtr, "\r\n%s%d,%d,%s\r\n", NETWORK_STATUS, 
01000                                                               WIFI_CHANNEL,
01001                                                               status_id,
01002                                                               network->get_mac_address());
01003                 break;
01004             case NETWORK_IF_STATUS:
01005                 sprintf(nextStrPtr, "\r\n%s%d,%d, %d\r\n", NETWORK_STATUS, 
01006                                                            WIFI_CHANNEL,
01007                                                            status_id,
01008                                                            (uint8_t)is_connected);
01009                 break;
01010             case INTERFACE_TYPE:
01011                 sprintf(nextStrPtr, "\r\n%s%d,%d,%d\r\n", NETWORK_STATUS, 
01012                                                               WIFI_CHANNEL,
01013                                                               status_id,
01014                                                               WIFI_STATION);
01015                 break;
01016             case IPv4_ADDRESS:
01017                 sprintf(nextStrPtr, "\r\n%s%d,%d,%s\r\n", NETWORK_STATUS, 
01018                                                               WIFI_CHANNEL,
01019                                                               status_id,
01020                                                               network->get_ip_address());
01021                 break;
01022             case SUBNET_MASK:
01023                 sprintf(nextStrPtr, "\r\n%s%d,%d,%s\r\n", NETWORK_STATUS, 
01024                                                               WIFI_CHANNEL,
01025                                                               status_id,
01026                                                               network->get_netmask());
01027                 break;
01028             case GATEWAY_ADDRESS:
01029                 sprintf(nextStrPtr, "\r\n%s%d,%d,%s\r\n", NETWORK_STATUS, 
01030                                                               WIFI_CHANNEL,
01031                                                               status_id,
01032                                                               network->get_gateway());
01033                 break;
01034             case PRIMARY_DNS_SERVER:
01035                 sprintf(nextStrPtr, "\r\n%s%d,%d,%s\r\n", NETWORK_STATUS, 
01036                                                               WIFI_CHANNEL,
01037                                                               status_id,
01038                                                               DEFAULT_DNS_ADDRESS);
01039                 break;
01040             case SECONDARY_DNS_SERVER:
01041                 sprintf(nextStrPtr, "\r\n%s%d,%d,%s\r\n", NETWORK_STATUS, 
01042                                                               WIFI_CHANNEL,
01043                                                               status_id,
01044                                                               DEFAULT_DNS_ADDRESS);
01045                 break;
01046             case IPv6_ADDRESS:
01047                 sprintf(nextStrPtr, "\r\n%s%d,%d,::\r\n", NETWORK_STATUS, 
01048                                                               WIFI_CHANNEL,
01049                                                               status_id);
01050                 break;
01051             default:
01052                 sprintf(nextStrPtr, "\r\n%s,::\r\n", NETWORK_STATUS);
01053                 break;
01054         }
01055         nextStrPtr += strlen(nextStrPtr) ; // progress to end of current string
01056     }
01057     sprintf(nextStrPtr, "%s", UDDRP_WRITE_OK);
01058 }
01059 
01060 void WiFiManager::getWiFiMACaddress()
01061 {
01062     char * mp = new char[20];
01063     sscanf(network->get_mac_address(),"%02s:%2s:%2s:%2s:%2s:%2s",&mp[0],&mp[2],&mp[4],&mp[6],&mp[8],&mp[10]);
01064     responseString = (char *) malloc(100);
01065     
01066     sprintf(responseString, "\r\n%s%d,%sOK\r\n", LOCAL_ADDRESS_RESP, 
01067                                                  WIFI_IF_ID,
01068                                                  mp);
01069     delete mp;
01070 }
01071 
01072 
01073 void WiFiManager::getWiFiStatus(){
01074     
01075     responseString = (char *) malloc(MAX_RESPONSE_STRING_LEN);
01076     wifi_stat_id_t status_id;
01077     char * nextStrPtr = responseString;
01078     for(int i=0; i< NumWiFiStatus;i++){
01079         status_id = wifiStatusIds[i]; // get current status id
01080         switch(status_id){
01081             case WIFI_SSID:
01082                 sprintf(nextStrPtr, "\r\n%s%d,%s\r\n", WIFI_NETWORK_STATUS, 
01083                                                        status_id,
01084                                                        wifi_config->ssid);
01085                 break;
01086             case WIFI_BSSID:
01087                 sprintf(nextStrPtr, "\r\n%s%d,%s\r\n", WIFI_NETWORK_STATUS, 
01088                                                        status_id,
01089                                                        network->get_mac_address());
01090                 break;
01091             case WIFI__CURRENT_CHANNEL:
01092                 sprintf(nextStrPtr, "\r\n%s%d,%d\r\n", WIFI_NETWORK_STATUS, 
01093                                                        status_id,
01094                                                        DEFAULT_WIFI_CHANNEL);
01095                 break;
01096             case WIFI_STA_STATUS:
01097                 sprintf(nextStrPtr, "\r\n%s%d,%d\r\n", WIFI_NETWORK_STATUS, 
01098                                                        status_id,
01099                                                        (uint8_t)is_connected);
01100                 break;
01101             case WIFI_RSSI:
01102                 sprintf(nextStrPtr, "\r\n%s%d,%d\r\n", WIFI_NETWORK_STATUS, 
01103                                                        status_id,
01104                                                        network->get_rssi());
01105                 break;
01106             default:
01107                 sprintf(nextStrPtr, "\r\n%s,::\r\n", WIFI_NETWORK_STATUS);
01108                 break;
01109         }
01110         nextStrPtr += strlen(nextStrPtr) ; // progress to end of current string
01111     }
01112     sprintf(nextStrPtr, "%s", UDDRP_WRITE_OK);
01113 }
01114 
01115 
01116 void WiFiManager::free_DataMsg()
01117 {
01118     // free memory after processing
01119     _aT2WiFiDatamPool->free(data_msg);
01120     data_msg = NULL;
01121 }
01122 
01123 
01124 
01125 void WiFiManager::status_callback(nsapi_event_t status, intptr_t param)
01126 {
01127     dbg_printf(LOG, "[WIFI-MAN] about to call status_callback_event... \r\n");
01128     _event_queue.call_in(50, this, &WiFiManager::status_callback_event, status, param);
01129 }
01130 void WiFiManager::status_callback_event(nsapi_event_t status, intptr_t param)
01131 {
01132     switch(param) {
01133         case NSAPI_STATUS_LOCAL_UP:
01134             dbg_printf(LOG, "[WIFI-MAN] Local IP address set!\r\n");
01135             dbg_printf(LOG, "[WIFI-MAN] IP address: %s\n", network->get_ip_address());
01136             break;
01137         case NSAPI_STATUS_GLOBAL_UP:
01138             dbg_printf(LOG, "Global IP address set!\r\n");
01139             dbg_printf(LOG, "[WIFI-MAN] IP address: %s\n", network->get_ip_address());
01140             dbg_printf(LOG, "[WIFI-MAN] Connected to the network %s\n", wifi_config->ssid);
01141             if(outputBuffersAvailable())
01142             {
01143                 responseString = (char *) malloc(MAX_RESPONSE_STRING_LEN); 
01144                 sprintf(responseString, "\r\n%s%d,%s,%d\r\n", WIFI_LINK_ENABLED, 
01145                                                               WIFI_CHANNEL,
01146                                                               network->get_mac_address(),
01147                                                               DEFAULT_WIFI_CHANNEL);
01148                 
01149                 wifiBusy = 0;
01150                 is_connected = true;
01151             }
01152             break;
01153         case NSAPI_STATUS_DISCONNECTED:
01154             dbg_printf(LOG, "No connection to network!\r\n");
01155             dbg_printf(LOG, "\n [WIFI-MAN] No connection to network!\n");
01156             if(outputBuffersAvailable())
01157             {
01158                 responseString = (char *) malloc(100);
01159                 sprintf(responseString, "\r\n%s%d,5\r\n", WIFI_LINK_DISABLED, WIFI_CHANNEL);
01160                 //sendATresponseString(AT_EVENT);
01161             }
01162             wifiBusy = 0;
01163             is_connected = false;
01164             break;
01165         case NSAPI_STATUS_CONNECTING:
01166             dbg_printf(LOG, "Connecting to network!\r\n");
01167             break;
01168         default:
01169             dbg_printf(LOG, "Not supported");
01170             break;
01171     }
01172 }
01173 
01174 
01175 
01176    
01177 nsapi_error_t WiFiManager::connect()
01178 {
01179     getWiFiInstance();
01180     if(network == NULL)
01181     {
01182         dbg_printf(LOG, "\n [WIFI-MAN] Error instantiating WiFi!! \n");
01183         return 0;
01184     }
01185     nsapi_error_t error;
01186     dbg_printf(LOG, "\n [WIFI-MAN] About to connect to WiFi network\n");
01187     network->attach(callback(this, &WiFiManager::status_callback));
01188     error = network->set_blocking(false);
01189     if(error)
01190     {
01191         dbg_printf(LOG, "\n [WIFI-MAN] Could not set non-blocking mode for Wifi -- aborting!! - \n");
01192         return error;
01193     }
01194     dbg_printf(LOG, "[WIFI-MAN] Connecting to network ssid = %s passwd = %s  security = %s \r\n", 
01195                                                     wifi_config->ssid, 
01196                                                     "****************", 
01197                                                     sec2str(wifi_config->security));
01198     error = network->connect(wifi_config->ssid,
01199                              wifi_config->pass,
01200                              wifi_config->security);
01201     dbg_printf(LOG, "[WIFI-MAN] network->connect called. error = %d\r\n", error);
01202     return error;
01203 }
01204 
01205 void WiFiManager::processGetHostByNameResult(nsapi_error_t result, SocketAddress *address)
01206 {
01207     
01208     dbg_printf(LOG, "gethostbyname_callback called... result = %d \r\n", result);
01209     print_memory_info();
01210     if(outputBuffersAvailable())
01211     {
01212         responseBytes = new uint8_t[HOSTNAME_RESPONSE_LEN]; //malloc(HOSTNAME_RESPONSE_LEN);
01213         int i = 0;
01214         responseBytes[i++] = IPv4_CONNECTION; // connect type IPv4
01215         responseBytes[i++] = TCP_PROTOCOL; // Protocol = TCP
01216         if(is_connected && result>=0)
01217         {
01218             memcpy(&responseBytes[i], address->get_ip_bytes(), 4); // remote IPv4 address
01219             strcpy(internet_config->remote_IPv4Address, address->get_ip_address());
01220             i +=4;
01221             uint16_t port = address->get_port();
01222             internet_config->remote_port = port;
01223             memcpy(&responseBytes[i], &port, 2); // remote IPv4 port #
01224             i +=2;
01225             // local IPv4 address
01226             int ipAddr[4];
01227             strcpy(internet_config->local_IPv4Address, network->get_ip_address());
01228             sscanf(internet_config->local_IPv4Address, "%d.%d.%d.%d", &ipAddr[0], &ipAddr[1], 
01229                                                                      &ipAddr[2], &ipAddr[3]);
01230             responseBytes[i++] = (uint8_t) ipAddr[0];
01231             responseBytes[i++] = (uint8_t) ipAddr[1];
01232             responseBytes[i++] = (uint8_t) ipAddr[2];
01233             responseBytes[i++] = (uint8_t) ipAddr[3];
01234             // local port number
01235             responseBytes[i++] = 0;
01236             responseBytes[i]   = 0;
01237             printBufferInHex(responseBytes, HOSTNAME_RESPONSE_LEN);
01238             sendATresponseBytes(CONNECT_EVENT, HOSTNAME_RESPONSE_LEN);
01239         }
01240         else
01241         {
01242             // if unconnected set ip and port to zeroes
01243             memset(&responseBytes[i], 0x00, 6);
01244             delete responseBytes;
01245             dbg_printf(LOG, "\r\nHOSTNAME TRANSLATION FAILURE : error code = %d \r\n", result);
01246             if(responseString == NULL)
01247             {
01248                 responseString = (char *) malloc(100);
01249                 sprintf(responseString, "\r\nHOSTNAME TRANSLATION FAILURE : error code = %d \r\n", result);
01250                 sendATresponseString(AT_EVENT);
01251             }
01252             use_full_hostname = not use_full_hostname;
01253        }
01254        wifiBusy = 0;
01255        backgroundTaskCompleted = true;
01256    }
01257     
01258 }
01259 
01260 void WiFiManager::gethostbyname_callback(nsapi_error_t res, SocketAddress *addr)
01261 {
01262     nsapi_error_t result = res;
01263     SocketAddress *address = new SocketAddress;
01264     address = addr;
01265     _event_queue.call(this, &WiFiManager::processGetHostByNameResult, 
01266                                     result, address);
01267     
01268 #ifdef DNANUDGE_DEBUG
01269     callback_semaphore.release();
01270 #endif
01271 }   
01272 
01273 void WiFiManager::sendSocketConnectionEvent()
01274 {
01275     // 
01276     responseString = (char *) malloc(MAX_RESPONSE_STRING_LEN); 
01277     sprintf(responseString, "\r\n%s%d,%d,%d,%s,%d,%s,%d\r\n", PEER_CONNECTED_URC, 
01278                                                               IP_PEER_HANDLE,
01279                                                               IPv4_CONNECTION,
01280                                                               TCP_PROTOCOL,
01281                                                               internet_config->local_IPv4Address,
01282                                                               DEFAULT_LOCAL_PORT,
01283                                                               internet_config->remote_IPv4Address,
01284                                                               internet_config->remote_port);
01285     sendATresponseString(AT_EVENT);
01286 }
01287 
01288 
01289 nsapi_error_t WiFiManager::disconnect()
01290 {
01291     nsapi_error_t error;
01292     error = network->disconnect();
01293     if(error < 0)
01294     {
01295         responseString = (char *) malloc(100); 
01296         sprintf(responseString, "%s", UDDRP_ERROR);
01297         sendATresponseString(AT_EVENT);
01298     }
01299     return error;
01300 }
01301 
01302 #define MIX_HDR_AND_BODY
01303 void WiFiManager::sendResponseDownloadData(at_cmd_resp_t at_cmd, const uint8_t * buf, int bufLen)
01304 {    
01305 
01306     at_data_resp = new at_data_msg_t;
01307     at_data_resp->at_resp = at_cmd;
01308     size_t bufSize = sizeof(at_data_resp->buffer);
01309     int pos = 0;
01310     at_data_resp->dataLen = 0;
01311     bool queueResult = true;
01312     int hdrLen = 0;
01313     int wait_count = 0;
01314     do {
01315         if(!queueResult){
01316             wait_count++;
01317             dbg_printf(LOG, "[WIFI-MAN] ATCMD Queue full waiting %d ms so far...\n", wait_count*10);
01318             wait_ms(10);
01319         }
01320         else {            
01321             if(http_response_hdr_sent == false && chunkNum==1){ // only do this for first chunk
01322                 bool status = copyResponseHdr2Queue(buf);  
01323                 if(status == true){
01324                     dbg_printf(LOG, "[WIFI-MAN] Http Response header copied to response buffer [bytes = %d] \r\n",at_data_resp->dataLen);
01325                     hdrLen =  at_data_resp->dataLen;
01326                     http_response_hdr_sent = true;  
01327                 } 
01328                 else {     
01329                     dbg_printf(LOG, "[WIFI-MAN] Http Response header copy failed\r\n");
01330                 }
01331             }
01332             int cpyLen = (bufLen - pos) > bufSize? bufSize : (bufLen - pos) ;
01333             dbg_printf(LOG, "[WIFI-MAN] Http Response body [bytes = %d] \r\n",cpyLen);
01334             at_data_resp->dataLen += cpyLen;
01335             memcpy(&at_data_resp->buffer[hdrLen], &buf[pos], cpyLen);
01336             dbg_printf(LOG, "[WIFI-MAN] Http Response header and body copied to response buffer [bytes = %d] \r\n",at_data_resp->dataLen);
01337         }
01338         queueResult = queueWiFiDataResponse(*at_data_resp);
01339         if(queueResult){ 
01340             pos+= at_data_resp->dataLen;
01341             at_data_resp->dataLen = 0;
01342             hdrLen = 0; 
01343         }
01344     }while(queueResult ==  false || pos < bufLen);
01345     dbg_printf(LOG, "[WIFI-MAN] response data queued - deleting data memory\r\n");
01346     delete at_data_resp;
01347     at_data_resp = NULL;
01348 }
01349 
01350 bool WiFiManager::copyResponseHdr2Queue(const uint8_t * buf)
01351 {
01352     const char *arbPtr = (const char *)buf - MAX_HTTP_HDR_LEN;
01353     const char *hdrPtr;
01354     int len;
01355     bool hdrFound = false;
01356     int i;
01357     for(i=0;i<(MAX_HTTP_HDR_LEN-50);i++)
01358     {
01359         // get location of start of the http header string
01360         hdrPtr = strstr(&arbPtr[i], HTTP_HEADER_START_LINE);
01361         len = strlen(HTTP_HEADER_START_LINE);
01362         // validate that header string
01363         if((strstr(&arbPtr[i+len], HTTP_HEADER_START_LINE) == NULL ||
01364            (strstr(&arbPtr[i+len], HTTP_HEADER_START_LINE) > (const char*)buf)) && //
01365             strstr(&arbPtr[i+len], HTTP_HEADER_CONTENT_TYPE) != NULL &&
01366             strstr(&arbPtr[i+len], HTTP_HEADER_CONTENT_LEN) != NULL  &&
01367             hdrPtr != NULL)
01368         {
01369             hdrFound = true;
01370             break;
01371         }
01372     }
01373     // calculate header length 
01374     int hdrLen = (const char*) buf -hdrPtr;
01375     // copy header 
01376     memcpy(at_data_resp->buffer, (const uint8_t *) hdrPtr, hdrLen);
01377     dbg_printf(LOG, "[i = %d] This is the header\r\n%s\r\n", i, hdrPtr);
01378     if(hdrFound == false)
01379     {
01380         dbg_printf(LOG, "[WIFI-MAN] copy failed: HTTP header not found!!\r\n");
01381         return false;
01382     }
01383     at_data_resp->dataLen = hdrLen;
01384     return true;
01385 }
01386 
01387 void WiFiManager::return_response(HttpResponse* res) {
01388     
01389     at_data_resp = new at_data_msg_t;
01390     int numChars = 0;
01391     // create message pointer for response header generation
01392     char * msgPtr = (char *)at_data_resp->buffer;
01393     // do status line
01394     numChars = sprintf(msgPtr, "HTTP/1.1 %d %s\r\n", res->get_status_code(), res->get_status_message().c_str());
01395     msgPtr += numChars;
01396     for (size_t ix = 0; ix < res->get_headers_length(); ix++) {
01397         numChars = sprintf(msgPtr, "%s: %s\r\n", 
01398                            res->get_headers_fields()[ix]->c_str(), 
01399                            res->get_headers_values()[ix]->c_str());
01400         msgPtr += numChars;
01401     }
01402     numChars = sprintf(msgPtr, "\r\n\r\n");
01403     msgPtr += numChars;
01404     // print out generated header
01405     dbg_printf(LOG, "[WiFi MAN] generated response header:\n");
01406     dbg_printf(LOG, "%s\r\n", (char *)at_data_resp->buffer);
01407     // calculate header length 
01408     at_data_resp->dataLen = (msgPtr - (char *)at_data_resp->buffer);
01409     
01410     // package and send on wifi data queue    
01411     at_data_resp->at_resp = AT_HTTPS_RESP;
01412     bool queueResult = true;
01413     int wait_count = 0;
01414     do
01415     {
01416         if(!queueResult){
01417             wait_count++;
01418             dbg_printf(LOG, "ATCMD Queue full waiting %d ms so far...\n", wait_count*10);
01419             wait_ms(10);
01420         }
01421         queueResult = queueWiFiDataResponse(*at_data_resp);
01422     }while(queueResult == false);
01423     delete at_data_resp;
01424     at_data_resp = NULL;
01425 }
01426 
01427 
01428 void WiFiManager::printBufferInHex(const uint8_t *buf, int pLen)
01429 {
01430     print_debug_hex(buf, pLen);
01431 }
01432 
01433 //#define TRY_PRINTF
01434 
01435 void WiFiManager::body_callback(const char *at, uint32_t length) {    
01436     dbg_printf(LOG, "\n Chunked response: Chunk %d : Total Bytes = %d\n", chunkNum , length);
01437     chunkNum++;
01438     dbg_printf(LOG, "This is the start when response is excluded\r\n%s\r\nend of packet \r\n", at);
01439     if(http_response == NULL)
01440     {
01441         dbg_printf(LOG, "[WIFI-MAN] response pointer NULL!!\r\n");
01442     }
01443     else
01444     {
01445         dbg_printf(LOG, "[WIFI-MAN] response pointer NULL not!!\r\n");
01446     }
01447 #ifdef SEND_DEBUG_MESSAGES
01448     if(responseString == NULL && chunkNum==1)
01449     {
01450         responseString = (char *) malloc(100);
01451         sprintf(responseString, "\r\nHTTPS BODY CALLBACK RECEIVED:: length= %d\r\n", length);
01452         sendATresponseString(AT_EVENT);
01453     }
01454 #endif
01455     sendResponseDownloadData(AT_HTTPS_RESP_DOWNLOAD, (uint8_t *)at, length);
01456 }
01457 
01458 //#define ENABLE_MBED_TRACE
01459 bool WiFiManager::createTLSconnection(const char * hostName)
01460 {
01461 #ifdef ENABLE_MBED_TRACE
01462     mbed_trace_init();
01463 #endif
01464     socket = new TLSSocket();
01465     nsapi_error_t r;
01466     // make sure to check the return values for the calls below (should return NSAPI_ERROR_OK)
01467     r = socket->open(network);
01468     if(r != NSAPI_ERROR_OK)
01469     { 
01470         dbg_printf(LOG, "TLS open failed!!\n");
01471         return false;
01472     }
01473     dbg_printf(LOG, "TLS open passed!!\n");
01474     r = socket->set_root_ca_cert(SSL_CA_PEM);
01475     if(r != NSAPI_ERROR_OK)
01476     { 
01477         dbg_printf(LOG, "TLS set_root_ca_cert failed!!\n");
01478         socket->close();
01479         dbg_printf(LOG, "closing TLS socket!!\n");
01480         return false;
01481     }
01482     dbg_printf(LOG, "TLS set_root_ca_cert passed!!\n");
01483     int start_ms = _event_queue.tick();
01484     int elapsed_ms;
01485     do{
01486         r = socket->connect(hostName, 443);
01487         elapsed_ms = _event_queue.tick() - start_ms;
01488         if(r == NSAPI_ERROR_OK)
01489         { 
01490             dbg_printf(LOG, "TLS connection successful for https site :  %s"
01491                             " \r\n[TLS conn elapsed_ms = %d]\n", hostName, elapsed_ms);
01492             return true;
01493         }
01494     }while(elapsed_ms < TLS_RETRY_TIMEOUT_MS);
01495     char errstr[100];
01496     mbedtls_strerror(r, errstr, 100);
01497     dbg_printf(LOG, "TLS connect failed (err = %d) for hostname '%s' -- ERROR = %s !!\n", r, hostName, errstr);
01498     socket->close();
01499     return false;
01500 }
01501 
01502 
01503 void WiFiManager::updateRemotePeerDetails()
01504 {
01505     dbg_printf(LOG, "Updating internet_config... \r\n");
01506     nsapi_error_t error;
01507     SocketAddress * address = new SocketAddress;
01508     error = socket->getpeername(address);
01509     if(error>=0)   
01510     {
01511         strcpy(internet_config->remote_IPv4Address, address->get_ip_address());
01512         uint16_t port = address->get_port();
01513         internet_config->remote_port = port;
01514     }
01515     else  
01516     {
01517         strcpy(internet_config->remote_IPv4Address, "");
01518         internet_config->remote_port = 0;
01519     }
01520     delete address;
01521 }
01522 
01523 
01524 void WiFiManager::sendDebugMessage()
01525 {
01526 #ifdef SEND_HTTPS_DEBUG_MESSAGES
01527     sendATresponseString(AT_EVENT);
01528     wait_ms(100);
01529 #else
01530     free(responseString);
01531 #endif
01532 }
01533 #define TESTING_HTTPS
01534 
01535 //#define DONT_USE_TLS_SOCKET
01536 bool WiFiManager::createHttpsRequest()
01537 {
01538     int  starttime;
01539     int stoptime;
01540     // reset chunk #;
01541     chunkNum = 0;
01542     http_response_hdr_sent = false;
01543     dbg_printf(LOG, "\n[WIFI MAN] Http Request received:\n");
01544     http_req_cfg = (http_request_t *) data_msg->buffer;
01545 #ifdef FULL_DEBUG_ENABLED
01546     dbg_printf(LOG, "\n[WIFI MAN] uri = %s\n", http_req_cfg->request_URI);
01547     dbg_printf(LOG, "\n[WIFI MAN] internet cfg url = %s\n", internet_config->url);
01548 #endif
01549     char full_url[100];
01550     char host[60] ;
01551     strncpy(full_url,internet_config->url, strlen(internet_config->url)+1);
01552     //strncpy(host,http_req_cfg->hostName, strlen(http_req_cfg->hostName)+1);
01553     char *eu = strstr(internet_config->url,HTTPS_URL_PREFIX);
01554     if(eu == NULL)
01555         eu = internet_config->url;
01556     else
01557         eu += strlen(HTTPS_URL_PREFIX);
01558     char *eu2 = strstr(eu, "/"); // find the api path
01559     int hLen = eu2 != NULL ? eu2-eu-1:  strlen(eu);
01560         
01561     
01562     strncpy(host,eu, hLen+1);
01563     strncat(full_url, http_req_cfg->request_URI, strlen(http_req_cfg->request_URI)+1);
01564 #ifdef FULL_DEBUG_ENABLED
01565     dbg_printf(LOG, "\n[WIFI MAN] server host name = %s\n", host);
01566     dbg_printf(LOG, "\n[WIFI MAN] server url+uri = %s\n", full_url);
01567     dbg_printf(LOG, "\n[WIFI MAN] Host = %s\n", http_req_cfg->hostName);
01568     dbg_printf(LOG, "\n[WIFI MAN] Accept = %s\n", http_req_cfg->AcceptVal);
01569     dbg_printf(LOG, "\n[WIFI MAN] Content-Type = %s\n", http_req_cfg->contentType);
01570     dbg_printf(LOG, "\n[WIFI MAN] contentLenstr = %s\n", http_req_cfg->contentLen);
01571 #endif
01572                                            
01573     int bodyLen;
01574     sscanf(http_req_cfg->contentLen, "%d", &bodyLen);
01575 #ifdef FULL_DEBUG_ENABLED
01576     dbg_printf(LOG, "contenLenstr = %s bodyLen = %d\n", http_req_cfg->contentLen, bodyLen);
01577     if(bodyLen > 10){
01578         dbg_printf(LOG, "\n [WIFI MAN] Message Body:\n");
01579         printBufferInHex(http_req_cfg->body, bodyLen);
01580     }
01581 #endif    
01582     if(strstr(internet_config->url, "http:")!=NULL) // http request
01583     {
01584         http_request = new HttpRequest(network,  
01585                                        http_req_cfg->method, 
01586                                        full_url,
01587                                        callback(this, &WiFiManager::body_callback));
01588         setHttpHeader("Host", http_req_cfg->hostName);
01589         setHttpHeader("Accept", http_req_cfg->AcceptVal);
01590         if(http_req_cfg->method == HTTP_GET){
01591             dbg_printf(LOG, "HTTP_GET -- ignoring body\n");
01592             http_response = http_request->send(NULL, 0);
01593         }
01594         else{
01595             setHttpHeader("Content-Type", http_req_cfg->contentType);
01596             setHttpHeader("Content-Length", http_req_cfg->contentLen);
01597             http_response = http_request->send(http_req_cfg->body, bodyLen);
01598         }
01599         free_DataMsg();
01600         if (!http_response) {
01601             char buf[100];
01602             mbedtls_strerror(http_request->get_error(), buf, 100);
01603             dbg_printf(LOG, "HttpRequest failed (error code %s)\n", buf);
01604             delete http_request; // free the memory
01605             return false;
01606         }
01607         delete http_request; // free the memory
01608         dbg_printf(LOG, "\n----- HTTP POST response -----\n");
01609     }
01610     else
01611     {
01612         mbed_stats_heap_t heap_stats;
01613         mbed_stats_heap_get(&heap_stats);
01614         dbg_printf(LOG, "Heap size: %lu / %lu bytes\r\n", heap_stats.current_size, heap_stats.reserved_size);
01615         starttime = Kernel::get_ms_count();
01616 #ifndef DONT_USE_TLS_SOCKET
01617         if(https_connection_active == false){
01618             bool tlsResult;
01619             tlsResult = createTLSconnection(host);
01620 #ifdef ENABLE_MBED_TRACE
01621             mbed_trace_free(); // free trace memory
01622 #endif
01623             stoptime = Kernel::get_ms_count();
01624             dbg_printf(LOG, "\r\nTLS connection time : %d ms\r\n", (stoptime - starttime));
01625             if(tlsResult == false){
01626                  delete socket;
01627                  dbg_printf(LOG, "TLS Socket connection failed - deleting data msg\r\n");
01628                  free_DataMsg();
01629                  dbg_printf(LOG, "data msg deleted \r\n");
01630                  http_result = TLS_CONNECTION_FAILED;
01631                  return false;
01632             }
01633             // update remote peer details after socket connection
01634             updateRemotePeerDetails();
01635             // send socket connection event before proceeding to send https request
01636             // give about 2 ms
01637             sendSocketConnectionEvent();
01638         }        
01639         // Pass in `socket`, instead of `network` as first argument, and omit the `SSL_CA_PEM` argument
01640         stoptime = Kernel::get_ms_count();
01641         dbg_printf(LOG, "\r\nTLS connection time : %d ms\r\n", (stoptime - starttime));
01642         starttime = Kernel::get_ms_count();
01643         https_request = new HttpsRequest(socket, 
01644                                          http_req_cfg->method, 
01645                                          full_url,
01646                                          callback(this, &WiFiManager::body_callback));
01647 #ifdef SEND_DEBUG_MESSAGES
01648         responseString = (char *) malloc(100);
01649         sprintf(responseString, "\r\nHTTP REQUEST OBJECT CREATED\r\n");
01650         sendDebugMessage();
01651 #endif
01652 #else
01653         https_request = new HttpsRequest(network, 
01654                                          SSL_CA_PEM,
01655                                          http_req_cfg->method, 
01656                                          full_url,
01657                                          callback(this, &WiFiManager::body_callback));
01658 #endif        
01659 #ifdef TESTING_HTTPS
01660         dbg_printf(LOG, "http_req_cfg->method = %d\n", http_req_cfg->method);
01661         if(http_req_cfg->method == HTTP_GET){
01662             dbg_printf(LOG, "HTTP_GET -- ignoring body\n");
01663             setHttpsHeader("Host", host);
01664             setHttpsHeader("Accept", http_req_cfg->AcceptVal);
01665             http_response = https_request->send(NULL, 0);
01666         }
01667         else{
01668             setHttpsHeader("Host", host);
01669             setHttpsHeader("Authorization", aws_id_token);
01670             setHttpsHeader("Accept", http_req_cfg->AcceptVal);
01671             setHttpsHeader("Content-Type", http_req_cfg->contentType);
01672             setHttpsHeader("Content-Length", http_req_cfg->contentLen);
01673             dbg_printf(LOG, "https headers setup - about to send request\r\n");
01674             // Grab the heap statistics
01675             dbg_printf(LOG, "Heap size: %lu / %lu bytes\r\n", heap_stats.current_size, heap_stats.reserved_size);
01676             dbg_printf(LOG, "\n[WIFI MAN] Token Length: %d \r\n IdToken: \r\n %s\r\n", strlen(aws_id_token), aws_id_token);
01677             
01678 #ifdef PRINT_REQUEST_LOGS  
01679             uint8_t *http_req_log_buf = (uint8_t*)calloc(2048, 1);
01680             https_request->set_request_log_buffer(http_req_log_buf, 2048);
01681 #endif
01682             http_response = https_request->send(http_req_cfg->body, bodyLen);
01683         }
01684 #else
01685         setHttpsHeader("Host", host);
01686         setHttpsHeader("Authorization", aws_id_token);
01687         setHttpsHeader("Accept", http_req_cfg->AcceptVal);
01688         setHttpsHeader("Content-Type", http_req_cfg->contentType);
01689         setHttpsHeader("Content-Length", http_req_cfg->contentLen);
01690         http_response = https_request->send(http_req_cfg->body, bodyLen);
01691 #endif      
01692 #ifdef PRINT_REQUEST_LOGS  
01693         printHttpRequestLogBuffer();
01694 #endif
01695         nsapi_error_t error = https_request->get_error();
01696         if(error < 0)
01697         {
01698             char buf[100];
01699             mbedtls_strerror(error, buf, 100);
01700             printf("HttpsRequest failed (error code %s)\n", buf);
01701             delete https_request; // free the memory
01702             https_request = NULL;
01703             https_connection_active = false; // reset true whenever connection fails
01704             socket->close();
01705             delete socket;
01706             socket = NULL;
01707             free_DataMsg();
01708             http_result = HTTP_REQUEST_FAILED;
01709             return false;
01710         }
01711         https_connection_active = true; // set true whenever connection succeeds
01712         dbg_printf(LOG, "\n----- HTTPS POST response -----\r\n");
01713     } 
01714     if(http_response_hdr_sent == false)
01715     {
01716         socket->close();
01717         delete socket;
01718         https_connection_active = false; 
01719 #ifdef SEND_DEBUG_MESSAGES
01720         responseString = (char *) malloc(100);
01721         sprintf(responseString, "\r\n[WIFI-MAN] NO RESPONSE RECEIVED:: CLOSING CURRENT TLS CONNECTION.\r\n");
01722         sendDebugMessage();
01723 #endif
01724         //return_response(http_response);
01725     }
01726     free_DataMsg();
01727     delete https_request; // free the request & response memory
01728     dbg_printf(LOG, "deleted https_request\r\n");
01729     https_request = NULL;
01730     http_result = RESPONSE_OK;
01731     stoptime = Kernel::get_ms_count();
01732     dbg_printf(LOG, "\r\nhttp request to response time : %d ms\r\n", (stoptime - starttime));
01733     return true;
01734 }
01735 
01736 void WiFiManager::createHttpRequest(http_method method,
01737                                     const char* url,
01738                                     Callback<void(const char *at, uint32_t length)> body_callback)
01739 {
01740     http_request = new HttpRequest(network, 
01741                                    method, url, body_callback);;
01742 }
01743 
01744 void WiFiManager::setHttpHeader(string key, string value)
01745 {
01746     http_request->set_header(key, value);
01747 }
01748 
01749 void WiFiManager::setHttpsHeader(string key, string value)
01750 {
01751     https_request->set_header(key, value);
01752 }
01753 
01754 void WiFiManager::printHttpRequestLogBuffer()
01755 {   
01756     
01757     // after the request is done:
01758 #ifdef PRINT_BUFFER_IN_HEX
01759     dbg_printf(LOG, "\n----- Request buffer Hex-----\n");
01760     for (size_t ix = 0; ix < https_request->get_request_log_buffer_length(); ix++) {
01761         if(ix%16 == 0)dbg_printf(LOG, "\n[%04x] ", ix);
01762         dbg_printf(LOG, "%02x ", http_req_log_buf[ix]);
01763     }
01764 #endif
01765     dbg_printf(LOG, "\n[ request size = %d bytes]\r\n", https_request->get_request_log_buffer_length());
01766     dbg_printf(LOG, "----- Request buffer string -----\r\n%s ", (char *)http_req_log_buf);
01767     //wait_ms(100);
01768     free(http_req_log_buf);
01769 }
01770 void WiFiManager::sendHttpsRequest(const char * body, int bodyLen)
01771 {
01772 }
01773 
01774 void WiFiManager::sendHttpRequest(const char * body, int bodyLen)
01775 {
01776 }
01777