diff options
Diffstat (limited to 'src/GeneralUtils.cpp')
-rw-r--r-- | src/GeneralUtils.cpp | 388 |
1 files changed, 388 insertions, 0 deletions
diff --git a/src/GeneralUtils.cpp b/src/GeneralUtils.cpp new file mode 100644 index 0000000..4237b14 --- /dev/null +++ b/src/GeneralUtils.cpp @@ -0,0 +1,388 @@ +/* + * GeneralUtils.cpp + * + * Created on: May 20, 2017 + * Author: kolban + */ + +#include "GeneralUtils.h" +#include <esp_log.h> +#include <string.h> +#include <stdio.h> +#include <string> +#include <sstream> +#include <iomanip> +#include <FreeRTOS.h> +#include <esp_err.h> +#include <nvs.h> +#include <esp_wifi.h> + +static const char* LOG_TAG = "GeneralUtils"; + +static const char kBase64Alphabet[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ" + "abcdefghijklmnopqrstuvwxyz" + "0123456789+/"; + +GeneralUtils::GeneralUtils() { + // TODO Auto-generated constructor stub + +} + +GeneralUtils::~GeneralUtils() { + // TODO Auto-generated destructor stub +} + +static int base64EncodedLength(size_t length) { + return (length + 2 - ((length + 2) % 3)) / 3 * 4; +} // base64EncodedLength + + +static int base64EncodedLength(const std::string &in) { + return base64EncodedLength(in.length()); +} // base64EncodedLength + + +static void a3_to_a4(unsigned char * a4, unsigned char * a3) { + a4[0] = (a3[0] & 0xfc) >> 2; + a4[1] = ((a3[0] & 0x03) << 4) + ((a3[1] & 0xf0) >> 4); + a4[2] = ((a3[1] & 0x0f) << 2) + ((a3[2] & 0xc0) >> 6); + a4[3] = (a3[2] & 0x3f); +} // a3_to_a4 + + +static void a4_to_a3(unsigned char * a3, unsigned char * a4) { + a3[0] = (a4[0] << 2) + ((a4[1] & 0x30) >> 4); + a3[1] = ((a4[1] & 0xf) << 4) + ((a4[2] & 0x3c) >> 2); + a3[2] = ((a4[2] & 0x3) << 6) + a4[3]; +} // a4_to_a3 + + +/** + * @brief Encode a string into base 64. + * @param [in] in + * @param [out] out + */ +bool GeneralUtils::base64Encode(const std::string &in, std::string *out) { + int i = 0, j = 0; + size_t enc_len = 0; + unsigned char a3[3]; + unsigned char a4[4]; + + out->resize(base64EncodedLength(in)); + + int input_len = in.size(); + std::string::const_iterator input = in.begin(); + + while (input_len--) { + a3[i++] = *(input++); + if (i == 3) { + a3_to_a4(a4, a3); + + for (i = 0; i < 4; i++) { + (*out)[enc_len++] = kBase64Alphabet[a4[i]]; + } + + i = 0; + } + } + + if (i) { + for (j = i; j < 3; j++) { + a3[j] = '\0'; + } + + a3_to_a4(a4, a3); + + for (j = 0; j < i + 1; j++) { + (*out)[enc_len++] = kBase64Alphabet[a4[j]]; + } + + while ((i++ < 3)) { + (*out)[enc_len++] = '='; + } + } + + return (enc_len == out->size()); +} // base64Encode + + +static int DecodedLength(const std::string &in) { + int numEq = 0; + int n = in.size(); + + for (std::string::const_reverse_iterator it = in.rbegin(); *it == '='; ++it) { + ++numEq; + } + return ((6 * n) / 8) - numEq; +} // DecodedLength + + +static unsigned char b64_lookup(unsigned char c) { + if(c >='A' && c <='Z') return c - 'A'; + if(c >='a' && c <='z') return c - 71; + if(c >='0' && c <='9') return c + 4; + if(c == '+') return 62; + if(c == '/') return 63; + return 255; +}; // b64_lookup + + +/** + * @brief Decode a chunk of data that is base64 encoded. + * @param [in] in The string to be decoded. + * @param [out] out The resulting data. + */ +bool GeneralUtils::base64Decode(const std::string &in, std::string *out) { + int i = 0, j = 0; + size_t dec_len = 0; + unsigned char a3[3]; + unsigned char a4[4]; + + int input_len = in.size(); + std::string::const_iterator input = in.begin(); + + out->resize(DecodedLength(in)); + + while (input_len--) { + if (*input == '=') { + break; + } + + a4[i++] = *(input++); + if (i == 4) { + for (i = 0; i <4; i++) { + a4[i] = b64_lookup(a4[i]); + } + + a4_to_a3(a3,a4); + + for (i = 0; i < 3; i++) { + (*out)[dec_len++] = a3[i]; + } + + i = 0; + } + } + + if (i) { + for (j = i; j < 4; j++) { + a4[j] = '\0'; + } + + for (j = 0; j < 4; j++) { + a4[j] = b64_lookup(a4[j]); + } + + a4_to_a3(a3,a4); + + for (j = 0; j < i - 1; j++) { + (*out)[dec_len++] = a3[j]; + } + } + + return (dec_len == out->size()); + } // base64Decode + +/* +void GeneralUtils::hexDump(uint8_t* pData, uint32_t length) { + uint32_t index=0; + std::stringstream ascii; + std::stringstream hex; + char asciiBuf[80]; + char hexBuf[80]; + hex.str(""); + ascii.str(""); + while(index < length) { + hex << std::setfill('0') << std::setw(2) << std::hex << (int)pData[index] << ' '; + if (std::isprint(pData[index])) { + ascii << pData[index]; + } else { + ascii << '.'; + } + index++; + if (index % 16 == 0) { + strcpy(hexBuf, hex.str().c_str()); + strcpy(asciiBuf, ascii.str().c_str()); + ESP_LOGD(tag, "%s %s", hexBuf, asciiBuf); + hex.str(""); + ascii.str(""); + } + } + if (index %16 != 0) { + while(index % 16 != 0) { + hex << " "; + index++; + } + strcpy(hexBuf, hex.str().c_str()); + strcpy(asciiBuf, ascii.str().c_str()); + ESP_LOGD(tag, "%s %s", hexBuf, asciiBuf); + //ESP_LOGD(tag, "%s %s", hex.str().c_str(), ascii.str().c_str()); + } + FreeRTOS::sleep(1000); +} +*/ + +/* +void GeneralUtils::hexDump(uint8_t* pData, uint32_t length) { + uint32_t index=0; + static std::stringstream ascii; + static std::stringstream hex; + hex.str(""); + ascii.str(""); + while(index < length) { + hex << std::setfill('0') << std::setw(2) << std::hex << (int)pData[index] << ' '; + if (std::isprint(pData[index])) { + ascii << pData[index]; + } else { + ascii << '.'; + } + index++; + if (index % 16 == 0) { + ESP_LOGD(tag, "%s %s", hex.str().c_str(), ascii.str().c_str()); + hex.str(""); + ascii.str(""); + } + } + if (index %16 != 0) { + while(index % 16 != 0) { + hex << " "; + index++; + } + ESP_LOGD(tag, "%s %s", hex.str().c_str(), ascii.str().c_str()); + } + FreeRTOS::sleep(1000); +} +*/ + +/** + * @brief Dump a representation of binary data to the console. + * + * @param [in] pData Pointer to the start of data to be logged. + * @param [in] length Length of the data (in bytes) to be logged. + * @return N/A. + */ +void GeneralUtils::hexDump(uint8_t* pData, uint32_t length) { + char ascii[80]; + char hex[80]; + char tempBuf[80]; + uint32_t lineNumber = 0; + + ESP_LOGD(LOG_TAG, " 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f ----------------"); + strcpy(ascii, ""); + strcpy(hex, ""); + uint32_t index=0; + while(index < length) { + sprintf(tempBuf, "%.2x ", pData[index]); + strcat(hex, tempBuf); + if (isprint(pData[index])) { + sprintf(tempBuf, "%c", pData[index]); + } else { + sprintf(tempBuf, "."); + } + strcat(ascii, tempBuf); + index++; + if (index % 16 == 0) { + ESP_LOGD(LOG_TAG, "%.4x %s %s", lineNumber*16, hex, ascii); + strcpy(ascii, ""); + strcpy(hex, ""); + lineNumber++; + } + } + if (index %16 != 0) { + while(index % 16 != 0) { + strcat(hex, " "); + index++; + } + ESP_LOGD(LOG_TAG, "%.4x %s %s", lineNumber*16, hex, ascii); + } +} // hexDump + +/** + * @brief Convert an IP address to string. + * @param ip The 4 byte IP address. + * @return A string representation of the IP address. + */ +std::string GeneralUtils::ipToString(uint8_t *ip) { + std::stringstream s; + s << (int)ip[0] << '.' << (int)ip[1] << '.' << (int)ip[2] << '.' << (int)ip[3]; + return s.str(); +} // ipToString + + +/** + * @brief Convert an ESP error code to a string. + * @param [in] errCode The errCode to be converted. + * @return A string representation of the error code. + */ +const char* GeneralUtils::errorToString(esp_err_t errCode) { + switch(errCode) { + case ESP_OK: + return "OK"; + case ESP_FAIL: + return "Fail"; + case ESP_ERR_NO_MEM: + return "No memory"; + case ESP_ERR_INVALID_ARG: + return "Invalid argument"; + case ESP_ERR_INVALID_SIZE: + return "Invalid state"; + case ESP_ERR_INVALID_STATE: + return "Invalid state"; + case ESP_ERR_NOT_FOUND: + return "Not found"; + case ESP_ERR_NOT_SUPPORTED: + return "Not supported"; + case ESP_ERR_TIMEOUT: + return "Timeout"; + case ESP_ERR_NVS_NOT_INITIALIZED: + return "ESP_ERR_NVS_NOT_INITIALIZED"; + case ESP_ERR_NVS_NOT_FOUND: + return "ESP_ERR_NVS_NOT_FOUND"; + case ESP_ERR_NVS_TYPE_MISMATCH: + return "ESP_ERR_NVS_TYPE_MISMATCH"; + case ESP_ERR_NVS_READ_ONLY: + return "ESP_ERR_NVS_READ_ONLY"; + case ESP_ERR_NVS_NOT_ENOUGH_SPACE: + return "ESP_ERR_NVS_NOT_ENOUGH_SPACE"; + case ESP_ERR_NVS_INVALID_NAME: + return "ESP_ERR_NVS_INVALID_NAME"; + case ESP_ERR_NVS_INVALID_HANDLE: + return "ESP_ERR_NVS_INVALID_HANDLE"; + case ESP_ERR_NVS_REMOVE_FAILED: + return "ESP_ERR_NVS_REMOVE_FAILED"; + case ESP_ERR_NVS_KEY_TOO_LONG: + return "ESP_ERR_NVS_KEY_TOO_LONG"; + case ESP_ERR_NVS_PAGE_FULL: + return "ESP_ERR_NVS_PAGE_FULL"; + case ESP_ERR_NVS_INVALID_STATE: + return "ESP_ERR_NVS_INVALID_STATE"; + case ESP_ERR_NVS_INVALID_LENGTH: + return "ESP_ERR_NVS_INVALID_LENGTH"; + case ESP_ERR_WIFI_NOT_INIT: + return "ESP_ERR_WIFI_NOT_INIT"; + //case ESP_ERR_WIFI_NOT_START: + // return "ESP_ERR_WIFI_NOT_START"; + case ESP_ERR_WIFI_IF: + return "ESP_ERR_WIFI_IF"; + case ESP_ERR_WIFI_MODE: + return "ESP_ERR_WIFI_MODE"; + case ESP_ERR_WIFI_STATE: + return "ESP_ERR_WIFI_STATE"; + case ESP_ERR_WIFI_CONN: + return "ESP_ERR_WIFI_CONN"; + case ESP_ERR_WIFI_NVS: + return "ESP_ERR_WIFI_NVS"; + case ESP_ERR_WIFI_MAC: + return "ESP_ERR_WIFI_MAC"; + case ESP_ERR_WIFI_SSID: + return "ESP_ERR_WIFI_SSID"; + case ESP_ERR_WIFI_PASSWORD: + return "ESP_ERR_WIFI_PASSWORD"; + case ESP_ERR_WIFI_TIMEOUT: + return "ESP_ERR_WIFI_TIMEOUT"; + case ESP_ERR_WIFI_WAKE_FAIL: + return "ESP_ERR_WIFI_WAKE_FAIL"; + } + return "Unknown ESP_ERR error"; +} // errorToString + |