this is using the mbed os version 5-13-1
Revision 122:62166886db5f, committed 2019-06-11
- 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
--- 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, "");
+}