mirror of
https://github.com/pvvx/RTL00_WEB.git
synced 2025-07-31 20:31:05 +00:00
first commit
This commit is contained in:
commit
fa343db334
154 changed files with 18186 additions and 0 deletions
258
project/src/console/adc_tst.c
Normal file
258
project/src/console/adc_tst.c
Normal file
|
|
@ -0,0 +1,258 @@
|
|||
/*
|
||||
* adc_tst.c
|
||||
*
|
||||
* Created on: 04/04/2017.
|
||||
* Author: pvvx
|
||||
*/
|
||||
|
||||
#include <platform_opts.h>
|
||||
#include "rtl8195a.h"
|
||||
#include "FreeRTOS.h"
|
||||
#include "rtl8195a/rtl_libc.h"
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
#include "objects.h"
|
||||
#include "PinNames.h"
|
||||
#include "hal_adc.h"
|
||||
#include "analogin_api.h"
|
||||
#include "strproc.h"
|
||||
//------------------------------------------------------------------------------
|
||||
analogin_t adc;
|
||||
|
||||
LOCAL void fATADI(int argc, char *argv[]) {
|
||||
|
||||
int count = 8;
|
||||
int channel = 2;
|
||||
union {
|
||||
unsigned int ui[2];
|
||||
unsigned short us[4];
|
||||
}x;
|
||||
uint16_t adcdat;
|
||||
memset(&adc, 0, sizeof(adc));
|
||||
|
||||
|
||||
// ConfigDebugErr |= (_DBG_ADC_|_DBG_GDMA_);
|
||||
// ConfigDebugInfo |= (_DBG_ADC_|_DBG_GDMA_);
|
||||
|
||||
if (argc > 1) {
|
||||
channel = atoi(argv[1]);
|
||||
channel &= 0x03;
|
||||
if(!channel) channel = 2;
|
||||
}
|
||||
|
||||
if (argc > 2) {
|
||||
count = atoi(argv[2]);
|
||||
}
|
||||
|
||||
analogin_init(&adc, (channel+1) | (PORT_V << 4));
|
||||
|
||||
PSAL_ADC_HND pSalADCHND = &((&(adc.SalADCMngtAdpt))->pSalHndPriv->SalADCHndPriv);
|
||||
|
||||
uint32_t sum = 0;
|
||||
for (uint32_t i = 1; i <= count; i++) {
|
||||
RtkADCReceiveBuf(pSalADCHND, &x.ui);
|
||||
adcdat = x.us[channel];
|
||||
if((i % 8) == 0 || (i == count)) {
|
||||
printf("0x%04x\n", adcdat);
|
||||
} else {
|
||||
printf("0x%04x, ", adcdat);
|
||||
}
|
||||
sum += adcdat;
|
||||
}
|
||||
analogin_deinit(&adc);
|
||||
printf("ADC%d = 0x%04x\n", channel, sum / count);
|
||||
// sys_adc_calibration(0, &channel, &count);
|
||||
}
|
||||
|
||||
LOCAL void fATADD(int argc, char *argv[]) {
|
||||
|
||||
int count = 64;
|
||||
int channel = 2;
|
||||
uint16_t adcdat;
|
||||
memset(&adc, 0, sizeof(adc));
|
||||
|
||||
|
||||
// ConfigDebugErr |= (_DBG_ADC_|_DBG_GDMA_);
|
||||
// ConfigDebugInfo |= (_DBG_ADC_|_DBG_GDMA_);
|
||||
|
||||
if (argc > 1) {
|
||||
channel = atoi(argv[1]);
|
||||
channel &= 0x03;
|
||||
if(!channel) channel = 1;
|
||||
}
|
||||
|
||||
if (argc > 2) {
|
||||
count = atoi(argv[2]);
|
||||
if (count <= 2) {
|
||||
count = 64;
|
||||
}
|
||||
};
|
||||
|
||||
analogin_init(&adc, (channel+1) | (PORT_V << 4));
|
||||
SAL_ADC_TRANSFER_BUF trbuf;
|
||||
trbuf.pDataBuf = zalloc(count*4);
|
||||
if(trbuf.pDataBuf) {
|
||||
trbuf.DataLen = count/2; // x32 bit ?
|
||||
trbuf.RSVD = 0;
|
||||
adc.SalADCHndPriv.SalADCHndPriv.pRXBuf = &trbuf;
|
||||
adc.SalADCHndPriv.SalADCHndPriv.OpType = ADC_DMA_TYPE;
|
||||
|
||||
adc.HalADCInitData.ADCEndian = ADC_DATA_ENDIAN_LITTLE; //ADC endian selection,
|
||||
//but actually it's for 32-bit ADC data swap control
|
||||
//1'b0: no swap,
|
||||
//1'b1: swap the upper 16-bit and the lower 16-bit
|
||||
// adc.HalADCInitData.ADCCompOnly = ADC_FEATURE_DISABLED; //ADC compare mode only enable (without FIFO enable)
|
||||
// adc.HalADCInitData.ADCEnManul = ADC_FEATURE_ENABLED; // ADC_FEATURE_DISABLED; //ADC enable manually
|
||||
// adc.HalADCInitData.ADCIdx = channel+1; //ADC index used (1..3 ?)
|
||||
// adc.HalADCInitData.ADCBurstSz = 8; //ADC DMA operation threshold
|
||||
// adc.HalADCInitData.ADCOneShotTD = 8; //ADC one shot mode threshold
|
||||
// adc.HalADCInitData.ADCDataRate = 0; // 0xff; // ADC down sample data rate ??
|
||||
adc.HalADCInitData.ADCAudioEn = ADC_FEATURE_ENABLED; //ADC audio mode enable // ADC_FEATURE_DISABLED
|
||||
// adc.HalADCInitData.ADCOneShotEn = ADC_FEATURE_DISABLED; //ADC one shot mode threshold
|
||||
adc.HalADCInitData.ADCInInput = ADC_FEATURE_ENABLED; //ADC Input is internal?
|
||||
// adc.HalADCInitData.ADCEn = ADC_DISABLE; //ADC_ENABLE;
|
||||
|
||||
HalADCInit8195a(&adc.HalADCInitData);
|
||||
/* Read Content */
|
||||
HAL_ADC_READ32(REG_ADC_FIFO_READ);
|
||||
HAL_ADC_READ32(REG_ADC_INTR_STS);
|
||||
RtkADCReceive(&adc.SalADCHndPriv.SalADCHndPriv);
|
||||
while(adc.SalADCHndPriv.SalADCHndPriv.DevSts != ADC_STS_IDLE);
|
||||
uint16 * ptr = (uint16 *) trbuf.pDataBuf;
|
||||
// RtkADCDMAInit(&adc.SalADCHndPriv.SalADCHndPriv);
|
||||
for (uint32_t i = 1; i <= count; i++) {
|
||||
if((i % 16) == 0 || (i == count)) {
|
||||
printf("%04x\n", *ptr);
|
||||
} else {
|
||||
printf("%04x ", *ptr);
|
||||
}
|
||||
ptr++;
|
||||
}
|
||||
uint32_t sum = 0;
|
||||
ptr = (uint16 *) trbuf.pDataBuf;
|
||||
for (uint32_t i = 1; i <= count; i++) {
|
||||
printf("%d\n", *ptr);
|
||||
sum += *ptr;
|
||||
ptr++;
|
||||
if((i%512)==0) vTaskDelay(10);
|
||||
}
|
||||
/*
|
||||
printf("OpType:\t\t%p\n", adc.SalADCHndPriv.SalADCHndPriv.OpType);
|
||||
printf("pRXBuf:\t\t%p\n", adc.SalADCHndPriv.SalADCHndPriv.pRXBuf);
|
||||
printf("pDataBuf:\t%p\n", adc.SalADCHndPriv.SalADCHndPriv.pRXBuf->pDataBuf);
|
||||
printf("DataLen:\t%p\n", adc.SalADCHndPriv.SalADCHndPriv.pRXBuf->DataLen);
|
||||
printf("ADCDataRate:\t%p\n", adc.HalADCInitData.ADCDataRate);
|
||||
printf("ADCData:\t%p\n", adc.HalADCInitData.ADCData);
|
||||
printf("ADCIdx:\t\t%p\n", adc.HalADCInitData.ADCIdx);
|
||||
printf("ADCPWCtrl:\t%p\n", adc.HalADCInitData.ADCPWCtrl);
|
||||
printf("ADCAnaParAd3:\t%p\n", adc.HalADCInitData.ADCAnaParAd3);
|
||||
printf("ADC%d = 0x%04x\n", channel, analogin_read_u16(&adc));
|
||||
printf("ADC%d = 0x%04x\n", channel, analogin_read_u16(&adc));
|
||||
*/
|
||||
analogin_deinit(&adc);
|
||||
free(trbuf.pDataBuf);
|
||||
printf("ADC%d = 0x%04x\n", channel, sum / count);
|
||||
|
||||
}
|
||||
else {
|
||||
error_printf("%s: malloc failed!\n", __func__);
|
||||
};
|
||||
|
||||
// sys_adc_calibration(0, &channel, &count);
|
||||
}
|
||||
|
||||
LOCAL void fATADC(int argc, char *argv[]) {
|
||||
|
||||
int count = 8;
|
||||
int channel = 2;
|
||||
uint16_t adcdat;
|
||||
memset(&adc, 0, sizeof(adc));
|
||||
|
||||
|
||||
// ConfigDebugErr |= (_DBG_ADC_|_DBG_GDMA_);
|
||||
// ConfigDebugInfo |= (_DBG_ADC_|_DBG_GDMA_);
|
||||
|
||||
if (argc > 1) {
|
||||
channel = atoi(argv[1]);
|
||||
channel &= 0x03;
|
||||
if(!channel) channel = 1;
|
||||
}
|
||||
|
||||
if (argc > 2) {
|
||||
count = atoi(argv[2]);
|
||||
}
|
||||
|
||||
analogin_init(&adc, (channel+1) | (PORT_V << 4));
|
||||
|
||||
uint32_t sum = 0;
|
||||
for (uint32_t i = 1; i <= count; i++) {
|
||||
adcdat = analogin_read_u16(&adc);
|
||||
if((i % 8) == 0 || (i == count)) {
|
||||
printf("0x%04x\n", adcdat);
|
||||
} else {
|
||||
printf("0x%04x, ", adcdat);
|
||||
}
|
||||
sum += adcdat;
|
||||
}
|
||||
analogin_deinit(&adc);
|
||||
printf("ADC%d = 0x%04x\n", channel, sum / count);
|
||||
// sys_adc_calibration(0, &channel, &count);
|
||||
}
|
||||
|
||||
LOCAL void fATSA(int argc, char *argv[]) {
|
||||
// u32 tConfigDebugInfo = ConfigDebugInfo;
|
||||
int channel;
|
||||
char *ptmp;
|
||||
u16 offset, gain, adcdat;
|
||||
memset(&adc, 0, sizeof(adc));
|
||||
|
||||
if (argc < 2) {
|
||||
printf("Usage: ATSA=CHANNEL(0~2)\n");
|
||||
printf("Usage: ATSA=k_get\n");
|
||||
printf("Usage: ATSA=k_set[offet(hex),gain(hex)]\n");
|
||||
return;
|
||||
}
|
||||
|
||||
if (strcmp(argv[1], "k_get") == 0) {
|
||||
sys_adc_calibration(0, &offset, &gain);
|
||||
// printf("[ATSA] offset = 0x%04X, gain = 0x%04X", offset, gain);
|
||||
} else if (strcmp(argv[1], "k_set") == 0) {
|
||||
if (argc != 4) {
|
||||
printf("Usage: ATSA=k_set[offet(hex),gain(hex)]\n");
|
||||
return;
|
||||
}
|
||||
offset = strtoul(argv[2], &ptmp, 16);
|
||||
gain = strtoul(argv[3], &ptmp, 16);
|
||||
sys_adc_calibration(1, &offset, &gain);
|
||||
// printf("[ATSA] offset = 0x%04X, gain = 0x%04X", offset, gain);
|
||||
} else {
|
||||
channel = atoi(argv[1]);
|
||||
if (channel < 0 || channel > 2) {
|
||||
printf("Usage: ATSA=CHANNEL(0~2)\n");
|
||||
return;
|
||||
}
|
||||
// Remove debug info massage
|
||||
// ConfigDebugInfo = 0;
|
||||
if (channel == 0)
|
||||
analogin_init(&adc, AD_1);
|
||||
else if (channel == 1)
|
||||
analogin_init(&adc, AD_2);
|
||||
else
|
||||
analogin_init(&adc, AD_3);
|
||||
// analogin_read_u16(&adc);
|
||||
adcdat = analogin_read_u16(&adc) >> 4;
|
||||
analogin_deinit(&adc);
|
||||
// Recover debug info massage
|
||||
// ConfigDebugInfo = tConfigDebugInfo;
|
||||
|
||||
printf("A%d = 0x%04X\n", channel, adcdat);
|
||||
}
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
MON_RAM_TAB_SECTION COMMAND_TABLE console_commands_adc[] = {
|
||||
{ "ATADC", 0, fATADC, ": ADC Test" },
|
||||
{ "ATADD", 0, fATADD, ": ADC DMA Test" },
|
||||
{ "ATADI", 0, fATADI, ": ADC Irq Test" },
|
||||
{ "ATSA" , 0, fATSA , ": ADC at" }
|
||||
};
|
||||
359
project/src/console/atcmd_user.c
Normal file
359
project/src/console/atcmd_user.c
Normal file
|
|
@ -0,0 +1,359 @@
|
|||
#include <platform_opts.h>
|
||||
|
||||
#ifdef CONFIG_AT_USR
|
||||
|
||||
#include "FreeRTOS.h"
|
||||
#include "task.h"
|
||||
#include "semphr.h"
|
||||
#include "at_cmd/log_service.h"
|
||||
#include "at_cmd/atcmd_wifi.h"
|
||||
#include <lwip_netconf.h>
|
||||
#include "tcpip.h"
|
||||
#include <dhcp/dhcps.h>
|
||||
#include <wifi/wifi_conf.h>
|
||||
#include <wifi/wifi_util.h>
|
||||
#include "tcm_heap.h"
|
||||
#include "rtl8195a/rtl_libc.h"
|
||||
|
||||
#include "sleep_ex_api.h"
|
||||
|
||||
#include "lwip/tcp_impl.h"
|
||||
|
||||
extern char str_rom_57ch3Dch0A[]; // "=========================================================\n" 57
|
||||
|
||||
#define printf rtl_printf // DiagPrintf
|
||||
|
||||
/* RAM/TCM/Heaps info */
|
||||
extern void ShowMemInfo(void);
|
||||
/*
|
||||
void ShowMemInfo(void)
|
||||
{
|
||||
printf("\nCLK CPU\t\t%d Hz\nRAM heap\t%d bytes\nTCM heap\t%d bytes\n",
|
||||
HalGetCpuClk(), xPortGetFreeHeapSize(), tcm_heap_freeSpace());
|
||||
}
|
||||
*/
|
||||
//------------------------------------------------------------------------------
|
||||
// Mem, Tasks info
|
||||
//------------------------------------------------------------------------------
|
||||
LOCAL void fATST(int argc, char *argv[]) {
|
||||
ShowMemInfo();
|
||||
#if 0 //CONFIG_DEBUG_LOG > 1
|
||||
dump_mem_block_list();
|
||||
tcm_heap_dump();
|
||||
#endif;
|
||||
printf("\n");
|
||||
#if (configGENERATE_RUN_TIME_STATS == 1)
|
||||
char *cBuffer = pvPortMalloc(512);
|
||||
if(cBuffer != NULL) {
|
||||
vTaskGetRunTimeStats((char *)cBuffer);
|
||||
printf("%s", cBuffer);
|
||||
}
|
||||
vPortFree(cBuffer);
|
||||
#endif
|
||||
#if defined(configUSE_TRACE_FACILITY) && (configUSE_TRACE_FACILITY == 1) && (configUSE_STATS_FORMATTING_FUNCTIONS == 1)
|
||||
{
|
||||
char * pcWriteBuffer = malloc(1024);
|
||||
if(pcWriteBuffer) {
|
||||
vTaskList((char*)pcWriteBuffer);
|
||||
printf("\nTask List:\n");
|
||||
printf(&str_rom_57ch3Dch0A[7]); // "==========================================\n"
|
||||
printf("Name\t Status Priority HighWaterMark TaskNumber\n%s\n", pcWriteBuffer);
|
||||
free(pcWriteBuffer);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
/*-------------------------------------------------------------------------------------
|
||||
Копирует данные из области align(4) (flash, registers, ...) в область align(1) (ram)
|
||||
--------------------------------------------------------------------------------------*/
|
||||
extern void copy_align4_to_align1(unsigned char * pd, void * ps, unsigned int len);
|
||||
/*
|
||||
static void copy_align4_to_align1(unsigned char * pd, void * ps, unsigned int len)
|
||||
{
|
||||
union {
|
||||
unsigned char uc[4];
|
||||
unsigned int ud;
|
||||
}tmp;
|
||||
unsigned int *p = (unsigned int *)((unsigned int)ps & (~3));
|
||||
unsigned int xlen = (unsigned int)ps & 3;
|
||||
// unsigned int size = len;
|
||||
|
||||
if(xlen) {
|
||||
tmp.ud = *p++;
|
||||
while (len) {
|
||||
len--;
|
||||
*pd++ = tmp.uc[xlen++];
|
||||
if(xlen & 4) break;
|
||||
}
|
||||
}
|
||||
xlen = len >> 2;
|
||||
while(xlen) {
|
||||
tmp.ud = *p++;
|
||||
*pd++ = tmp.uc[0];
|
||||
*pd++ = tmp.uc[1];
|
||||
*pd++ = tmp.uc[2];
|
||||
*pd++ = tmp.uc[3];
|
||||
xlen--;
|
||||
}
|
||||
if(len & 3) {
|
||||
tmp.ud = *p;
|
||||
pd[0] = tmp.uc[0];
|
||||
if(len & 2) {
|
||||
pd[1] = tmp.uc[1];
|
||||
if(len & 1) {
|
||||
pd[2] = tmp.uc[2];
|
||||
}
|
||||
}
|
||||
}
|
||||
// return size;
|
||||
}
|
||||
*/
|
||||
int print_hex_dump(uint8_t *buf, int len, unsigned char k) {
|
||||
uint32_t ss[2];
|
||||
ss[0] = 0x78323025; // "%02x"
|
||||
ss[1] = k; // ","...'\0'
|
||||
uint8_t * ptr = buf;
|
||||
int result = 0;
|
||||
while (len--) {
|
||||
if (len == 0)
|
||||
ss[1] = 0;
|
||||
result += printf((uint8_t *) &ss, *ptr++);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
extern char str_rom_hex_addr[]; // in *.ld "[Addr] .0 .1 .2 .3 .4 .5 .6 .7 .8 .9 .A .B .C .D .E .F\n"
|
||||
void dump_bytes(uint32 addr, int size)
|
||||
{
|
||||
uint8 buf[17];
|
||||
u32 symbs_line = sizeof(buf)-1;
|
||||
printf(str_rom_hex_addr);
|
||||
while (size) {
|
||||
if (symbs_line > size) symbs_line = size;
|
||||
printf("%08X ", addr);
|
||||
copy_align4_to_align1(buf, addr, symbs_line);
|
||||
print_hex_dump(buf, symbs_line, ' ');
|
||||
int i;
|
||||
for(i = 0 ; i < symbs_line ; i++) {
|
||||
if(buf[i] < 0x20 || buf[i] > 0x7E) {
|
||||
buf[i] = '.';
|
||||
}
|
||||
}
|
||||
buf[symbs_line] = 0;
|
||||
i = (sizeof(buf)-1) - symbs_line;
|
||||
while(i--) printf(" ");
|
||||
printf(" %s\r\n", buf);
|
||||
addr += symbs_line;
|
||||
size -= symbs_line;
|
||||
}
|
||||
}
|
||||
//------------------------------------------------------------------------------
|
||||
// Dump byte register
|
||||
//------------------------------------------------------------------------------
|
||||
LOCAL void fATSB(int argc, char *argv[])
|
||||
{
|
||||
int size = 16;
|
||||
uint32 addr = Strtoul(argv[1],0,16);
|
||||
if (argc > 2) {
|
||||
size = Strtoul(argv[2],0,10);
|
||||
if (size <= 0 || size > 16384)
|
||||
size = 16;
|
||||
}
|
||||
if(addr + size > SPI_FLASH_BASE) {
|
||||
flash_turnon();
|
||||
dump_bytes(addr, size);
|
||||
SpicDisableRtl8195A();
|
||||
}
|
||||
else {
|
||||
dump_bytes(addr, size);
|
||||
}
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Dump dword register
|
||||
//------------------------------------------------------------------------------
|
||||
LOCAL void fATSD(int argc, char *argv[])
|
||||
{
|
||||
/*
|
||||
if (argc > 2) {
|
||||
int size = Strtoul(argv[2],0,10);
|
||||
if (size <= 0 || size > 16384)
|
||||
argv[2] = "16";
|
||||
}
|
||||
*/
|
||||
CmdDumpWord(argc-1, (unsigned char**)(argv+1));
|
||||
}
|
||||
//------------------------------------------------------------------------------
|
||||
// Write dword register
|
||||
//------------------------------------------------------------------------------
|
||||
LOCAL void fATSW(int argc, char *argv[])
|
||||
{
|
||||
CmdWriteWord(argc-1, (unsigned char**)(argv+1));
|
||||
}
|
||||
|
||||
/* Get one byte from the 4-byte address */
|
||||
#define ip4_addr1(ipaddr) (((u8_t*)(ipaddr))[0])
|
||||
#define ip4_addr2(ipaddr) (((u8_t*)(ipaddr))[1])
|
||||
#define ip4_addr3(ipaddr) (((u8_t*)(ipaddr))[2])
|
||||
#define ip4_addr4(ipaddr) (((u8_t*)(ipaddr))[3])
|
||||
/* These are cast to u16_t, with the intent that they are often arguments
|
||||
* to printf using the U16_F format from cc.h. */
|
||||
#define ip4_addr1_16(ipaddr) ((u16_t)ip4_addr1(ipaddr))
|
||||
#define ip4_addr2_16(ipaddr) ((u16_t)ip4_addr2(ipaddr))
|
||||
#define ip4_addr3_16(ipaddr) ((u16_t)ip4_addr3(ipaddr))
|
||||
#define ip4_addr4_16(ipaddr) ((u16_t)ip4_addr4(ipaddr))
|
||||
|
||||
#define IP2STR(ipaddr) ip4_addr1_16(ipaddr), \
|
||||
ip4_addr2_16(ipaddr), \
|
||||
ip4_addr3_16(ipaddr), \
|
||||
ip4_addr4_16(ipaddr)
|
||||
|
||||
#define IPSTR "%d.%d.%d.%d"
|
||||
|
||||
extern const char * const tcp_state_str[];
|
||||
/*
|
||||
static const char * const tcp_state_str[] = {
|
||||
"CLOSED",
|
||||
"LISTEN",
|
||||
"SYN_SENT",
|
||||
"SYN_RCVD",
|
||||
"ESTABLISHED",
|
||||
"FIN_WAIT_1",
|
||||
"FIN_WAIT_2",
|
||||
"CLOSE_WAIT",
|
||||
"CLOSING",
|
||||
"LAST_ACK",
|
||||
"TIME_WAIT"
|
||||
};
|
||||
*/
|
||||
/******************************************************************************
|
||||
* FunctionName : debug
|
||||
* Parameters :
|
||||
* Returns :
|
||||
*******************************************************************************/
|
||||
void print_udp_pcb(void)
|
||||
{
|
||||
struct udp_pcb *pcb;
|
||||
bool prt_none = true;
|
||||
rtl_printf("UDP pcbs:\n");
|
||||
for(pcb = udp_pcbs; pcb != NULL; pcb = pcb->next) {
|
||||
rtl_printf("flg:%02x\t" IPSTR ":%d\t" IPSTR ":%d\trecv:%p\n", pcb->flags, IP2STR(&pcb->local_ip), pcb->local_port, IP2STR(&pcb->remote_ip), pcb->remote_port, pcb->recv );
|
||||
prt_none = false;
|
||||
};
|
||||
if(prt_none) rtl_printf("none\n");
|
||||
}
|
||||
/******************************************************************************
|
||||
* FunctionName : debug
|
||||
* Parameters :
|
||||
* Returns :
|
||||
*******************************************************************************/
|
||||
void print_tcp_pcb(void)
|
||||
{
|
||||
struct tcp_pcb *pcb;
|
||||
rtl_printf("Active PCB states:\n");
|
||||
bool prt_none = true;
|
||||
for(pcb = tcp_active_pcbs; pcb != NULL; pcb = pcb->next) {
|
||||
rtl_printf("Port %d|%d\tflg:%02x\ttmr:%p\t%s\n", pcb->local_port, pcb->remote_port, pcb->flags, pcb->tmr, tcp_state_str[pcb->state]);
|
||||
prt_none = false;
|
||||
};
|
||||
if(prt_none) rtl_printf("none\n");
|
||||
rtl_printf("Listen PCB states:\n");
|
||||
prt_none = true;
|
||||
for(pcb = (struct tcp_pcb *)tcp_listen_pcbs.pcbs; pcb != NULL; pcb = pcb->next) {
|
||||
rtl_printf("Port %d|%d\tflg:%02x\ttmr:%p\t%s\n", pcb->local_port, pcb->remote_port, pcb->flags, pcb->tmr, tcp_state_str[pcb->state]);
|
||||
prt_none = false;
|
||||
};
|
||||
if(prt_none) rtl_printf("none\n");
|
||||
rtl_printf("TIME-WAIT PCB states:\n");
|
||||
prt_none = true;
|
||||
for(pcb = tcp_tw_pcbs; pcb != NULL; pcb = pcb->next) {
|
||||
rtl_printf("Port %d|%d\tflg:%02x\ttmr:%p \t%s\n", pcb->local_port, pcb->remote_port, pcb->flags, pcb->tmr, tcp_state_str[pcb->state]);
|
||||
prt_none = false;
|
||||
};
|
||||
if(prt_none) rtl_printf("none\n");
|
||||
}
|
||||
/******************************************************************************
|
||||
* FunctionName : debug
|
||||
* Parameters :
|
||||
* Returns :
|
||||
*******************************************************************************/
|
||||
LOCAL void fATLW(int argc, char *argv[]) // Info Lwip
|
||||
{
|
||||
print_udp_pcb();
|
||||
print_tcp_pcb();
|
||||
}
|
||||
//------------------------------------------------------------------------------
|
||||
// Deep sleep
|
||||
//------------------------------------------------------------------------------
|
||||
LOCAL void fATDS(int argc, char *argv[])
|
||||
{
|
||||
uint32 sleep_ms = 10000;
|
||||
if(argc > 1) sleep_ms = atoi(argv[1]);
|
||||
#if 0
|
||||
if(argc > 2) {
|
||||
printf("%u ms waiting low level on PB_1 before launching Deep-Sleep...\n", sleep_ms);
|
||||
// turn off log uart
|
||||
HalDeinitLogUart(); // sys_log_uart_off();
|
||||
|
||||
// initialize wakeup pin
|
||||
gpio_t gpio_wake;
|
||||
gpio_init(&gpio_wake, PB_1);
|
||||
gpio_dir(&gpio_wake, PIN_INPUT);
|
||||
gpio_mode(&gpio_wake, PullDown);
|
||||
TickType_t sttime = xTaskGetTickCount();
|
||||
|
||||
do {
|
||||
if(gpio_read(&gpio_wake) == 0) {
|
||||
// Enter deep sleep... Wait give rising edge at PB_1 to wakeup system.
|
||||
deepsleep_ex(DSLEEP_WAKEUP_BY_GPIO, 0);
|
||||
};
|
||||
vTaskDelay(1);
|
||||
} while(xTaskGetTickCount() - sttime < sleep_ms);
|
||||
HalInitLogUart(); // sys_log_uart_on();
|
||||
printf("No set pin low in deep sleep!\n");
|
||||
}
|
||||
else {
|
||||
printf("Deep-Sleep %u ms\n", sleep_ms);
|
||||
HalLogUartWaitTxFifoEmpty();
|
||||
// Enter deep sleep... Wait timer ms
|
||||
deepsleep_ex(DSLEEP_WAKEUP_BY_TIMER, sleep_ms);
|
||||
}
|
||||
#else
|
||||
HalLogUartWaitTxFifoEmpty();
|
||||
deepsleep_ex(DSLEEP_WAKEUP_BY_TIMER, sleep_ms);
|
||||
#endif
|
||||
}
|
||||
/*------------------------------------------------------------------------------
|
||||
* power saving mode
|
||||
*----------------------------------------------------------------------------*/
|
||||
LOCAL void fATSP(int argc, char *argv[])
|
||||
{
|
||||
if(argc > 2) {
|
||||
switch (argv[1][0]) {
|
||||
case 'a': // acquire
|
||||
{
|
||||
acquire_wakelock(atoi(argv[2]));
|
||||
break;
|
||||
}
|
||||
case 'r': // release
|
||||
{
|
||||
release_wakelock(atoi(argv[2]));
|
||||
break;
|
||||
}
|
||||
};
|
||||
};
|
||||
printf("WakeLock Status %d\n", get_wakelock_status());
|
||||
}
|
||||
//------------------------------------------------------------------------------
|
||||
//------------------------------------------------------------------------------
|
||||
MON_RAM_TAB_SECTION COMMAND_TABLE console_commands_at[] = {
|
||||
{"ATST", 0, fATST, ": Memory info"},
|
||||
{"ATLW", 0, fATLW, ": LwIP Info"},
|
||||
{"ATSB", 1, fATSB, "=<ADDRES(hex)>[,COUNT(dec)]: Dump byte register"},
|
||||
{"ATSD", 1, fATSD, "=<ADDRES(hex)>[,COUNT(dec)]: Dump dword register"},
|
||||
{"ATSW", 2, fATSW, "=<ADDRES(hex)>,<DATA(hex)>: Set register"},
|
||||
{"ATDS", 0, fATDS, "=[TIME(ms)]: Deep sleep"},
|
||||
{"ATSP", 0, fATSP, "=<a,r>,<wakelock_status:1|2|4|8>: Power"}
|
||||
};
|
||||
|
||||
#endif //#ifdef CONFIG_AT_USR
|
||||
38
project/src/console/flash_tst.c
Normal file
38
project/src/console/flash_tst.c
Normal file
|
|
@ -0,0 +1,38 @@
|
|||
/*
|
||||
* flash_tst.c
|
||||
*
|
||||
* Created on: 10/04/2017
|
||||
* Author: pvvx
|
||||
*/
|
||||
|
||||
#include <platform_opts.h>
|
||||
#include "rtl8195a.h"
|
||||
#include "flash_api.h"
|
||||
#include "rtl8195a/rtl_libc.h"
|
||||
|
||||
extern void dump_bytes(uint32 addr, int size);
|
||||
|
||||
LOCAL void FlashDump(int argc, char *argv[]) {
|
||||
if (argc > 1) {
|
||||
int addr;
|
||||
sscanf(argv[1], "%x", &addr);
|
||||
int size = 16;
|
||||
if (argc > 2) {
|
||||
size = atoi(argv[2]);
|
||||
if (size <= 0 || size > 16384) {
|
||||
size = 16;
|
||||
};
|
||||
};
|
||||
flash_turnon();
|
||||
dump_bytes(addr + SPI_FLASH_BASE, size);
|
||||
SpicDisableRtl8195A();
|
||||
}
|
||||
}
|
||||
|
||||
MON_RAM_TAB_SECTION COMMAND_TABLE console_flash_tst[] = {
|
||||
{"FLASHDB", 1, FlashDump, ": <faddr(HEX)>[,size]: Flash Dump"}
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
99
project/src/console/gpio_irq_test.c
Normal file
99
project/src/console/gpio_irq_test.c
Normal file
|
|
@ -0,0 +1,99 @@
|
|||
/*
|
||||
* test.c
|
||||
*
|
||||
* Created on: 12 марта 2017 г.
|
||||
* Author: PVV
|
||||
*/
|
||||
|
||||
#include <platform_opts.h>
|
||||
#include "device.h"
|
||||
#include "gpio_api.h" // mbed
|
||||
#include "gpio_irq_api.h" // mbed
|
||||
#include "gpio_irq_ex_api.h" // mbed
|
||||
#include "timer_api.h"
|
||||
#include "diag.h"
|
||||
#include "main.h"
|
||||
|
||||
#include "hal_diag.h"
|
||||
#include "rtl8195a/rtl_libc.h"
|
||||
|
||||
#define GPIO_LED_PIN PA_4
|
||||
#define GPIO_IRQ_PIN PC_4
|
||||
|
||||
gpio_irq_t gpio_btn;
|
||||
gpio_t gpio_led;
|
||||
gtimer_t my_timer;
|
||||
|
||||
uint32_t lo_time_us, hi_time_us;
|
||||
uint32_t lo_time_cnt, hi_time_cnt;
|
||||
uint32_t old_tsf;
|
||||
uint32_t lo, hi, fr;
|
||||
|
||||
uint32_t io_irq_count;
|
||||
|
||||
LOCAL void gpio_demo_irq_handler(uint32_t id, gpio_irq_event event) {
|
||||
|
||||
// gpio_irq_disable(&gpio_btn);
|
||||
io_irq_count++;
|
||||
uint32_t new_tsf = get_tsf();
|
||||
uint32_t delta_us = (uint32_t) new_tsf - (uint32_t) old_tsf;
|
||||
if (event & 1) {
|
||||
lo_time_us += delta_us;
|
||||
lo_time_cnt++;
|
||||
gpio_irq_set(&gpio_btn, IRQ_LOW, 1);
|
||||
} else {
|
||||
hi_time_us += delta_us;
|
||||
hi_time_cnt++;
|
||||
gpio_irq_set(&gpio_btn, IRQ_HIGH, 1);
|
||||
}
|
||||
old_tsf = new_tsf;
|
||||
// gpio_irq_enable(&gpio_btn);
|
||||
}
|
||||
|
||||
LOCAL void timer1_timeout_handler(uint32_t id) {
|
||||
|
||||
if (lo_time_cnt && hi_time_cnt) {
|
||||
lo = lo_time_us / lo_time_cnt;
|
||||
hi = hi_time_us / hi_time_cnt;
|
||||
fr = hi + lo;
|
||||
lo_time_cnt = 0;
|
||||
lo_time_us = 0;
|
||||
hi_time_cnt = 0;
|
||||
hi_time_us = 0;
|
||||
printf("Period: %lu us, Lo: %lu us, Hi: %lu us\n", fr, lo, hi);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Main program.
|
||||
* @param None
|
||||
* @retval None
|
||||
*/
|
||||
LOCAL void fATTT(int argc, char *argv[]) {
|
||||
|
||||
lo_time_cnt = 0;
|
||||
lo_time_us = 0;
|
||||
hi_time_cnt = 0;
|
||||
hi_time_us = 0;
|
||||
|
||||
// Init LED control pin
|
||||
gpio_init(&gpio_led, GPIO_LED_PIN);
|
||||
gpio_dir(&gpio_led, PIN_OUTPUT); // Direction: Output
|
||||
gpio_mode(&gpio_led, PullNone); // No pull
|
||||
gpio_write(&gpio_led, 0);
|
||||
|
||||
// Initial Push Button pin as interrupt source
|
||||
gpio_irq_init(&gpio_btn, GPIO_IRQ_PIN, gpio_demo_irq_handler,
|
||||
(uint32_t) (&gpio_led));
|
||||
gpio_irq_set(&gpio_btn, IRQ_FALL, 1); // Falling Edge Trigger
|
||||
gpio_irq_enable(&gpio_btn);
|
||||
|
||||
// Initial a periodical timer
|
||||
gtimer_init(&my_timer, TIMER1);
|
||||
gtimer_start_periodical(&my_timer, 1000000, (void*) timer1_timeout_handler,
|
||||
(uint32_t) &gpio_led);
|
||||
}
|
||||
|
||||
MON_RAM_TAB_SECTION COMMAND_TABLE console_commands_test[] = { { "ATTT", 0,
|
||||
fATTT, ": Test" } };
|
||||
|
||||
39
project/src/console/power_tst.c
Normal file
39
project/src/console/power_tst.c
Normal file
|
|
@ -0,0 +1,39 @@
|
|||
/*
|
||||
* power_tst.c
|
||||
*
|
||||
* Created on: 04 апр. 2017 г.
|
||||
* Author: PVV
|
||||
*/
|
||||
|
||||
#include "rtl8195a.h"
|
||||
#include "freertos_pmu.h"
|
||||
#include "rtl8195a/rtl_libc.h"
|
||||
/*------------------------------------------------------------------------------
|
||||
* power saving mode
|
||||
*----------------------------------------------------------------------------*/
|
||||
void fATSP(int argc, char *argv[])
|
||||
{
|
||||
if(argc > 2) {
|
||||
switch (argv[1][0]) {
|
||||
case 'a': // acquire
|
||||
{
|
||||
acquire_wakelock(atoi(argv[2]));
|
||||
break;
|
||||
}
|
||||
case 'r': // release
|
||||
{
|
||||
release_wakelock(atoi(argv[2]));
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
printf("WakeLock Status %d\n", get_wakelock_status());
|
||||
}
|
||||
|
||||
|
||||
MON_RAM_TAB_SECTION COMMAND_TABLE console_commands_pwrs[] = {
|
||||
{"ATSP", 0, fATSP, "=<a,r>,<wakelock_status:1|2|4|8>: Power"}
|
||||
|
||||
};
|
||||
|
||||
|
||||
59
project/src/console/pwm_tst.c
Normal file
59
project/src/console/pwm_tst.c
Normal file
|
|
@ -0,0 +1,59 @@
|
|||
/*
|
||||
* pwm_tst.c
|
||||
*
|
||||
* Created on: 19/04/2017.
|
||||
* Author: pvvx
|
||||
*/
|
||||
|
||||
#include <platform_opts.h>
|
||||
#include "rtl8195a.h"
|
||||
#include "FreeRTOS.h"
|
||||
#include "rtl8195a/rtl_libc.h"
|
||||
|
||||
//#include "device.h"
|
||||
#include "pwmout_api.h" // mbed
|
||||
//#include "main.h"
|
||||
#include "web_utils.h"
|
||||
#include "objects.h"
|
||||
#include "pinmap.h"
|
||||
|
||||
extern const PinMap PinMap_PWM[];
|
||||
extern u32 gTimerRecord;
|
||||
|
||||
HAL_PWM_ADAPTER pwm_hal_adp;
|
||||
|
||||
LOCAL void fATPWM(int argc, char *argv[]) {
|
||||
|
||||
uint8_t pin = ahextoul(argv[1]);
|
||||
uint32_t period = ahextoul(argv[2]);
|
||||
uint32_t pulse = ahextoul(argv[3]);
|
||||
|
||||
uint32_t peripheral = pinmap_peripheral(pin, PinMap_PWM);
|
||||
|
||||
if(pwm_hal_adp.enable) {
|
||||
HAL_Pwm_Disable(&pwm_hal_adp);
|
||||
gTimerRecord &= ~(1 << pwm_hal_adp.gtimer_id);
|
||||
rtl_memset((void *)&pwm_hal_adp, 0, sizeof(HAL_PWM_ADAPTER));
|
||||
};
|
||||
if((period) && (unlikely(peripheral != NC))
|
||||
&& (HAL_Pwm_Init(&pwm_hal_adp, RTL_GET_PERI_IDX(peripheral), RTL_GET_PERI_SEL(peripheral)) == HAL_OK)) {
|
||||
HAL_Pwm_SetDuty(&pwm_hal_adp, period, pulse);
|
||||
HAL_Pwm_Enable(&pwm_hal_adp);
|
||||
} else {
|
||||
printf("Error parameters!");
|
||||
};
|
||||
}
|
||||
|
||||
LOCAL void fATWLED(int argc, char *argv[]) {
|
||||
HalPinCtrlRtl8195A(WL_LED, 2, 1);
|
||||
HalPinCtrlRtl8195A(EGTIM, ahextoul(argv[1]), 1);
|
||||
}
|
||||
//------------------------------------------------------------------------------
|
||||
// atpwm=34,1048575,524287
|
||||
// atpwm=34,122,61 (8.187kHz)
|
||||
// atsw 40000368 85001002 (8.187kHz)
|
||||
// atsd 40000360 6
|
||||
MON_RAM_TAB_SECTION COMMAND_TABLE console_commands_adc[] = {
|
||||
{ "ATWLED", 0, fATWLED, ": WLED Test" },
|
||||
{ "ATPWM", 3, fATPWM, "=<pin>,<period>,<pulse>: PWM Test" }
|
||||
};
|
||||
83
project/src/console/spi_tst.c
Normal file
83
project/src/console/spi_tst.c
Normal file
|
|
@ -0,0 +1,83 @@
|
|||
/*
|
||||
* spi_test.c
|
||||
*/
|
||||
#include <platform_opts.h>
|
||||
#include "rtl8195a.h"
|
||||
#include "spi_api.h"
|
||||
#include "spi_ex_api.h"
|
||||
#include "rtl8195a/rtl_libc.h"
|
||||
|
||||
#define SPI0_MOSI PC_2
|
||||
#define SPI0_MISO PC_3
|
||||
#define SPI0_SCLK PC_1
|
||||
#define SPI0_CS PC_0
|
||||
|
||||
spi_t spi_master;
|
||||
|
||||
LOCAL void show_reg_spi(int i) {
|
||||
rtl_printf("Regs SPI:\n");
|
||||
for(int x = 0; x < 64 ; x += 4) {
|
||||
rtl_printf("0x%08x ", HAL_SSI_READ32(i, x));
|
||||
if((x & 0x0F) == 0x0C) rtl_printf("\n");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
LOCAL void fATSSI(int argc, char *argv[])
|
||||
{
|
||||
int len = 128;
|
||||
int count = 32;
|
||||
int clk = 1000000;
|
||||
int ssn = 0;
|
||||
if(argc > 1) {
|
||||
len = atoi(argv[1]);
|
||||
if(len > 32768 || len <= 0) {
|
||||
len = 128;
|
||||
error_printf("%s: len = %u!\n", __func__, len);
|
||||
};
|
||||
};
|
||||
if(argc > 2) {
|
||||
count = atoi(argv[2]);
|
||||
if(count > 10000 || count <= 0) {
|
||||
count = 32;
|
||||
error_printf("%s: count = %u!\n", __func__, count);
|
||||
};
|
||||
};
|
||||
if(argc > 3) {
|
||||
clk = atoi(argv[3]);
|
||||
if(clk <= 0) {
|
||||
clk = 1000000;
|
||||
error_printf("%s: clk = %u!\n", __func__, clk);
|
||||
};
|
||||
};
|
||||
if(argc > 4) {
|
||||
ssn = atoi(argv[4]);
|
||||
if(ssn > 7 || ssn < 0) {
|
||||
ssn = 0;
|
||||
error_printf("%s: ssn = %u!\n", __func__, ssn);
|
||||
};
|
||||
};
|
||||
char* buff = pvPortMalloc(len);
|
||||
if(buff) {
|
||||
spi_init(&spi_master, SPI0_MOSI, SPI0_MISO, SPI0_SCLK, SPI0_CS); // CS заданный тут нигде не используется
|
||||
spi_format(&spi_master, 16, 3, 0);
|
||||
spi_frequency(&spi_master, clk);
|
||||
spi_slave_select(&spi_master, ssn); // выбор CS
|
||||
for(int i = 0; i < len; i++) buff[i] = (char)i;
|
||||
while(count--) {
|
||||
spi_master_write_stream(&spi_master, buff, len);
|
||||
while(spi_busy(&spi_master));
|
||||
rtl_printf("Master write: %d\n", count);
|
||||
};
|
||||
// show_reg_spi(spi_master.spi_adp.Index);
|
||||
spi_free(&spi_master);
|
||||
free(buff);
|
||||
}
|
||||
else {
|
||||
error_printf("%s: error malloc!\n", __func__);
|
||||
};
|
||||
}
|
||||
|
||||
MON_RAM_TAB_SECTION COMMAND_TABLE console_commands_spitst[] = {
|
||||
{"ATSSI", 0, fATSSI, "[len[,count[,clk[,ssn]]]]: Spi test"}
|
||||
};
|
||||
338
project/src/console/wifi_console.c
Normal file
338
project/src/console/wifi_console.c
Normal file
|
|
@ -0,0 +1,338 @@
|
|||
/*
|
||||
* wifi_console.c
|
||||
*
|
||||
* Created on: 03/04/2017
|
||||
* Author: pvvx
|
||||
*/
|
||||
|
||||
#include <autoconf.h>
|
||||
#include "FreeRTOS.h"
|
||||
#include "diag.h"
|
||||
#include "wifi_api.h"
|
||||
#include "wifi_conf.h"
|
||||
#include "rtl8195a/rtl_libc.h"
|
||||
#include "hal_platform.h"
|
||||
|
||||
#include "section_config.h"
|
||||
#include "hal_diag.h"
|
||||
#include "lwip/netif.h"
|
||||
|
||||
|
||||
extern struct netif xnetif[NET_IF_NUM];
|
||||
|
||||
//==========================================================
|
||||
//--- CONSOLE --------------------------
|
||||
|
||||
// ATPN=<SSID>[,password[,encryption[,auto reconnect[,reconnect pause]]]: WIFI Connect to AP
|
||||
LOCAL void fATPN(int argc, char *argv[]){
|
||||
if(argc > 1) {
|
||||
if(argv[1][0] == '?') {
|
||||
show_wifi_st_cfg();
|
||||
}
|
||||
else {
|
||||
strncpy(wifi_st_cfg.ssid, argv[1], NDIS_802_11_LENGTH_SSID);
|
||||
if(argc > 2) {
|
||||
strncpy(wifi_st_cfg.password, argv[2], NDIS_802_11_LENGTH_SSID);
|
||||
int i = strlen(wifi_st_cfg.password);
|
||||
if(i > 7) {
|
||||
wifi_st_cfg.security_type = RTW_SECURITY_WPA2_AES_PSK;
|
||||
}
|
||||
else if(!i) {
|
||||
wifi_st_cfg.security_type = RTW_SECURITY_OPEN;
|
||||
}
|
||||
else {
|
||||
printf("password len < 8!\n");
|
||||
wifi_st_cfg.security_type = RTW_SECURITY_OPEN;
|
||||
}
|
||||
}
|
||||
else {
|
||||
wifi_st_cfg.password[0] = 0;
|
||||
wifi_st_cfg.security_type = RTW_SECURITY_OPEN;
|
||||
}
|
||||
if(argc > 3) {
|
||||
wifi_ap_cfg.security_type = translate_rtw_security(atoi(argv[3]));
|
||||
}
|
||||
if(argc > 4) {
|
||||
wifi_st_cfg.autoreconnect = atoi(argv[3]);
|
||||
}
|
||||
else wifi_st_cfg.autoreconnect = 0;
|
||||
if(argc > 5) {
|
||||
wifi_st_cfg.reconnect_pause = atoi(argv[3]);
|
||||
}
|
||||
else wifi_st_cfg.reconnect_pause = 5;
|
||||
show_wifi_st_cfg();
|
||||
wifi_run(wifi_run_mode | RTW_MODE_STA);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ATPA=<SSID>[,password[,encryption[,channel[,hidden[,max connections]]]]]: Start WIFI AP
|
||||
LOCAL void fATPA(int argc, char *argv[]){
|
||||
if(argc > 1) {
|
||||
if(argv[1][0] == '?') {
|
||||
show_wifi_ap_cfg();
|
||||
}
|
||||
else {
|
||||
strncpy(wifi_ap_cfg.ssid, argv[1], NDIS_802_11_LENGTH_SSID);
|
||||
if(argc > 2) {
|
||||
strncpy(wifi_ap_cfg.password, argv[2], NDIS_802_11_LENGTH_SSID);
|
||||
int i = strlen(wifi_ap_cfg.password);
|
||||
if(i > 7) {
|
||||
wifi_ap_cfg.security_type = RTW_SECURITY_WPA2_AES_PSK;
|
||||
}
|
||||
else if(i == 0) {
|
||||
wifi_ap_cfg.security_type = RTW_SECURITY_OPEN;
|
||||
}
|
||||
else {
|
||||
printf("password len < 8!\n");
|
||||
wifi_ap_cfg.security_type = RTW_SECURITY_OPEN;
|
||||
}
|
||||
}
|
||||
else {
|
||||
wifi_ap_cfg.password[0] = 0;
|
||||
wifi_ap_cfg.security_type = RTW_SECURITY_OPEN;
|
||||
}
|
||||
if(argc > 3) {
|
||||
if(argv[3][0]=='0') wifi_st_cfg.security_type = RTW_SECURITY_OPEN;
|
||||
else wifi_st_cfg.security_type = RTW_SECURITY_WEP_PSK;
|
||||
}
|
||||
if(argc > 4) {
|
||||
wifi_ap_cfg.channel = atoi(argv[4]);
|
||||
}
|
||||
else wifi_ap_cfg.channel = 1;
|
||||
if(argc > 5) {
|
||||
wifi_ap_cfg.ssid_hidden = atoi(argv[5]);
|
||||
}
|
||||
else wifi_ap_cfg.ssid_hidden = 0;
|
||||
|
||||
if(argc > 6) {
|
||||
wifi_ap_cfg.max_sta = atoi(argv[6]);
|
||||
}
|
||||
else wifi_ap_cfg.max_sta = 3;
|
||||
|
||||
show_wifi_ap_cfg();
|
||||
wifi_run(wifi_run_mode | RTW_MODE_AP);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// WIFI Connect, Disconnect
|
||||
LOCAL void fATWR(int argc, char *argv[]){
|
||||
rtw_mode_t mode = RTW_MODE_NONE;
|
||||
if(argc > 1) mode = atoi(argv[1]);
|
||||
wifi_run(mode);
|
||||
}
|
||||
|
||||
// Close connections
|
||||
LOCAL void fATOF(int argc, char *argv[]){
|
||||
connect_close();
|
||||
}
|
||||
|
||||
// Open connections
|
||||
LOCAL void fATON(int argc, char *argv[]){
|
||||
connect_start();
|
||||
}
|
||||
|
||||
LOCAL void fATWI(int argc, char *argv[]) {
|
||||
rtw_wifi_setting_t Setting;
|
||||
if((wifi_run_mode & RTW_MODE_AP)
|
||||
&& wifi_get_setting(wlan_ap_name, &Setting) == 0) {
|
||||
wifi_show_setting(wlan_ap_name, &Setting);
|
||||
// show_wifi_ap_ip();
|
||||
printf("\tIP: " IPSTR "\n", IP2STR(&xnetif[WLAN_AP_NETIF_NUM].ip_addr));
|
||||
}
|
||||
if((wifi_run_mode & RTW_MODE_STA)
|
||||
&& wifi_get_setting(wlan_st_name, &Setting) == 0) {
|
||||
wifi_show_setting(wlan_st_name, &Setting);
|
||||
// show_wifi_st_ip();
|
||||
printf("\tIP: " IPSTR "\n", IP2STR(&xnetif[WLAN_ST_NETIF_NUM].ip_addr));
|
||||
}
|
||||
printf("\nWIFI config:\n");
|
||||
printf(&str_rom_57ch3Dch0A[25]); // "================================\n"
|
||||
show_wifi_cfg();
|
||||
printf("\nWIFI AP config:\n");
|
||||
printf(&str_rom_57ch3Dch0A[25]); // "================================\n"
|
||||
show_wifi_ap_cfg();
|
||||
printf("\nWIFI ST config:\n");
|
||||
printf(&str_rom_57ch3Dch0A[25]); // "================================\n"
|
||||
show_wifi_st_cfg();
|
||||
printf("\n");
|
||||
#if 1
|
||||
if(argc > 2) {
|
||||
uint8_t c = argv[1][0] | 0x20;
|
||||
if(c == 's') {
|
||||
int i = atoi(argv[2]);
|
||||
printf("Save configs(%d)..\n", i);
|
||||
write_wifi_cfg(atoi(argv[2]));
|
||||
}
|
||||
else if(c == 'l') {
|
||||
wifi_cfg.load_flg = atoi(argv[2]);
|
||||
}
|
||||
else if(c == 'm') {
|
||||
wifi_cfg.mode = atoi(argv[2]);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
extern uint8_t rtw_power_percentage_idx;
|
||||
|
||||
LOCAL void fATWT(int argc, char *argv[]) {
|
||||
if(argc > 1) {
|
||||
int txpwr = atoi(argv[1]);
|
||||
debug_printf("set tx power (%d)...\n", txpwr);
|
||||
if(rltk_set_tx_power_percentage(txpwr) != RTW_SUCCESS) {
|
||||
error_printf("Error set tx power (%d)!", wifi_cfg.tx_pwr);
|
||||
}
|
||||
}
|
||||
printf("TX power = %d\n", rtw_power_percentage_idx);
|
||||
}
|
||||
|
||||
//-- Test tsf (64-bits counts, 1 us step) ---
|
||||
|
||||
#include "hal_com_reg.h"
|
||||
|
||||
#define ReadTSF_Lo32() (*((volatile unsigned int *)(WIFI_REG_BASE + REG_TSFTR)))
|
||||
#define ReadTSF_Hi32() (*((volatile unsigned int *)(WIFI_REG_BASE + REG_TSFTR1)))
|
||||
|
||||
LOCAL uint64_t get_tsf(void)
|
||||
{
|
||||
return *((uint64_t *)(WIFI_REG_BASE + REG_TSFTR));
|
||||
}
|
||||
|
||||
LOCAL void fATSF(int argc, char *argv[])
|
||||
{
|
||||
uint64_t tsf = get_tsf();
|
||||
printf("\nTSF: %08x%08x\n", (uint32_t)(tsf>>32), (uint32_t)(tsf));
|
||||
}
|
||||
|
||||
/* -------- WiFi Scan ------------------------------- */
|
||||
unsigned char *tab_txt_rtw_secyrity[] = {
|
||||
"OPEN ",
|
||||
"WEP ",
|
||||
"WPA TKIP",
|
||||
"WPA AES",
|
||||
"WPA2 AES",
|
||||
"WPA2 TKIP",
|
||||
"WPA2 Mixed",
|
||||
"WPA/WPA2 AES",
|
||||
"Unknown"
|
||||
};
|
||||
unsigned int *tab_code_rtw_secyrity[] = {
|
||||
RTW_SECURITY_OPEN,
|
||||
RTW_SECURITY_WEP_PSK,
|
||||
RTW_SECURITY_WPA_TKIP_PSK,
|
||||
RTW_SECURITY_WPA_AES_PSK,
|
||||
RTW_SECURITY_WPA2_AES_PSK,
|
||||
RTW_SECURITY_WPA2_TKIP_PSK,
|
||||
RTW_SECURITY_WPA2_MIXED_PSK,
|
||||
RTW_SECURITY_WPA_WPA2_MIXED,
|
||||
RTW_SECURITY_UNKNOWN
|
||||
};
|
||||
|
||||
volatile uint8_t scan_end;
|
||||
|
||||
/* -------- WiFi Scan ------------------------------- */
|
||||
LOCAL rtw_result_t _scan_result_handler( rtw_scan_handler_result_t* malloced_scan_result )
|
||||
{
|
||||
if (malloced_scan_result->scan_complete != RTW_TRUE) {
|
||||
rtw_scan_result_t* record = &malloced_scan_result->ap_details;
|
||||
record->SSID.val[record->SSID.len] = 0; /* Ensure the SSID is null terminated */
|
||||
if(scan_end == 1) {
|
||||
printf("\nScan networks:\n\n");
|
||||
printf("N\tType\tMAC\t\t\tSignal\tCh\tWPS\tSecyrity\tSSID\n\n");
|
||||
};
|
||||
printf("%d\t", scan_end++);
|
||||
printf("%s\t", (record->bss_type == RTW_BSS_TYPE_ADHOC)? "Adhoc": "Infra");
|
||||
printf(MAC_FMT, MAC_ARG(record->BSSID.octet));
|
||||
printf("\t%d\t", record->signal_strength);
|
||||
printf("%d\t", record->channel);
|
||||
printf("%d\t", record->wps_type);
|
||||
int i = 0;
|
||||
for(; record->security != tab_code_rtw_secyrity[i] && tab_code_rtw_secyrity[i] != RTW_SECURITY_UNKNOWN; i++);
|
||||
printf("%s \t", tab_txt_rtw_secyrity[i]);
|
||||
printf("%s\n", record->SSID.val);
|
||||
} else {
|
||||
scan_end = 0;
|
||||
printf("\n");
|
||||
}
|
||||
return RTW_SUCCESS;
|
||||
}
|
||||
/* -------- WiFi Scan ------------------------------- */
|
||||
#define scan_channels 14
|
||||
LOCAL void fATSN(int argc, char *argv[])
|
||||
{
|
||||
int i;
|
||||
u8 *channel_list = (u8*)pvPortMalloc(scan_channels*2);
|
||||
if(channel_list) {
|
||||
scan_end = 1;
|
||||
u8 * pscan_config = &channel_list[scan_channels];
|
||||
//parse command channel list
|
||||
for(i = 1; i <= scan_channels; i++){
|
||||
*(channel_list + i - 1) = i;
|
||||
*(pscan_config + i - 1) = PSCAN_ENABLE;
|
||||
};
|
||||
if(wifi_set_pscan_chan(channel_list, pscan_config, scan_channels) < 0){
|
||||
printf("ERROR: wifi set partial scan channel fail\n");
|
||||
} else if(wifi_scan_networks(_scan_result_handler, NULL ) != RTW_SUCCESS){
|
||||
printf("ERROR: wifi scan failed\n");
|
||||
} else {
|
||||
i = 300;
|
||||
while(i-- && scan_end) {
|
||||
vTaskDelay(10);
|
||||
};
|
||||
};
|
||||
vPortFree(channel_list);
|
||||
} else {
|
||||
printf("ERROR: Can't malloc memory for channel list\n");
|
||||
};
|
||||
}
|
||||
|
||||
#if defined(CONFIG_ENABLE_WPS_AP) && CONFIG_ENABLE_WPS_AP
|
||||
extern void cmd_ap_wps(int argc, char **argv);
|
||||
extern void cmd_wps(int argc, char **argv);
|
||||
//extern void cmd_wifi_on(int argc, char **argv);
|
||||
#endif
|
||||
#if CONFIG_ENABLE_P2P
|
||||
extern void cmd_wifi_p2p_start(int argc, char **argv);
|
||||
extern void cmd_wifi_p2p_stop(int argc, char **argv);
|
||||
extern void cmd_p2p_listen(int argc, char **argv);
|
||||
extern void cmd_p2p_find(int argc, char **argv);
|
||||
extern void cmd_p2p_peers(int argc, char **argv);
|
||||
extern void cmd_p2p_info(int argc, char **argv);
|
||||
extern void cmd_p2p_disconnect(int argc, char **argv);
|
||||
extern void cmd_p2p_connect(int argc, char **argv);
|
||||
extern void cmd_wifi_p2p_auto_go_start(int argc, char **argv);
|
||||
extern void cmd_p2p_peers(int argc, char **argv);
|
||||
#endif //CONFIG_ENABLE_P2P
|
||||
|
||||
|
||||
MON_RAM_TAB_SECTION COMMAND_TABLE console_cmd_wifi_api[] = {
|
||||
{"ATPN", 1, fATPN, "=<SSID>[,password[,encryption[,auto-reconnect[,reconnect pause]]]: WIFI Connect to AP"},
|
||||
{"ATPA", 1, fATPA, "=<SSID>[,password[,encryption[,channel[,hidden[,max connections]]]]]: Start WIFI AP"},
|
||||
#if defined(CONFIG_ENABLE_WPS_AP) && CONFIG_ENABLE_WPS_AP
|
||||
{"WPS_AP", 1, cmd_ap_wps, "=<pbc/pin>[,pin]: WiFi AP WPS"},
|
||||
{"WPS_ST", 1, cmd_wps, "=<pbc/pin>[,pin]: WiFi Station WPS"},
|
||||
#endif
|
||||
#if CONFIG_ENABLE_P2P
|
||||
{"P2P_START", 0, cmd_wifi_p2p_start, ": p2p start" },
|
||||
{"P2P_ASTART", 0, cmd_wifi_p2p_auto_go_start, ": p2p auto go start" },
|
||||
{"P2P_STOP", 0, cmd_wifi_p2p_stop, ": p2p stop"},
|
||||
{"P2P_PEERS", 0, cmd_p2p_peers, ": p2p peers" },
|
||||
{"P2P_FIND", 0, cmd_p2p_find, ": p2p find"},
|
||||
{"P2P_INFO", 0, cmd_p2p_info, ": p2p info"},
|
||||
{"P2P_DISCCONNECT", 0, cmd_p2p_disconnect, ": p2p disconnect"},
|
||||
{"P2P_CONNECT", 0, cmd_p2p_connect, ": p2p connect"},
|
||||
#endif
|
||||
{"ATWR", 0, fATWR, ": WIFI Connect, Disconnect"},
|
||||
// {"ATON", 0, fATON, ": Open connections"},
|
||||
// {"ATOF", 0, fATOF, ": Close connections"},
|
||||
{"ATWI", 0, fATWI, ": WiFi Info"},
|
||||
#if CONFIG_DEBUG_LOG > 3
|
||||
{"ATWT", 1, fATWT, "=<tx_power>: WiFi tx power: 0 - 100%, 1 - 75%, 2 - 50%, 3 - 25%, 4 - 12.5%"},
|
||||
{"ATSF", 0, fATSF, ": Test TSF value"},
|
||||
#endif
|
||||
{"ATSN", 0, fATSN, ": Scan networks"}
|
||||
};
|
||||
|
||||
|
||||
50
project/src/console/wlan_tst.c
Normal file
50
project/src/console/wlan_tst.c
Normal file
|
|
@ -0,0 +1,50 @@
|
|||
/*
|
||||
* wlan_tst.c
|
||||
*
|
||||
* Created on: 10 апр. 2017 г.
|
||||
* Author: PVV
|
||||
*/
|
||||
#include <platform_opts.h>
|
||||
#include "rtl8195a.h"
|
||||
#include "drv_types.h"
|
||||
//#include "section_config.h"
|
||||
//#include "hal_diag.h"
|
||||
#include "rtl8195a/rtl_libc.h"
|
||||
|
||||
extern void dump_bytes(uint32 addr, int size);
|
||||
extern Rltk_wlan_t rltk_wlan_info[2]; // in wrapper.h
|
||||
|
||||
LOCAL void tst_wlan_struct(int argc, char *argv[])
|
||||
{
|
||||
printf("Test: sizeof(struct _ADAPTER) = %d\n", sizeof(struct _ADAPTER)); //6088
|
||||
printf("mlmeextpriv\t+%d\n", offsetof(struct _ADAPTER, mlmeextpriv)); //+1256
|
||||
printf("TSFValue\t+%d\n", offsetof(struct _ADAPTER, mlmeextpriv.TSFValue)); //+1992
|
||||
printf("stapriv\t\t+%d\n", offsetof(struct _ADAPTER, stapriv)); //+3024 [164]
|
||||
printf("pwrctrlpriv.bInternalAutoSuspend +%d\n", offsetof(struct _ADAPTER, pwrctrlpriv.bInternalAutoSuspend)); //+5061
|
||||
printf("eeprompriv\t+%d\n", offsetof(struct _ADAPTER, eeprompriv)); // +5128
|
||||
printf("HalData\t\t+%d\n", offsetof(struct _ADAPTER, HalData)); //+5656
|
||||
printf("HalFunc\t\t+%d\n", offsetof(struct _ADAPTER, HalFunc)); //+5664
|
||||
printf("bDriverStopped\t+%d\n", offsetof(struct _ADAPTER, bDriverStopped)); //+5880
|
||||
printf("hw_init_completed +%d\n", offsetof(struct _ADAPTER, hw_init_completed)); //+5905
|
||||
printf("stats\t\t+%d\n", offsetof(struct _ADAPTER, stats)); //+6024
|
||||
printf("hw_init_mutex\t+%d\n", offsetof(struct _ADAPTER, hw_init_mutex)); //+6060
|
||||
printf("fix_rate\t+%d\n", offsetof(struct _ADAPTER, fix_rate)); //+6084
|
||||
|
||||
printf("rltk_wlan_info = %p\n", &rltk_wlan_info);
|
||||
dump_bytes((u32)&rltk_wlan_info, sizeof(rltk_wlan_info));
|
||||
_adapter * ad = *(_adapter **)((rltk_wlan_info[0].dev)->priv);
|
||||
printf("adapter0 = %p, %p\n", ad, ad->pbuddy_adapter);
|
||||
ad = *(_adapter **)((rltk_wlan_info[1].dev)->priv);
|
||||
printf("adapter1 = %p, %p\n", ad, ad->pbuddy_adapter);
|
||||
vTaskDelay(5);
|
||||
dump_bytes((u32)ad,sizeof(struct _ADAPTER));
|
||||
vTaskDelay(5);
|
||||
|
||||
if (sizeof(struct _ADAPTER) != 6088) {
|
||||
printf("Error: Check WiFi adapter struct!\n");
|
||||
};
|
||||
}
|
||||
|
||||
MON_RAM_TAB_SECTION COMMAND_TABLE console_wlan_tst[] = {
|
||||
{"CHKWL", 0, tst_wlan_struct, ": Chk wlan struct"}
|
||||
};
|
||||
1269
project/src/tcpsrv/tcp_srv_conn.c
Normal file
1269
project/src/tcpsrv/tcp_srv_conn.c
Normal file
File diff suppressed because it is too large
Load diff
97
project/src/user/main.c
Normal file
97
project/src/user/main.c
Normal file
|
|
@ -0,0 +1,97 @@
|
|||
/*
|
||||
*
|
||||
*/
|
||||
|
||||
#include "platform_autoconf.h"
|
||||
#include "autoconf.h"
|
||||
#include "FreeRTOS.h"
|
||||
#include "task.h"
|
||||
#include "diag.h"
|
||||
#include "hal_crypto.h"
|
||||
#include "hal_log_uart.h"
|
||||
#include "hal_misc.h"
|
||||
#include "diag.h"
|
||||
//#include "wdt_api.h"
|
||||
//#include <osdep_service.h>
|
||||
#include "hal_platform.h"
|
||||
#include "rtl8195a_sys_on.h"
|
||||
|
||||
#ifdef CONFIG_WDG_ON_IDLE
|
||||
#include "hal_peri_on.h"
|
||||
#include "rtl8195a_peri_on.h"
|
||||
#endif
|
||||
|
||||
/* ---------------------------------------------------
|
||||
* Customized Signature (Image Name)
|
||||
* ---------------------------------------------------*/
|
||||
#include "section_config.h"
|
||||
SECTION(".custom.validate.rodata")
|
||||
const unsigned char cus_sig[32] = "WEB Sample";
|
||||
|
||||
#ifdef CONFIG_DEBUG_LOG
|
||||
#define DEBUG_MAIN_LEVEL CONFIG_DEBUG_LOG
|
||||
#else
|
||||
#define DEBUG_MAIN_LEVEL 0
|
||||
#endif
|
||||
|
||||
#ifndef CONFIG_INIT_NET
|
||||
#define CONFIG_INIT_NET 1
|
||||
#endif
|
||||
#ifndef CONFIG_INTERACTIVE_MODE
|
||||
#define CONFIG_INTERACTIVE_MODE 1
|
||||
#endif
|
||||
|
||||
extern void user_init_thrd(void);
|
||||
|
||||
/* RAM/TCM/Heaps info */
|
||||
void ShowMemInfo(void)
|
||||
{
|
||||
DiagPrintf("\nCLK CPU\t\t%d Hz\nRAM heap\t%d bytes\nTCM heap\t%d bytes\n",
|
||||
HalGetCpuClk(), xPortGetFreeHeapSize(), tcm_heap_freeSpace());
|
||||
}
|
||||
|
||||
/* main */
|
||||
void main(void)
|
||||
{
|
||||
#if DEBUG_MAIN_LEVEL > 3
|
||||
ConfigDebugErr = -1;
|
||||
ConfigDebugInfo = ~(_DBG_SPI_FLASH_);//|_DBG_TCM_HEAP_);
|
||||
ConfigDebugWarn = -1;
|
||||
CfgSysDebugErr = -1;
|
||||
CfgSysDebugInfo = -1;
|
||||
CfgSysDebugWarn = -1;
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_WDG_ON_IDLE
|
||||
HAL_PERI_ON_WRITE32(REG_SOC_FUNC_EN, HAL_PERI_ON_READ32(REG_SOC_FUNC_EN) & 0x1FFFFF);
|
||||
#if CONFIG_DEBUG_LOG > 3
|
||||
WDGInitial(CONFIG_WDG_ON_IDLE * 3000); // 30 s
|
||||
#else
|
||||
WDGInitial(CONFIG_WDG_ON_IDLE * 1000); // 10 s
|
||||
#endif
|
||||
WDGStart();
|
||||
#endif
|
||||
|
||||
#if (defined(CONFIG_CRYPTO_STARTUP) && (CONFIG_CRYPTO_STARTUP))
|
||||
if(rtl_cryptoEngine_init() != 0 ) {
|
||||
DBG_8195A("Crypto engine init failed!\n");
|
||||
}
|
||||
#endif
|
||||
|
||||
#if DEBUG_MAIN_LEVEL > 1
|
||||
vPortFree(pvPortMalloc(4)); // Init RAM heap
|
||||
ShowMemInfo(); // RAM/TCM/Heaps info
|
||||
#endif
|
||||
|
||||
/* wlan & user_start intialization */
|
||||
xTaskCreate(user_init_thrd, "user_init", 1024, NULL, tskIDLE_PRIORITY + 1 + PRIORITIE_OFFSET, NULL);
|
||||
|
||||
/*Enable Schedule, Start Kernel*/
|
||||
#if defined(CONFIG_KERNEL) && !TASK_SCHEDULER_DISABLED
|
||||
#ifdef PLATFORM_FREERTOS
|
||||
vTaskStartScheduler();
|
||||
#endif
|
||||
#else
|
||||
RtlConsolTaskRom(NULL);
|
||||
#endif
|
||||
}
|
||||
77
project/src/user/user_start.c
Normal file
77
project/src/user/user_start.c
Normal file
|
|
@ -0,0 +1,77 @@
|
|||
/*
|
||||
* user_start.c
|
||||
*
|
||||
* Created on: 26/03/2017
|
||||
* Author: pvvx
|
||||
*/
|
||||
#include "user_config.h"
|
||||
#include "platform_autoconf.h"
|
||||
#include "autoconf.h"
|
||||
#include "FreeRTOS.h"
|
||||
#include "task.h"
|
||||
#include "diag.h"
|
||||
#include "netbios/netbios.h"
|
||||
#include "user/sys_cfg.h"
|
||||
#include "web/web_srv.h"
|
||||
#include "webfs/webfs.h"
|
||||
|
||||
struct SystemCfg syscfg = {
|
||||
.cfg.w = SYS_CFG_DEBUG_ENA | SYS_CFG_NETBIOS_ENA,
|
||||
#if defined(USE_WEB)
|
||||
.web_port = USE_WEB,
|
||||
#else
|
||||
.web_port = 0,
|
||||
#endif
|
||||
.web_twrec = 5,
|
||||
.web_twcls = 5
|
||||
};
|
||||
|
||||
void connect_start(void)
|
||||
{
|
||||
info_printf("\%s: Time at start %d ms.\n", __func__, xTaskGetTickCount());
|
||||
}
|
||||
|
||||
void connect_close(void)
|
||||
{
|
||||
info_printf("\%s: Time at start %d ms.\n", __func__, xTaskGetTickCount());
|
||||
}
|
||||
|
||||
void user_start(void)
|
||||
{
|
||||
info_printf("\%s: Time at start %d ms.\n", __func__, xTaskGetTickCount());
|
||||
|
||||
}
|
||||
|
||||
void sys_write_cfg(void)
|
||||
{
|
||||
flash_write_cfg(&syscfg, FEEP_ID_SYS_CFG, sizeof(syscfg));
|
||||
}
|
||||
|
||||
|
||||
void user_init_thrd(void) {
|
||||
|
||||
flash_read_cfg(&syscfg, FEEP_ID_SYS_CFG, sizeof(syscfg));
|
||||
|
||||
if(!syscfg.cfg.b.debug_print_enable) print_off = 1;
|
||||
|
||||
/* Initilaize the console stack */
|
||||
|
||||
console_init();
|
||||
|
||||
/* Web Disk Init */
|
||||
WEBFSInit();
|
||||
|
||||
/* Load cfg, init WiFi + LwIP init, WiFi start if wifi_cfg.mode != RTW_MODE_NONE */
|
||||
wifi_init();
|
||||
|
||||
if(syscfg.cfg.b.netbios_ena) netbios_init();
|
||||
|
||||
// webstuff_init(); // httpd_init();
|
||||
webserver_init(syscfg.web_port);
|
||||
|
||||
// xTaskCreate(x_init_thrd, "wifi_init", 1024, NULL, tskIDLE_PRIORITY + 1 + PRIORITIE_OFFSET, NULL);
|
||||
|
||||
/* Kill init thread after all init tasks done */
|
||||
vTaskDelete(NULL);
|
||||
}
|
||||
|
||||
688
project/src/web/web_int_callbacks.c
Normal file
688
project/src/web/web_int_callbacks.c
Normal file
|
|
@ -0,0 +1,688 @@
|
|||
/******************************************************************************
|
||||
* 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 "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 "user/sys_cfg.h"
|
||||
#include "wifi_api.h"
|
||||
#include "sys_api.h"
|
||||
#include "esp_comp.h"
|
||||
|
||||
#ifdef USE_NETBIOS
|
||||
#include "netbios.h"
|
||||
#endif
|
||||
|
||||
#ifdef USE_SNTP
|
||||
#include "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
|
||||
|
||||
#define atoi rom_atoi
|
||||
|
||||
#define mMIN(a, b) ((a<b)?a:b)
|
||||
#define ifcmp(a) if(rom_xstrcmp(cstr, a))
|
||||
|
||||
extern struct netif xnetif[NET_IF_NUM]; /* network interface structure */
|
||||
|
||||
//#define TEST_SEND_WAVE
|
||||
|
||||
#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;
|
||||
}
|
||||
SetSCB(SCB_FCLOSE | SCB_DISCONNECT); // connection close
|
||||
}
|
||||
#endif // TEST_SEND_WAVE
|
||||
#if 0
|
||||
//===============================================================================
|
||||
// WiFi Saved Aps XML
|
||||
//-------------------------------------------------------------------------------
|
||||
void ICACHE_FLASH_ATTR wifi_aps_xml(TCP_SERV_CONN *ts_conn)
|
||||
{
|
||||
struct buf_html_string {
|
||||
uint8 ssid[32*6 + 1];
|
||||
uint8 psw[64*6 + 1];
|
||||
};
|
||||
WEB_SRV_CONN *web_conn = (WEB_SRV_CONN *) ts_conn->linkd;
|
||||
struct station_config config[5];
|
||||
struct buf_html_string * buf = (struct buf_html_string *)os_malloc(sizeof(struct buf_html_string));
|
||||
if(buf == NULL) return;
|
||||
int total_aps = wifi_station_get_ap_info(config);
|
||||
// Check if this is a first round call
|
||||
if(CheckSCB(SCB_RETRYCB)==0) {
|
||||
tcp_puts_fd("<total>%u</total><cur>%u</cur>", total_aps, wifi_station_get_current_ap_id());
|
||||
if(total_aps == 0) return;
|
||||
web_conn->udata_start = 0;
|
||||
}
|
||||
while(web_conn->msgbuflen + 74 + 32 <= web_conn->msgbufsize) {
|
||||
if(web_conn->udata_start < total_aps) {
|
||||
struct station_config *p = (struct station_config *)&config[web_conn->udata_start];
|
||||
if(web_conn->msgbuflen + 74 + htmlcode(buf->ssid, p->ssid, 32*6, 32) + htmlcode(buf->psw, p->password, 64*6, 64) > web_conn->msgbufsize) break;
|
||||
tcp_puts_fd("<aps id=\"%u\"><ss>%s</ss><ps>%s</ps><bs>" MACSTR "</bs><bt>%d</bt></aps>",
|
||||
web_conn->udata_start, buf->ssid, buf->psw, MAC2STR(p->bssid), p->bssid_set);
|
||||
web_conn->udata_start++;
|
||||
if(web_conn->udata_start >= total_aps) {
|
||||
ClrSCB(SCB_RETRYCB);
|
||||
os_free(buf);
|
||||
return;
|
||||
}
|
||||
}
|
||||
else {
|
||||
ClrSCB(SCB_RETRYCB);
|
||||
os_free(buf);
|
||||
return;
|
||||
}
|
||||
}
|
||||
// repeat in the next call ...
|
||||
SetSCB(SCB_RETRYCB);
|
||||
SetNextFunSCB(wifi_aps_xml);
|
||||
os_free(buf);
|
||||
return;
|
||||
}
|
||||
//===============================================================================
|
||||
// WiFi Scan XML
|
||||
//-------------------------------------------------------------------------------
|
||||
void ICACHE_FLASH_ATTR web_wscan_xml(TCP_SERV_CONN *ts_conn)
|
||||
{
|
||||
struct bss_scan_info si;
|
||||
WEB_SRV_CONN *web_conn = (WEB_SRV_CONN *) ts_conn->linkd;
|
||||
// Check if this is a first round call
|
||||
if(CheckSCB(SCB_RETRYCB)==0) {
|
||||
tcp_puts_fd("<total>%d</total>", total_scan_infos);
|
||||
if(total_scan_infos == 0) return;
|
||||
web_conn->udata_start = 0;
|
||||
}
|
||||
while(web_conn->msgbuflen + 96 + 32 <= web_conn->msgbufsize) {
|
||||
if(web_conn->udata_start < total_scan_infos) {
|
||||
struct bss_scan_info *p = (struct bss_scan_info *)buf_scan_infos;
|
||||
p += web_conn->udata_start;
|
||||
ets_memcpy(&si, p, sizeof(si));
|
||||
/*
|
||||
uint8 ssid[33];
|
||||
ssid[32] = '\0';
|
||||
ets_memcpy(ssid, si.ssid, 32); */
|
||||
uint8 ssid[32*6 + 1];
|
||||
if(web_conn->msgbuflen + 96 + htmlcode(ssid, si.ssid, 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></ap>", web_conn->udata_start, si.channel, si.authmode, MAC2STR(si.bssid), ssid, si.rssi, si.is_hidden);
|
||||
web_conn->udata_start++;
|
||||
if(web_conn->udata_start >= total_scan_infos) {
|
||||
ClrSCB(SCB_RETRYCB);
|
||||
return;
|
||||
}
|
||||
}
|
||||
else {
|
||||
ClrSCB(SCB_RETRYCB);
|
||||
return;
|
||||
}
|
||||
}
|
||||
// repeat in the next call ...
|
||||
SetSCB(SCB_RETRYCB);
|
||||
SetNextFunSCB(web_wscan_xml);
|
||||
return;
|
||||
}
|
||||
//===============================================================================
|
||||
// WiFi Probe Request XML
|
||||
//-------------------------------------------------------------------------------
|
||||
void ICACHE_FLASH_ATTR web_ProbeRequest_xml(TCP_SERV_CONN *ts_conn)
|
||||
{
|
||||
struct s_probe_requests pr;
|
||||
WEB_SRV_CONN *web_conn = (WEB_SRV_CONN *) ts_conn->linkd;
|
||||
// Check if this is a first round call
|
||||
uint32 cnt = (probe_requests_count < MAX_COUNT_BUF_PROBEREQS)? probe_requests_count : MAX_COUNT_BUF_PROBEREQS;
|
||||
if(CheckSCB(SCB_RETRYCB)==0) {
|
||||
if(cnt == 0) {
|
||||
tcp_strcpy_fd("<total>0</total>");
|
||||
return;
|
||||
}
|
||||
web_conn->udata_start = 0;
|
||||
}
|
||||
while(web_conn->msgbuflen + 92 <= web_conn->msgbufsize) {
|
||||
if(web_conn->udata_start < cnt) {
|
||||
struct s_probe_requests *p = (struct s_probe_requests *)&buf_probe_requests;
|
||||
p += web_conn->udata_start;
|
||||
ets_memcpy(&pr, p, sizeof(struct s_probe_requests));
|
||||
tcp_puts_fd("<pr id=\"%u\"><mac>" MACSTR "</mac><min>%d</min><max>%d</max></pr>", web_conn->udata_start, MAC2STR(pr.mac), pr.rssi_min, pr.rssi_max);
|
||||
web_conn->udata_start++;
|
||||
if(web_conn->udata_start >= cnt) {
|
||||
tcp_puts_fd("<total>%d</total>", cnt);
|
||||
ClrSCB(SCB_RETRYCB);
|
||||
return;
|
||||
}
|
||||
}
|
||||
else {
|
||||
ClrSCB(SCB_RETRYCB);
|
||||
return;
|
||||
}
|
||||
}
|
||||
// repeat in the next call ...
|
||||
SetSCB(SCB_RETRYCB);
|
||||
SetNextFunSCB(web_ProbeRequest_xml);
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
#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) {
|
||||
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) {
|
||||
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]);
|
||||
}
|
||||
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);
|
||||
SetSCB(SCB_FCLOSE | SCB_DISCONNECT); // connection close
|
||||
return;
|
||||
}
|
||||
}
|
||||
else {
|
||||
tcp_puts("%p = Bad address!\r\n", addr);
|
||||
ClrSCB(SCB_RETRYCB);
|
||||
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);
|
||||
copy_align4(web_conn->msgbuf, (void *)(web_conn->udata_start), len);
|
||||
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);
|
||||
else ifcmp("xml_") {
|
||||
cstr+=4;
|
||||
web_conn->udata_start&=~3;
|
||||
ifcmp("ram") tcp_puts("0x%08x", *((uint32*)web_conn->udata_start));
|
||||
else tcp_put('?');
|
||||
web_conn->udata_start += 4;
|
||||
}
|
||||
else ifcmp("sys_") {
|
||||
cstr+=4;
|
||||
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
|
||||
else ifcmp("restart") web_conn->web_disc_cb = (web_func_disc_cb)sys_reset;
|
||||
else ifcmp("ram") tcp_puts("0x%08x", *((uint32 *)(ahextoul(cstr+3)&(~3))));
|
||||
else ifcmp("rdec") tcp_puts("%d", *((uint32 *)(ahextoul(cstr+4)&(~3))));
|
||||
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('?');
|
||||
}
|
||||
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("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") {
|
||||
web_conn->web_disc_cb = (web_func_disc_cb)wifi_run;
|
||||
web_conn->web_disc_par = wifi_cfg.mode;
|
||||
}
|
||||
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("sleep") tcp_puts("%d", wifi_cfg.sleep);
|
||||
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("country") tcp_puts("%u", wifi_cfg.country_code);
|
||||
else ifcmp("ap_") {
|
||||
cstr+=3;
|
||||
ifcmp("ssid") {
|
||||
int len = os_strlen(wifi_ap_cfg.ssid);
|
||||
if(len > sizeof(wifi_ap_cfg.ssid)) {
|
||||
len = sizeof(wifi_ap_cfg.ssid);
|
||||
}
|
||||
os_memcpy((char *)&web_conn->msgbuf[web_conn->msgbuflen], wifi_ap_cfg.ssid, len);
|
||||
web_conn->msgbuflen += len;
|
||||
}
|
||||
else ifcmp("psw") {
|
||||
int len = os_strlen(wifi_ap_cfg.password);
|
||||
if(len > sizeof(wifi_ap_cfg.password)) {
|
||||
len = sizeof(wifi_ap_cfg.password);
|
||||
}
|
||||
os_memcpy((char *)&web_conn->msgbuf[web_conn->msgbuflen], wifi_ap_cfg.password, len);
|
||||
web_conn->msgbuflen += len;
|
||||
}
|
||||
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_type == RTW_SECURITY_OPEN) ? '0' : '1');
|
||||
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_netifn].hwaddr));
|
||||
else ifcmp("hostname") tcp_strcpy(lwip_host_name[wlan_ap_netifn]);
|
||||
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_netifn].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("arec") tcp_puts("%u", wifi_st_cfg.autoreconnect);
|
||||
else ifcmp("rect") tcp_puts("%u", wifi_st_cfg.reconnect_pause);
|
||||
else ifcmp("ssid") {
|
||||
int len = os_strlen(wifi_st_cfg.ssid);
|
||||
if(len > sizeof(wifi_st_cfg.ssid)) {
|
||||
len = sizeof(wifi_st_cfg.ssid);
|
||||
}
|
||||
os_memcpy((char *)&web_conn->msgbuf[web_conn->msgbuflen], wifi_st_cfg.ssid, len);
|
||||
web_conn->msgbuflen += len;
|
||||
}
|
||||
else ifcmp("psw") {
|
||||
int len = os_strlen(wifi_st_cfg.password);
|
||||
if(len > sizeof(wifi_st_cfg.password)) {
|
||||
len = sizeof(wifi_st_cfg.password);
|
||||
}
|
||||
os_memcpy((char *)&web_conn->msgbuf[web_conn->msgbuflen], wifi_st_cfg.password, len);
|
||||
web_conn->msgbuflen += len;
|
||||
}
|
||||
else ifcmp("mac") tcp_puts(MACSTR, MAC2STR(xnetif[wlan_st_netifn].hwaddr));
|
||||
else ifcmp("bssid") tcp_puts(MACSTR, MAC2STR(wifi_st_cfg.bssid));
|
||||
else ifcmp("sbss") tcp_puts("%u", wifi_st_cfg.flg);
|
||||
#if LWIP_NETIF_HOSTNAME
|
||||
else ifcmp("hostname") tcp_strcpy(lwip_host_name[wlan_st_netifn]);
|
||||
#endif
|
||||
else ifcmp("auth") tcp_puts("%u", wifi_st_cfg.security_type);
|
||||
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_") {
|
||||
cstr+=4;
|
||||
ifcmp("flash") {
|
||||
cstr+=5;
|
||||
if(*cstr == '_') {
|
||||
cstr++;
|
||||
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 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);
|
||||
}
|
||||
else ifcmp("ram") web_get_ram(ts_conn);
|
||||
else tcp_put('?');
|
||||
}
|
||||
else ifcmp("hexdmp") {
|
||||
if(cstr[6]=='d') ts_conn->flag.user_option1 = 1;
|
||||
else ts_conn->flag.user_option1 = 0;
|
||||
web_hexdump(ts_conn);
|
||||
}
|
||||
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", 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
|
||||
356
project/src/web/web_int_vars.c
Normal file
356
project/src/web/web_int_vars.c
Normal file
|
|
@ -0,0 +1,356 @@
|
|||
/******************************************************************************
|
||||
* FileName: webserver.c
|
||||
* Description: The web server mode configuration.
|
||||
*******************************************************************************/
|
||||
|
||||
#include "user_config.h"
|
||||
#ifdef USE_WEB
|
||||
#include "autoconf.h"
|
||||
#include "FreeRTOS.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 "flash_eep.h"
|
||||
#include "device_lock.h"
|
||||
#include "rtl8195a/rtl_libc.h"
|
||||
#include "user/sys_cfg.h"
|
||||
#include "wifi_api.h"
|
||||
#include "sys_api.h"
|
||||
#include "esp_comp.h"
|
||||
|
||||
#ifdef USE_NETBIOS
|
||||
#include "netbios.h"
|
||||
#endif
|
||||
|
||||
#ifdef USE_SNTP
|
||||
#include "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 *);
|
||||
#define atoi rom_atoi
|
||||
|
||||
typedef uint32 (* call_func)(uint32 a, uint32 b, uint32 c);
|
||||
|
||||
/******************************************************************************
|
||||
* 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;
|
||||
else ifcmp("sys_") {
|
||||
cstr+=4;
|
||||
ifcmp("restart") {
|
||||
if(val == 12345) web_conn->web_disc_cb = (web_func_disc_cb)sys_reset;
|
||||
}
|
||||
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
|
||||
#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
|
||||
}
|
||||
else ifcmp("cfg_") {
|
||||
cstr += 4;
|
||||
ifcmp("web_") {
|
||||
cstr += 4;
|
||||
ifcmp("port") {
|
||||
if(syscfg.web_port != val) {
|
||||
web_conn->web_disc_par = syscfg.web_port; // ts_conn->pcfg->port
|
||||
syscfg.web_port = val;
|
||||
web_conn->web_disc_cb = (web_func_disc_cb)webserver_reinit;
|
||||
}
|
||||
}
|
||||
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("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_inits();
|
||||
else sntp_close();
|
||||
}
|
||||
#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("rdcfg") web_conn->udata_stop = read_wifi_cfg(val);
|
||||
else ifcmp("newcfg") {
|
||||
web_conn->web_disc_cb = (web_func_disc_cb)wifi_run;
|
||||
web_conn->web_disc_par = wifi_cfg.mode;
|
||||
}
|
||||
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("sleep") wifi_cfg.sleep = val;
|
||||
else ifcmp("txpow") wifi_cfg.tx_pwr = val;
|
||||
else ifcmp("country") wifi_cfg.country_code = val;
|
||||
// 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 > sizeof(wifi_ap_cfg.ssid)) {
|
||||
len = sizeof(wifi_ap_cfg.ssid);
|
||||
}
|
||||
else 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(wifi_ap_cfg.ssid);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
else ifcmp("psw") {
|
||||
int len = os_strlen(pvar);
|
||||
if(len > sizeof(wifi_ap_cfg.password)) {
|
||||
len = sizeof(wifi_ap_cfg.password);
|
||||
}
|
||||
else 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_type = (val)? RTW_SECURITY_WEP_PSK : RTW_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;
|
||||
}
|
||||
os_memcpy(lwip_host_name[wlan_ap_netifn], pvar, len);
|
||||
lwip_host_name[wlan_ap_netifn][len] = 0;
|
||||
netbios_set_name(wlan_ap_netifn, pvar);
|
||||
}
|
||||
#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 > sizeof(wifi_st_cfg.ssid)) {
|
||||
len = sizeof(wifi_st_cfg.ssid);
|
||||
}
|
||||
else 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 > sizeof(wifi_st_cfg.password)) {
|
||||
len = sizeof(wifi_st_cfg.password);
|
||||
}
|
||||
else 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_type = val;
|
||||
else ifcmp("bssid") strtomac(pvar, wifi_st_cfg.bssid);
|
||||
else ifcmp("sbss") wifi_st_cfg.flg = 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;
|
||||
}
|
||||
os_memcpy(lwip_host_name[wlan_st_netifn], pvar, len);
|
||||
lwip_host_name[wlan_st_netifn][len] = 0;
|
||||
netbios_set_name(wlan_st_netifn, pvar);
|
||||
}
|
||||
#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
|
||||
}
|
||||
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
|
||||
}
|
||||
#if DEBUGSOO > 5
|
||||
else os_printf(" - none! ");
|
||||
#endif
|
||||
}
|
||||
|
||||
#endif // USE_WEB
|
||||
2073
project/src/web/web_srv.c
Normal file
2073
project/src/web/web_srv.c
Normal file
File diff suppressed because it is too large
Load diff
640
project/src/web/web_utils.c
Normal file
640
project/src/web/web_utils.c
Normal file
|
|
@ -0,0 +1,640 @@
|
|||
/*
|
||||
* 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(*ps) {
|
||||
*pd++ = *ps++;
|
||||
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;
|
||||
}
|
||||
/******************************************************************************
|
||||
* 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;
|
||||
}
|
||||
//=============================================================================
|
||||
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 = 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
|
||||
|
||||
347
project/src/web/web_websocket.c
Normal file
347
project/src/web/web_websocket.c
Normal file
|
|
@ -0,0 +1,347 @@
|
|||
/******************************************************************************
|
||||
* 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_utils.h"
|
||||
#include "web_websocket.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;
|
||||
}
|
||||
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 {
|
||||
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) {
|
||||
os_free(web_conn->msgbuf);
|
||||
web_conn->msgbuf = NULL;
|
||||
return false; // не докачивать, ошибка или закрытие
|
||||
}
|
||||
}
|
||||
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
|
||||
|
||||
|
||||
245
project/src/web/websock.c
Normal file
245
project/src/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
|
||||
|
||||
483
project/src/webfs/webfs.c
Normal file
483
project/src/webfs/webfs.c
Normal file
|
|
@ -0,0 +1,483 @@
|
|||
/*********************************************************************
|
||||
* WEBFS.c
|
||||
* RTL871x Flash WEB File System v1.0
|
||||
********************************************************************/
|
||||
#include "autoconf.h"
|
||||
#include "FreeRTOS.h"
|
||||
#include "task.h"
|
||||
#include "diag.h"
|
||||
#include <osdep_api.h>
|
||||
#include <osdep_service.h>
|
||||
#include "device_lock.h"
|
||||
#include "flash_api.h"
|
||||
//#include "flash_eep.h"
|
||||
|
||||
#include "webfs/webfs.h"
|
||||
#include "rtl8195a/rtl_libc.h"
|
||||
#include "esp_comp.h"
|
||||
|
||||
|
||||
#define WEBFS_CODE_ATTR
|
||||
#define WEBFS_DATA_ATTR
|
||||
|
||||
#define web_mutex_lock() device_mutex_lock(RT_DEV_LOCK_FLASH)
|
||||
#define web_mutex_unlock() device_mutex_unlock(RT_DEV_LOCK_FLASH)
|
||||
|
||||
// Supports long file names to 64 characters
|
||||
#define MAX_FILE_NAME_LEN 64 // VarNameSize
|
||||
uint32 disk_base_addr WEBFS_DATA_ATTR;
|
||||
#define WEBFS_HEAD_ADDR disk_base_addr
|
||||
/*
|
||||
*
|
||||
* Structure:
|
||||
*
|
||||
* [F][W][E][B][uint8 Ver Hi][uint8 Ver Lo] // заголовок диска
|
||||
* [uint16 Number of Files] // кол-во файлов на диске
|
||||
* [Name Hash 0]...[Name Hash N] // uint16 типа хеш на каждое имя файла
|
||||
* [File Record 0]...[File Record N] // uint32 указатели на адреса структур файлов, относительно начала диска
|
||||
*
|
||||
* File Record Structure:
|
||||
* [uint32 Len] размер файла с заголовком
|
||||
* [uint16 HeadLen] длина заголовка, включая размер, флаг, имя (адрес данных - адрес позиции len)
|
||||
* [uint16 Flags] бит 0 =1 - файл сжат GZIP, бит 1 = 1 - парсится - имеет динамические переменные
|
||||
* [File Name, 0] Имя файла с "СИ" терминатором
|
||||
* [File Data] данные файла
|
||||
*
|
||||
* Name hash (2 uint8s) is calculated as follows:
|
||||
* hash = 0
|
||||
* for each(uint8 in name)
|
||||
* hash += uint8
|
||||
* hash <<= 1
|
||||
*
|
||||
* Technically this means the hash only includes the
|
||||
* final 15 characters of a name.
|
||||
*
|
||||
* String FileNmae Structure (1 to 64 uint8s):
|
||||
* ["path/to/file.ext"][0x00]
|
||||
*
|
||||
*
|
||||
* Current version is 1.0
|
||||
*/
|
||||
// Lock WEBFS access during the upgrade
|
||||
volatile bool isWEBFSLocked WEBFS_DATA_ATTR;
|
||||
// Track the WEBFS File Handles
|
||||
// WEBFSStubs[0] is reserved for internal use (FAT access)
|
||||
WEBFS_STUB WEBFSStubs[MAX_WEBFS_OPENFILES+1] WEBFS_DATA_ATTR; // + HANDLE = 0
|
||||
// FAT record cache
|
||||
WEBFS_FAT_RECORD fatCache WEBFS_DATA_ATTR;
|
||||
// ID of currently loaded fatCache
|
||||
static uint32 fatCacheID WEBFS_DATA_ATTR;
|
||||
// Number of files in this WEBFS image
|
||||
uint16 numFiles WEBFS_DATA_ATTR;
|
||||
|
||||
LOCAL void GetFATRecord(uint16 fatID);
|
||||
LOCAL void WEBFS_Update(void);
|
||||
|
||||
/*****************************************************************************
|
||||
Function:
|
||||
void WEBFSInit(void)
|
||||
Description:
|
||||
Web Disk Init
|
||||
*****************************************************************************/
|
||||
void WEBFS_CODE_ATTR WEBFSInit(void)
|
||||
{
|
||||
disk_base_addr = WEBFS_base_addr();
|
||||
os_memset((char *) &WEBFSStubs, 0xff, sizeof(WEBFSStubs));
|
||||
// Validate the image and load numFiles
|
||||
WEBFS_Update();
|
||||
#if DEBUGSOO > 0
|
||||
os_printf("\nDisk init: %d files, addr = %p\n", numFiles, disk_base_addr);
|
||||
#endif
|
||||
// тут надо расчет контрольки тела диска или другой контроль...
|
||||
if(numFiles == 0) isWEBFSLocked = true;
|
||||
else isWEBFSLocked = false;
|
||||
}
|
||||
/*****************************************************************************
|
||||
Function:
|
||||
WEBFS_HANDLE WEBFSOpen(uint8* cFile)
|
||||
|
||||
Description:
|
||||
Opens a file in the WEBFS2 file system.
|
||||
|
||||
Precondition:
|
||||
None
|
||||
|
||||
Parameters:
|
||||
cFile - a null terminated file name to open
|
||||
|
||||
Returns:
|
||||
An WEBFS_HANDLE to the opened file if found, or WEBFS_INVALID_HANDLE
|
||||
if the file could not be found or no free handles exist.
|
||||
***************************************************************************/
|
||||
WEBFS_HANDLE WEBFS_CODE_ATTR WEBFSOpen(uint8* cFile)
|
||||
{
|
||||
WEBFS_HANDLE hWEBFS;
|
||||
uint16 nameHash;
|
||||
int i, len = 0;
|
||||
uint16 hashCache[16];
|
||||
uint8 bufname[MAX_FILE_NAME_LEN];
|
||||
uint8 *ptr;
|
||||
|
||||
// Make sure WEBFS is unlocked and we got a filename
|
||||
if(*cFile == '\0' || isWEBFSLocked == true)
|
||||
return WEBFS_INVALID_HANDLE;
|
||||
|
||||
// Calculate the name hash to speed up searching
|
||||
for(nameHash = 0, ptr = cFile; *ptr != '\0'; ptr++)
|
||||
{
|
||||
nameHash += *ptr;
|
||||
nameHash <<= 1;
|
||||
len++;
|
||||
}
|
||||
// Find a free file handle to use
|
||||
for(hWEBFS = 1; hWEBFS <= MAX_WEBFS_OPENFILES; hWEBFS++)
|
||||
if(WEBFSStubs[hWEBFS].addr == WEBFS_INVALID) break;
|
||||
if(hWEBFS == MAX_WEBFS_OPENFILES)
|
||||
return WEBFS_INVALID_HANDLE;
|
||||
// Read in hashes, and check remainder on a match. Store 8 in cache for performance
|
||||
for(i = 0; i < numFiles; i++) {
|
||||
// For new block of 8, read in data
|
||||
if((i & 0x0F) == 0) {
|
||||
WEBFSStubs[0].addr = 12 + i*2;
|
||||
WEBFSStubs[0].bytesRem = 32;
|
||||
WEBFSGetArray(0, (uint8*)hashCache, 32);
|
||||
}
|
||||
// If the hash matches, compare the full filename
|
||||
if(hashCache[i&0x0F] == nameHash)
|
||||
{
|
||||
GetFATRecord(i);
|
||||
// filename comparison
|
||||
WEBFSStubs[0].addr = fatCache.string;
|
||||
WEBFSStubs[0].bytesRem = MAX_FILE_NAME_LEN;
|
||||
WEBFSGetArray(0, bufname, MAX_FILE_NAME_LEN);
|
||||
if(os_strncmp(cFile, bufname, len) == 0) { // Filename matches, so return true
|
||||
WEBFSStubs[hWEBFS].addr = fatCache.data;
|
||||
WEBFSStubs[hWEBFS].bytesRem = fatCache.len;
|
||||
WEBFSStubs[hWEBFS].fatID = i;
|
||||
return hWEBFS;
|
||||
}
|
||||
}
|
||||
}
|
||||
// No file name matched, so return nothing
|
||||
return WEBFS_INVALID_HANDLE;
|
||||
}
|
||||
/*****************************************************************************
|
||||
Function: void WEBFSClose(WEBFS_HANDLE hWEBFS)
|
||||
Summary: Closes a file.
|
||||
Returns: None
|
||||
***************************************************************************/
|
||||
void WEBFS_CODE_ATTR WEBFSClose(WEBFS_HANDLE hWEBFS)
|
||||
{
|
||||
if(hWEBFS != 0 && hWEBFS <= MAX_WEBFS_OPENFILES)
|
||||
WEBFSStubs[hWEBFS].addr = WEBFS_INVALID;
|
||||
}
|
||||
/*****************************************************************************
|
||||
Function: uint16 WEBFSGetArray(WEBFS_HANDLE hWEBFS, uint8* cData, uint16 wLen)
|
||||
Description: Reads a series of uint8s from a file.
|
||||
Precondition: The file handle referenced by hWEBFS is already open.
|
||||
Parameters:
|
||||
hWEBFS - the file handle from which to read
|
||||
cData - where to store the uint8s that were read
|
||||
wLen - how many uint8s to read
|
||||
Returns:
|
||||
The number of uint8s successfully read. If this is less than wLen,
|
||||
an EOF occurred while attempting to read.
|
||||
***************************************************************************/
|
||||
uint16 WEBFS_CODE_ATTR WEBFSGetArray(WEBFS_HANDLE hWEBFS, uint8* cData, uint16 wLen)
|
||||
{
|
||||
// Make sure we're reading a valid address
|
||||
if(hWEBFS > MAX_WEBFS_OPENFILES) return 0;
|
||||
|
||||
// Determine how many we can actually read
|
||||
if(wLen > WEBFSStubs[hWEBFS].bytesRem) wLen = WEBFSStubs[hWEBFS].bytesRem;
|
||||
// Make sure we're reading a valid address
|
||||
if(WEBFSStubs[hWEBFS].addr == WEBFS_INVALID || wLen == 0) return 0;
|
||||
|
||||
if(cData != NULL) {
|
||||
|
||||
// Read the data
|
||||
web_mutex_lock();
|
||||
// if(wLen < 16)
|
||||
flash_stream_read(&flashobj, WEBFSStubs[hWEBFS].addr + WEBFS_HEAD_ADDR, wLen, cData);
|
||||
// else flash_burst_read(&flashobj, WEBFSStubs[hWEBFS].addr + WEBFS_HEAD_ADDR, wLen, cData);
|
||||
web_mutex_unlock();
|
||||
|
||||
// if(spi_flash_read(WEBFSStubs[hWEBFS].addr+WEBFS_HEAD_ADDR, cData, wLen) != SPI_FLASH_RESULT_OK)
|
||||
// return 0;
|
||||
};
|
||||
WEBFSStubs[hWEBFS].addr += wLen;
|
||||
WEBFSStubs[hWEBFS].bytesRem -= wLen;
|
||||
return wLen;
|
||||
}
|
||||
/*****************************************************************************
|
||||
Function:
|
||||
bool WEBFSSeek(WEBFS_HANDLE hWEBFS, uint32 dwOffset, WEBFS_SEEK_MODE tMode)
|
||||
Description: Moves the current read pointer to a new location.
|
||||
Precondition: The file handle referenced by hWEBFS is already open.
|
||||
Parameters:
|
||||
hWEBFS - the file handle to seek with
|
||||
dwOffset - offset from the specified position in the specified direction
|
||||
tMode - one of the WEBFS_SEEK_MODE constants
|
||||
Returns:
|
||||
true - the seek was successful
|
||||
false - either the new location or the handle itself was invalid
|
||||
***************************************************************************/
|
||||
bool WEBFS_CODE_ATTR WEBFSSeek(WEBFS_HANDLE hWEBFS, uint32 dwOffset, WEBFS_SEEK_MODE tMode)
|
||||
{
|
||||
uint32 temp;
|
||||
|
||||
// Make sure a valid file is open
|
||||
if(hWEBFS > MAX_WEBFS_OPENFILES || WEBFSStubs[hWEBFS].addr == WEBFS_INVALID)
|
||||
return false;
|
||||
|
||||
switch(tMode)
|
||||
{
|
||||
// Seek offset uint8s from start
|
||||
case WEBFS_SEEK_START:
|
||||
temp = WEBFSGetSize(hWEBFS);
|
||||
if(dwOffset > temp)
|
||||
return false;
|
||||
|
||||
WEBFSStubs[hWEBFS].addr = WEBFSGetStartAddr(hWEBFS) + dwOffset;
|
||||
WEBFSStubs[hWEBFS].bytesRem = temp - dwOffset;
|
||||
return true;
|
||||
|
||||
// Seek forwards offset uint8s
|
||||
case WEBFS_SEEK_FORWARD:
|
||||
if(dwOffset > WEBFSStubs[hWEBFS].bytesRem)
|
||||
return false;
|
||||
|
||||
WEBFSStubs[hWEBFS].addr += dwOffset;
|
||||
WEBFSStubs[hWEBFS].bytesRem -= dwOffset;
|
||||
return true;
|
||||
|
||||
// Seek backwards offset uint8s
|
||||
case WEBFS_SEEK_REWIND:
|
||||
temp = WEBFSGetStartAddr(hWEBFS);
|
||||
if(WEBFSStubs[hWEBFS].addr < temp + dwOffset)
|
||||
return false;
|
||||
|
||||
WEBFSStubs[hWEBFS].addr -= dwOffset;
|
||||
WEBFSStubs[hWEBFS].bytesRem += dwOffset;
|
||||
return true;
|
||||
|
||||
// Seek so that offset uint8s remain in file
|
||||
case WEBFS_SEEK_END:
|
||||
temp = WEBFSGetSize(hWEBFS);
|
||||
if(dwOffset > temp)
|
||||
return false;
|
||||
|
||||
WEBFSStubs[hWEBFS].addr = WEBFSGetEndAddr(hWEBFS) - dwOffset;
|
||||
WEBFSStubs[hWEBFS].bytesRem = dwOffset;
|
||||
return true;
|
||||
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
/*****************************************************************************
|
||||
Function: static void GetFATRecord(uint16 fatID)
|
||||
Description: Loads the FAT record for a specified handle.
|
||||
Precondition: None
|
||||
Parameters: fatID - the ID of the file whose FAT is to be loaded
|
||||
Returns: None
|
||||
Remarks: The FAT record will be stored in fatCache.
|
||||
***************************************************************************/
|
||||
LOCAL void WEBFS_CODE_ATTR GetFATRecord(uint16 fatID)
|
||||
{
|
||||
WEBFS_FHEADER fhead;
|
||||
if(fatID == fatCacheID || fatID >= numFiles) return;
|
||||
// Read the FAT record to the cache
|
||||
WEBFSStubs[0].bytesRem = sizeof(fhead) + 4;
|
||||
WEBFSStubs[0].addr = 12 + numFiles*2 + fatID *4;
|
||||
WEBFSGetArray(0, (uint8 *)&fatCache.data, 4);
|
||||
WEBFSStubs[0].addr = fatCache.data;
|
||||
WEBFSGetArray(0, (uint8 *)&fhead, sizeof(fhead));
|
||||
fatCache.len = fhead.blksize - fhead.headlen;
|
||||
fatCache.string = fatCache.data + 8;
|
||||
fatCache.flags = fhead.flags;
|
||||
fatCache.data = fatCache.data + fhead.headlen;
|
||||
fatCacheID = fatID;
|
||||
}
|
||||
/*****************************************************************************
|
||||
Function: uint16 WEBFSGetFlags(WEBFS_HANDLE hWEBFS)
|
||||
Description: Reads a file's flags.
|
||||
Precondition: The file handle referenced by hWEBFS is already open.
|
||||
Parameters: hWEBFS - the file handle from which to read the metadata
|
||||
Returns: The flags that were associated with the file
|
||||
***************************************************************************/
|
||||
uint16 WEBFS_CODE_ATTR WEBFSGetFlags(WEBFS_HANDLE hWEBFS)
|
||||
{
|
||||
// Make sure a valid file is open
|
||||
if(hWEBFS > MAX_WEBFS_OPENFILES || WEBFSStubs[hWEBFS].addr == WEBFS_INVALID)
|
||||
return 0;
|
||||
|
||||
//move to the point for reading
|
||||
GetFATRecord(WEBFSStubs[hWEBFS].fatID);
|
||||
return fatCache.flags;
|
||||
}
|
||||
/*****************************************************************************
|
||||
Function: uint32 WEBFSGetSize(WEBFS_HANDLE hWEBFS)
|
||||
Description: Reads the size of a file.
|
||||
Precondition: The file handle referenced by hWEBFS is already open.
|
||||
Parameters: hWEBFS - the file handle from which to read the metadata
|
||||
Returns: The size that was read as a uint32
|
||||
***************************************************************************/
|
||||
uint32 WEBFS_CODE_ATTR WEBFSGetSize(WEBFS_HANDLE hWEBFS)
|
||||
{
|
||||
// Make sure a valid file is open
|
||||
if(hWEBFS > MAX_WEBFS_OPENFILES || WEBFSStubs[hWEBFS].addr == WEBFS_INVALID)
|
||||
return 0;
|
||||
|
||||
// Move to the point for reading
|
||||
GetFATRecord(WEBFSStubs[hWEBFS].fatID);
|
||||
return fatCache.len;
|
||||
}
|
||||
/*****************************************************************************
|
||||
Function: uint32 WEBFSGetBytesRem(WEBFS_HANDLE hWEBFS)
|
||||
Description: Determines how many uint8s remain to be read.
|
||||
Precondition: The file handle referenced by hWEBFS is already open.
|
||||
Parameters: hWEBFS - the file handle from which to read the metadata
|
||||
Returns: The number of uint8s remaining in the file as a uint32
|
||||
***************************************************************************/
|
||||
uint32 WEBFS_CODE_ATTR WEBFSGetBytesRem(WEBFS_HANDLE hWEBFS)
|
||||
{
|
||||
// Make sure a valid file is open
|
||||
if(hWEBFS > MAX_WEBFS_OPENFILES || WEBFSStubs[hWEBFS].addr == WEBFS_INVALID)
|
||||
return 0;
|
||||
return WEBFSStubs[hWEBFS].bytesRem;
|
||||
}
|
||||
/*****************************************************************************
|
||||
Function: WEBFS_PTR WEBFSGetStartAddr(WEBFS_HANDLE hWEBFS)
|
||||
Description: Reads the starting address of a file.
|
||||
Precondition: The file handle referenced by hWEBFS is already open.
|
||||
Parameters: hWEBFS - the file handle from which to read the metadata
|
||||
Returns: The starting address of the file in the WEBFS image
|
||||
***************************************************************************/
|
||||
WEBFS_PTR WEBFS_CODE_ATTR WEBFSGetStartAddr(WEBFS_HANDLE hWEBFS)
|
||||
{
|
||||
// Make sure a valid file is open
|
||||
if(hWEBFS > MAX_WEBFS_OPENFILES || WEBFSStubs[hWEBFS].addr == WEBFS_INVALID)
|
||||
return 0;
|
||||
// Move to the point for reading
|
||||
GetFATRecord(WEBFSStubs[hWEBFS].fatID);
|
||||
return fatCache.data;
|
||||
}
|
||||
/*****************************************************************************
|
||||
Function: WEBFS_PTR WEBFSGetEndAddr(WEBFS_HANDLE hWEBFS)
|
||||
Description: Determines the ending address of a file.
|
||||
Precondition: The file handle referenced by hWEBFS is already open.
|
||||
Parameters: hWEBFS - the file handle from which to read the metadata
|
||||
Returns: The address just after the file ends (start address of next file)
|
||||
***************************************************************************/
|
||||
WEBFS_PTR WEBFS_CODE_ATTR WEBFSGetEndAddr(WEBFS_HANDLE hWEBFS)
|
||||
{
|
||||
// Make sure a valid file is open
|
||||
if(hWEBFS > MAX_WEBFS_OPENFILES || WEBFSStubs[hWEBFS].addr == WEBFS_INVALID)
|
||||
return WEBFS_INVALID;
|
||||
// Move to the point for reading
|
||||
GetFATRecord(WEBFSStubs[hWEBFS].fatID);
|
||||
return fatCache.data + fatCache.len;
|
||||
}
|
||||
/*****************************************************************************
|
||||
Function: bool WEBFSGetFilename(WEBFS_HANDLE hWEBFS, uint8* cName, uint16 wLen)
|
||||
Description: Reads the file name of a file that is already open.
|
||||
Precondition: The file handle referenced by hWEBFS is already open.
|
||||
Parameters:
|
||||
hWEBFS - the file handle from which to determine the file name
|
||||
cName - where to store the name of the file
|
||||
wLen - the maximum length of data to store in cName
|
||||
Returns:
|
||||
true - the file name was successfully located
|
||||
false - the file handle provided is not currently open
|
||||
***************************************************************************/
|
||||
bool WEBFS_CODE_ATTR WEBFSGetFilename(WEBFS_HANDLE hWEBFS, uint8* cName, uint16 wLen)
|
||||
{
|
||||
uint32 addr;
|
||||
|
||||
// Make sure a valid file is open
|
||||
if(hWEBFS > MAX_WEBFS_OPENFILES || WEBFSStubs[hWEBFS].addr == WEBFS_INVALID)
|
||||
return false;
|
||||
|
||||
// Move to the point for reading
|
||||
GetFATRecord(WEBFSStubs[hWEBFS].fatID);
|
||||
addr = fatCache.string;
|
||||
WEBFSStubs[0].addr = addr;
|
||||
WEBFSStubs[0].bytesRem = 255;
|
||||
|
||||
// Read the value and return
|
||||
WEBFSGetArray(0, cName, wLen);
|
||||
return true;
|
||||
}
|
||||
/*****************************************************************************
|
||||
Function: uint32 WEBFSGetPosition(WEBFS_HANDLE hWEBFS)
|
||||
Description: Determines the current position in the file
|
||||
Precondition: The file handle referenced by hWEBFS is already open.
|
||||
Parameters: hWEBFS - the file handle for which to determine position
|
||||
Returns: The position in the file as a uint32 (or WEBFS_PTR)
|
||||
***************************************************************************/
|
||||
uint32 WEBFS_CODE_ATTR WEBFSGetPosition(WEBFS_HANDLE hWEBFS)
|
||||
{
|
||||
return WEBFSStubs[hWEBFS].addr - WEBFSGetStartAddr(hWEBFS);
|
||||
}
|
||||
/*****************************************************************************
|
||||
Function: void WEBFS_Update(void)
|
||||
Summary: Validates the WEBFS Image
|
||||
Description: Verifies that the WEBFS image is valid, and reads the number of
|
||||
available files from the image header. This function is called on
|
||||
boot, and again after any image is written.
|
||||
Parameters: None
|
||||
Returns: None
|
||||
***************************************************************************/
|
||||
LOCAL void WEBFS_CODE_ATTR WEBFS_Update(void)
|
||||
{
|
||||
// Update numFiles
|
||||
WEBFS_DISK_HEADER dhead;
|
||||
WEBFSStubs[0].addr = 0;
|
||||
WEBFSStubs[0].bytesRem = sizeof(dhead);
|
||||
WEBFSGetArray(0, (uint8*)&dhead, sizeof(dhead));
|
||||
if(dhead.id == WEBFS_DISK_ID && dhead.ver == WEBFS_DISK_VER) { //"FWEB"1,0 ?
|
||||
numFiles = dhead.numFiles;
|
||||
}
|
||||
else numFiles = 0;
|
||||
fatCacheID = WEBFS_INVALID_FAT;
|
||||
}
|
||||
/****************************************************************************
|
||||
* WEBFS_max_size()
|
||||
***************************************************************************/
|
||||
uint32 WEBFS_CODE_ATTR WEBFS_max_size(void)
|
||||
{
|
||||
/*
|
||||
uint32 size = spi_flash_real_size();
|
||||
if(size > WEBFS_DISK_ADDR_BIGFLASH) size -= WEBFS_DISK_ADDR_BIGFLASH;
|
||||
else {
|
||||
size = WEBFS_DISK_ADDR_MINFLASH_END - WEBFS_DISK_ADDR_MINFLASH_START;
|
||||
}
|
||||
return size;
|
||||
*/
|
||||
return spi_flash_real_size() - WEBFS_DISK_FADDR;
|
||||
}
|
||||
/****************************************************************************
|
||||
* WEBFS_size()
|
||||
***************************************************************************/
|
||||
uint32 WEBFS_CODE_ATTR WEBFS_curent_size(void)
|
||||
{
|
||||
uint32 size = 0;
|
||||
web_mutex_lock();
|
||||
if(numFiles) flash_read_word(&flashobj, disk_base_addr + 8, &size);
|
||||
web_mutex_unlock();
|
||||
return size;
|
||||
}
|
||||
/****************************************************************************
|
||||
* WEBFS_size()
|
||||
***************************************************************************/
|
||||
uint32 WEBFS_CODE_ATTR WEBFS_base_addr(void)
|
||||
{
|
||||
/*
|
||||
uint32 webfs_faddr;
|
||||
if(flash_get_size(&flashobj) <= WEBFS_DISK_ADDR_BIGFLASH) webfs_faddr = WEBFS_DISK_ADDR_MINFLASH_START;
|
||||
else webfs_faddr = WEBFS_DISK_ADDR_BIGFLASH;
|
||||
return webfs_faddr;
|
||||
*/
|
||||
return WEBFS_DISK_FADDR;
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue