mirror of
https://github.com/ADElectronics/RTL00_WEB_WS2812.git
synced 2025-07-31 20:31:07 +00:00
1st
This commit is contained in:
parent
7f07f696e1
commit
c6c5eeed6f
1170 changed files with 608790 additions and 1 deletions
52
Firmware/RTLGDB/Project/web/web_auth.c
Normal file
52
Firmware/RTLGDB/Project/web/web_auth.c
Normal file
|
|
@ -0,0 +1,52 @@
|
|||
/*
|
||||
* web_auth.c
|
||||
*
|
||||
* Created on: 23/04/2017.
|
||||
* Author: pvvx
|
||||
*/
|
||||
#include "autoconf.h"
|
||||
#include "FreeRTOS.h"
|
||||
#include "diag.h"
|
||||
#include "web_utils.h"
|
||||
#include "wifi_api.h"
|
||||
#include "web_srv.h"
|
||||
#include "rtl8195a/rtl_libc.h"
|
||||
#include "esp_comp.h"
|
||||
|
||||
|
||||
/* ----------------------------------------------------------------------------------
|
||||
* pbuf[77] = Username and password are combined into a string "username:password"
|
||||
* Return: Authorization Level
|
||||
* 0 - Not Authorized */
|
||||
|
||||
uint8 UserAuthorization(uint8 *pbuf, size_t declen)
|
||||
{
|
||||
uint8 * psw = rtl_strchr(pbuf, ':');
|
||||
if(psw != NULL)
|
||||
{
|
||||
#if USE_WEB_AUTH_LEVEL
|
||||
if(rtl_strcmp(pbuf, "rtl871x:webfs_write") == 0)
|
||||
{
|
||||
return WEB_AUTH_LEVEL_WEBFS;
|
||||
}
|
||||
if(rtl_strcmp(pbuf, "rtl871x:ota_write") == 0)
|
||||
{
|
||||
return WEB_AUTH_LEVEL_OTA;
|
||||
}
|
||||
if(rtl_strcmp(pbuf, "rtl871x:supervisor") == 0)
|
||||
{
|
||||
return WEB_AUTH_LEVEL_SUPERVISOR;
|
||||
}
|
||||
#endif
|
||||
*psw++ = 0;
|
||||
if(rom_xstrcmp(wifi_ap_cfg.ssid, pbuf) && rom_xstrcmp( wifi_ap_cfg.password, psw))
|
||||
{
|
||||
return WEB_AUTH_LEVEL_USER;
|
||||
}
|
||||
if(rom_xstrcmp(wifi_st_cfg.ssid, pbuf) && rom_xstrcmp( wifi_st_cfg.password, psw))
|
||||
{
|
||||
return WEB_AUTH_LEVEL_USER1;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
733
Firmware/RTLGDB/Project/web/web_int_callbacks.c
Normal file
733
Firmware/RTLGDB/Project/web/web_int_callbacks.c
Normal file
|
|
@ -0,0 +1,733 @@
|
|||
/******************************************************************************
|
||||
* FileName: web_int_callbacks.c
|
||||
* Description: The web server inernal callbacks.
|
||||
*******************************************************************************/
|
||||
|
||||
#include "user_config.h"
|
||||
#ifdef USE_WEB
|
||||
#include "autoconf.h"
|
||||
#include "FreeRTOS.h"
|
||||
#include "task.h"
|
||||
#include "diag.h"
|
||||
#include "tcm_heap.h"
|
||||
#include "lwip/tcp.h"
|
||||
#include "flash_eep.h"
|
||||
#include "device_lock.h"
|
||||
#include "ethernetif.h"
|
||||
#include "tcpsrv/tcp_srv_conn.h"
|
||||
#include "web_srv_int.h"
|
||||
#include "web_utils.h"
|
||||
#include "webfs/webfs.h"
|
||||
#include "rtl8195a/rtl_libc.h"
|
||||
#include "sys_cfg.h"
|
||||
#include "wifi_api.h"
|
||||
#include "sys_api.h"
|
||||
#include "esp_comp.h"
|
||||
#include "sdk_ver.h"
|
||||
|
||||
#include "ledeffectsserver.h"
|
||||
|
||||
#ifdef USE_NETBIOS
|
||||
#include "netbios/netbios.h"
|
||||
#endif
|
||||
|
||||
#ifdef USE_SNTP
|
||||
#include "sntp/sntp.h"
|
||||
#endif
|
||||
|
||||
#ifdef USE_CAPTDNS
|
||||
#include "captdns.h"
|
||||
#endif
|
||||
|
||||
#ifdef USE_MODBUS
|
||||
#include "modbustcp.h"
|
||||
#include "mdbtab.h"
|
||||
#endif
|
||||
|
||||
#ifdef USE_RS485DRV
|
||||
#include "driver/rs485drv.h"
|
||||
#endif
|
||||
|
||||
#ifdef USE_OVERLAY
|
||||
#include "overlay.h"
|
||||
#endif
|
||||
|
||||
#undef atoi
|
||||
#define atoi rom_atoi
|
||||
|
||||
//#define mMIN(a, b) ((a<b)?a:b)
|
||||
#define ifcmp(a) if(rom_xstrcmp(cstr, a))
|
||||
|
||||
#define OpenFlash() { device_mutex_lock(RT_DEV_LOCK_FLASH); flash_turnon(); }
|
||||
#define CloseFlash() { SpicDisableRtl8195A(); device_mutex_unlock(RT_DEV_LOCK_FLASH); }
|
||||
|
||||
|
||||
extern struct netif xnetif[NET_IF_NUM]; /* network interface structure */
|
||||
|
||||
|
||||
#if WEB_DEBUG_FUNCTIONS
|
||||
//#define TEST_SEND_WAVE
|
||||
#endif // #if WEB_DEBUG_FUNCTIONS
|
||||
|
||||
#ifdef TEST_SEND_WAVE
|
||||
//-------------------------------------------------------------------------------
|
||||
// Test adc
|
||||
// Читает adc в одиночный буфер (~2килобайта) на ~20ksps и сохраняет в виде WAV
|
||||
// Правильное чтение организуется по прерыванию таймера(!).
|
||||
// Тут только демо!
|
||||
//-------------------------------------------------------------------------------
|
||||
typedef struct
|
||||
{ // https://ccrma.stanford.edu/courses/422/projects/WaveFormat/
|
||||
unsigned long int RIFF ;/* +00 'RIFF' */
|
||||
unsigned long int size8;/* +04 file size - 8 */
|
||||
unsigned long int WAVE ;/* +08 'WAVE' */
|
||||
unsigned long int fmt ;/* +12 'fmt ' */
|
||||
unsigned long int fsize;/* +16 указатель до 'fact' или 'data' */
|
||||
unsigned short int ccod;/* +20 01 00 Compression code: 1 - PCM/uncompressed */
|
||||
unsigned short int mono;/* +22 00 01 или 00 02 */
|
||||
unsigned long int freq ;/* +24 частота */
|
||||
unsigned long int bps ;/* +28 */
|
||||
unsigned short int blka;/* +32 1/2/4 BlockAlign*/
|
||||
unsigned short int bits;/* +34 разрядность 8/16 */
|
||||
unsigned long int data ;/* +36 'data' */
|
||||
unsigned long int dsize;/* +40 размер данных */
|
||||
} WAV_HEADER;
|
||||
const WAV_HEADER ICACHE_RODATA_ATTR wav_header =
|
||||
{0x46464952L,
|
||||
0x00000008L,
|
||||
0x45564157L,
|
||||
0x20746d66L,
|
||||
0x00000010L,
|
||||
0x0001 ,
|
||||
0x0001 ,
|
||||
0x000055f0L,
|
||||
0x000055f0L,
|
||||
0x0002 ,
|
||||
0x0010 ,
|
||||
0x61746164L,
|
||||
0x00000000L};
|
||||
#define WAV_HEADER_SIZE sizeof(wav_header)
|
||||
//===============================================================================
|
||||
// web_test_adc()
|
||||
//-------------------------------------------------------------------------------
|
||||
void ICACHE_FLASH_ATTR web_test_adc(TCP_SERV_CONN *ts_conn)
|
||||
{
|
||||
WEB_SRV_CONN *web_conn = (WEB_SRV_CONN *) ts_conn->linkd;
|
||||
unsigned int len = web_conn->msgbufsize - web_conn->msgbuflen;
|
||||
if(len > WAV_HEADER_SIZE + 10) {
|
||||
len -= WAV_HEADER_SIZE;
|
||||
WAV_HEADER * ptr = (WAV_HEADER *) &web_conn->msgbuf[web_conn->msgbuflen];
|
||||
os_memcpy(ptr, &wav_header, WAV_HEADER_SIZE);
|
||||
ptr->dsize = len;
|
||||
web_conn->msgbuflen += WAV_HEADER_SIZE;
|
||||
len >>= 1;
|
||||
read_adcs((uint16 *)(web_conn->msgbuf + web_conn->msgbuflen), len, 0x0808);
|
||||
web_conn->msgbuflen += len << 1;
|
||||
}
|
||||
if(!CheckSCB(SCB_WEBSOC)) SetSCB(SCB_FCLOSE | SCB_DISCONNECT); // connection close
|
||||
}
|
||||
#endif // TEST_SEND_WAVE
|
||||
|
||||
//===============================================================================
|
||||
// WiFi Scan XML
|
||||
//-------------------------------------------------------------------------------
|
||||
extern void wifi_set_timer_scan(int ms);
|
||||
static void ICACHE_FLASH_ATTR web_wscan_xml(TCP_SERV_CONN *ts_conn)
|
||||
{
|
||||
WEB_SRV_CONN *web_conn = (WEB_SRV_CONN *) ts_conn->linkd;
|
||||
web_scan_handler_t * pwscn_rec = &web_scan_handler_ptr;
|
||||
// Check if this is a first round call
|
||||
if(CheckSCB(SCB_RETRYCB)==0) {
|
||||
int i = 0;
|
||||
web_conn->udata_start = 0;
|
||||
if(pwscn_rec->flg == 2) {
|
||||
i = pwscn_rec->ap_count;
|
||||
wifi_set_timer_scan(7000);
|
||||
} else if(pwscn_rec->flg == 0) api_wifi_scan(NULL);
|
||||
tcp_puts_fd("<total>%d</total>", i);
|
||||
if(i == 0) return;
|
||||
}
|
||||
while(web_conn->msgbuflen + 96 + 10 + 32 <= web_conn->msgbufsize) {
|
||||
if(pwscn_rec->flg && web_conn->udata_start < pwscn_rec->ap_count) {
|
||||
rtw_scan_result_t *si = &pwscn_rec->ap_details[web_conn->udata_start];
|
||||
uint8 ssid[32*6 + 1];
|
||||
int len = si->SSID.len;
|
||||
if(len > 32) len = 32;
|
||||
si->SSID.val[len] = '\0';
|
||||
if(web_conn->msgbuflen + 96 + 10 + htmlcode(ssid, si->SSID.val, 32*6, 32) > web_conn->msgbufsize) break;
|
||||
tcp_puts_fd("<ap id=\"%d\"><ch>%d</ch><au>%d</au><bs>" MACSTR "</bs><ss>%s</ss><rs>%d</rs><hd>%d</hd><wp>%d</wp></ap>",
|
||||
web_conn->udata_start,
|
||||
si->channel,
|
||||
rtw_security_to_idx(si->security),
|
||||
MAC2STR(si->BSSID.octet),
|
||||
ssid,
|
||||
si->signal_strength,
|
||||
// si->band, // rtw_802_11_band_t
|
||||
si->bss_type & 3, // rtw_bss_type_t
|
||||
si->wps_type); // rtw_wps_type_t
|
||||
web_conn->udata_start++;
|
||||
if(web_conn->udata_start >= pwscn_rec->ap_count) {
|
||||
wifi_close_scan();
|
||||
ClrSCB(SCB_RETRYCB);
|
||||
return;
|
||||
}
|
||||
}
|
||||
else {
|
||||
wifi_close_scan();
|
||||
ClrSCB(SCB_RETRYCB);
|
||||
return;
|
||||
}
|
||||
}
|
||||
// repeat in the next call ...
|
||||
SetSCB(SCB_RETRYCB);
|
||||
SetNextFunSCB(web_wscan_xml);
|
||||
return;
|
||||
}
|
||||
#ifdef USE_MODBUS
|
||||
//===============================================================================
|
||||
// Mdb XML
|
||||
//-------------------------------------------------------------------------------
|
||||
void ICACHE_FLASH_ATTR web_modbus_xml(TCP_SERV_CONN *ts_conn)
|
||||
{
|
||||
WEB_SRV_CONN *web_conn = (WEB_SRV_CONN *) ts_conn->linkd;
|
||||
while(web_conn->msgbuflen + 24 <= web_conn->msgbufsize) {
|
||||
if(web_conn->udata_start < web_conn->udata_stop) {
|
||||
uint16 val16;
|
||||
if(RdMdbData((uint8 *)&val16, web_conn->udata_start, 1) != 0) tcp_puts_fd("<m%u>?</m%u>", web_conn->udata_start, web_conn->udata_start);
|
||||
else {
|
||||
if(ts_conn->flag.user_option2) {
|
||||
if(ts_conn->flag.user_option1) {
|
||||
tcp_puts_fd("<m%u>0x%04x</m%u>", web_conn->udata_start, val16, web_conn->udata_start);
|
||||
}
|
||||
else {
|
||||
tcp_puts_fd("<m%u>%04x</m%u>", web_conn->udata_start, val16, web_conn->udata_start);
|
||||
};
|
||||
}
|
||||
else {
|
||||
if(ts_conn->flag.user_option1) {
|
||||
tcp_puts_fd("<m%u>%d</m%u>", web_conn->udata_start, (sint32)((sint16)val16), web_conn->udata_start);
|
||||
}
|
||||
else {
|
||||
tcp_puts_fd("<m%u>%u</m%u>", web_conn->udata_start, val16, web_conn->udata_start);
|
||||
};
|
||||
};
|
||||
};
|
||||
web_conn->udata_start++;
|
||||
}
|
||||
else {
|
||||
ClrSCB(SCB_RETRYCB);
|
||||
return;
|
||||
}
|
||||
}
|
||||
// repeat in the next call ...
|
||||
SetSCB(SCB_RETRYCB);
|
||||
SetNextFunSCB(web_modbus_xml);
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
//===============================================================================
|
||||
// RAM hexdump
|
||||
//-------------------------------------------------------------------------------
|
||||
void ICACHE_FLASH_ATTR web_hexdump(TCP_SERV_CONN *ts_conn)
|
||||
{
|
||||
WEB_SRV_CONN *web_conn = (WEB_SRV_CONN *) ts_conn->linkd;
|
||||
union {
|
||||
uint32 dw[4];
|
||||
uint8 b[16];
|
||||
}data;
|
||||
web_conn->udata_start &= 0xfffffff0;
|
||||
uint32 *addr = (uint32 *)web_conn->udata_start;
|
||||
int i;
|
||||
web_conn->udata_stop &= 0xfffffff0;
|
||||
while(web_conn->msgbuflen + (9+3*16+17+2) <= web_conn->msgbufsize) {
|
||||
// if((uint32)addr < 0x9A000000) {
|
||||
if((uint32)addr >= 0x98000000 && (uint32)addr < 0x9A000000) {
|
||||
OpenFlash();
|
||||
}
|
||||
tcp_puts("%08x", addr);
|
||||
for(i=0 ; i < 4 ; i++) data.dw[i] = *addr++;
|
||||
web_conn->udata_start = (uint32)addr;
|
||||
if(ts_conn->flag.user_option1) { // dword or byte ?
|
||||
for(i=0 ; i < 4 ; i++) tcp_puts(" %08x", data.dw[i]);
|
||||
}
|
||||
else {
|
||||
for(i=0 ; i < 16 ; i++) tcp_puts(" %02x", data.b[i]);
|
||||
}
|
||||
if((uint32)addr >= 0x98000000 && (uint32)addr < 0x9A000000) {
|
||||
CloseFlash();
|
||||
}
|
||||
tcp_put(' '); tcp_put(' ');
|
||||
for(i=0 ; i < 16 ; i++) tcp_put((data.b[i] >=' ' && data.b[i] != 0x7F)? data.b[i] : '.');
|
||||
tcp_puts("\r\n");
|
||||
if((uint32)addr >= web_conn->udata_stop) {
|
||||
ClrSCB(SCB_RETRYCB);
|
||||
if(!CheckSCB(SCB_WEBSOC)) SetSCB(SCB_FCLOSE | SCB_DISCONNECT); // connection close
|
||||
return;
|
||||
}
|
||||
// } else {
|
||||
// tcp_puts("%p = Bad address!\r\n", addr);
|
||||
// ClrSCB(SCB_RETRYCB);
|
||||
// if(!CheckSCB(SCB_WEBSOC)) SetSCB(SCB_FCLOSE | SCB_DISCONNECT); // connection close
|
||||
// return;
|
||||
// };
|
||||
}
|
||||
// repeat in the next call ...
|
||||
SetSCB(SCB_RETRYCB);
|
||||
SetNextFunSCB(web_hexdump);
|
||||
return;
|
||||
}
|
||||
/******************************************************************************
|
||||
* FunctionName : web saved flash
|
||||
* Description : Processing the flash data send
|
||||
* Parameters : none (Calback)
|
||||
* Returns : none
|
||||
*******************************************************************************/
|
||||
void ICACHE_FLASH_ATTR web_get_flash(TCP_SERV_CONN *ts_conn)
|
||||
{
|
||||
WEB_SRV_CONN *web_conn = (WEB_SRV_CONN *)ts_conn->linkd;
|
||||
// Check if this is a first round call
|
||||
if(CheckSCB(SCB_RETRYCB)==0) {
|
||||
if(web_conn->udata_start == web_conn->udata_stop) return;
|
||||
#if DEBUGSOO > 2
|
||||
os_printf("file_size:%08x ", web_conn->udata_stop - web_conn->udata_start );
|
||||
#endif
|
||||
}
|
||||
// Get/put as many bytes as possible
|
||||
unsigned int len = mMIN(web_conn->msgbufsize - web_conn->msgbuflen, web_conn->udata_stop - web_conn->udata_start);
|
||||
// Read Flash addr = web_conn->webfinc_offsets, len = x, buf = sendbuf
|
||||
#if DEBUGSOO > 2
|
||||
os_printf("%08x..%08x ",web_conn->udata_start, web_conn->udata_start + len );
|
||||
#endif
|
||||
device_mutex_lock(RT_DEV_LOCK_FLASH);
|
||||
if(spi_flash_read(web_conn->udata_start, web_conn->msgbuf, len)) {
|
||||
web_conn->udata_start += len;
|
||||
web_conn->msgbuflen += len;
|
||||
if(web_conn->udata_start < web_conn->udata_stop) {
|
||||
SetNextFunSCB(web_get_flash);
|
||||
device_mutex_unlock(RT_DEV_LOCK_FLASH);
|
||||
SetSCB(SCB_RETRYCB);
|
||||
return;
|
||||
};
|
||||
};
|
||||
device_mutex_unlock(RT_DEV_LOCK_FLASH);
|
||||
ClrSCB(SCB_RETRYCB);
|
||||
// SetSCB(SCB_FCLOSE | SCB_DISCONNECT);
|
||||
return;
|
||||
}
|
||||
/******************************************************************************
|
||||
* FunctionName : web saved flash
|
||||
* Description : Processing the flash data send
|
||||
* Parameters : none (Calback)
|
||||
* Returns : none
|
||||
*******************************************************************************/
|
||||
void ICACHE_FLASH_ATTR web_get_ram(TCP_SERV_CONN *ts_conn)
|
||||
{
|
||||
WEB_SRV_CONN *web_conn = (WEB_SRV_CONN *)ts_conn->linkd;
|
||||
// Check if this is a first round call
|
||||
if(CheckSCB(SCB_RETRYCB)==0) { // On initial call, проверка параметров
|
||||
if(web_conn->udata_start == web_conn->udata_stop) {
|
||||
// SetSCB(SCB_FCLOSE | SCB_DISCONNECT);
|
||||
return;
|
||||
}
|
||||
#if DEBUGSOO > 2
|
||||
os_printf("file_size:%08x ", web_conn->udata_stop - web_conn->udata_start );
|
||||
#endif
|
||||
}
|
||||
// Get/put as many bytes as possible
|
||||
uint32 len = mMIN(web_conn->msgbufsize - web_conn->msgbuflen, web_conn->udata_stop - web_conn->udata_start);
|
||||
if((uint32)web_conn->udata_start >= 0x98000000 && (uint32)web_conn->udata_start < 0x9A000000) {
|
||||
OpenFlash();
|
||||
}
|
||||
copy_align4(web_conn->msgbuf, (void *)(web_conn->udata_start), len);
|
||||
if((uint32)web_conn->udata_start >= 0x98000000 && (uint32)web_conn->udata_start < 0x9A000000) {
|
||||
CloseFlash();
|
||||
}
|
||||
web_conn->msgbuflen += len;
|
||||
web_conn->udata_start += len;
|
||||
#if DEBUGSOO > 2
|
||||
os_printf("%08x-%08x ",web_conn->udata_start, web_conn->udata_start + len );
|
||||
#endif
|
||||
if(web_conn->udata_start != web_conn->udata_stop) {
|
||||
SetSCB(SCB_RETRYCB);
|
||||
SetNextFunSCB(web_get_ram);
|
||||
return;
|
||||
};
|
||||
ClrSCB(SCB_RETRYCB);
|
||||
// SetSCB(SCB_FCLOSE | SCB_DISCONNECT);
|
||||
return;
|
||||
}
|
||||
/******************************************************************************
|
||||
* FunctionName : web_callback
|
||||
* Description : callback
|
||||
* Parameters : struct TCP_SERV_CONN
|
||||
* Returns : none
|
||||
******************************************************************************/
|
||||
void ICACHE_FLASH_ATTR web_int_callback(TCP_SERV_CONN *ts_conn, uint8 *cstr)
|
||||
{
|
||||
WEB_SRV_CONN *web_conn = (WEB_SRV_CONN *)ts_conn->linkd;
|
||||
// uint8 *cstr = &web_conn->msgbuf[web_conn->msgbuflen];
|
||||
{
|
||||
uint8 *vstr = os_strchr(cstr, '=');
|
||||
if(vstr != NULL) {
|
||||
*vstr++ = '\0';
|
||||
web_int_vars(ts_conn, cstr, vstr);
|
||||
return;
|
||||
}
|
||||
}
|
||||
#if DEBUGSOO > 3
|
||||
os_printf("[%s]\n", cstr);
|
||||
#endif
|
||||
ifcmp("start") tcp_puts("0x%08x", web_conn->udata_start);
|
||||
else ifcmp("stop") tcp_puts("0x%08x", web_conn->udata_stop);
|
||||
// **************************************************************************************************** //
|
||||
// **************************************** User settings ********************************************* //
|
||||
else ifcmp("ws_")
|
||||
{
|
||||
cstr += 3;
|
||||
ifcmp("filt_")
|
||||
{
|
||||
cstr += 5;
|
||||
ifcmp("rbw_")
|
||||
{
|
||||
cstr += 4;
|
||||
|
||||
ifcmp("enbl") tcp_puts("%d", filt_rainbow.enabled);
|
||||
else ifcmp("huesteps") tcp_puts("%d", filt_rainbow.hue_steps);
|
||||
else ifcmp("cyclesteps") tcp_puts("%d", filt_rainbow.cycle_steps);
|
||||
}
|
||||
else ifcmp("fd_")
|
||||
{
|
||||
cstr += 3;
|
||||
|
||||
ifcmp("enbl") tcp_puts("%d", filt_fade.enabled);
|
||||
else ifcmp("min") tcp_puts("%d", filt_fade.min);
|
||||
else ifcmp("max") tcp_puts("%d", filt_fade.max);
|
||||
else ifcmp("cyclesteps") tcp_puts("%d", filt_fade.steps);
|
||||
}
|
||||
}
|
||||
}
|
||||
// **************************************************************************************************** //
|
||||
// **************************************************************************************************** //
|
||||
#if USE_WEB_AUTH_LEVEL
|
||||
else ifcmp("realm") tcp_puts("%u", web_conn->auth_realm);
|
||||
else ifcmp("auth") tcp_puts("%u", web_conn->auth_level);
|
||||
#endif
|
||||
else ifcmp("xml_")
|
||||
{
|
||||
cstr+=4;
|
||||
ifcmp("scan") web_wscan_xml(ts_conn);
|
||||
#if WEB_DEBUG_FUNCTIONS
|
||||
else
|
||||
{
|
||||
#if USE_WEB_AUTH_LEVEL
|
||||
if(web_conn->auth_level < WEB_AUTH_LEVEL_USER)
|
||||
return;
|
||||
else
|
||||
#endif
|
||||
{
|
||||
web_conn->udata_start&=~3;
|
||||
ifcmp("ram") tcp_puts("0x%08x", *((uint32*)web_conn->udata_start));
|
||||
else tcp_put('?');
|
||||
web_conn->udata_start += 4;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
else ifcmp("sys_")
|
||||
{
|
||||
cstr+=4;
|
||||
ifcmp("url") tcp_strcpy(get_new_hostname());
|
||||
else ifcmp("cid") tcp_puts("%08x", HalGetChipId());
|
||||
else ifcmp("fid") tcp_puts("%08x", spi_flash_get_id());
|
||||
else ifcmp("fsize") tcp_puts("%u", spi_flash_real_size()); // flashchip->chip_size
|
||||
else ifcmp("sdkver") tcp_strcpy_fd(SDK_VERSION);
|
||||
else ifcmp("sysver") tcp_strcpy_fd(SYS_VERSION);
|
||||
else ifcmp("webver") tcp_strcpy_fd(WEB_SVERSION);
|
||||
else ifcmp("heap") tcp_puts("%u", xPortGetFreeHeapSize());
|
||||
else ifcmp("heapm") tcp_puts("%u", xPortGetMinimumEverFreeHeapSize());
|
||||
else ifcmp("tcmh") tcp_puts("%u", tcm_heap_freeSpace());
|
||||
else ifcmp("time") tcp_puts("%u", xTaskGetTickCount());
|
||||
else ifcmp("mactime") {
|
||||
if(wifi_mode) {
|
||||
union {
|
||||
uint32 dw[2];
|
||||
uint64 dd;
|
||||
}ux;
|
||||
ux.dd = *((uint64_t *)(WIFI_REG_BASE + 0x0560)); // REG_TSFTR -> #include "hal_com_reg.h"
|
||||
tcp_puts("0x%08x%08x", ux.dw[1], ux.dw[0]);
|
||||
}
|
||||
}
|
||||
else ifcmp("clkcpu") tcp_puts("%u", HalGetCpuClk());
|
||||
else ifcmp("debug") tcp_put('1' - (print_off & 1)); // rtl_print on/off
|
||||
#if WEB_DEBUG_FUNCTIONS
|
||||
else ifcmp("restart") {
|
||||
#if USE_WEB_AUTH_LEVEL
|
||||
if(web_conn->auth_level < WEB_AUTH_LEVEL_USER) return;
|
||||
#endif
|
||||
webserver_qfn((web_ex_func_cb)sys_reset, NULL, 200);
|
||||
}
|
||||
else ifcmp("ram") tcp_puts("0x%08x", *((uint32 *)(ahextoul(cstr+3)&(~3))));
|
||||
else ifcmp("rdec") tcp_puts("%d", *((uint32 *)(ahextoul(cstr+4)&(~3))));
|
||||
#endif // #if WEB_DEBUG_FUNCTIONS
|
||||
else ifcmp("ip") {
|
||||
uint32 cur_ip;
|
||||
if(netif_default != NULL) cur_ip = netif_default->ip_addr.addr;
|
||||
tcp_puts(IPSTR, IP2STR(&cur_ip));
|
||||
}
|
||||
#ifdef USE_NETBIOS
|
||||
else ifcmp("netbios") {
|
||||
if(syscfg.cfg.b.netbios_ena) tcp_strcpy(netbios_name);
|
||||
}
|
||||
#endif
|
||||
else tcp_put('?');
|
||||
}
|
||||
#ifdef WEB_INA219_DRV
|
||||
else ifcmp("ina219") {
|
||||
if(CheckSCB(SCB_WEBSOC)) {
|
||||
extern int ina219_ws(TCP_SERV_CONN *ts_conn, char cmd);
|
||||
int x = ina219_ws(ts_conn, cstr[6]);
|
||||
if(x < 0) SetSCB(SCB_FCLOSE|SCB_DISCONNECT);
|
||||
else tcp_puts("%d", x);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
#ifdef WEB_MLX90614_DRV
|
||||
else ifcmp("mlx90614") {
|
||||
if(CheckSCB(SCB_WEBSOC)) {
|
||||
extern int mlx90614_ws(TCP_SERV_CONN *ts_conn, char cmd);
|
||||
int x = mlx90614_ws(ts_conn, cstr[6]);
|
||||
if(x < 0) SetSCB(SCB_FCLOSE|SCB_DISCONNECT);
|
||||
else tcp_puts("%d", x);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
#ifdef WEB_ADC_DRV
|
||||
else ifcmp("adc")
|
||||
{
|
||||
if(CheckSCB(SCB_WEBSOC))
|
||||
{
|
||||
extern int adc_ws(TCP_SERV_CONN *ts_conn, char cmd);
|
||||
int x = adc_ws(ts_conn, cstr[6]);
|
||||
if(x < 0) SetSCB(SCB_FCLOSE|SCB_DISCONNECT);
|
||||
else tcp_puts("%d", x);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
#ifdef WEB_MPU6050
|
||||
else ifcmp("mpu6050")
|
||||
{
|
||||
if (CheckSCB(SCB_WEBSOC))
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
#endif
|
||||
else ifcmp("cfg_") {
|
||||
cstr += 4;
|
||||
ifcmp("web_") {
|
||||
cstr += 4;
|
||||
ifcmp("port") tcp_puts("%u", syscfg.web_port);
|
||||
else ifcmp("twrec") tcp_puts("%u", syscfg.web_twrec);
|
||||
else ifcmp("twcls") tcp_puts("%u", syscfg.web_twcls);
|
||||
else ifcmp("twd") tcp_put((syscfg.cfg.b.web_time_wait_delete)? '1' : '0');
|
||||
else tcp_put('?');
|
||||
}
|
||||
else ifcmp("sleep") tcp_put((syscfg.cfg.b.powersave_enable)? '1' : '0');
|
||||
else ifcmp("pinclr") tcp_put((syscfg.cfg.b.pin_clear_cfg_enable)? '1' : '0');
|
||||
else ifcmp("debug") tcp_put((syscfg.cfg.b.debug_print_enable)? '1' : '0');
|
||||
#ifdef USE_NETBIOS
|
||||
else ifcmp("netbios") tcp_put((syscfg.cfg.b.netbios_ena)? '1' : '0');
|
||||
#endif
|
||||
#ifdef USE_SNTP
|
||||
else ifcmp("sntp") tcp_put((syscfg.cfg.b.sntp_ena)? '1' : '0');
|
||||
#endif
|
||||
#ifdef USE_CAPTDNS
|
||||
else ifcmp("cdns") tcp_put((syscfg.cfg.b.cdns_ena)? '1' : '0');
|
||||
#endif
|
||||
else tcp_put('?');
|
||||
}
|
||||
else ifcmp("wifi_") {
|
||||
cstr+=5;
|
||||
ifcmp("rdcfg") read_wifi_cfg(-1);
|
||||
else ifcmp("newcfg") webserver_qfn((web_ex_func_cb)wifi_run, (void *)((uint32)wifi_cfg.mode), 200);
|
||||
else ifcmp("cmode") tcp_puts("%d", wifi_mode);
|
||||
else ifcmp("mode") tcp_puts("%d", wifi_cfg.mode);
|
||||
else ifcmp("bgn") tcp_puts("%d", wifi_cfg.bgn);
|
||||
else ifcmp("txpow") tcp_puts("%u", wifi_cfg.tx_pwr);
|
||||
else ifcmp("lflg") tcp_puts("%u", wifi_cfg.load_flg);
|
||||
else ifcmp("sflg") tcp_puts("%u", wifi_cfg.save_flg);
|
||||
else ifcmp("adpt") tcp_puts("%u", wifi_cfg.adaptivity);
|
||||
else ifcmp("country") tcp_puts("%u", wifi_cfg.country_code);
|
||||
else ifcmp("ap_") {
|
||||
cstr+=3;
|
||||
ifcmp("ssid") {
|
||||
wifi_ap_cfg.ssid[NDIS_802_11_LENGTH_SSID] = '\0';
|
||||
tcp_strcpy(wifi_ap_cfg.ssid);
|
||||
}
|
||||
else ifcmp("psw") {
|
||||
wifi_ap_cfg.password[IW_PASSPHRASE_MAX_SIZE] = '\0';
|
||||
tcp_strcpy(wifi_ap_cfg.password);
|
||||
}
|
||||
else ifcmp("chl") tcp_puts("%u", wifi_ap_cfg.channel);
|
||||
else ifcmp("mcns") tcp_puts("%u", wifi_ap_cfg.max_sta);
|
||||
else ifcmp("auth") tcp_put((wifi_ap_cfg.security) ? '1' : '0');
|
||||
else ifcmp("hssid") tcp_put((wifi_ap_cfg.ssid_hidden & 1) + '0');
|
||||
else ifcmp("bint") tcp_puts("%u", wifi_ap_cfg.beacon_interval);
|
||||
else ifcmp("mac") tcp_puts(MACSTR, MAC2STR(xnetif[WLAN_AP_NETIF_NUM].hwaddr));
|
||||
else ifcmp("hostname") tcp_strcpy(lwip_host_name[1]);
|
||||
else ifcmp("dhcp") tcp_puts("%u", wifi_ap_dhcp.mode);
|
||||
else ifcmp("ip") tcp_puts(IPSTR, IP2STR(&wifi_ap_dhcp.ip));
|
||||
else ifcmp("gw") tcp_puts(IPSTR, IP2STR(&wifi_ap_dhcp.gw));
|
||||
else ifcmp("msk") tcp_puts(IPSTR, IP2STR(&wifi_ap_dhcp.mask));
|
||||
else ifcmp("cip") tcp_puts(IPSTR, IP2STR(&xnetif[WLAN_ST_NETIF_NUM].ip_addr.addr));
|
||||
// else ifcmp("mac") strtomac(pvar, wifi_ap_cfg.macaddr);
|
||||
// else ifcmp("sip") tcp_puts(IPSTR, IP2STR(&wifi_ap_dhcp.start_ip));
|
||||
// else ifcmp("eip") tcp_puts(IPSTR, IP2STR(&wifi_ap_dhcp.end_ip));
|
||||
#if DEBUGSOO > 2
|
||||
else os_printf(" - none! ");
|
||||
#endif
|
||||
}
|
||||
else ifcmp("st_") {
|
||||
cstr+=3;
|
||||
ifcmp("rssi") {
|
||||
int rssi;
|
||||
wifi_get_rssi(&rssi);
|
||||
tcp_puts("%d", rssi);
|
||||
}
|
||||
else ifcmp("status") tcp_puts("%u", wifi_st_status);
|
||||
else ifcmp("arec") tcp_puts("%u", wifi_st_cfg.autoreconnect);
|
||||
else ifcmp("rect") tcp_puts("%u", wifi_st_cfg.reconnect_pause);
|
||||
ifcmp("ssid") {
|
||||
wifi_st_cfg.ssid[NDIS_802_11_LENGTH_SSID] = '\0';
|
||||
tcp_strcpy(wifi_st_cfg.ssid);
|
||||
}
|
||||
else ifcmp("psw") {
|
||||
wifi_st_cfg.password[IW_PASSPHRASE_MAX_SIZE] = '\0';
|
||||
tcp_strcpy(wifi_st_cfg.password);
|
||||
}
|
||||
else ifcmp("mac") tcp_puts(MACSTR, MAC2STR(xnetif[WLAN_ST_NETIF_NUM].hwaddr));
|
||||
else ifcmp("bssid") tcp_puts(MACSTR, MAC2STR(wifi_st_cfg.bssid));
|
||||
else ifcmp("sbss") tcp_puts("%u", wifi_st_cfg.flg);
|
||||
else ifcmp("sleep") tcp_puts("%d", wifi_st_cfg.sleep);
|
||||
else ifcmp("dtim") tcp_puts("%u", wifi_st_cfg.dtim);
|
||||
#if LWIP_NETIF_HOSTNAME
|
||||
else ifcmp("hostname") tcp_strcpy(lwip_host_name[0]);
|
||||
#endif
|
||||
else ifcmp("auth") tcp_puts("%u", wifi_st_cfg.security);
|
||||
else ifcmp("dhcp") tcp_puts("%u", wifi_st_dhcp.mode);
|
||||
else ifcmp("ip") tcp_puts(IPSTR, IP2STR(&wifi_st_dhcp.ip));
|
||||
else ifcmp("gw") tcp_puts(IPSTR, IP2STR(&wifi_st_dhcp.gw));
|
||||
else ifcmp("msk") tcp_puts(IPSTR, IP2STR(&wifi_st_dhcp.mask));
|
||||
#if DEBUGSOO > 5
|
||||
else os_printf(" - none!\n");
|
||||
#endif
|
||||
}
|
||||
#if DEBUGSOO > 5
|
||||
else os_printf(" - none!\n");
|
||||
#endif
|
||||
}
|
||||
else ifcmp("bin_") {
|
||||
#if USE_WEB_AUTH_LEVEL
|
||||
if(web_conn->auth_level < WEB_AUTH_LEVEL_USER) return;
|
||||
#endif
|
||||
cstr+=4;
|
||||
ifcmp("flash") {
|
||||
cstr+=5;
|
||||
if(*cstr == '_') {
|
||||
cstr++;
|
||||
#if WEB_DEBUG_FUNCTIONS
|
||||
ifcmp("all") {
|
||||
web_conn->udata_start = 0;
|
||||
web_conn->udata_stop = spi_flash_real_size();
|
||||
web_get_flash(ts_conn);
|
||||
}
|
||||
else ifcmp("sec_") {
|
||||
web_conn->udata_start = ahextoul(cstr+4) << 12;
|
||||
web_conn->udata_stop = web_conn->udata_start + FLASH_SECTOR_SIZE;
|
||||
web_get_flash(ts_conn);
|
||||
}
|
||||
else
|
||||
#endif // #if WEB_DEBUG_FUNCTIONS
|
||||
ifcmp("disk") {
|
||||
web_conn->udata_start = WEBFS_base_addr();
|
||||
web_conn->udata_stop = web_conn->udata_start + WEBFS_curent_size();
|
||||
web_get_flash(ts_conn);
|
||||
}
|
||||
else tcp_put('?');
|
||||
}
|
||||
else web_get_flash(ts_conn);
|
||||
}
|
||||
#if WEB_DEBUG_FUNCTIONS
|
||||
else ifcmp("ram") web_get_ram(ts_conn);
|
||||
#endif // #if WEB_DEBUG_FUNCTIONS
|
||||
else tcp_put('?');
|
||||
}
|
||||
#if WEB_DEBUG_FUNCTIONS
|
||||
else ifcmp("hexdmp") {
|
||||
#if USE_WEB_AUTH_LEVEL
|
||||
if(web_conn->auth_level < WEB_AUTH_LEVEL_USER) return;
|
||||
#endif
|
||||
if(cstr[6]=='d') ts_conn->flag.user_option1 = 1;
|
||||
else ts_conn->flag.user_option1 = 0;
|
||||
web_hexdump(ts_conn);
|
||||
}
|
||||
#endif // #if WEB_DEBUG_FUNCTIONS
|
||||
else ifcmp("web_") {
|
||||
cstr+=4;
|
||||
ifcmp("port") tcp_puts("%u", ts_conn->pcfg->port);
|
||||
else ifcmp("host") tcp_puts(IPSTR ":%d", IP2STR(&(ts_conn->pcb->local_ip.addr)), ts_conn->pcb->local_port);
|
||||
else ifcmp("remote") tcp_puts(IPSTR ":%d", IP2STR(&(ts_conn->remote_ip.dw)), ts_conn->remote_port);
|
||||
else ifcmp("twrec") tcp_puts("%u", ts_conn->pcfg->time_wait_rec);
|
||||
else ifcmp("twcls") tcp_puts("%u", ts_conn->pcfg->time_wait_cls);
|
||||
else tcp_put('?');
|
||||
}
|
||||
else ifcmp("wfs_") {
|
||||
cstr+=4;
|
||||
ifcmp("files") tcp_puts("%u", numFiles);
|
||||
else ifcmp("addr") tcp_puts("0x%08x", WEBFS_base_addr());
|
||||
else ifcmp("size") tcp_puts("%u", WEBFS_curent_size());
|
||||
else ifcmp("max_size") tcp_puts("%u", WEBFS_max_size());
|
||||
else tcp_put('?');
|
||||
}
|
||||
#ifdef USE_OVERLAY
|
||||
else ifcmp("ovl") {
|
||||
cstr += 3;
|
||||
if(*cstr == ':') {
|
||||
int i = ovl_loader(cstr + 1);
|
||||
if (i == 0) {
|
||||
if(CheckSCB(SCB_WEBSOC)) {
|
||||
tcp_puts("%d", ovl_call(1));
|
||||
}
|
||||
else {
|
||||
web_conn->web_disc_cb = (web_func_disc_cb)ovl_call; // адрес старта оверлея
|
||||
web_conn->web_disc_par = 1; // параметр функции - инициализация
|
||||
}
|
||||
}
|
||||
tcp_puts("%d", i);
|
||||
}
|
||||
else if(*cstr == '$') {
|
||||
if(ovl_call != NULL) tcp_puts("%d", ovl_call(ahextoul(cstr + 1)));
|
||||
else tcp_put('?');
|
||||
}
|
||||
else if(*cstr == '@') {
|
||||
if(ovl_call != NULL) tcp_puts("%d", ovl_call((int) cstr + 1));
|
||||
else tcp_put('?');
|
||||
}
|
||||
else tcp_put('?');
|
||||
}
|
||||
#endif
|
||||
#ifdef USE_SNTP
|
||||
else ifcmp("sntp_") {
|
||||
cstr += 5;
|
||||
ifcmp("time") tcp_puts("%u", sntp_gen_system_time(0)); // get_sntp_time
|
||||
else tcp_put('?');
|
||||
}
|
||||
#endif
|
||||
#ifdef TEST_SEND_WAVE
|
||||
else ifcmp("test_adc") web_test_adc(ts_conn);
|
||||
#endif
|
||||
else ifcmp("hellomsg") tcp_puts_fd("Web on RTL871x!");
|
||||
else tcp_put('?');
|
||||
}
|
||||
|
||||
#endif // USE_WEB
|
||||
427
Firmware/RTLGDB/Project/web/web_int_vars.c
Normal file
427
Firmware/RTLGDB/Project/web/web_int_vars.c
Normal file
|
|
@ -0,0 +1,427 @@
|
|||
/******************************************************************************
|
||||
* FileName: webserver.c
|
||||
* Description: The web server mode configuration.
|
||||
*******************************************************************************/
|
||||
|
||||
#include "user_config.h"
|
||||
#ifdef USE_WEB
|
||||
#include "autoconf.h"
|
||||
#include "FreeRTOS.h"
|
||||
#include "freertos_pmu.h"
|
||||
#include "task.h"
|
||||
#include "diag.h"
|
||||
#include "lwip/ip.h"
|
||||
#include "lwip/ip_addr.h"
|
||||
#include "lwip/tcp.h"
|
||||
#include "tcpsrv/tcp_srv_conn.h"
|
||||
#include "ethernetif.h"
|
||||
#include "web_srv_int.h"
|
||||
#include "web_utils.h"
|
||||
#include "webfs/webfs.h"
|
||||
#include "flash_eep.h"
|
||||
#include "device_lock.h"
|
||||
#include "rtl8195a/rtl_libc.h"
|
||||
#include "sys_cfg.h"
|
||||
#include "wifi_api.h"
|
||||
#include "sys_api.h"
|
||||
#include "esp_comp.h"
|
||||
|
||||
#include "ledeffectsserver.h"
|
||||
|
||||
#ifdef USE_NETBIOS
|
||||
#include "netbios/netbios.h"
|
||||
#endif
|
||||
|
||||
#ifdef USE_SNTP
|
||||
#include "sntp/sntp.h"
|
||||
#endif
|
||||
|
||||
#ifdef USE_LWIP_PING
|
||||
#include "lwip/app/ping.h"
|
||||
struct ping_option pingopt; // for test
|
||||
#endif
|
||||
|
||||
#ifdef USE_CAPTDNS
|
||||
#include "captdns.h"
|
||||
#endif
|
||||
|
||||
#ifdef USE_MODBUS
|
||||
#include "modbustcp.h"
|
||||
#include "mdbtab.h"
|
||||
#endif
|
||||
|
||||
#ifdef USE_RS485DRV
|
||||
#include "driver/rs485drv.h"
|
||||
#include "mdbrs485.h"
|
||||
#endif
|
||||
|
||||
#ifdef USE_OVERLAY
|
||||
#include "overlay.h"
|
||||
#endif
|
||||
|
||||
extern void web_get_ram(TCP_SERV_CONN *ts_conn);
|
||||
extern void web_get_flash(TCP_SERV_CONN *ts_conn);
|
||||
extern void web_hexdump(TCP_SERV_CONN *ts_conn);
|
||||
|
||||
#define ifcmp(a) if(rom_xstrcmp(cstr, a))
|
||||
|
||||
extern int rom_atoi(const char *);
|
||||
#undef atoi
|
||||
#define atoi rom_atoi
|
||||
|
||||
typedef uint32 (* call_func)(uint32 a, uint32 b, uint32 c);
|
||||
extern QueueHandle_t xQueueWebSrv;
|
||||
|
||||
/******************************************************************************
|
||||
* FunctionName : parse_url
|
||||
* Description : parse the received data from the server
|
||||
* Parameters : CurHTTP -- the result of parsing the url
|
||||
* Returns : none
|
||||
*******************************************************************************/
|
||||
void ICACHE_FLASH_ATTR web_int_vars(TCP_SERV_CONN *ts_conn, uint8 *pcmd, uint8 *pvar)
|
||||
{
|
||||
WEB_SRV_CONN *web_conn = (WEB_SRV_CONN *)ts_conn->linkd;
|
||||
uint32 val = ahextoul(pvar);
|
||||
char *cstr = pcmd;
|
||||
#if DEBUGSOO > 1
|
||||
os_printf("[%s=%s]\n", pcmd, pvar);
|
||||
#endif
|
||||
ifcmp("start") web_conn->udata_start = val;
|
||||
else ifcmp("stop") web_conn->udata_stop = val;
|
||||
// **************************************************************************************************** //
|
||||
// **************************************** User settings ********************************************* //
|
||||
else ifcmp("ws_")
|
||||
{
|
||||
cstr += 3;
|
||||
ifcmp("filt_")
|
||||
{
|
||||
cstr += 5;
|
||||
ifcmp("rbw_")
|
||||
{
|
||||
cstr += 4;
|
||||
|
||||
ifcmp("enbl") filt_rainbow.enabled = (uint8_t)val;
|
||||
else ifcmp("huesteps") filt_rainbow.hue_steps = (uint8_t)val;
|
||||
else ifcmp("cyclesteps") filt_rainbow.cycle_steps = (uint8_t)val;
|
||||
}
|
||||
else ifcmp("fd_")
|
||||
{
|
||||
cstr += 3;
|
||||
|
||||
ifcmp("enbl") filt_fade.enabled = (uint8_t)val;
|
||||
else ifcmp("min") filt_fade.min = (uint8_t)val;
|
||||
else ifcmp("max") filt_fade.max = (uint8_t)val;
|
||||
else ifcmp("cyclesteps") filt_fade.steps = (uint8_t)val;
|
||||
}
|
||||
}
|
||||
}
|
||||
// **************************************************************************************************** //
|
||||
// **************************************************************************************************** //
|
||||
#if USE_WEB_AUTH_LEVEL
|
||||
else ifcmp("user") web_conn->auth_level = UserAuthorization(pvar, strlen(pvar));
|
||||
else if(web_conn->auth_level < WEB_AUTH_LEVEL_USER) {
|
||||
if(!web_conn->auth_realm) web_conn->auth_realm = WEB_AUTH_LEVEL_USER;
|
||||
SetSCB(SCB_AUTH);
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
#if WEB_DEBUG_FUNCTIONS
|
||||
else ifcmp("sys_") {
|
||||
cstr+=4;
|
||||
ifcmp("restart") {
|
||||
if(val == 12345) webserver_qfn((web_ex_func_cb)sys_reset, NULL, 200);
|
||||
}
|
||||
else ifcmp("ram") { uint32 *ptr = (uint32 *)(ahextoul(cstr+3)&(~3)); str_array(pvar, ptr, 32); }
|
||||
else ifcmp("debug") print_off = (!val) & 1; // rtl_print on/off
|
||||
else ifcmp("dsleep") deepsleep_ex(DSLEEP_WAKEUP_BY_TIMER, val);
|
||||
#ifdef USE_LWIP_PING
|
||||
else ifcmp("ping") {
|
||||
// struct ping_option *pingopt = (struct ping_option *)UartDev.rcv_buff.pRcvMsgBuff;
|
||||
pingopt.ip = ipaddr_addr(pvar);
|
||||
pingopt.count = 3;
|
||||
pingopt.recv_function=NULL;
|
||||
pingopt.sent_function=NULL;
|
||||
ping_start(&pingopt);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
#endif // #if WEB_DEBUG_FUNCTIONS
|
||||
else ifcmp("cfg_") {
|
||||
cstr += 4;
|
||||
ifcmp("web_") {
|
||||
cstr += 4;
|
||||
ifcmp("port") {
|
||||
if(syscfg.web_port != val) {
|
||||
webserver_qfn((web_ex_func_cb)webserver_reinit, (void *)((uint32)syscfg.web_port), 200);
|
||||
syscfg.web_port = val;
|
||||
}
|
||||
}
|
||||
else ifcmp("twd") {
|
||||
if(val) {
|
||||
syscfg.cfg.b.web_time_wait_delete = 1;
|
||||
ts_conn->pcfg->flag.pcb_time_wait_free = 1;
|
||||
}
|
||||
else {
|
||||
syscfg.cfg.b.web_time_wait_delete = 0;
|
||||
ts_conn->pcfg->flag.pcb_time_wait_free = 0;
|
||||
}
|
||||
}
|
||||
else ifcmp("twrec") {
|
||||
syscfg.web_twrec = val;
|
||||
ts_conn->pcfg->time_wait_rec = val;
|
||||
}
|
||||
else ifcmp("twcls") {
|
||||
syscfg.web_twcls = val;
|
||||
ts_conn->pcfg->time_wait_cls = val;
|
||||
}
|
||||
#if DEBUGSOO > 5
|
||||
else os_printf(" - none!\n");
|
||||
#endif
|
||||
}
|
||||
else ifcmp("pinclr") syscfg.cfg.b.pin_clear_cfg_enable = (val)? 1 : 0;
|
||||
else ifcmp("sleep") {
|
||||
syscfg.cfg.b.powersave_enable = (val)? 1 : 0;
|
||||
if(val) release_wakelock(~WAKELOCK_WLAN);
|
||||
else acquire_wakelock(~WAKELOCK_WLAN);
|
||||
}
|
||||
else ifcmp("debug") {
|
||||
syscfg.cfg.b.debug_print_enable = val;
|
||||
print_off = (!val) & 1; // rtl_print on/off
|
||||
}
|
||||
else ifcmp("save") {
|
||||
if(val == 2) SetSCB(SCB_SYSSAVE); // по закрытию соединения вызвать sys_write_cfg()
|
||||
else if(val == 1) sys_write_cfg();
|
||||
}
|
||||
#ifdef USE_NETBIOS
|
||||
else ifcmp("netbios") {
|
||||
syscfg.cfg.b.netbios_ena = (val)? 1 : 0;
|
||||
if(syscfg.cfg.b.netbios_ena) netbios_init();
|
||||
else netbios_off();
|
||||
}
|
||||
#endif
|
||||
#ifdef USE_SNTP
|
||||
else ifcmp("sntp") {
|
||||
syscfg.cfg.b.sntp_ena = (val)? 1 : 0;
|
||||
if(syscfg.cfg.b.sntp_ena) sntp_init();
|
||||
else sntp_stop();
|
||||
}
|
||||
#endif
|
||||
#ifdef USE_CAPTDNS
|
||||
else ifcmp("cdns") {
|
||||
syscfg.cfg.b.cdns_ena = (val)? 1 : 0;
|
||||
if(syscfg.cfg.b.cdns_ena && wifi_softap_get_station_num()) captdns_init();
|
||||
else captdns_close();
|
||||
}
|
||||
#endif
|
||||
#if DEBUGSOO > 5
|
||||
else os_printf(" - none!\n");
|
||||
#endif
|
||||
// sys_write_cfg();
|
||||
}
|
||||
else ifcmp("wifi_") {
|
||||
cstr+=5;
|
||||
ifcmp("scan") api_wifi_scan(NULL);
|
||||
else ifcmp("rdcfg") web_conn->udata_stop = read_wifi_cfg(val);
|
||||
else ifcmp("newcfg") webserver_qfn((web_ex_func_cb)wifi_run, (void *)((uint32) wifi_cfg.mode), 200);
|
||||
else ifcmp("mode") wifi_cfg.mode = val;
|
||||
else ifcmp("bgn") wifi_cfg.bgn = val;
|
||||
else ifcmp("lflg") wifi_cfg.load_flg = val;
|
||||
else ifcmp("sflg") wifi_cfg.save_flg = val;
|
||||
else ifcmp("txpow") wifi_cfg.tx_pwr = val;
|
||||
else ifcmp("adpt") wifi_cfg.adaptivity = val;
|
||||
else ifcmp("country") wifi_cfg.country_code = val;
|
||||
// .. mac wifi_set_mac_address()
|
||||
|
||||
// else ifcmp("scan") {
|
||||
// web_conn->web_disc_par = val;
|
||||
// web_conn->web_disc_cb = (web_func_disc_cb)wifi_start_scan;
|
||||
// }
|
||||
else ifcmp("save") { write_wifi_cfg(val); }
|
||||
else ifcmp("ap_") {
|
||||
cstr+=3;
|
||||
ifcmp("ssid") {
|
||||
if(pvar[0]!='\0') {
|
||||
int len = os_strlen(pvar);
|
||||
if(len > NDIS_802_11_LENGTH_SSID) {
|
||||
len = NDIS_802_11_LENGTH_SSID;
|
||||
}
|
||||
os_memset(wifi_ap_cfg.ssid, 0, sizeof(wifi_ap_cfg.ssid));
|
||||
os_memcpy(wifi_ap_cfg.ssid, pvar, len);
|
||||
#ifdef USE_NETBIOS
|
||||
// netbios_set_name(wlan_ap_netifn, wifi_ap_cfg.ssid);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
else ifcmp("psw") {
|
||||
int len = os_strlen(pvar);
|
||||
if(len > IW_PASSPHRASE_MAX_SIZE) {
|
||||
len = IW_PASSPHRASE_MAX_SIZE;
|
||||
}
|
||||
os_memset(wifi_ap_cfg.password, 0, sizeof(wifi_ap_cfg.password));
|
||||
os_memcpy(wifi_ap_cfg.password, pvar, len);
|
||||
}
|
||||
else ifcmp("chl") wifi_ap_cfg.channel = val;
|
||||
else ifcmp("mcns") wifi_ap_cfg.max_sta = val;
|
||||
else ifcmp("auth") wifi_ap_cfg.security = val; // =1 IDX_SECURITY_WPA2_AES_PSK, =0 IDX_SECURITY_OPEN
|
||||
else ifcmp("hssid") wifi_ap_cfg.ssid_hidden = val;
|
||||
else ifcmp("bint") wifi_ap_cfg.beacon_interval = val;
|
||||
#if LWIP_NETIF_HOSTNAME
|
||||
else ifcmp("hostname") {
|
||||
int len = os_strlen(pvar);
|
||||
if(len >= LWIP_NETIF_HOSTNAME_SIZE) {
|
||||
len = LWIP_NETIF_HOSTNAME_SIZE-1;
|
||||
}
|
||||
if(len) {
|
||||
os_memset(lwip_host_name[1], 0, LWIP_NETIF_HOSTNAME_SIZE);
|
||||
os_memcpy(lwip_host_name[1], pvar, len);
|
||||
}
|
||||
netbios_set_name(WLAN_AP_NETIF_NUM, lwip_host_name[1]);
|
||||
if(wifi_cfg.save_flg & BID_AP_HOSTNAME) {
|
||||
WEB_SRV_QFNK x;
|
||||
x.fnc = write_wifi_cfg;
|
||||
x.param = (void *)BID_AP_HOSTNAME;
|
||||
xQueueSendToBack(xQueueWebSrv, &x, 0);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
else ifcmp("dhcp") wifi_ap_dhcp.mode = val;
|
||||
else ifcmp("ip") wifi_ap_dhcp.ip = ipaddr_addr(pvar);
|
||||
else ifcmp("gw") wifi_ap_dhcp.gw = ipaddr_addr(pvar);
|
||||
else ifcmp("msk") wifi_ap_dhcp.mask = ipaddr_addr(pvar);
|
||||
// else ifcmp("mac") strtomac(pvar, wifi_ap_cfg.macaddr);
|
||||
// else ifcmp("sip") wifi_ap_dhcp.start_ip = ipaddr_addr(pvar);
|
||||
// else ifcmp("eip") wifi_ap_dhcp.end_ip = ipaddr_addr(pvar);
|
||||
#if DEBUGSOO > 2
|
||||
else os_printf(" - none! ");
|
||||
#endif
|
||||
}
|
||||
else ifcmp("st_") {
|
||||
cstr+=3;
|
||||
ifcmp("arec") wifi_st_cfg.autoreconnect = val;
|
||||
else ifcmp("rect") wifi_st_cfg.reconnect_pause = val;
|
||||
else ifcmp("ssid") {
|
||||
if(pvar[0]!='\0') {
|
||||
int len = os_strlen(pvar);
|
||||
if(len > NDIS_802_11_LENGTH_SSID) {
|
||||
len = NDIS_802_11_LENGTH_SSID;
|
||||
}
|
||||
os_memset(wifi_st_cfg.ssid, 0, sizeof(wifi_st_cfg.ssid));
|
||||
os_memcpy(wifi_st_cfg.ssid, pvar, len);
|
||||
}
|
||||
}
|
||||
else ifcmp("psw") {
|
||||
int len = os_strlen(pvar);
|
||||
if(len > IW_PASSPHRASE_MAX_SIZE) {
|
||||
len = IW_PASSPHRASE_MAX_SIZE;
|
||||
}
|
||||
os_memset(wifi_st_cfg.password, 0, sizeof(wifi_st_cfg.password));
|
||||
os_memcpy(wifi_st_cfg.password, pvar, len);
|
||||
}
|
||||
else ifcmp("auth") wifi_st_cfg.security = val;
|
||||
else ifcmp("bssid") strtomac(pvar, wifi_st_cfg.bssid);
|
||||
else ifcmp("sbss") wifi_st_cfg.flg = val;
|
||||
else ifcmp("sleep") wifi_st_cfg.sleep = val;
|
||||
else ifcmp("dtim") wifi_st_cfg.dtim = val;
|
||||
#if LWIP_NETIF_HOSTNAME
|
||||
else ifcmp("hostname") {
|
||||
int len = os_strlen(pvar);
|
||||
if(len >= LWIP_NETIF_HOSTNAME_SIZE) {
|
||||
len = LWIP_NETIF_HOSTNAME_SIZE-1;
|
||||
}
|
||||
if(len) {
|
||||
os_memset(lwip_host_name[0], 0, LWIP_NETIF_HOSTNAME_SIZE);
|
||||
os_memcpy(lwip_host_name[0], pvar, len);
|
||||
netbios_set_name(WLAN_ST_NETIF_NUM, lwip_host_name[0]);
|
||||
}
|
||||
if(wifi_cfg.save_flg & BID_ST_HOSTNAME) {
|
||||
WEB_SRV_QFNK x;
|
||||
x.fnc = write_wifi_cfg;
|
||||
x.param = (void *)BID_ST_HOSTNAME;
|
||||
x.pause_ms = 0;
|
||||
xQueueSendToBack(xQueueWebSrv, &x, 0);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
else ifcmp("dhcp") wifi_st_dhcp.mode = val;
|
||||
else ifcmp("ip") wifi_st_dhcp.ip = ipaddr_addr(pvar);
|
||||
else ifcmp("gw") wifi_st_dhcp.gw = ipaddr_addr(pvar);
|
||||
else ifcmp("msk") wifi_st_dhcp.mask = ipaddr_addr(pvar);
|
||||
// else ifcmp("mac") strtomac(pvar, wifi_st_cfg.mac);
|
||||
// else ifcmp("sbss") wifi_st_cfg.bssidx = val;
|
||||
#if DEBUGSOO > 5
|
||||
else os_printf(" - none!\n");
|
||||
#endif
|
||||
}
|
||||
#if DEBUGSOO > 5
|
||||
else os_printf(" - none!\n");
|
||||
#endif
|
||||
}
|
||||
#if WEB_DEBUG_FUNCTIONS
|
||||
else if(web_conn->bffiles[0]==WEBFS_WEBCGI_HANDLE && CheckSCB(SCB_GET)) {
|
||||
ifcmp("hexdmp") {
|
||||
#if DEBUGSOO > 5
|
||||
os_printf("hexdmp(%p)\n", val);
|
||||
#endif
|
||||
if(val > 0) {
|
||||
if(cstr[6]=='d') ts_conn->flag.user_option1 = 1;
|
||||
else ts_conn->flag.user_option1 = 0;
|
||||
uint32 x = ahextoul(cstr+7);
|
||||
web_conn->udata_start = x;
|
||||
web_conn->udata_stop = val + web_conn->udata_start;
|
||||
#if DEBUGSOO > 5
|
||||
os_printf("start=%p, stop=%p\n", web_conn->udata_start, web_conn->udata_stop);
|
||||
#endif
|
||||
web_conn->fileType = HTTP_TXT;
|
||||
SetSCB(SCB_RETRYCB | SCB_FCALBACK);
|
||||
SetNextFunSCB(web_hexdump);
|
||||
};
|
||||
}
|
||||
else ifcmp("flash") {
|
||||
cstr+=5;
|
||||
if(*cstr == '_') {
|
||||
cstr++;
|
||||
ifcmp("all") {
|
||||
web_conn->udata_start = 0;
|
||||
web_conn->udata_stop = spi_flash_real_size();
|
||||
web_conn->fileType = HTTP_BIN;
|
||||
SetSCB(SCB_RETRYCB | SCB_FCALBACK);
|
||||
SetNextFunSCB(web_get_flash);
|
||||
}
|
||||
else ifcmp("sec_") {
|
||||
web_conn->udata_start = ahextoul(cstr+4) << 12;
|
||||
web_conn->udata_stop = web_conn->udata_start + FLASH_SECTOR_SIZE*val;
|
||||
web_conn->fileType = HTTP_BIN;
|
||||
SetSCB(SCB_RETRYCB | SCB_FCALBACK);
|
||||
SetNextFunSCB(web_get_flash);
|
||||
}
|
||||
else ifcmp("disk") {
|
||||
web_conn->udata_start = WEBFS_base_addr();
|
||||
web_conn->udata_stop = web_conn->udata_start + WEBFS_curent_size();
|
||||
web_conn->fileType = HTTP_BIN;
|
||||
SetSCB(SCB_RETRYCB | SCB_FCALBACK);
|
||||
SetNextFunSCB(web_get_flash);
|
||||
}
|
||||
else tcp_put('?');
|
||||
}
|
||||
else {
|
||||
web_conn->fileType = HTTP_BIN;
|
||||
SetSCB(SCB_RETRYCB | SCB_FCALBACK);
|
||||
SetNextFunSCB(web_get_flash);
|
||||
}
|
||||
}
|
||||
else ifcmp("bin_ram") {
|
||||
web_conn->fileType = HTTP_BIN;
|
||||
SetSCB(SCB_RETRYCB | SCB_FCALBACK);
|
||||
SetNextFunSCB(web_get_ram);
|
||||
}
|
||||
#if DEBUGSOO > 5
|
||||
else os_printf(" - none! ");
|
||||
#endif
|
||||
}
|
||||
#endif // #if WEB_DEBUG_FUNCTIONS
|
||||
#if DEBUGSOO > 5
|
||||
else os_printf(" - none! ");
|
||||
#endif
|
||||
}
|
||||
|
||||
#endif // USE_WEB
|
||||
2076
Firmware/RTLGDB/Project/web/web_srv.c
Normal file
2076
Firmware/RTLGDB/Project/web/web_srv.c
Normal file
File diff suppressed because it is too large
Load diff
210
Firmware/RTLGDB/Project/web/web_srv.h
Normal file
210
Firmware/RTLGDB/Project/web/web_srv.h
Normal file
|
|
@ -0,0 +1,210 @@
|
|||
/*
|
||||
* File: web_srv.h
|
||||
* Description: The web server configration.
|
||||
* Small WEB server ESP8266EX
|
||||
* Author: PV`
|
||||
*/
|
||||
|
||||
#ifndef _INCLUDE_WEB_SRV_H_
|
||||
#define _INCLUDE_WEB_SRV_H_
|
||||
|
||||
#include "tcpsrv/tcp_srv_conn.h"
|
||||
#ifdef WEBSOCKET_ENA
|
||||
#include "websock.h"
|
||||
#endif
|
||||
|
||||
#define WEB_SVERSION "0.2.0"
|
||||
#define DEFAULT_WEB_PORT USE_WEB // 80
|
||||
#define USE_WEB_AUTH_LEVEL 0 // 1
|
||||
|
||||
/****************************************************************************
|
||||
***************************************************************************/
|
||||
|
||||
typedef enum
|
||||
{
|
||||
WEB_AUTH_NONE = 0,
|
||||
WEB_AUTH_LEVEL_USER,
|
||||
WEB_AUTH_LEVEL_USER1,
|
||||
WEB_AUTH_LEVEL_WEBFS,
|
||||
WEB_AUTH_LEVEL_OTA,
|
||||
WEB_AUTH_LEVEL_SUPERVISOR
|
||||
} WEB_AUTH_LEVEL_TYPE;
|
||||
|
||||
// File type definitions
|
||||
typedef enum
|
||||
{
|
||||
HTTP_TXT = 0, // File is a text document
|
||||
HTTP_HTML, // File is HTML (extension .htm)
|
||||
HTTP_CGI, // File is HTML (extension .cgi)
|
||||
HTTP_XML, // File is XML (extension .xml)
|
||||
HTTP_CSS, // File is stylesheet (extension .css)
|
||||
HTTP_ICO, // File is ICO vnd.microsoft.icon
|
||||
HTTP_GIF, // File is GIF image (extension .gif)
|
||||
HTTP_PNG, // File is PNG image (extension .png)
|
||||
HTTP_JPG, // File is JPG image (extension .jpg)
|
||||
HTTP_SVG, // File is SVG image (extension .svg)
|
||||
HTTP_JAVA, // File is java (extension .js)
|
||||
HTTP_SWF, // File is ShockWave-Flash (extension .swf)
|
||||
HTTP_WAV, // File is audio (extension .wav)
|
||||
HTTP_PDF, // File is PDF (extension .pdf)
|
||||
HTTP_ZIP, // File is ZIP (extension .zip)
|
||||
HTTP_BIN, // File is BIN (extension .bin)
|
||||
HTTP_UNKNOWN // File type is unknown
|
||||
} HTTP_FILE_TYPE;
|
||||
|
||||
|
||||
// extended state data for each connection
|
||||
#define FileNameSize 64
|
||||
#define VarNameSize 64
|
||||
#define CmdNameSize 32
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint16 httpStatus; // Request method/status
|
||||
uint16 uri_len;
|
||||
uint16 head_len;
|
||||
uint16 cookie_len;
|
||||
uint8 pFilename[FileNameSize];
|
||||
uint8 *puri; // указатель на строку с переменными запроса к файлу
|
||||
uint8 *phead; // HTTP Headers
|
||||
uint8 *pcookie; // cookie
|
||||
uint8 *pcontent; // content
|
||||
uint32 content_len; //
|
||||
uint8 httpver; // версия HTTP клиента в BCD (0x00 = неизвестен; 0x09 = HTTP/0.9; 0x10 = HTTP/1.0; 0x11 = HTTP/1.1)
|
||||
uint8 fileType; // File type to return with Content-Type
|
||||
} HTTP_CONN;
|
||||
|
||||
|
||||
typedef void (* web_func_cb)(TCP_SERV_CONN *ts_conn);
|
||||
typedef uint32 (* web_ex_func_cb)(uint32 flg); // внешняя или отложенная функция
|
||||
|
||||
typedef struct
|
||||
{
|
||||
web_ex_func_cb fnc;
|
||||
void * param;
|
||||
uint16 pause_ms;
|
||||
} WEB_SRV_QFNK;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint32 webflag; // флаги для http/web сервера
|
||||
uint8 bffiles[4]; // четыре Files pointers для оработки вложенных файлов include
|
||||
uint32 udata_start; // udata "start=0x..."
|
||||
uint32 udata_stop; // udata "stop=0x..."
|
||||
uint8 *msgbuf; // указатель на текущий буфер вывода
|
||||
uint16 msgbuflen; // кол-во занятых байт в буфере msgbuf
|
||||
uint16 msgbufsize; // размер буфера
|
||||
web_func_cb func_web_cb; // calback функция у httpd для обработки приема/передачи кусками
|
||||
uint32 content_len; // размер файла для передачи (GET/POST) или приема, если принимается внешний файл (POST + SCB_RXDATA)
|
||||
#ifdef WEBSOCKET_ENA
|
||||
WS_FRSTAT ws; // параметры websoc
|
||||
#endif
|
||||
#if USE_WEB_AUTH_LEVEL
|
||||
uint8 auth_level; // Уровень авторизации пользователя по паролю WEB_AUTH_LEVEL_TYPE
|
||||
uint8 auth_realm; // Требуемый уровень авторизации (минимальный уровень) WEB_AUTH_LEVEL_TYPE
|
||||
#endif
|
||||
uint8 fileType; // File type to return with Content-Type (if SCB_FCALBACK)
|
||||
} WEB_SRV_CONN;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
WEBFS_MAX_HANDLE = 251,
|
||||
WEBFS_NODISK_HANDLE,
|
||||
WEBFS_WEBCGI_HANDLE,
|
||||
WEBFS_UPLOAD_HANDLE
|
||||
} WEBFS_NUM_HANDLE;
|
||||
|
||||
// webflag:
|
||||
|
||||
#define SCB_CLOSED 0x000001 // соединение закрыто
|
||||
#define SCB_DISCONNECT 0x000002 // выход на DISCONNECT
|
||||
#define SCB_FCLOSE 0x000004 // закрыть файлы
|
||||
#define SCB_FOPEN 0x000008 // файл(ы) открыт(ы)
|
||||
#define SCB_FCALBACK 0x000010 // file use ~calback~
|
||||
#define SCB_FGZIP 0x000020 // файл GZIP
|
||||
#define SCB_CHUNKED 0x000040 // передача шинковкой
|
||||
#define SCB_RETRYCB 0x000080 // вызвать повтор CalBack
|
||||
#define SCB_POST 0x000100 // POST
|
||||
#define SCB_GET 0x000200 // GET
|
||||
#define SCB_AUTH 0x000400 // необходима авторизация
|
||||
#define SCB_FINDCB 0x000800 // используется парсингом ~calback~
|
||||
#define SCB_RXDATA 0x001000 // прием данных (файла)
|
||||
#define SCB_HEAD_OK 0x002000 // заголовок HTTP принят и обработан
|
||||
#define SCB_BNDR 0x004000 // прилеплен Content-Type: multipart/form-data; boundary="..."
|
||||
#define SCB_REDIR 0x008000 // Redirect 302
|
||||
#define SCB_WEBSOC 0x010000 // WebSocket
|
||||
#define SCB_WSDATA 0x020000 // WebSocket data
|
||||
#define SCB_SYSSAVE 0x040000 // по закрытию соединения вызвать sys_write_cfg()
|
||||
|
||||
|
||||
#define SCB_OPEN 0
|
||||
|
||||
#define SetSCB(a) web_conn->webflag |= a
|
||||
#define FreeSCB() web_conn->webflag = SCB_FREE
|
||||
#define SetNextFunSCB(a) web_conn->func_web_cb = a
|
||||
#define ClrSCB(a) web_conn->webflag &= ~(a)
|
||||
#define CheckSCB(a) (web_conn->webflag & (a))
|
||||
|
||||
#define FreeSCB() web_conn->webflag = SCB_FREE
|
||||
#define OpenSCB() web_conn->webflag = SCB_OPEN
|
||||
|
||||
#define MAXLENBOUNDARY 64
|
||||
typedef struct s_http_upload
|
||||
{
|
||||
uint16 status;
|
||||
uint16 sizeboundary;
|
||||
uint8 boundary[MAXLENBOUNDARY+1];
|
||||
uint8 name[VarNameSize];
|
||||
uint8 filename[VarNameSize];
|
||||
#ifdef USE_OVERLAY
|
||||
uint32 segs; // кол-во сегментов оверлея // пока в web_conn->web_disc_par
|
||||
uint32 start; // адрес запуска оверлея
|
||||
#endif
|
||||
uint32 fsize;
|
||||
uint32 faddr;
|
||||
uint8 *pbndr;
|
||||
uint8 *pnext;
|
||||
} HTTP_UPLOAD;
|
||||
|
||||
typedef struct s_http_response
|
||||
{
|
||||
uint32 status;
|
||||
uint32 flag;
|
||||
const char * headers;
|
||||
const char * default_content;
|
||||
} HTTP_RESPONSE;
|
||||
|
||||
// HTTP_RESPONSE.flags:
|
||||
#define HTTP_RESP_FLG_END 0x8000
|
||||
#define HTTP_RESP_FLG_NONE 0x0000
|
||||
#define HTTP_RESP_FLG_FINDFILE 0x0001
|
||||
#define HTTP_RESP_FLG_REDIRECT 0x0002
|
||||
|
||||
#define tcp_put(a) web_conn->msgbuf[web_conn->msgbuflen++] = a
|
||||
#define tcp_htmlstrcpy(str, len) web_conn->msgbuflen += htmlcode(&web_conn->msgbuf[web_conn->msgbuflen], str, web_conn->msgbufsize - web_conn->msgbuflen - 1, len)
|
||||
//#define tcp_urlstrcpy(str, len) web_conn->msgbuflen += urlencode(&web_conn->msgbuf[web_conn->msgbuflen], str, web_conn->msgbufsize - web_conn->msgbuflen - 1, len)
|
||||
#define tcp_puts(...) web_conn->msgbuflen += rtl_sprintf((char *)&web_conn->msgbuf[web_conn->msgbuflen], __VA_ARGS__)
|
||||
#define tcp_puts_fd(...) web_conn->msgbuflen += rtl_sprintf((char *)&web_conn->msgbuf[web_conn->msgbuflen], __VA_ARGS__)
|
||||
/*
|
||||
#define tcp_puts_fd(fmt, ...) do { \
|
||||
static const char flash_str[] ICACHE_RODATA_ATTR = fmt; \
|
||||
web_conn->msgbuflen += rtl_sprintf((char *)&web_conn->msgbuf[web_conn->msgbuflen], (char *)flash_str, ##__VA_ARGS__); \
|
||||
} while(0)
|
||||
*/
|
||||
//#define tcp_strcpy(a) web_conn->msgbuflen += ets_strlen((char *)ets_strcpy((char *)&web_conn->msgbuf[web_conn->msgbuflen], (char *)a))
|
||||
#define tcp_strcpy(a) web_conn->msgbuflen += rom_xstrcpy((char *)&web_conn->msgbuf[web_conn->msgbuflen], (const char *)a)
|
||||
#define tcp_strcpy_fd(a) web_conn->msgbuflen += rom_xstrcpy((char *)&web_conn->msgbuf[web_conn->msgbuflen], (const char *)a)
|
||||
/*
|
||||
#define tcp_strcpy_fd(fmt) do { \
|
||||
static const char flash_str[] ICACHE_RODATA_ATTR = fmt; \
|
||||
web_conn->msgbuflen += rom_xstrcpy((char *)&web_conn->msgbuf[web_conn->msgbuflen], (char *)flash_str); \
|
||||
} while(0)
|
||||
*/
|
||||
uint32 ahextoul(uint8 *s);
|
||||
err_t webserver_init(uint16 portn);
|
||||
err_t webserver_close(uint16 portn);
|
||||
err_t webserver_reinit(uint16 portn);
|
||||
|
||||
BaseType_t webserver_qfn(web_ex_func_cb fnc, void * param, uint16 pause_ms); // вызов функции из task с low priority
|
||||
|
||||
#endif /* _INCLUDE_WEB_SRV_H_ */
|
||||
48
Firmware/RTLGDB/Project/web/web_srv_int.h
Normal file
48
Firmware/RTLGDB/Project/web/web_srv_int.h
Normal file
|
|
@ -0,0 +1,48 @@
|
|||
/*
|
||||
* File: web_srv_int.h
|
||||
* Description: The web server configration.
|
||||
* Small WEB server ESP8266EX
|
||||
*
|
||||
* Author: PV` 12/2014
|
||||
*/
|
||||
|
||||
#ifndef _INCLUDE_WEB_SRV_INT_H_
|
||||
#define _INCLUDE_WEB_SRV_INT_H_
|
||||
|
||||
#include "web_srv.h"
|
||||
|
||||
#define WEB_NAME_VERSION "PVs/0.2"
|
||||
|
||||
// lifetime (sec) of static responses as string 60*60*24*14=1209600"
|
||||
#define FILE_CACHE_MAX_AGE_SEC 3600 // время для кеша файлов, ставить 0 пока тест!
|
||||
|
||||
#define MAX_HTTP_HEAD_BUF TCP_SRV_SERVER_MAX_RXBUF // максимальный размер HTTP запроса (GET)
|
||||
|
||||
#define RESCHKS_SEND_SIZE 16
|
||||
#define RESCHKE_SEND_SIZE 8
|
||||
#define RESCHK_SEND_SIZE (RESCHKS_SEND_SIZE + RESCHKE_SEND_SIZE)
|
||||
|
||||
#define MIN_SEND_SIZE (256 + RESCHK_SEND_SIZE) // минимальный размер буфера для передачи файла
|
||||
#define MAX_SEND_SIZE ((TCP_SND_BUF) + RESCHK_SEND_SIZE) // ((TCP_MSS*4) + RESCHK_SEND_SIZE) // максимальный размер буфера для передачи 4*MSS = 5840 (MSS=1460)
|
||||
|
||||
#define HTTP_SEND_SIZE 384 // минимальный размер буфера для передачи заголовка HTTP
|
||||
#define SCB_SEND_SIZE 128 // минимальный резерв в буфере для callback
|
||||
|
||||
#define webfile bffiles[0] // File pointer for main file
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
void web_int_vars(TCP_SERV_CONN *ts_conn, uint8 *pcmd, uint8 *pvar);
|
||||
void web_int_cookie(HTTP_CONN *CurHTTP, TCP_SERV_CONN *ts_conn);
|
||||
void web_int_callback(TCP_SERV_CONN *ts_conn, uint8 *cstr);
|
||||
|
||||
void web_hexdump(TCP_SERV_CONN *ts_conn);
|
||||
bool web_inc_fopen(TCP_SERV_CONN *ts_conn, uint8 *cFile);
|
||||
bool web_inc_fclose(WEB_SRV_CONN *web_conn);
|
||||
|
||||
bool web_trim_bufi(TCP_SERV_CONN *ts_conn, uint8 *pdata, uint32 data_len);
|
||||
bool web_feee_bufi(TCP_SERV_CONN *ts_conn);
|
||||
//uint8 * head_find_ctr(HTTP_CONN *CurHTTP, const uint8 * c, int clen, int dlen);
|
||||
uint8 UserAuthorization(uint8 *pbuf, size_t declen);
|
||||
|
||||
#endif /* _INCLUDE_WEB_SRV_INT_H_ */
|
||||
680
Firmware/RTLGDB/Project/web/web_utils.c
Normal file
680
Firmware/RTLGDB/Project/web/web_utils.c
Normal file
|
|
@ -0,0 +1,680 @@
|
|||
/*
|
||||
* 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 ) { // "'" '
|
||||
if(lend >= 6) {
|
||||
ret += 6;
|
||||
lend -= 6;
|
||||
s++;
|
||||
*d++ = '&';
|
||||
*d++ = 'a';
|
||||
*d++ = 'p';
|
||||
*d++ = 'o';
|
||||
*d++ = 's';
|
||||
*d++ = ';';
|
||||
}
|
||||
else break;
|
||||
} else if ( *s == '"' ) { // "
|
||||
if(lend >= 6) {
|
||||
ret += 6;
|
||||
lend -= 6;
|
||||
s++;
|
||||
*d++ = '&';
|
||||
*d++ = 'q';
|
||||
*d++ = 'u';
|
||||
*d++ = 'o';
|
||||
*d++ = 't';
|
||||
*d++ = ';';
|
||||
}
|
||||
else break;
|
||||
} else if ( *s == '&' ) { // &
|
||||
if(lend >= 5) {
|
||||
ret += 5;
|
||||
lend -= 5;
|
||||
s++;
|
||||
*d++ = '&';
|
||||
*d++ = 'a';
|
||||
*d++ = 'm';
|
||||
*d++ = 'p';
|
||||
*d++ = ';';
|
||||
}
|
||||
else break;
|
||||
} else if ( *s == '<' ) { // <
|
||||
if(lend >= 4) {
|
||||
ret += 4;
|
||||
lend -= 4;
|
||||
s++;
|
||||
*d++ = '&';
|
||||
*d++ = 'l';
|
||||
*d++ = 't';
|
||||
*d++ = ';';
|
||||
}
|
||||
else break;
|
||||
} else if ( *s == '>' ) { // >
|
||||
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
|
||||
|
||||
48
Firmware/RTLGDB/Project/web/web_utils.h
Normal file
48
Firmware/RTLGDB/Project/web/web_utils.h
Normal file
|
|
@ -0,0 +1,48 @@
|
|||
/******************************************************************************
|
||||
* FileName: web_utils.h
|
||||
* Alternate SDK
|
||||
* Author: PV`
|
||||
* (c) PV` 2015
|
||||
*******************************************************************************/
|
||||
|
||||
#ifndef _INCLUDE_WEB_UTILS_H_
|
||||
#define _INCLUDE_WEB_UTILS_H_
|
||||
|
||||
typedef enum {
|
||||
SEG_ID_ROM = 0,
|
||||
SEG_ID_SRAM,
|
||||
SEG_ID_TCM,
|
||||
SEG_ID_FLASH,
|
||||
SEG_ID_SDRAM,
|
||||
SEG_ID_SOC,
|
||||
SEG_ID_CPU,
|
||||
SEG_ID_ERR,
|
||||
SEG_ID_MAX
|
||||
} SEG_ID;
|
||||
|
||||
extern const uint32 tab_seg_def[];
|
||||
SEG_ID get_seg_id(uint32 addr, int32 size);
|
||||
|
||||
int rom_atoi(const char *s);
|
||||
void copy_align4(void *ptrd, void *ptrs, uint32 len);
|
||||
uint32 hextoul(uint8 *s);
|
||||
uint32 ahextoul(uint8 *s);
|
||||
uint8 * cmpcpystr(uint8 *pbuf, uint8 *pstr, uint8 a, uint8 b, uint16 len);
|
||||
uint8 * web_strnstr(const uint8* buffer, const uint8* token, int n);
|
||||
bool base64decode(const uint8 *in, int len, uint8_t *out, int *outlen);
|
||||
size_t base64encode(char* target, size_t target_len, const char* source, size_t source_len);
|
||||
void strtomac(uint8 *s, uint8 *macaddr);
|
||||
//uint32 strtoip(uint8 *s); // ipaddr_addr();
|
||||
int urldecode(uint8 *d, uint8 *s, uint16 lend, uint16 lens);
|
||||
//int urlencode(uint8 *d, uint8 *s, uint16 lend, uint16 lens);
|
||||
int htmlcode(uint8 *d, uint8 *s, uint16 lend, uint16 lens);
|
||||
void print_hex_dump(uint8 *buf, uint32 len, uint8 k);
|
||||
// char* str_to_upper_case(char* text);
|
||||
uint32 str_array(uint8 *s, uint32 *buf, uint32 max_buf);
|
||||
uint32 str_array_w(uint8 *s, uint16 *buf, uint32 max_buf);
|
||||
uint32 str_array_b(uint8 *s, uint8 *buf, uint32 max_buf);
|
||||
char* word_to_lower_case(char* text);
|
||||
int rom_xstrcmp(char * pd, const char * ps);
|
||||
int rom_xstrcpy(char * pd, const char * ps);
|
||||
|
||||
#endif /* _INCLUDE_WEB_UTILS_H_ */
|
||||
352
Firmware/RTLGDB/Project/web/web_websocket.c
Normal file
352
Firmware/RTLGDB/Project/web/web_websocket.c
Normal file
|
|
@ -0,0 +1,352 @@
|
|||
/******************************************************************************
|
||||
* FileName: web_websocket.c
|
||||
* Description: websocket for web
|
||||
* Author: pvvx
|
||||
* 2016
|
||||
*******************************************************************************/
|
||||
#include "user_config.h"
|
||||
#ifdef WEBSOCKET_ENA
|
||||
#include "autoconf.h"
|
||||
#include "FreeRTOS.h"
|
||||
#include "task.h"
|
||||
#include "diag.h"
|
||||
//#include "bios.h"
|
||||
//#include "osapi.h"
|
||||
//#include "sdk/rom2ram.h"
|
||||
#include "lwip/tcp.h"
|
||||
#include "tcpsrv/tcp_srv_conn.h"
|
||||
#include "web_srv_int.h"
|
||||
#include "web_srv.h"
|
||||
#include "web_utils.h"
|
||||
#include "web_websocket.h"
|
||||
#include "websock.h"
|
||||
#include "rtl8195a/rtl_libc.h"
|
||||
#include "esp_comp.h"
|
||||
|
||||
#if 0
|
||||
#undef DEBUGSOO
|
||||
#define DEBUGSOO 4
|
||||
#endif
|
||||
|
||||
#define copy_s4d1 rtl_memcpy
|
||||
|
||||
//#define mMIN(a, b) ((a<b)?a:b)
|
||||
|
||||
#define MAX_RX_BUF_SIZE 8192
|
||||
|
||||
const char txt_wsping[] ICACHE_RODATA_ATTR = "ws:ping";
|
||||
const char txt_wspong[] ICACHE_RODATA_ATTR = "ws:pong";
|
||||
|
||||
//=============================================================================
|
||||
// websock_tx_frame() - передача фрейма
|
||||
//=============================================================================
|
||||
err_t ICACHE_FLASH_ATTR
|
||||
websock_tx_frame(TCP_SERV_CONN *ts_conn, uint32 opcode, uint8 *raw_data, uint32 raw_len)
|
||||
{
|
||||
err_t err = WebsocketTxFrame(ts_conn, opcode, raw_data, raw_len);
|
||||
if(err != ERR_OK) {
|
||||
#if DEBUGSOO > 3
|
||||
os_printf("ws%utx[%u] error %d!\n", opcode, raw_len, err);
|
||||
#endif
|
||||
((WEB_SRV_CONN *)ts_conn->linkd)->webflag |= SCB_DISCONNECT;
|
||||
}
|
||||
else {
|
||||
if((opcode & WS_OPCODE_BITS) == WS_OPCODE_CLOSE) {
|
||||
((WEB_SRV_CONN *)ts_conn->linkd)->ws.flg |= WS_FLG_CLOSE;
|
||||
}
|
||||
}
|
||||
return err;
|
||||
}
|
||||
//=============================================================================
|
||||
// websock_tx_close_err() - вывод сообщения закрытия или ошибки
|
||||
//=============================================================================
|
||||
err_t ICACHE_FLASH_ATTR
|
||||
websock_tx_close_err(TCP_SERV_CONN *ts_conn, uint32 err)
|
||||
{
|
||||
uint8 uc[2];
|
||||
uc[1] = err;
|
||||
uc[0] = err>>8;
|
||||
return websock_tx_frame(ts_conn, WS_OPCODE_CLOSE | WS_FRAGMENT_FIN, uc, 2);
|
||||
}
|
||||
//=============================================================================
|
||||
// websock_rx_data() прием данных
|
||||
//=============================================================================
|
||||
#define MAX_WS_DATA_BLK_SIZE (tcp_sndbuf(ts_conn->pcb)-8) // (TCP_MSS - 8)
|
||||
//=============================================================================
|
||||
bool ICACHE_FLASH_ATTR
|
||||
websock_rx_data(TCP_SERV_CONN *ts_conn)
|
||||
{
|
||||
// HTTP_CONN *CurHTTP;
|
||||
WEB_SRV_CONN *web_conn = (WEB_SRV_CONN *)ts_conn->linkd;
|
||||
if(web_conn == NULL) return false;
|
||||
WS_FRSTAT *ws = &web_conn->ws;
|
||||
uint16 len;
|
||||
uint8 *pstr;
|
||||
|
||||
#if DEBUGSOO > 3
|
||||
os_printf("ws_rx[%u]%u ", ts_conn->sizei, ts_conn->cntri);
|
||||
#endif
|
||||
if(ts_conn->sizei == 0) return true; // докачивать
|
||||
tcpsrv_unrecved_win(ts_conn);
|
||||
if((ws->flg & WS_FLG_CLOSE) != 0) {
|
||||
// убить буфер ts_conn->pbufi, конец давно :)
|
||||
web_feee_bufi(ts_conn);
|
||||
SetSCB(SCB_DISCONNECT);
|
||||
return false;
|
||||
}
|
||||
if(ts_conn->sizei > MAX_RX_BUF_SIZE) {
|
||||
#if DEBUGSOO > 0
|
||||
os_printf("ws:rxbuf_full! ");
|
||||
#endif
|
||||
// убить буфер ts_conn->pbufi и ответить ошибкой WS_CLOSE_UNEXPECTED_ERROR
|
||||
web_feee_bufi(ts_conn);
|
||||
websock_tx_close_err(ts_conn, WS_CLOSE_MESSAGE_TOO_BIG); // WS_CLOSE_UNEXPECTED_ERROR);
|
||||
SetSCB(SCB_DISCONNECT);
|
||||
return false;
|
||||
}
|
||||
pstr = ts_conn->pbufi;// + ts_conn->cntri;
|
||||
len = ts_conn->sizei;// - ts_conn->cntri;
|
||||
while(ts_conn->cntri < ts_conn->sizei || (ws->flg & WS_FLG_FIN) != 0) {
|
||||
pstr = ts_conn->pbufi;// + ts_conn->cntri;
|
||||
len = ts_conn->sizei;// - ts_conn->cntri;
|
||||
if((ws->flg & WS_FLG_FIN) != 0 // обработка
|
||||
|| ws->frame_len > ws->cur_len) {
|
||||
ws->flg &= ~WS_FLG_FIN;
|
||||
len = mMIN(ws->frame_len - ws->cur_len, mMIN(MAX_WS_DATA_BLK_SIZE, len));
|
||||
// размаскировать
|
||||
if((ws->flg & WS_FLG_MASK) != 0) WebsocketMask(ws, pstr, len);
|
||||
#if DEBUGSOO > 3
|
||||
os_printf("wsfr[%u]blk[%u]at:%u ", ws->frame_len, len, ws->cur_len);
|
||||
#endif
|
||||
switch(ws->status) {
|
||||
case sw_frs_binary:
|
||||
#if DEBUGSOO > 1
|
||||
os_printf("ws:bin ");
|
||||
#endif
|
||||
if(ws->frame_len != 0) {
|
||||
// пока просто эхо
|
||||
uint32 opcode = WS_OPCODE_BINARY;
|
||||
if(ws->cur_len != 0) opcode = WS_OPCODE_CONTINUE;
|
||||
if(ws->frame_len == ws->cur_len + len) opcode |= WS_FRAGMENT_FIN;
|
||||
if(websock_tx_frame(ts_conn, opcode, pstr, len) != ERR_OK) {
|
||||
return false; // не докачивать, ошибка или закрытие
|
||||
}
|
||||
}
|
||||
ws->cur_len += len;
|
||||
ts_conn->cntri += len;
|
||||
break;
|
||||
case sw_frs_text:
|
||||
#if DEBUGSOO > 1
|
||||
os_printf("ws:txt ");
|
||||
|
||||
#if DEBUGSOO > 2
|
||||
if(ws->frame_len != 0) {
|
||||
uint8 tt = pstr[len];
|
||||
pstr[len] = 0;
|
||||
os_printf("'%s' ", pstr);
|
||||
pstr[len] = tt;
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
if(ws->frame_len == ws->cur_len + len && ws->frame_len != 0) { // полное соо
|
||||
web_conn->msgbufsize = tcp_sndbuf(ts_conn->pcb); // сколько можем выввести сейчас?
|
||||
if (web_conn->msgbufsize < MIN_SEND_SIZE) {
|
||||
#if DEBUGSOO > 0
|
||||
os_printf("ws:sndbuf=%u! ", web_conn->msgbufsize);
|
||||
#endif
|
||||
websock_tx_close_err(ts_conn, WS_CLOSE_UNEXPECTED_ERROR);
|
||||
SetSCB(SCB_FCLOSE|SCB_DISCONNECT);
|
||||
return false;
|
||||
}
|
||||
web_conn->msgbufsize -= 16;
|
||||
if(ws->frame_len == (sizeof(txt_wsping)-1) && rom_xstrcmp(pstr, txt_wsping) != 0){
|
||||
copy_s4d1(pstr, (void *)txt_wspong, sizeof(txt_wspong) - 1);
|
||||
if(websock_tx_frame(ts_conn, WS_OPCODE_TEXT | WS_FRAGMENT_FIN, pstr, sizeof(txt_wspong) - 1) != ERR_OK) {
|
||||
return false; // не докачивать, ошибка или закрытие
|
||||
}
|
||||
}
|
||||
else {
|
||||
if(web_conn->msgbuf) os_free(web_conn->msgbuf);
|
||||
web_conn->msgbuf = (uint8 *) os_malloc(web_conn->msgbufsize);
|
||||
if (web_conn->msgbuf == NULL) {
|
||||
#if DEBUGSOO > 0
|
||||
os_printf("ws:mem!\n");
|
||||
#endif
|
||||
websock_tx_close_err(ts_conn, WS_CLOSE_UNEXPECTED_ERROR);
|
||||
SetSCB(SCB_FCLOSE|SCB_DISCONNECT);
|
||||
return false;
|
||||
};
|
||||
web_conn->msgbuflen = 0;
|
||||
uint32 opcode;
|
||||
if(CheckSCB(SCB_RETRYCB)) { // повторный callback? да
|
||||
if(web_conn->func_web_cb != NULL) web_conn->func_web_cb(ts_conn);
|
||||
if(!CheckSCB(SCB_RETRYCB)) {
|
||||
// ClrSCB(SCB_FCLOSE | SCB_DISCONNECT);
|
||||
opcode = WS_OPCODE_CONTINUE | WS_FRAGMENT_FIN;
|
||||
}
|
||||
else opcode = WS_OPCODE_CONTINUE;
|
||||
}
|
||||
else {
|
||||
pstr[len] = '\0';
|
||||
uint8 *vstr = os_strchr(pstr, '=');
|
||||
if(vstr != NULL) {
|
||||
*vstr++ = '\0';
|
||||
web_int_vars(ts_conn, pstr, vstr);
|
||||
}
|
||||
else {
|
||||
web_conn->msgbuf[0] = 0;
|
||||
web_int_callback(ts_conn, pstr);
|
||||
}
|
||||
if(CheckSCB(SCB_RETRYCB)) opcode = WS_OPCODE_TEXT;
|
||||
else {
|
||||
// ClrSCB(SCB_FCLOSE | SCB_DISCONNECT);
|
||||
opcode = WS_OPCODE_TEXT | WS_FRAGMENT_FIN;
|
||||
}
|
||||
}
|
||||
if(web_conn->msgbuflen != 0) {
|
||||
if(websock_tx_frame(ts_conn, opcode, web_conn->msgbuf, web_conn->msgbuflen) != ERR_OK) {
|
||||
if(web_conn->msgbuf) os_free(web_conn->msgbuf);
|
||||
web_conn->msgbuf = NULL;
|
||||
return false; // не докачивать, ошибка или закрытие
|
||||
}
|
||||
}
|
||||
if(web_conn->msgbuf) os_free(web_conn->msgbuf);
|
||||
web_conn->msgbuf = NULL;
|
||||
if(CheckSCB(SCB_RETRYCB)) return false;
|
||||
}
|
||||
}
|
||||
/*
|
||||
if(0) {
|
||||
uint32 opcode = WS_OPCODE_TEXT;
|
||||
if(ws->cur_len != 0) opcode = WS_OPCODE_CONTINUE;
|
||||
if(ws->frame_len == ws->cur_len + len) opcode |= WS_FRAGMENT_FIN;
|
||||
if(websock_tx_frame(ts_conn, opcode, pstr, len) != ERR_OK) {
|
||||
return false; // не докачивать, ошибка или закрытие
|
||||
}
|
||||
}
|
||||
*/
|
||||
ws->cur_len += len;
|
||||
ts_conn->cntri += len;
|
||||
return true; // докачивать
|
||||
// break;
|
||||
// break;
|
||||
case sw_frs_ping:
|
||||
#if DEBUGSOO > 1
|
||||
os_printf("ws:ping ");
|
||||
#endif
|
||||
{
|
||||
uint32 opcode = WS_OPCODE_PONG;
|
||||
if(ws->cur_len != 0) opcode = WS_OPCODE_CONTINUE;
|
||||
if(ws->frame_len == ws->cur_len + len) opcode |= WS_FRAGMENT_FIN;
|
||||
if(websock_tx_frame(ts_conn, opcode, pstr, len) != ERR_OK) {
|
||||
return false; // не докачивать, ошибка или закрытие
|
||||
}
|
||||
}
|
||||
ws->cur_len += len;
|
||||
ts_conn->cntri += len;
|
||||
return true; // докачивать
|
||||
// break;
|
||||
case sw_frs_pong:
|
||||
#if DEBUGSOO > 1
|
||||
os_printf("ws:pong ");
|
||||
#endif
|
||||
ws->cur_len += len;
|
||||
ts_conn->cntri += len;
|
||||
break;
|
||||
// return true;
|
||||
case sw_frs_close:
|
||||
#if DEBUGSOO > 1
|
||||
os_printf("ws:close ");
|
||||
#endif
|
||||
// if((ws->flg & WS_FLG_CLOSE) == 0) {
|
||||
{
|
||||
if(len >= 2) {
|
||||
uint32 close_code = (pstr[0]<<8) | pstr[1];
|
||||
#if DEBUGSOO > 1
|
||||
os_printf("code:%d ", close_code);
|
||||
#endif
|
||||
if(close_code == WS_CLOSE_NORMAL) websock_tx_close_err(ts_conn, WS_CLOSE_NORMAL);
|
||||
// else websock_tx_frame(ts_conn, WS_OPCODE_CLOSE | WS_FRAGMENT_FIN, NULL, 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
websock_tx_close_err(ts_conn, WS_CLOSE_NORMAL);
|
||||
// websock_tx_frame(ts_conn, WS_OPCODE_CLOSE | WS_FRAGMENT_FIN, NULL, 0);
|
||||
}
|
||||
}
|
||||
ts_conn->flag.pcb_time_wait_free = 1;
|
||||
SetSCB(SCB_DISCONNECT);
|
||||
// ts_conn->cntri = ts_conn->sizei;
|
||||
/* ws->cur_len += len;
|
||||
ts_conn->cntri += len; */
|
||||
return false;
|
||||
default:
|
||||
#if DEBUGSOO > 0
|
||||
os_printf("ws:f?! ");
|
||||
#endif
|
||||
websock_tx_close_err(ts_conn, WS_CLOSE_UNEXPECTED_ERROR);
|
||||
SetSCB(SCB_DISCONNECT);
|
||||
// ts_conn->cntri = ts_conn->sizei;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else
|
||||
if(ws->cur_len >= ws->frame_len) { // прием и разбор нового фрейма
|
||||
if((ws->flg & WS_FLG_FIN) != 0) { // обработка
|
||||
#if DEBUGSOO > 3
|
||||
os_printf("ws_rx:fin=%u ", ws->cur_len);
|
||||
#endif
|
||||
}
|
||||
else {
|
||||
uint32 ret = WebsocketHead(ws, pstr, len);
|
||||
if(ret >= WS_CLOSE_NORMAL) { // error или close
|
||||
|
||||
#if DEBUGSOO > 0
|
||||
os_printf("ws:txerr=%u ", ret);
|
||||
#endif
|
||||
websock_tx_close_err(ts_conn, ret);
|
||||
// ts_conn->cntri = ts_conn->sizei; // убить буфер ts_conn->pbufi
|
||||
return false; // error
|
||||
}
|
||||
else if(ret == 0) {
|
||||
#if DEBUGSOO > 3
|
||||
os_printf("ws_rx... ");
|
||||
#endif
|
||||
return true; // докачивать
|
||||
}
|
||||
ts_conn->cntri += ws->head_len; // вычесть заголовок
|
||||
/*
|
||||
switch(ws->status) {
|
||||
case sw_frs_binary:
|
||||
break;
|
||||
case sw_frs_text:
|
||||
if(ws->frame_len > MAX_RX_BUF_SIZE) {
|
||||
websock_tx_close_err(ts_conn, WS_CLOSE_MESSAGE_TOO_BIG);
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
}
|
||||
*/
|
||||
}
|
||||
}
|
||||
#if DEBUGSOO > 3
|
||||
os_printf("trim%u-%u ", ts_conn->sizei, ts_conn->sizei - ts_conn->cntri );
|
||||
#endif
|
||||
if(!web_trim_bufi(ts_conn, &ts_conn->pbufi[ts_conn->cntri], ts_conn->sizei - ts_conn->cntri)) {
|
||||
#if DEBUGSOO > 0
|
||||
os_printf("ws:trim_err! ");
|
||||
#endif
|
||||
// убить буфер ts_conn->pbufi и ответить ошибкой WS_CLOSE_UNEXPECTED_ERROR
|
||||
websock_tx_close_err(ts_conn, WS_CLOSE_UNEXPECTED_ERROR);
|
||||
SetSCB(SCB_DISCONNECT);
|
||||
// ts_conn->cntri = ts_conn->sizei;
|
||||
return false;
|
||||
};
|
||||
}
|
||||
return false; // не докачивать, ошибка или закрытие
|
||||
}
|
||||
//=============================================================================
|
||||
//=============================================================================
|
||||
#endif // WEBSOCKET_ENA
|
||||
|
||||
|
||||
18
Firmware/RTLGDB/Project/web/web_websocket.h
Normal file
18
Firmware/RTLGDB/Project/web/web_websocket.h
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
#ifndef _WEB_WEBSOCKET_H_
|
||||
/******************************************************************************
|
||||
* FileName: web_websocket.h
|
||||
* Description: websocket for web ESP8266
|
||||
* Author: PV`
|
||||
* (c) PV` 2016
|
||||
*******************************************************************************/
|
||||
#define _WEB_WEBSOCKET_H_
|
||||
#include "user_config.h"
|
||||
#ifdef WEBSOCKET_ENA
|
||||
#include "websock.h"
|
||||
|
||||
err_t websock_tx_close_err(TCP_SERV_CONN *ts_conn, uint32 err);
|
||||
bool websock_rx_data(TCP_SERV_CONN *ts_conn);
|
||||
err_t websock_tx_frame(TCP_SERV_CONN *ts_conn, uint32 opcode, uint8 *raw_data, uint32 raw_len);
|
||||
|
||||
#endif // WEBSOCKET_ENA
|
||||
#endif /* _WEB_WEBSOCKET_H_ */
|
||||
245
Firmware/RTLGDB/Project/web/websock.c
Normal file
245
Firmware/RTLGDB/Project/web/websock.c
Normal file
|
|
@ -0,0 +1,245 @@
|
|||
/******************************************************************************
|
||||
* FileName: websock.c
|
||||
* Description: websocket for web ESP8266
|
||||
* Author: PV`
|
||||
* (c) PV` 2016
|
||||
*******************************************************************************/
|
||||
#include "user_config.h"
|
||||
#ifdef WEBSOCKET_ENA
|
||||
#include "autoconf.h"
|
||||
#include "FreeRTOS.h"
|
||||
#include "task.h"
|
||||
#include "diag.h"
|
||||
#include "tcpsrv/tcp_srv_conn.h"
|
||||
#include "web_utils.h" // base64encode()
|
||||
#include "web_srv.h"
|
||||
//#include "phy/phy.h"
|
||||
#include "device_lock.h"
|
||||
#include "lwip/tcp.h"
|
||||
#include "websock.h"
|
||||
#include "rtl8195a/rtl_libc.h"
|
||||
#include "esp_comp.h"
|
||||
#include "hal_crypto.h"
|
||||
|
||||
// HTTP/1.1 101 Web Socket Protocol Handshake\r\n
|
||||
const uint8 WebSocketHTTPOkKey[] ICACHE_RODATA_ATTR = "HTTP/1.1 101 Switching Protocols\r\nAccess-Control-Allow-Origin: *\r\nUpgrade: websocket\r\nConnection: Upgrade\r\nSec-WebSocket-Accept: %s\r\n\r\n";
|
||||
const uint8 WebSocketAddKey[] ICACHE_RODATA_ATTR = "258EAFA5-E914-47DA-95CA-C5AB0DC85B11";
|
||||
const uint8 *HTTPUpgrade = "Upgrade:";
|
||||
const uint8 *HTTPwebsocket = "websocket";
|
||||
const uint8 *HTTPSecWebSocketKey = "Sec-WebSocket-Key:";
|
||||
|
||||
//=============================================================================
|
||||
// WebSocketAcceptKey()
|
||||
// 1) взять строковое значение из заголовка Sec-WebSocket-Key и объединить со
|
||||
// строкой 258EAFA5-E914-47DA-95CA-C5AB0DC85B11
|
||||
// 2) вычислить бинарный хеш SHA-1 (бинарная строка из 20 символов) от полученной
|
||||
// в первом пункте строки
|
||||
// 3) закодировать хеш в Base64
|
||||
// skey[24+36]:'dGhlIHNhbXBsZSBub25jZQ==258EAFA5-E914-47DA-95CA-C5AB0DC85B11'
|
||||
// cha:'b37a4f2cc0624f1690f64606cf385945b2bec4ea'
|
||||
// key[28]:'s3pPLMBiTxaQ9kYGzzhZRbK+xOo='
|
||||
//=============================================================================
|
||||
uint8 buff[maxsizeWebSocketKey + sizeWebSocketAddKey]; // [68]
|
||||
bool ICACHE_FLASH_ATTR WebSocketAcceptKey(uint8* dkey, uint8* skey)
|
||||
{
|
||||
int len = 0;
|
||||
bool ret = false;
|
||||
uint8 keybuf[CRYPTO_SHA1_DIGEST_LENGTH];
|
||||
uint8 * buff = os_malloc(maxsizeWebSocketKey + sizeWebSocketAddKey);
|
||||
if(buff) {
|
||||
while(skey[len] >= '+' && len < maxsizeWebSocketKey) {
|
||||
buff[len] = skey[len];
|
||||
len++;
|
||||
};
|
||||
if(len > minsizeWebSocketKey) {
|
||||
rtl_memcpy(&buff[len], WebSocketAddKey, sizeWebSocketAddKey+1);
|
||||
device_mutex_lock(RT_DEV_LOCK_CRYPTO);
|
||||
rtl_crypto_sha1(buff, len + sizeWebSocketAddKey, keybuf);
|
||||
device_mutex_unlock(RT_DEV_LOCK_CRYPTO);
|
||||
// rtl_cryptoEngine_info();
|
||||
len = base64encode(dkey, FileNameSize, keybuf, CRYPTO_SHA1_DIGEST_LENGTH);
|
||||
#if DEBUGSOO > 2
|
||||
os_printf("\ncha:'");
|
||||
print_hex_dump(keybuf, CRYPTO_SHA1_DIGEST_LENGTH, '\0');
|
||||
os_printf("'\n");
|
||||
os_printf("key[%u]:'%s'\n", len, dkey);
|
||||
#endif
|
||||
ret = true;
|
||||
}
|
||||
os_free(buff);
|
||||
}
|
||||
return ret;
|
||||
|
||||
}
|
||||
//=============================================================================
|
||||
// websock_mask() размаскирование блока
|
||||
//=============================================================================
|
||||
void ICACHE_FLASH_ATTR
|
||||
WebsocketMask(WS_FRSTAT *ws, uint8 *raw_data, uint32 raw_len)
|
||||
{
|
||||
uint32 i, x = ws->cur_len;
|
||||
#if DEBUGSOO > 3
|
||||
os_printf("mask[%u]%u ", raw_len, x);
|
||||
#endif
|
||||
for (i = 0; i < raw_len; i++) {
|
||||
raw_data[i] ^= ws->mask.uc[x++ & 3];
|
||||
}
|
||||
}
|
||||
//=============================================================================
|
||||
// websock_head() разбор заголовка
|
||||
//=============================================================================
|
||||
uint32 ICACHE_FLASH_ATTR
|
||||
WebsocketHead(WS_FRSTAT *ws, uint8 *raw_data, uint32 raw_len)
|
||||
{
|
||||
// определить размер заголовка фрейма
|
||||
uint32 head_len = 2;
|
||||
if(raw_len < head_len) return 0; // докачивать
|
||||
uint32 data_len = raw_data[1] & WS_SIZE1_BITS;
|
||||
if(data_len == 127) head_len = 10;
|
||||
else if(data_len == 126) head_len = 4;
|
||||
if(raw_data[1] & WS_MASK_FLG) head_len += 4;
|
||||
if(raw_len < head_len) return 0; // докачивать
|
||||
ws->head_len = head_len;
|
||||
ws->cur_len = 0;
|
||||
ws->flg = 0;
|
||||
data_len = raw_data[1] & WS_SIZE1_BITS;
|
||||
if(data_len >= 126) {
|
||||
if(data_len == 127) {
|
||||
uint32 i;
|
||||
for(i = 3; i < 6; i++) {
|
||||
if(raw_data[i] != 0) {
|
||||
ws->status = sw_frs_close;
|
||||
ws->frame_len = 0;
|
||||
return WS_CLOSE_MESSAGE_TOO_BIG;
|
||||
}
|
||||
}
|
||||
data_len = (raw_data[6] << 24) | (raw_data[7] << 16) | (raw_data[8] << 8) | raw_data[9];
|
||||
}
|
||||
else {
|
||||
data_len = (raw_data[2] << 8) | raw_data[3];
|
||||
}
|
||||
}
|
||||
if(raw_data[1] & WS_MASK_FLG) {
|
||||
ws->flg |= WS_FLG_MASK;
|
||||
ws->mask.uc[0] = raw_data[head_len-4];
|
||||
ws->mask.uc[1] = raw_data[head_len-3];
|
||||
ws->mask.uc[2] = raw_data[head_len-2];
|
||||
ws->mask.uc[3] = raw_data[head_len-1];
|
||||
}
|
||||
// else ws->mask = 0;
|
||||
uint8 opcode = raw_data[0] & WS_OPCODE_BITS;
|
||||
switch(opcode) {
|
||||
case WS_OPCODE_PING: // эхо - дублировать прием
|
||||
raw_data[0] &= ~WS_FRAGMENT_FIN;
|
||||
raw_data[0] |= WS_OPCODE_PONG;
|
||||
ws->status = sw_frs_pong;
|
||||
ws->frame_len = data_len;
|
||||
break;
|
||||
case WS_OPCODE_PONG: // эхо - дублировать прием
|
||||
ws->status = sw_frs_ping;
|
||||
ws->frame_len = data_len;
|
||||
break;
|
||||
case WS_OPCODE_CONTINUE: // продолжить
|
||||
if(ws->status == sw_frs_pong) {
|
||||
ws->frame_len = data_len;
|
||||
break;
|
||||
}
|
||||
else ws->frame_len += data_len;
|
||||
break;
|
||||
case WS_OPCODE_CLOSE: //
|
||||
ws->status = sw_frs_close;
|
||||
ws->frame_len = data_len;
|
||||
break;
|
||||
case WS_OPCODE_TEXT:
|
||||
ws->status = sw_frs_text;
|
||||
ws->frame_len = data_len;
|
||||
break;
|
||||
case WS_OPCODE_BINARY:
|
||||
ws->status = sw_frs_binary;
|
||||
ws->frame_len = data_len;
|
||||
break;
|
||||
default:
|
||||
ws->status = sw_frs_close;
|
||||
ws->frame_len = 0;
|
||||
return WS_CLOSE_WRONG_TYPE;
|
||||
}
|
||||
// uint32 len = mMIN(raw_len - head_len, data_len);
|
||||
// if((ws->flg & WS_FLG_MASK) != 0) websock_mask(ws, &raw_data[head_len], mMIN(raw_len - head_len, len));
|
||||
// ws->cur_len += len;
|
||||
if((raw_data[0] & WS_FRAGMENT_FIN) != 0) { // конец - данные на обработку
|
||||
ws->flg |= WS_FLG_FIN;
|
||||
}
|
||||
#if DEBUGSOO > 1
|
||||
os_printf("ws#%02xrx[%u] ", raw_data[0], data_len);
|
||||
#endif
|
||||
return 1;
|
||||
/*
|
||||
if(data_len + head_len <= raw_len) { // весь пакет уже в буфере?
|
||||
return 1;
|
||||
}
|
||||
return 0; // докачивать */
|
||||
}
|
||||
//=============================================================================
|
||||
// websock_tx_frame() - передача фрейма
|
||||
//=============================================================================
|
||||
err_t ICACHE_FLASH_ATTR
|
||||
WebsocketTxFrame(TCP_SERV_CONN *ts_conn, uint32 opcode, uint8 *raw_data, uint32 raw_len)
|
||||
{
|
||||
union {
|
||||
uint8 uc[8];
|
||||
uint16 uw[4];
|
||||
uint32 ud[2];
|
||||
}head;
|
||||
union {
|
||||
uint8 uc[4];
|
||||
uint16 uw[2];
|
||||
uint32 ud;
|
||||
}mask;
|
||||
if(raw_data == NULL) raw_len = 0;
|
||||
head.ud[0] = opcode;
|
||||
uint32 head_len;
|
||||
if(raw_len > 126) {
|
||||
head.uc[1] = 126;
|
||||
head.uc[2] = raw_len>>8;
|
||||
head.uc[3] = raw_len;
|
||||
head_len = 4;
|
||||
}
|
||||
else {
|
||||
head.uc[1] = raw_len;
|
||||
head_len = 2;
|
||||
};
|
||||
if(opcode & (WS_MASK_FLG << 8)) {
|
||||
mask.ud ^= rand();
|
||||
head.uc[1] |= WS_MASK_FLG;
|
||||
head.uc[head_len] = mask.uc[0];
|
||||
head.uc[head_len+1] = mask.uc[1];
|
||||
head.uc[head_len+2] = mask.uc[2];
|
||||
head.uc[head_len+3] = mask.uc[3];
|
||||
head_len += 4;
|
||||
}
|
||||
uint32 len = tcp_sndbuf(ts_conn->pcb);
|
||||
err_t err = 1; // ERR_BUF;
|
||||
if(len >= raw_len + head_len) {
|
||||
#if DEBUGSOO > 1
|
||||
os_printf("ws#%02xtx[%u] ", head.uc[0], raw_len);
|
||||
#endif
|
||||
ts_conn->flag.nagle_disabled = 0;
|
||||
tcp_nagle_disable(ts_conn->pcb);
|
||||
err = tcpsrv_int_sent_data(ts_conn, head.uc, head_len);
|
||||
ts_conn->flag.nagle_disabled = 1;
|
||||
if(err == ERR_OK && raw_len != 0) {
|
||||
if(opcode & (WS_MASK_FLG << 8)) {
|
||||
uint32 i;
|
||||
for (i = 0; i < raw_len; i++) {
|
||||
raw_data[i] ^= mask.uc[i & 3];
|
||||
}
|
||||
}
|
||||
err = tcpsrv_int_sent_data(ts_conn, raw_data, raw_len);
|
||||
}
|
||||
}
|
||||
return err;
|
||||
}
|
||||
|
||||
|
||||
#endif // WEBSOCKET_ENA
|
||||
|
||||
110
Firmware/RTLGDB/Project/web/websock.h
Normal file
110
Firmware/RTLGDB/Project/web/websock.h
Normal file
|
|
@ -0,0 +1,110 @@
|
|||
/*
|
||||
* File: websock.h
|
||||
* Small WEB server ESP8266EX
|
||||
* Author: PV`
|
||||
*/
|
||||
|
||||
#ifndef _WEBSOCK_H_
|
||||
#define _WEBSOCK_H_
|
||||
#include "lwip/err.h"
|
||||
#include "tcpsrv/tcp_srv_conn.h"
|
||||
|
||||
//#define WS_NONBLOCK 0x02
|
||||
|
||||
/*
|
||||
0 1 2 3
|
||||
7 6 5 4 3 2 1 0 7 6 5 4 3 2 1 0 7 6 5 4 3 2 1 0 7 6 5 4 3 2 1 0
|
||||
+-+-+-+-+-------+-+-------------+-------------------------------+
|
||||
|F|R|R|R| опкод |М| Длина тела | Расширенная длина тела |
|
||||
|I|S|S|S|(4бита)|А| (7бит) | (2 байта) |
|
||||
|N|V|V|V| |С| |(если длина тела==126 или 127) |
|
||||
| |1|2|3| |К| | |
|
||||
| | | | | |А| | |
|
||||
+-+-+-+-+-------+-+-------------+ - - - - - - - - - - - - - - - +
|
||||
|4 5 6 7 |
|
||||
| Продолжение расширенной длины тела, если длина тела = 127 |
|
||||
+ - - - - - - - - - - - - - - - +-------------------------------+
|
||||
|8 9 10 11 |
|
||||
| | Ключ маски, если МАСКА = 1 |
|
||||
+-------------------------------+-------------------------------+
|
||||
|12 13 14 15 |
|
||||
| Ключ маски (продолжение) | Данные фрейма ("тело") |
|
||||
+-------------------------------- - - - - - - - - - - - - - - - +
|
||||
|16 17 18 19 |
|
||||
: Данные продолжаются ... :
|
||||
+ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +
|
||||
| Данные продолжаются ... |
|
||||
+---------------------------------------------------------------+
|
||||
|
||||
*/
|
||||
|
||||
#define WS_FRAGMENT_FIN 0x80
|
||||
//#define WS_RSVD_BITS (7 << 4)
|
||||
#define WS_OPCODE_BITS 0x7F
|
||||
#define WS_OPCODE_CONTINUE 0x0 // фрейм-продолжение для фрагментированного сообщения
|
||||
#define WS_OPCODE_TEXT 0x1 // текстовый фрейм
|
||||
#define WS_OPCODE_BINARY 0x2 // двоичный фрейм
|
||||
#define WS_OPCODE_CLOSE 0x8 // закрытие соединения
|
||||
#define WS_OPCODE_PING 0x9
|
||||
#define WS_OPCODE_PONG 0xa
|
||||
#define WS_MASK_FLG (1 << 7)
|
||||
#define WS_SIZE1_BITS 0x7F
|
||||
|
||||
|
||||
#define WS_CLOSE_NORMAL 1000
|
||||
#define WS_CLOSE_GOING_AWAY 1001
|
||||
#define WS_CLOSE_PROTOCOL_ERROR 1002
|
||||
#define WS_CLOSE_NOT_ALLOWED 1003
|
||||
#define WS_CLOSE_RESERVED 1004
|
||||
#define WS_CLOSE_NO_CODE 1005
|
||||
#define WS_CLOSE_DIRTY 1006
|
||||
#define WS_CLOSE_WRONG_TYPE 1007
|
||||
#define WS_CLOSE_POLICY_VIOLATION 1008
|
||||
#define WS_CLOSE_MESSAGE_TOO_BIG 1009
|
||||
#define WS_CLOSE_UNEXPECTED_ERROR 1011
|
||||
|
||||
typedef struct _WS_FRSTAT
|
||||
{
|
||||
uint32 frame_len; // размер данных в заголовке фрейма
|
||||
uint32 cur_len; // счетчик обработанных данных
|
||||
union {
|
||||
unsigned char uc[4];
|
||||
unsigned int ud;
|
||||
} mask; // маска принимаемых данных
|
||||
uint8 status;
|
||||
uint8 flg;
|
||||
uint8 head_len;
|
||||
} WS_FRSTAT; // __attribute__((packed))
|
||||
|
||||
#define WS_FLG_MASK 0x01
|
||||
#define WS_FLG_FIN 0x02
|
||||
#define WS_FLG_CLOSE 0x04 // уже передано WS_CLOSE
|
||||
|
||||
enum WS_FRAME_STATE {
|
||||
sw_frs_none = 0,
|
||||
sw_frs_text,
|
||||
sw_frs_binary,
|
||||
sw_frs_close,
|
||||
sw_frs_ping,
|
||||
sw_frs_pong
|
||||
};
|
||||
|
||||
extern const uint8 WebSocketHTTPOkKey[]; // ICACHE_RODATA_ATTR = "HTTP/1.1 101 Switching Protocols\r\nUpgrade: websocket\r\nConnection: Upgrade\r\nSec-WebSocket-Accept:%s\r\n\r\n"
|
||||
extern const uint8 WebSocketAddKey[]; // ICACHE_RODATA_ATTR = "258EAFA5-E914-47DA-95CA-C5AB0DC85B11";
|
||||
#define sizeWebSocketAddKey 36
|
||||
#define maxsizeWebSocketKey 64
|
||||
#define minsizeWebSocketKey 8
|
||||
extern const uint8 *HTTPUpgrade; // = "Upgrade:";
|
||||
#define sizeHTTPUpgrade 8
|
||||
extern const uint8 *HTTPwebsocket; // = "websocket";
|
||||
#define sizeHTTPwebsocket 9
|
||||
extern const uint8 *HTTPSecWebSocketKey; // = "Sec-WebSocket-Key:";
|
||||
#define sizeHTTPSecWebSocketKey 18
|
||||
|
||||
|
||||
bool WebSocketAcceptKey(uint8* dkey, uint8* skey);
|
||||
void WebsocketMask(WS_FRSTAT *ws, uint8 *raw_data, uint32 raw_len);
|
||||
uint32 WebsocketHead(WS_FRSTAT *ws, uint8 *raw_data, uint32 raw_len);
|
||||
err_t WebsocketTxFrame(TCP_SERV_CONN *ts_conn, uint32 opcode, uint8 *raw_data, uint32 raw_len);
|
||||
|
||||
#endif /* _WEBSOCK_H_ */
|
||||
Loading…
Add table
Add a link
Reference in a new issue