RTL00_WEB_VS/RTLGDB/Project/web/web_utils.c

681 lines
19 KiB
C
Raw Normal View History

2017-11-28 19:31:40 +00:00
/*
* web_utils.c
*
* Created on: 25 дек. 2014 г.
* Author: PV`
*/
#include "user_config.h"
#include "autoconf.h"
#include "FreeRTOS.h"
#include "task.h"
#include "diag.h"
//#include "bios.h"
//#include "sdk/add_func.h"
//#include "ets_sys.h"
//#include "os_type.h"
//#include "osapi.h"
//#include "user_interface.h"
#include "web_utils.h"
#include "esp_comp.h"
#define mMIN(a, b) ((a<b)?a:b)
/******************************************************************************
* xstrcpy() из сегментов flash и IRAM с возвратом размера строки:
* на выходе размер строки, без учета терминатора '\0'
*******************************************************************************/
int ICACHE_RAM_ATTR rom_xstrcpy(char * pd, const char * ps)
{
#if 0
union {
unsigned char uc[4];
unsigned int ud;
}tmp;
if(ps == 0 || pd == 0) return (0);
*pd = 0;
unsigned int len = 0;
unsigned int *p = (unsigned int *)((unsigned int)ps & (~3));
unsigned int xlen = (unsigned int)ps & 3;
while(1) {
tmp.ud = *p++;
do {
if((*pd++ = tmp.uc[xlen++]) == 0) return len;
len++;
xlen &= 3;
} while(xlen);
}
#else
int len = 0;
while((*pd++ = *ps++) != 0) len++;
return len;
#endif
}
/******************************************************************************
* сравнение строки в ram со строкой в сегменте flash и IRAM
* = 1 если шаблон совпадает
*******************************************************************************/
int ICACHE_RAM_ATTR rom_xstrcmp(char * pd, const char * ps)
{
#if 0
union {
unsigned char uc[4];
unsigned int ud;
}tmp;
if(ps == 0 || pd == 0) return 0;
unsigned int *p = (unsigned int *)((unsigned int)ps & (~3));
unsigned int xlen = (unsigned int)ps & 3;
while(1) {
tmp.ud = *p++;
do {
if(tmp.uc[xlen] == 0) return 1;
if(tmp.uc[xlen++] != *pd || *pd++ == 0) return 0;
xlen &= 3;
} while(xlen);
}
#else
while(*ps) {
if(*pd++ != *ps++) return 0;
}
return 1;
#endif
}
/******************************************************************************
* rom_atoi
*******************************************************************************/
int ICACHE_FLASH_ATTR rom_atoi(const char *s)
{
int n=0, neg=0;
while (*s == ' ') s++;
switch (*s) {
case '-': neg=1;
case '+': s++;
}
/* Compute n as a negative number to avoid overflow on INT_MIN */
while (*s >= '0' && *s <= '9')
n = 10*n - (*s++ - '0');
return neg ? n : -n;
}
/******************************************************************************
* get_seg_id()
*******************************************************************************/
const char * const txt_tab_seg[] = {
"ROM" // 0
"SRAM", // 1
"TCM", // 2
"FLASH", // 3 // -> flash On
"SDRAM", // 4 // -> Test ChipID or HAL_PERI_ON_WRITE32(REG_SOC_FUNC_EN, HAL_PERI_ON_READ32(REG_SOC_FUNC_EN) | BIT(21)); // Flag SDRAM Off
"SOC", // 5 // protected !
"CPU", // 6 // protected !
"UNK", // 7
};
const uint32 tab_seg_def[] = {
0x00000000, 0x00050000,
0x10000000, 0x10070000,
0x1fff0000, 0x20000000,
0x98000000, 0xA0000000,
0x30000000, 0x30200000,
0x40000000, 0x40800000,
0xE0000000, 0xE0010000,
0x00000000, 0xFFFFFFFF
};
SEG_ID get_seg_id(uint32 addr, int32 size) {
SEG_ID ret = SEG_ID_ERR;
uint32 * ptr = (uint32 *) &tab_seg_def;
if (size > 0) {
do {
ret++;
if (addr >= ptr[0] && addr + size <= ptr[1]) {
return ret;
};
ptr += 2;
} while (ret < SEG_ID_MAX);
};
return 0;
}
/******************************************************************************
* copy_align4
* копирует данные из области кеширования flash и т.д.
*******************************************************************************/
void ICACHE_FLASH_ATTR copy_align4(void *ptrd, void *ptrs, uint32 len)
{
union {
uint8 uc[4];
uint32 ud;
}tmp;
uint8 *pd = ptrd;
uint32 *p = (uint32 *)((uint32)ptrs & (~3));
uint32 xlen = ((uint32)ptrs) & 3;
if(xlen) {
if(((uint32)p >= 0x10000000)&&((uint32)p < 0x9A002000)) tmp.ud = *p++;
else {
tmp.ud = 0;
p++;
}
while (len) {
*pd++ = tmp.uc[xlen++];
len--;
if(xlen >= 4) break;
}
}
xlen = len >> 2;
while(xlen) {
if(((uint32)p >= 0x10000000)&&((uint32)p < 0x9A002000)) tmp.ud = *p++;
else {
tmp.ud = 0;
p++;
}
*pd++ = tmp.uc[0];
*pd++ = tmp.uc[1];
*pd++ = tmp.uc[2];
*pd++ = tmp.uc[3];
xlen--;
}
len &= 3;
if(len) {
if(((uint32)p >= 0x10000000)&&((uint32)p < 0x9A002000)) tmp.ud = *p;
else tmp.ud = 0;
uint8 * ptmp = tmp.uc;
while (len--) *pd++ = *ptmp++;
}
}
/******************************************************************************
* FunctionName : hextoul
*******************************************************************************/
// bool conv_str_hex(uint32 * dest, uint8 *s);
uint32 ICACHE_FLASH_ATTR hextoul(uint8 *s)
{
/*
uint32 val;
if(!conv_str_hex(&val, s)) return 0;
return val;
*/
uint32 val = 0;
while (*s)
{
if (*s >= '0' && *s <= '9')
{
val <<= 4;
val |= *s - '0';
}
else if (*s >= 'A' && *s <= 'F')
{
val <<= 4;
val |= *s - 'A' + 10;
}
else if (*s >= 'a' && *s <= 'f')
{
val <<= 4;
val |= *s - 'a' + 10;
}
else break;
s++;
};
return val;
}
/******************************************************************************
* FunctionName : ahextoul
*******************************************************************************/
// bool convert_para_str(uint32 * dest, uint8 *s);
uint32 ICACHE_FLASH_ATTR ahextoul(uint8 *s)
{
/*
uint32 ret;
if(!convert_para_str(&ret, s)) return 0;
return ret;
*/
if((s[0]=='0') && ((s[1] | 0x20) =='x')) return hextoul(s+2);
return rom_atoi(s);
}
/******************************************************************************
* FunctionName : cmpcpystr
* Description : выбирает слово из строки текста с заданными начальным символом
* и конечным терминатором. Терминатор и стартовый символ не копирует, если заданы.
* Parameters : При задании начального символа = '\0' берется любой символ (>' ').
Копирует до символа <' ' или терминатора.
Задается ограничение размера буфера для копируемого слова (с дописыванием в буфер '\0'!).
* Returns : Зависит от значения терминатора, указывает на терминатор в строке,
если терминатор найден.
Если NULL, то начальный или конечный терминатор не найден.
*******************************************************************************/
uint8 * ICACHE_FLASH_ATTR cmpcpystr(uint8 *pbuf, uint8 *pstr, uint8 a, uint8 b, uint16 len)
{
if(len == 0) pbuf = NULL;
if(pstr == NULL) {
if(pbuf != NULL) *pbuf='\0';
return NULL;
};
uint8 c;
do {
c = *pstr;
if(c < ' ') { // строка кончилась
if(pbuf != NULL) *pbuf='\0';
return NULL; // id не найден
};
if((a == '\0')&&(c > ' ')) break; // не задан -> любой символ
pstr++;
if(c == a) break; // нашли стартовый символ (некопируемый в буфер)
}while(1);
if(pbuf != NULL) {
while(len--) {
c = *pstr;
if(c == b) { // нашли терминирующий символ (некопируемый в буфер)
*pbuf='\0';
return pstr; // конечный терминатор найден
};
// if(c <= ' ') { // строка кончилась или пробел
if(c < ' ') { // строка кончилась или пробел
*pbuf='\0';
return NULL; // конечный терминатор не найден
};
pstr++;
*pbuf++ = c;
};
*--pbuf='\0'; // закрыть буфер
};
do {
c = *pstr;
if(c == b) return pstr; // нашли терминирующий символ
// if(c <= ' ') return NULL; // строка кончилась
if(c < ' ') return NULL; // строка кончилась
pstr++;
}while(1);
}
/******************************************************************************
* FunctionName : str_array
* Набирает из строки s массив слов в buf в кол-ве до max_buf
* возврат - кол-во переменных в строке
* Разделитель переменных в строке ','
* Если нет переменной, то пропускает изменение в buf
* Примеры:
* Строка "1,2,3,4" -> buf = 0x01 0x02 0x03 0x04
* Строка "1,,3," -> buf = 0x01 (не изменено) 0x03 (не изменено)
*******************************************************************************/
uint32 ICACHE_FLASH_ATTR str_array(uint8 *s, uint32 *buf, uint32 max_buf)
{
uint32 ret = 0;
uint8 *sval = NULL;
while(max_buf > ret) {
if(sval == NULL) {
if (*s == '-' && s[1] >= '0' && s[1] <= '9') {
sval = s;
s++;
}
else if (*s >= '0' && *s <= '9') sval = s;
}
if(*s == ',' || *s <= ')') {
if(sval != NULL) {
*buf = ahextoul(sval);
sval = NULL;
}
buf++;
ret++;
if(*s < ')') return ret;
}
s++;
}
return ret;
}
uint32 ICACHE_FLASH_ATTR str_array_w(uint8 *s, uint16 *buf, uint32 max_buf)
{
uint32 ret = 0;
uint8 *sval = NULL;
while(max_buf > ret) {
if(sval == NULL) {
if (*s == '-' && s[1] >= '0' && s[1] <= '9') {
sval = s;
s++;
}
else if (*s >= '0' && *s <= '9') sval = s;
}
if(*s == ',' || *s <= ')') {
if(sval != NULL) {
*buf = ahextoul(sval);
sval = NULL;
}
buf++;
ret++;
if(*s < ')') return ret;
}
s++;
}
return ret;
}
uint32 ICACHE_FLASH_ATTR str_array_b(uint8 *s, uint8 *buf, uint32 max_buf)
{
uint32 ret = 0;
uint8 *sval = NULL;
while(max_buf > ret) {
if(sval == NULL) {
if (*s == '-' && s[1] >= '0' && s[1] <= '9') {
sval = s;
s++;
}
else if (*s >= '0' && *s <= '9') sval = s;
}
if(*s == ',' || *s == '.' || *s <= ')') {
if(sval != NULL) {
*buf = ahextoul(sval);
sval = NULL;
}
buf++;
ret++;
if(*s < ')') return ret;
}
s++;
}
return ret;
}
/******************************************************************************
* FunctionName : strtmac
*******************************************************************************/
void ICACHE_FLASH_ATTR strtomac(uint8 *s, uint8 *macaddr)
{
uint8 pbuf[4];
s = cmpcpystr(pbuf, s, 0, ':', 3);
*macaddr++ = hextoul(pbuf);
int i = 4;
while(i--) {
s = cmpcpystr(pbuf, s, ':', ':', 3);
*macaddr++ = hextoul(pbuf);
}
s = cmpcpystr(pbuf, s, ':', ' ', 3);
*macaddr++ = hextoul(pbuf);
}
/******************************************************************************
* FunctionName : urldecode
*******************************************************************************/
int ICACHE_FLASH_ATTR urldecode(uint8 *d, uint8 *s, uint16 lend, uint16 lens)
{
uint16 ret = 0;
if(s != NULL) while ((lens--) && (lend--) && (*s > ' ')) {
if ((*s == '%')&&(lens > 1)) {
s++;
int i = 2;
uint8 val = 0;
while(i--) {
if (*s >= '0' && *s <= '9') {
val <<= 4;
val |= *s - '0';
} else if (*s >= 'A' && *s <= 'F') {
val <<= 4;
val |= *s - 'A' + 10;
} else if (*s >= 'a' && *s <= 'f') {
val <<= 4;
val |= *s - 'a' + 10;
} else
break;
s++;
lens--;
};
s--;
*d++ = val;
} else if (*s == '+')
*d++ = ' ';
else
*d++ = *s;
ret++;
s++;
}
*d = '\0';
return ret;
}
/******************************************************************************
* FunctionName : urlencode
*******************************************************************************/
/*int ICACHE_FLASH_ATTR urlencode(uint8 *d, uint8 *s, uint16 lend, uint16 lens)
{
uint16 ret = 0;
if(s != NULL) while ((lens--) && (lend--) && (*s != '\0')) {
if ( (48 <= *s && *s <= 57) //0-9
|| (65 <= *s && *s <= 90) //abc...xyz
|| (97 <= *s && *s <= 122) //ABC...XYZ
|| (*s == '~' || *s == '!' || *s == '*' || *s == '(' || *s == ')' || *s == '\'')) {
*d++ = *s++;
ret++;
} else {
if(lend >= 3) {
ret += 3;
lend -= 3;
*d++ = '%';
uint8 val = *s >> 4;
if(val <= 9) val += '0';
else val += 0x41 - 10;
*d++ = val;
val = *s++ & 0x0F;
if(val <= 9) val += '0';
else val += 0x41 - 10;
*d++ = val;
}
else break;
}
}
*d = '\0';
return ret;
}*/
/******************************************************************************
* FunctionName : htmlcode
*******************************************************************************/
int ICACHE_FLASH_ATTR htmlcode(uint8 *d, uint8 *s, uint16 lend, uint16 lens)
{
uint16 ret = 0;
if(s != NULL) while ((lens--) && (lend--) && (*s != '\0')) {
if ( *s == 0x27 ) { // "'" &apos;
if(lend >= 6) {
ret += 6;
lend -= 6;
s++;
*d++ = '&';
*d++ = 'a';
*d++ = 'p';
*d++ = 'o';
*d++ = 's';
*d++ = ';';
}
else break;
} else if ( *s == '"' ) { // &quot;
if(lend >= 6) {
ret += 6;
lend -= 6;
s++;
*d++ = '&';
*d++ = 'q';
*d++ = 'u';
*d++ = 'o';
*d++ = 't';
*d++ = ';';
}
else break;
} else if ( *s == '&' ) { // &amp;
if(lend >= 5) {
ret += 5;
lend -= 5;
s++;
*d++ = '&';
*d++ = 'a';
*d++ = 'm';
*d++ = 'p';
*d++ = ';';
}
else break;
} else if ( *s == '<' ) { // &lt;
if(lend >= 4) {
ret += 4;
lend -= 4;
s++;
*d++ = '&';
*d++ = 'l';
*d++ = 't';
*d++ = ';';
}
else break;
} else if ( *s == '>' ) { // &gt;
if(lend >= 4) {
ret += 4;
lend -= 4;
s++;
*d++ = '&';
*d++ = 'g';
*d++ = 't';
*d++ = ';';
}
else break;
} else {
*d++ = *s++;
ret++;
}
}
*d = '\0';
return ret;
}
//=============================================================================
extern size_t rtl_strlen(const char *str);
extern int rtl_strncmp(const char *s1, const char *s2, size_t n);
uint8* ICACHE_FLASH_ATTR
web_strnstr(const uint8* buffer, const uint8* token, int len)
{
const uint8* p;
int tokenlen = rtl_strlen(token);
if (tokenlen == 0) {
return (uint8 *)buffer;
};
for (p = buffer; *p && (p + tokenlen <= buffer + len); p++) {
if ((*p == *token) && (rtl_strncmp(p, token, tokenlen) == 0)) {
return (uint8 *)p;
};
};
return NULL;
}
//=============================================================================
static const uint8_t base64map[128] ICACHE_RODATA_ATTR =
{
255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
255,255,255,255,255,255,255,255,255,255,255, 62,255,255,255, 63,
52, 53, 54, 55, 56, 57, 58, 59, 60, 61,255,255,255, 0,255,255,
255, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25,255,255,255,255,255,
255, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40,
41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51,255,255,255,255,255
};
//=============================================================================
bool ICACHE_FLASH_ATTR base64decode(const uint8 *in, int len, uint8_t *out, int *outlen)
{
// uint8 *map = (uint8 *)UartDev.rcv_buff.pRcvMsgBuff;
// ets_memcpy(map, base64map, 128);
uint8 *map = (uint8 *) base64map;
int g, t, x, y, z;
uint8_t c;
g = 3;
for (x = y = z = t = 0; x < len; x++) {
if ((c = map[in[x]&0x7F]) == 0xff) continue;
if (c == 254) { /* this is the end... */
c = 0;
if (--g < 0) return false;
}
else if (g != 3) return false; /* only allow = at end */
t = (t<<6) | c;
if (++y == 4) {
out[z++] = (uint8_t)((t>>16)&255);
if (g > 1) out[z++] = (uint8_t)((t>>8)&255);
if (g > 2) out[z++] = (uint8_t)(t&255);
y = t = 0;
}
/* check that we don't go past the output buffer */
if (z > *outlen) return false;
}
if (y != 0) return false;
*outlen = z;
return true;
}
//=============================================================================
/* Table 6-bit-index-to-ASCII used for base64-encoding */
const uint8_t base64_table[] = {
'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H',
'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P',
'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z',
'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h',
'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p',
'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z',
'0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
'+', '/'
};
// ld: PROVIDE ( base64_table = 0x3FFFD600 );
//extern const uint8_t base64_table[];
//=============================================================================
/** Base64 encoding */
size_t ICACHE_FLASH_ATTR base64encode(char* target, size_t target_len, const char* source, size_t source_len)
{
size_t i;
sint8 j;
size_t target_idx = 0;
size_t longer = 3 - (source_len % 3);
size_t source_len_b64 = source_len + longer;
size_t len = (((source_len_b64) * 4) / 3);
uint8 x = 5;
uint8 current = 0;
if(target == NULL || target_len < len) return 0;
for (i = 0; i < source_len_b64; i++) {
uint8 b = (i < source_len ? source[i] : 0);
for (j = 7; j >= 0; j--, x--) {
uint8 shift = ((b & (1 << j)) != 0) ? 1 : 0;
current |= shift << x;
if (x == 0) {
target[target_idx++] = base64_table[current];
x = 6;
current = 0;
}
}
}
for (i = len - longer; i < len; i++) {
target[i] = '=';
}
return len;
}
/*
//=============================================================================
void ICACHE_FLASH_ATTR print_hex_dump(uint8 *buf, uint32 len, uint8 k)
{
if(!system_get_os_print()) return; // if(*((uint8 *)(0x3FFE8000)) == 0) return;
uint32 ss[2];
ss[0] = 0x78323025; // "%02x"
ss[1] = k; // ","...'\0'
uint8* ptr = buf;
while(len--) {
if(len == 0) ss[1] = 0;
ets_printf((uint8 *)&ss[0], *ptr++);
}
}
*/
//=============================================================================
#define LowerCase(a) ((('A' <= a) && (a <= 'Z')) ? a + 32 : a)
char* ICACHE_FLASH_ATTR word_to_lower_case(char* text) {
for(; *text ==' '; text++);
char* p = text;
for (; *p >= ' '; p++) {
*p = LowerCase(*p);
}
return text;
}
#if 0
//=============================================================================
/* char UpperCase(char ch) {
return (('a' <= ch) && (ch <= 'z')) ? ch - 32 : ch; }*/
#define UpperCase(a) ((('a' <= a) && (a <= 'z')) ? a - 32 : a)
char* ICACHE_FLASH_ATTR str_to_upper_case(char* text) {
char* p = text;
for (; *p; ++p) {
*p = UpperCase(*p);
}
return text;
}
#endif