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

Dependencies:   mbed-http

Files at this revision

API Documentation at this revision

Comitter:
ocomeni
Date:
Tue Jun 11 20:23:43 2019 +0000
Branch:
PassingRegression
Parent:
121:ac4f59839e4f
Child:
123:a49e9ffbaca6
Commit message:
added error handling for Cloud connection keep alive

Changed in this revision

mbed_app.json Show annotated file Show diff for this revision Revisions of this file
source/ATCmdManager.cpp Show annotated file Show diff for this revision Revisions of this file
source/ATCmdManager.h Show annotated file Show diff for this revision Revisions of this file
source/WiFiManager.cpp Show annotated file Show diff for this revision Revisions of this file
source/WiFiManager.h Show annotated file Show diff for this revision Revisions of this file
source/common_config.h Show annotated file Show diff for this revision Revisions of this file
source/common_types.h Show annotated file Show diff for this revision Revisions of this file
source/debug.cpp Show diff for this revision Revisions of this file
source/debug2.cpp Show annotated file Show diff for this revision Revisions of this file
--- a/mbed_app.json	Sat Jun 01 15:29:03 2019 +0000
+++ b/mbed_app.json	Tue Jun 11 20:23:43 2019 +0000
@@ -43,6 +43,8 @@
          "*": {
             "platform.stdio-baud-rate": 115200,
             "platform.stdio-convert-newlines": true,
+            "platform.fatal-error-auto-reboot-enabled": 1,
+            "platform.thread-stats-enabled":1,
             "mbed-trace.enable": 1,
             "mbed-http.http-buffer-size": 1024,
             "nsapi.default-wifi-security": "WPA_WPA2",
--- a/source/ATCmdManager.cpp	Sat Jun 01 15:29:03 2019 +0000
+++ b/source/ATCmdManager.cpp	Tue Jun 11 20:23:43 2019 +0000
@@ -283,7 +283,9 @@
             {
                 // AT Event state 
                 dbg_printf(LOG, "\n [ATCMD MAN] AT_SOCKET_KEEP_ALIVE OK RESPONSE RECEIVED!!\r\n");
-                sendAtEvent("\r\nCLOUD CONNECTION OK\r\n");
+#ifdef SEND_CLOUD_OK_MSG
+                sendAtConfirmation("\r\nCLOUD CONNECTION OK\r\n");
+#endif
                 at_resp = AT_RESP_NONE;
                 break;
             }
@@ -291,7 +293,9 @@
             {
                 // AT Event state 
                 dbg_printf(LOG, "\n [ATCMD MAN] AT_SOCKET_KEEP_ALIVE FAILED RESPONSE RECEIVED!!\r\n");
+#ifdef SEND_CLOUD_OK_MSG
                 sendAtEvent("\r\nCLOUD CONNECTION FAILED\r\n");
+#endif
                 at_resp = AT_RESP_NONE;
                 break;
             }
@@ -1390,7 +1394,7 @@
             break;
         case AT_EXT_DATA_MODE:
         {
-            outputEDMdata((const uint8_t *) buf, len, AT_MSG_ID, EVENT_MSG_TYPE, BLE_CHANNEL);
+            outputEDMdata((const uint8_t *) buf, len, AT_MSG_ID, EVENT_MSG_TYPE, NO_CHANNEL);
             break;
         }
         default:
@@ -1485,7 +1489,30 @@
     int msWait = (pLen + 5+20)/20;
     wait_ms(msWait);
 }
