#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() {
}
GeneralUtils::~GeneralUtils() {
}
static int base64EncodedLength(size_t length) {
return (length + 2 - ((length + 2) % 3)) / 3 * 4;
}
static int base64EncodedLength(const std::string &in) {
return base64EncodedLength(in.length());
}
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);
}
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];
}
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());
}
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;
}
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;
};
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());
}
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);
}
}
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();
}
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_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";
}