-
+void ATCmdManager::filterHttpResponse()
+{
+    char * respbuf = (char *) resp_data->buffer;
+    char * strPtr;
+    char * strPtr2;
+    dbg_printf(LOG, "Header before trim:\r\n%s\r\n", respbuf);
+    strPtr  = strstr(respbuf, "Date:"); // find start of the last required entry
+    if(strPtr == NULL) return;
+    strPtr2  = strstr(respbuf, "Connection:"); // find start of the last required entry
+    if(strPtr == NULL) return;
+    if(strPtr2 > strPtr)
+    {
+        strPtr = strPtr2;
+    }
+    strPtr2 = strstr(strPtr, "\r\n"); // find end of the last required entry
+    if(strPtr2 == NULL) return;
+    strPtr  = strstr(strPtr2, "\r\n\r\n"); // find start of body
+    if(strPtr == NULL) return;
+    int hdrLen = (strPtr - respbuf);
+    int bytes2trim = (strPtr - strPtr2);
+    memmove(strPtr2, strPtr, (resp_data->dataLen-(hdrLen-bytes2trim)));
+    resp_data->dataLen -= bytes2trim; // reduce the length by bytes to trim
+    dbg_printf(LOG, "Header after trim:\r\n%s\r\n", respbuf);
+}
 void ATCmdManager::return_response(bool download) {
     char * resp = (char *) resp_data->buffer;
     dbg_printf(LOG, "\n[ATCMD MAN] received response:\n");
@@ -1497,6 +1524,13 @@
     {
         printBufferInHex((uint8_t *)resp, resp_data->dataLen);
     }
+#ifdef TRIM_AWS_HEADER_ENTRIES
+    int offset = resp - strstr(resp,"HTTP/1.1");
+    if(offset >=0 && offset < 2) // must be at start of header
+    {
+        filterHttpResponse();
+    }
+#endif
     outputEDMdata((const uint8_t *)resp, resp_data->dataLen, DATA_MSG_ID, 
                   EVENT_MSG_TYPE, WIFI_CHANNEL);
     _wiFi2ATDatamPool->free(resp_data);
--- a/source/ATCmdManager.h	Sat Jun 01 15:29:03 2019 +0000
+++ b/source/ATCmdManager.h	Tue Jun 11 20:23:43 2019 +0000
@@ -164,6 +164,7 @@
     void        sendBleDisconnectEvent();
     bool        dequeueBleDataResponse();
     bool        queueBleDataRequest(at_ble_msg_t data_req);
+    void        filterHttpResponse();
     
     /**
     * Allows timeout to be changed between commands
--- a/source/WiFiManager.cpp	Sat Jun 01 15:29:03 2019 +0000
+++ b/source/WiFiManager.cpp	Tue Jun 11 20:23:43 2019 +0000
@@ -50,7 +50,7 @@
     watchdogCnt = 0;
     //_event_queue.call_every(10000, this, &WiFiManager::callWifiWatchDog);
     keep_alive_id = _event_queue.call_every(CLOUD_KEEP_ALIVE_INTERVAL, this, &WiFiManager::callInternetKeepAlive);
-    watchDogTick.attach(callback(this, &WiFiManager::callWifiWatchDogIsr), 10.0); // call flip function every 10 seconds
+    //watchDogTick.attach(callback(this, &WiFiManager::callWifiWatchDogIsr), 10.0); // call flip function every 10 seconds
     
 }
 
@@ -102,33 +102,42 @@
     {
         setNextCommand(WIFI_CMD_INTERNET_KEEP_ALIVE);
     }
+    else
+    {
+        setNextCommand(WIFI_CMD_TLS_CONNECT);
+    }
 }
 
 
 void WiFiManager::keepSocketAlive()
 {
     // Send data
-    nsapi_error_t serr;
+    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);
-    serr = socket->send(HELLO_MSG, sizeof(HELLO_MSG));
+    error = socket->send(HELLO_MSG, sizeof(HELLO_MSG));
     
-    if(serr <= 0)
+    if(error < 0)
     {
        queueATresponse(AT_SOCKET_KEEP_ALIVE_FAILED);
+       https_connection_active = false;
+       socket->close();
+       delete socket;
+       return;
     }
     
     // Receive data
     char buf[500];
-    nsapi_size_or_error_t error;
     error = socket->recv(buf, 500);
-    if(error > 0)
+    if(error >= 0)
     {
         dbg_printf(LOG, "\n[WIFI MAN] KEEP ALIVE SERVER RESPONSE: \r\n %s\r\n", buf);
         queueATresponse(AT_SOCKET_KEEP_ALIVE_OK);
+        https_connection_active = true;
     }
     else
     {
        queueATresponse(AT_SOCKET_KEEP_ALIVE_FAILED);
+       https_connection_active = false;
     }
 }
 
@@ -242,7 +251,10 @@
                 nsapi_size_or_error_t cnt_err;
                 cnt_err = getAvailableAPs(lastScanCount);
                 wifiCmd = WIFI_CMD_NONE;
-                queueATresponse(AT_DETAILED_SCAN_RESP);
+                if(cnt_err >= 0)
+                {
+                    queueATresponse(AT_DETAILED_SCAN_RESP);
+                }
                 wifiBusy = 0;
                 break;
             }
@@ -399,6 +411,23 @@
                 keep_alive_id = _event_queue.call_every(CLOUD_KEEP_ALIVE_INTERVAL, this, &WiFiManager::callInternetKeepAlive);
                 //network->attach(callback(this, &WiFiManager::status_callback));
                 break;
+            }            
+            case WIFI_CMD_TLS_CONNECT:
+            {
+                char* hostName = strstr(internet_config->url,"//");
+                wifiBusy = 1;
+                if(hostName != NULL)
+                {
+                    hostName += 2; 
+                    https_connection_active = createTLSconnection(hostName);
+                    if(https_connection_active == false)
+                    {
+                        queueATresponse(AT_SOCKET_KEEP_ALIVE_FAILED);
+                    }
+                }
+                wifiCmd = WIFI_CMD_NONE;
+                wifiBusy = 0;
+                break;
             }
             case WIFI_CMD_INTERNET_KEEP_ALIVE:
                 wifiBusy = 1;
@@ -1138,12 +1167,14 @@
     {
         dbg_printf(LOG, "[WIFI-MAN] response pointer NULL not!!\r\n");
     }
+#ifdef SEND_DEBUG_MESSAGES
     if(responseString == NULL && chunkNum==1)
     {
         responseString = (char *) malloc(100);
         sprintf(responseString, "\r\nHTTPS BODY CALLBACK RECEIVED\r\n");
         sendATresponseString(AT_EVENT);
     }
+#endif
     sendResponseDownloadData(AT_HTTPS_RESP_DOWNLOAD, (uint8_t *)at, length);
 }
 
--- a/source/WiFiManager.h	Sat Jun 01 15:29:03 2019 +0000
+++ b/source/WiFiManager.h	Tue Jun 11 20:23:43 2019 +0000
@@ -61,10 +61,10 @@
 private:
     Mutex _wmutex; // Protect wifi thread
     wifi_config_t     *wifi_config;
+    WiFiInterface *network;
     internet_config_t *internet_config;
     // define event queue
     events::EventQueue &_event_queue;
-    WiFiInterface *network;
     HttpsRequest* https_request;
     HttpRequest* http_request;
     HttpResponse* http_response;
--- a/source/common_config.h	Sat Jun 01 15:29:03 2019 +0000
+++ b/source/common_config.h	Tue Jun 11 20:23:43 2019 +0000
@@ -51,7 +51,10 @@
 #define MAX_BLE_POOL_DATA_SIZE    40
 #define BLE_PROCESS_QUEUES_INTERVAL_MS  200 // check BLE queues every 200 ms
 //#define ENABLE_MEMORY_CHECKS
-#define SEND_DEBUG_MESSAGES
+//#define SEND_DEBUG_MESSAGES
+
+#define TRIM_AWS_HEADER_ENTRIES
+#define SEND_CLOUD_OK_MSG
 typedef enum
 {
   IF_HW_ADDRESS = 0,
--- a/source/common_types.h	Sat Jun 01 15:29:03 2019 +0000
+++ b/source/common_types.h	Tue Jun 11 20:23:43 2019 +0000
@@ -87,6 +87,7 @@
   WIFI_CMD_WIFI_STATUS,
   WIFI_CMD_SEND_HTTPS_REQ,
   WIFI_CMD_SEND_HTTP_REQ,
+  WIFI_CMD_TLS_CONNECT,
   WIFI_CMD_INTERNET_KEEP_ALIVE
 }wifi_cmd_t;
 
--- a/source/debug.cpp	Sat Jun 01 15:29:03 2019 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,372 +0,0 @@
-/**
-******************************************************************************
-* @file         debug.c
-* @brief        Source file containing logic responsible for:
-* @details
-*
-******************************************************************************
-* @author       TTP
-* @copyright (c) 2017 TTP (The Technology Partnership) plc
-*
-******************************************************************************
-*/
-
-//-------- Includes ----------------------------------------------------------//
-
-#include "debug.h"
-#include <mbed.h>
-//#include "clocks.h"
-
-//-------- Defines -----------------------------------------------------------//
-
-#define FILE_CODE       "dbgm"
-#define ERROR       "err"
-
-#define DBG_RX_BUFFER_SIZE_BYTES        (1024)
-#define DBG_RX_BUFFER_MASK              (DBG_RX_BUFFER_SIZE_BYTES - 1)
-
-#define DBG_TX_BUFFER_SIZE_BYTES        (1024) 
-
-#if (DBG_RX_BUFFER_SIZE_BYTES & DBG_RX_BUFFER_MASK)
-    #error Rx buffer size is not power of 2
-#endif
-
-//-------- Constants & enums -------------------------------------------------//
-
-
-//-------- Structs & typedefs ------------------------------------------------//
-
-//-------- Global Variables --------------------------------------------------//
-
-/**
-*@brief         Global array of length ::DBG_TX_BUFFER_SIZE_BYTES to store
-*               the current debug print statement of the firmware. 
-*/
-static char g_dbg_buffer[DBG_TX_BUFFER_SIZE_BYTES];
-
-//-------- Static Variables --------------------------------------------------//
-
-static const char dbg_tx_terminate_string[] = {'\n', '\r'}; ///<Array of characters representing the terminate sequence of a debug transmit string
-
-static uint8_t current_debug_level; ///<Variable keeping track of the current debug level
-
-static char fw_ver_string[REL_FW_VER_STRING_LEN_BYTES + SVN_FW_VER_STRING_LEN_BYTES];
-static uint8_t fw_ver_bytes[5];
-
-static data_mode_e dbg_data_mode;
-
-//Rx buffer to be used for both ASCII and binary mode
-static uint8_t dbg_rx_buffer[DBG_RX_BUFFER_SIZE_BYTES];
-static volatile uint16_t dbg_rx_pos;
-static volatile uint32_t dbg_rx_count;
-static volatile uint16_t dbg_rx_cmd_count;
-
-//static char g_dbg_buffer[DBG_TX_BUFFER_SIZE_BYTES];
-
-//-------- Static function prototypes ----------------------------------------//
-
-static void set_fw_ver_string(void);
-static void set_fw_ver_bytes(void);
-static char get_rx_byte_from_buffer(void);
-static const char* debug_level_to_string(uint8_t debug_level);
-
-//-------- Function implementations ------------------------------------------//
-#ifdef BOX_MICRO_CODE
-static inline void disable_dbg_rx_intrup(void)
-{
-  __HAL_PCD_DISABLE(&hpcd_USB_OTG_FS);
-}
-
-static inline void enable_dbg_rx_intrup(void)
-{
-  __HAL_PCD_ENABLE(&hpcd_USB_OTG_FS);
-}
-#endif
-/**
-* @brief        Starting function to supervise the
-*               - Initialisation of UART2 responsible for acting as the debug port for the firmware
-*               - Initialisation of the UART2 transmit and receive buffers
-*               - Initial read from UART2
-*
-* @param        None 
-* @retval       None 
-*/
-//#define DEBUG_ENABLED
-void initialise_debug(uint8_t debug_level=NONE)
-{   
-  memset(g_dbg_buffer, 0, sizeof(g_dbg_buffer));
-  
-  //. Set the version strings
-  set_fw_ver_string();
-  set_fw_ver_bytes();
-#ifdef DEBUG_ENABLED  
-  current_debug_level = (LOG | ERR | TXT | DBG); //NONE; // 
-#else
-  current_debug_level = debug_level; // 
-#endif
-  dbg_data_mode = DATA_ASCII;
-  dbg_rx_pos = 0;
-  dbg_rx_count = 0;
-  dbg_rx_cmd_count = 0;
-}
-
-/**
-* @brief
-* @param
-* @param
-* @retval
-*/
-const char* get_dbg_tx_terminate_string(void)
-{
-  if (dbg_data_mode == DATA_ASCII)
-  { 
-    return dbg_tx_terminate_string;
-  }
-  else
-  {  
-    return NULL;
-  }
-}
-
-/**
-* @brief
-* @param
-* @param
-* @retval
-*/
-uint8_t get_dbg_tx_terminate_string_len(void)
-{
-  if (dbg_data_mode == DATA_ASCII)
-  {  
-    return sizeof(dbg_tx_terminate_string);
-  }
-  else
-  {  
-    return 0;
-  }
-}
-
-static const char* debug_level_to_string(uint8_t debug_level)
-{
-  switch(debug_level)
-  {
-  case LOG:
-    return "LOG";
-      
-  case ERR:
-    return "ERR";
-    
-  case DBG:
-    return "DBG";
-    
-  case TXT:
-    return "TXT";
-      
-  default:
-    return "INV"; //Invalid
-  }
-}
-
-
-//void dbg_printf(uint8_t debug_level, ...)
-//{
-//    dbg_print(FILE_CODE, __LINE__, debug_level, ...);
-//}
-void dbg_print(const char *file_code, uint16_t line_number, 
-                uint8_t debug_level, const char *text, ...)
-{
-  //const char *file_code, uint16_t line_number,
-                
-  if (current_debug_level & debug_level)
-  {
-    //Re-init the gloabl debug buffer  
-    memset(g_dbg_buffer, 0, sizeof(g_dbg_buffer));
-    uint16_t len_bytes = 0;
-    
-    if (debug_level != TXT)
-    {
-      //sprintf(g_dbg_buffer, "|%s|%10u|", debug_level_to_string(debug_level), Kernel::get_ms_count());
-      sprintf(g_dbg_buffer, "|%s|%s|%4d|%10u|", debug_level_to_string(debug_level), file_code, line_number, Kernel::get_ms_count());
-      len_bytes = strlen(g_dbg_buffer);
-    }
-    
-    va_list args;
-    va_start(args, text); 
-    vsnprintf(&g_dbg_buffer[len_bytes], (sizeof(g_dbg_buffer) - len_bytes - 2), text, args);
-    printf("%s", g_dbg_buffer);
-    va_end(args);
-    
-    len_bytes = strlen(g_dbg_buffer);
-    g_dbg_buffer[len_bytes++] = '\r';
-    g_dbg_buffer[len_bytes++] = '\n';
-#ifdef WRITE_TO_FILE_ENABLED   
-    if (debug_level == LOG || debug_level == ERROR)
-    {
-      write_to_file(SYS_LOG, (const uint8_t *)g_dbg_buffer, len_bytes);
-    }
-    
-    if (dbg_data_mode == DATA_ASCII)
-    {
-      transmit_bytes_over_usb((uint8_t *)g_dbg_buffer, len_bytes);    
-    }
-#endif
-  }
-}
-
-/**
-    Function used to send data during firmware update (in binary mode)
-*/
-#ifdef WRITE_TO_FILE_ENABLED  
-void debug_send_data(uint8_t *pData, uint16_t length)
-{
-  transmit_bytes_over_usb(pData, length);
-}
-#endif
-
-/**
-* @brief        Function to set the debug level. Currently only 2 debug levels
-*               are provided as mentioned in ::debug_log_level_e.
-*               LOG is constantly enabled
-*
-* @param        (uint8_t) debug_level  
-* @retval       None
-*/
-void set_debug_level(uint8_t debug_level)
-{
-  current_debug_level = (LOG | ERR | TXT | debug_level);
-  dbg_printf(LOG, "Current debug level set to %02x", current_debug_level);
-}
-
-/**
-* @brief        Function to get the current debug level set. 
-*
-* @param        None 
-* @retval       (uint8_t) current_debug_level
-*/
-uint8_t get_debug_level(void)
-{
-  return current_debug_level;
-}
-
-/**
-* @brief        Function to set the micro firmware version 
-*               Firmware version follows the following format: 
-*               major.minor.patch.svn_revision
-*               
-*               If 'svnversion' is not installed on the machine, the svn
-*               revision is returned null. In that instance, the svn revision
-*               is set to n.a
-*
-* @param        None 
-* @retval       None
-*/
-static void set_fw_ver_string(void)
-{
-  memset(fw_ver_string, 0, sizeof(fw_ver_string));
-  
-  memcpy(fw_ver_string, REL_FW_VER_STRING, REL_FW_VER_STRING_LEN_BYTES);
-  
-  uint8_t rel_fw_string_len_bytes = strlen(REL_FW_VER_STRING);
-  
-  fw_ver_string[rel_fw_string_len_bytes] = '.';
-#ifdef BOX_MICRO_CODE   
-  if (strlen(SVN_FW_VERSION_STRING) == 0)
-  {
-    //svnversion is not installed on the machine
-    memcpy(&fw_ver_string[rel_fw_string_len_bytes + 1], "n.a", 4);
-  }
-  else
-  {
-    memcpy(&fw_ver_string[rel_fw_string_len_bytes + 1], SVN_FW_VERSION_STRING, SVN_FW_VER_STRING_LEN_BYTES);
-  }
-#endif
-}
-
-/**
-* @brief        Function to get the firmware version 
-*
-* @param        None 
-* @retval       (const char *) fw_ver_string
-*/
-const char* get_fw_ver_string(void)
-{
-  return fw_ver_string;
-}
-
-static void set_fw_ver_bytes(void)
-{
-  memset(fw_ver_bytes, 0, sizeof(fw_ver_bytes));
-  
-  uint16_t val = 0;
-  sscanf(fw_ver_string, "%hhx.%hhx.%hhx.%hx", &fw_ver_bytes[0], &fw_ver_bytes[1], &fw_ver_bytes[2], &val);
-  
-  fw_ver_bytes[3] = (val >> 8) & 0xff;
-  fw_ver_bytes[4] = val & 0xff;
-}
-
-const uint8_t* get_fw_ver_bytes(void)
-{
-  return fw_ver_bytes;
-}
-
-void debug_setDataMode(data_mode_e mode)
-{  
-  dbg_data_mode = mode;
-}
-
-void print_debug_hex(const uint8_t* p_buffer, uint16_t len)
-{
-  //print out the rxvd EDM bytes  
-  
-  uint16_t quo = len / 8;
-  uint16_t rem = len % 8;
-  
-  uint16_t i = 0;
-  uint16_t j = 0;
-  for (i = 0; i < quo; i++)
-  { 
-    dbg_printf(LOG, "[%3d]: %02x %02x %02x %02x %02x %02x %02x %02x", j,
-                    p_buffer[j + 0], p_buffer[j + 1], p_buffer[j + 2], p_buffer[j + 3],
-                    p_buffer[j + 4], p_buffer[j + 5], p_buffer[j + 6], p_buffer[j + 7]);
-    j += 8;
-  }
-  
-  if (rem == 7)
-  {
-    dbg_printf(LOG, "[%3d]: %02x %02x %02x %02x %02x %02x %02x", j,
-                    p_buffer[j + 0], p_buffer[j + 1], p_buffer[j + 2], p_buffer[j + 3],
-                    p_buffer[j + 4], p_buffer[j + 5], p_buffer[j + 6]);      
-  }
-  else if (rem == 6)
-  { 
-    dbg_printf(LOG, "[%3d]: %02x %02x %02x %02x %02x %02x", j,
-                    p_buffer[j + 0], p_buffer[j + 1], p_buffer[j + 2], p_buffer[j + 3],
-                    p_buffer[j + 4], p_buffer[j + 5]);     
-  }
-  else if (rem == 5)
-  {
-    dbg_printf(LOG, "[%3d]: %02x %02x %02x %02x %02x", j,
-                    p_buffer[j + 0], p_buffer[j + 1], p_buffer[j + 2], p_buffer[j + 3],
-                    p_buffer[j + 4]);      
-  }
-  else if (rem == 4)
-  {
-    dbg_printf(LOG, "[%3d]: %02x %02x %02x %02x", j,
-                    p_buffer[j + 0], p_buffer[j + 1], p_buffer[j + 2], p_buffer[j + 3]);   
-  }
-  else if (rem == 3)
-  {
-    dbg_printf(LOG, "[%3d]: %02x %02x %02x", j,
-                    p_buffer[j + 0], p_buffer[j + 1], p_buffer[j + 2]);      
-  }
-  else if (rem == 2)
-  {
-    dbg_printf(LOG, "[%3d]: %02x %02x", j, p_buffer[j + 0], p_buffer[j + 1]);     
-  }
-  else if (rem == 1)
-  {
-    dbg_printf(LOG, "[%3d]: %02x", j, p_buffer[j]);    
-  }  
-
-  dbg_printf(LOG, ""); 
-}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/source/debug2.cpp	Tue Jun 11 20:23:43 2019 +0000
@@ -0,0 +1,372 @@
+/**
+******************************************************************************
+* @file         debug.c
+* @brief        Source file containing logic responsible for:
+* @details
+*
+******************************************************************************
+* @author       TTP
+* @copyright (c) 2017 TTP (The Technology Partnership) plc
+*
+******************************************************************************
+*/
+
+//-------- Includes ----------------------------------------------------------//
+
+#include "debug.h"
+#include <mbed.h>
+//#include "clocks.h"
+
+//-------- Defines -----------------------------------------------------------//
+
+#define FILE_CODE       "dbgm"
+#define ERROR       "err"
+
+#define DBG_RX_BUFFER_SIZE_BYTES        (1024)
+#define DBG_RX_BUFFER_MASK              (DBG_RX_BUFFER_SIZE_BYTES - 1)
+
+#define DBG_TX_BUFFER_SIZE_BYTES        (1024) 
+
+#if (DBG_RX_BUFFER_SIZE_BYTES & DBG_RX_BUFFER_MASK)
+    #error Rx buffer size is not power of 2
+#endif
+
+//-------- Constants & enums -------------------------------------------------//
+
+
+//-------- Structs & typedefs ------------------------------------------------//
+
+//-------- Global Variables --------------------------------------------------//
+
+/**
+*@brief         Global array of length ::DBG_TX_BUFFER_SIZE_BYTES to store
+*               the current debug print statement of the firmware. 
+*/
+static char g_dbg_buffer[DBG_TX_BUFFER_SIZE_BYTES];
+
+//-------- Static Variables --------------------------------------------------//
+
+static const char dbg_tx_terminate_string[] = {'\n', '\r'}; ///<Array of characters representing the terminate sequence of a debug transmit string
+
+static uint8_t current_debug_level; ///<Variable keeping track of the current debug level
+
+static char fw_ver_string[REL_FW_VER_STRING_LEN_BYTES + SVN_FW_VER_STRING_LEN_BYTES];
+static uint8_t fw_ver_bytes[5];
+
+static data_mode_e dbg_data_mode;
+
+//Rx buffer to be used for both ASCII and binary mode
+static uint8_t dbg_rx_buffer[DBG_RX_BUFFER_SIZE_BYTES];
+static volatile uint16_t dbg_rx_pos;
+static volatile uint32_t dbg_rx_count;
+static volatile uint16_t dbg_rx_cmd_count;
+
+//static char g_dbg_buffer[DBG_TX_BUFFER_SIZE_BYTES];
+
+//-------- Static function prototypes ----------------------------------------//
+
+static void set_fw_ver_string(void);
+static void set_fw_ver_bytes(void);
+static char get_rx_byte_from_buffer(void);
+static const char* debug_level_to_string(uint8_t debug_level);
+
+//-------- Function implementations ------------------------------------------//
+#ifdef BOX_MICRO_CODE
+static inline void disable_dbg_rx_intrup(void)
+{
+  __HAL_PCD_DISABLE(&hpcd_USB_OTG_FS);
+}
+
+static inline void enable_dbg_rx_intrup(void)
+{
+  __HAL_PCD_ENABLE(&hpcd_USB_OTG_FS);
+}
+#endif
+/**
+* @brief        Starting function to supervise the
+*               - Initialisation of UART2 responsible for acting as the debug port for the firmware
+*               - Initialisation of the UART2 transmit and receive buffers
+*               - Initial read from UART2
+*
+* @param        None 
+* @retval       None 
+*/
+//#define DEBUG_ENABLED
+void initialise_debug(uint8_t debug_level=NONE)
+{   
+  memset(g_dbg_buffer, 0, sizeof(g_dbg_buffer));
+  
+  //. Set the version strings
+  set_fw_ver_string();
+  set_fw_ver_bytes();
+#ifdef DEBUG_ENABLED  
+  current_debug_level = (LOG | ERR | TXT | DBG); //NONE; // 
+#else
+  current_debug_level = debug_level; // 
+#endif
+  dbg_data_mode = DATA_ASCII;
+  dbg_rx_pos = 0;
+  dbg_rx_count = 0;
+  dbg_rx_cmd_count = 0;
+}
+
+/**
+* @brief
+* @param
+* @param
+* @retval
+*/
+const char* get_dbg_tx_terminate_string(void)
+{
+  if (dbg_data_mode == DATA_ASCII)
+  { 
+    return dbg_tx_terminate_string;
+  }
+  else
+  {  
+    return NULL;
+  }
+}
+
+/**
+* @brief
+* @param
+* @param
+* @retval
+*/
+uint8_t get_dbg_tx_terminate_string_len(void)
+{
+  if (dbg_data_mode == DATA_ASCII)
+  {  
+    return sizeof(dbg_tx_terminate_string);
+  }
+  else
+  {  
+    return 0;
+  }
+}
+
+static const char* debug_level_to_string(uint8_t debug_level)
+{
+  switch(debug_level)
+  {
+  case LOG:
+    return "LOG";
+      
+  case ERR:
+    return "ERR";
+    
+  case DBG:
+    return "DBG";
+    
+  case TXT:
+    return "TXT";
+      
+  default:
+    return "INV"; //Invalid
+  }
+}
+
+
+//void dbg_printf(uint8_t debug_level, ...)
+//{
+//    dbg_print(FILE_CODE, __LINE__, debug_level, ...);
+//}
+void dbg_print(const char *file_code, uint16_t line_number, 
+                uint8_t debug_level, const char *text, ...)
+{
+  //const char *file_code, uint16_t line_number,
+                
+  if (current_debug_level & debug_level)
+  {
+    //Re-init the gloabl debug buffer  
+    memset(g_dbg_buffer, 0, sizeof(g_dbg_buffer));
+    uint16_t len_bytes = 0;
+    
+    if (debug_level != TXT)
+    {
+      //sprintf(g_dbg_buffer, "|%s|%10u|", debug_level_to_string(debug_level), Kernel::get_ms_count());
+      sprintf(g_dbg_buffer, "|%s|%s|%4d|%10u|", debug_level_to_string(debug_level), file_code, line_number, Kernel::get_ms_count());
+      len_bytes = strlen(g_dbg_buffer);
+    }
+    
+    va_list args;
+    va_start(args, text); 
+    vsnprintf(&g_dbg_buffer[len_bytes], (sizeof(g_dbg_buffer) - len_bytes - 2), text, args);
+    printf("%s", g_dbg_buffer);
+    va_end(args);
+    
+    len_bytes = strlen(g_dbg_buffer);
+    g_dbg_buffer[len_bytes++] = '\r';
+    g_dbg_buffer[len_bytes++] = '\n';
+#ifdef WRITE_TO_FILE_ENABLED   
+    if (debug_level == LOG || debug_level == ERROR)
+    {
+      write_to_file(SYS_LOG, (const uint8_t *)g_dbg_buffer, len_bytes);
+    }
+    
+    if (dbg_data_mode == DATA_ASCII)
+    {
+      transmit_bytes_over_usb((uint8_t *)g_dbg_buffer, len_bytes);    
+    }
+#endif
+  }
+}
+
+/**
+    Function used to send data during firmware update (in binary mode)
+*/
+#ifdef WRITE_TO_FILE_ENABLED  
+void debug_send_data(uint8_t *pData, uint16_t length)
+{
+  transmit_bytes_over_usb(pData, length);
+}
+#endif
+
+/**
+* @brief        Function to set the debug level. Currently only 2 debug levels
+*               are provided as mentioned in ::debug_log_level_e.
+*               LOG is constantly enabled
+*
+* @param        (uint8_t) debug_level  
+* @retval       None
+*/
+void set_debug_level(uint8_t debug_level)
+{
+  current_debug_level = (LOG | ERR | TXT | debug_level);
+  dbg_printf(LOG, "Current debug level set to %02x", current_debug_level);
+}
+
+/**
+* @brief        Function to get the current debug level set. 
+*
+* @param        None 
+* @retval       (uint8_t) current_debug_level
+*/
+uint8_t get_debug_level(void)
+{
+  return current_debug_level;
+}
+
+/**
+* @brief        Function to set the micro firmware version 
+*               Firmware version follows the following format: 
+*               major.minor.patch.svn_revision
+*               
+*               If 'svnversion' is not installed on the machine, the svn
+*               revision is returned null. In that instance, the svn revision
+*               is set to n.a
+*
+* @param        None 
+* @retval       None
+*/
+static void set_fw_ver_string(void)
+{
+  memset(fw_ver_string, 0, sizeof(fw_ver_string));
+  
+  memcpy(fw_ver_string, REL_FW_VER_STRING, REL_FW_VER_STRING_LEN_BYTES);
+  
+  uint8_t rel_fw_string_len_bytes = strlen(REL_FW_VER_STRING);
+  
+  fw_ver_string[rel_fw_string_len_bytes] = '.';
+#ifdef BOX_MICRO_CODE   
+  if (strlen(SVN_FW_VERSION_STRING) == 0)
+  {
+    //svnversion is not installed on the machine
+    memcpy(&fw_ver_string[rel_fw_string_len_bytes + 1], "n.a", 4);
+  }
+  else
+  {
+    memcpy(&fw_ver_string[rel_fw_string_len_bytes + 1], SVN_FW_VERSION_STRING, SVN_FW_VER_STRING_LEN_BYTES);
+  }
+#endif
+}
+
+/**
+* @brief        Function to get the firmware version 
+*
+* @param        None 
+* @retval       (const char *) fw_ver_string
+*/
+const char* get_fw_ver_string(void)
+{
+  return fw_ver_string;
+}
+
+static void set_fw_ver_bytes(void)
+{
+  memset(fw_ver_bytes, 0, sizeof(fw_ver_bytes));
+  
+  uint16_t val = 0;
+  sscanf(fw_ver_string, "%hhx.%hhx.%hhx.%hx", &fw_ver_bytes[0], &fw_ver_bytes[1], &fw_ver_bytes[2], &val);
+  
+  fw_ver_bytes[3] = (val >> 8) & 0xff;
+  fw_ver_bytes[4] = val & 0xff;
+}
+
+const uint8_t* get_fw_ver_bytes(void)
+{
+  return fw_ver_bytes;
+}
+
+void debug_setDataMode(data_mode_e mode)
+{  
+  dbg_data_mode = mode;
+}
+
+void print_debug_hex(const uint8_t* p_buffer, uint16_t len)
+{
+  //print out the rxvd EDM bytes  
+  
+  uint16_t quo = len / 8;
+  uint16_t rem = len % 8;
+  
+  uint16_t i = 0;
+  uint16_t j = 0;
+  for (i = 0; i < quo; i++)
+  { 
+    dbg_printf(LOG, "[%3d]: %02x %02x %02x %02x %02x %02x %02x %02x", j,
+                    p_buffer[j + 0], p_buffer[j + 1], p_buffer[j + 2], p_buffer[j + 3],
+                    p_buffer[j + 4], p_buffer[j + 5], p_buffer[j + 6], p_buffer[j + 7]);
+    j += 8;
+  }
+  
+  if (rem == 7)
+  {
+    dbg_printf(LOG, "[%3d]: %02x %02x %02x %02x %02x %02x %02x", j,
+                    p_buffer[j + 0], p_buffer[j + 1], p_buffer[j + 2], p_buffer[j + 3],
+                    p_buffer[j + 4], p_buffer[j + 5], p_buffer[j + 6]);      
+  }
+  else if (rem == 6)
+  { 
+    dbg_printf(LOG, "[%3d]: %02x %02x %02x %02x %02x %02x", j,
+                    p_buffer[j + 0], p_buffer[j + 1], p_buffer[j + 2], p_buffer[j + 3],
+                    p_buffer[j + 4], p_buffer[j + 5]);     
+  }
+  else if (rem == 5)
+  {
+    dbg_printf(LOG, "[%3d]: %02x %02x %02x %02x %02x", j,
+                    p_buffer[j + 0], p_buffer[j + 1], p_buffer[j + 2], p_buffer[j + 3],
+                    p_buffer[j + 4]);      
+  }
+  else if (rem == 4)
+  {
+    dbg_printf(LOG, "[%3d]: %02x %02x %02x %02x", j,
+                    p_buffer[j + 0], p_buffer[j + 1], p_buffer[j + 2], p_buffer[j + 3]);   
+  }
+  else if (rem == 3)
+  {
+    dbg_printf(LOG, "[%3d]: %02x %02x %02x", j,
+                    p_buffer[j + 0], p_buffer[j + 1], p_buffer[j + 2]);      
+  }
+  else if (rem == 2)
+  {
+    dbg_printf(LOG, "[%3d]: %02x %02x", j, p_buffer[j + 0], p_buffer[j + 1]);     
+  }
+  else if (rem == 1)
+  {
+    dbg_printf(LOG, "[%3d]: %02x", j, p_buffer[j]);    
+  }  
+
+  dbg_printf(LOG, ""); 
+}