mirror of
https://github.com/ghsecuritylab/ameba_ws2812b.git
synced 2024-11-01 09:54:15 +00:00
1197 lines
35 KiB
C
1197 lines
35 KiB
C
/*
|
|
FreeRTOS V6.0.4 - Copyright (C) 2010 Real Time Engineers Ltd.
|
|
|
|
***************************************************************************
|
|
* *
|
|
* If you are: *
|
|
* *
|
|
* + New to FreeRTOS, *
|
|
* + Wanting to learn FreeRTOS or multitasking in general quickly *
|
|
* + Looking for basic training, *
|
|
* + Wanting to improve your FreeRTOS skills and productivity *
|
|
* *
|
|
* then take a look at the FreeRTOS eBook *
|
|
* *
|
|
* "Using the FreeRTOS Real Time Kernel - a Practical Guide" *
|
|
* http://www.FreeRTOS.org/Documentation *
|
|
* *
|
|
* A pdf reference manual is also available. Both are usually delivered *
|
|
* to your inbox within 20 minutes to two hours when purchased between 8am *
|
|
* and 8pm GMT (although please allow up to 24 hours in case of *
|
|
* exceptional circumstances). Thank you for your support! *
|
|
* *
|
|
***************************************************************************
|
|
|
|
This file is part of the FreeRTOS distribution.
|
|
|
|
FreeRTOS is free software; you can redistribute it and/or modify it under
|
|
the terms of the GNU General Public License (version 2) as published by the
|
|
Free Software Foundation AND MODIFIED BY the FreeRTOS exception.
|
|
***NOTE*** The exception to the GPL is included to allow you to distribute
|
|
a combined work that includes FreeRTOS without being obliged to provide the
|
|
source code for proprietary components outside of the FreeRTOS kernel.
|
|
FreeRTOS is distributed in the hope that it will be useful, but WITHOUT
|
|
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
|
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
|
more details. You should have received a copy of the GNU General Public
|
|
License and the FreeRTOS license exception along with FreeRTOS; if not it
|
|
can be viewed here: http://www.freertos.org/a00114.html and also obtained
|
|
by writing to Richard Barry, contact details for whom are available on the
|
|
FreeRTOS WEB site.
|
|
|
|
1 tab == 4 spaces!
|
|
|
|
http://www.FreeRTOS.org - Documentation, latest information, license and
|
|
contact details.
|
|
|
|
http://www.SafeRTOS.com - A version that is certified for use in safety
|
|
critical systems.
|
|
|
|
http://www.OpenRTOS.com - Commercial support, development, porting,
|
|
licensing and training services.
|
|
*/
|
|
|
|
/*
|
|
Implements a simplistic WEB server. Every time a connection is made and
|
|
data is received a dynamic page that shows the current TCP/IP statistics
|
|
is generated and returned. The connection is then closed.
|
|
|
|
This file was adapted from a FreeRTOS lwIP slip demo supplied by a third
|
|
party.
|
|
*/
|
|
|
|
/* ------------------------ System includes ------------------------------- */
|
|
|
|
|
|
/* ------------------------ FreeRTOS includes ----------------------------- */
|
|
#include "FreeRTOS.h"
|
|
#include "task.h"
|
|
#include "semphr.h"
|
|
|
|
/* ------------------------ lwIP includes --------------------------------- */
|
|
#include "lwip/api.h"
|
|
#include "lwip/tcpip.h"
|
|
#include "lwip/memp.h"
|
|
#include "lwip/stats.h"
|
|
#include "netif/loopif.h"
|
|
|
|
/* ------------------------ Project includes ------------------------------ */
|
|
#include <string.h>
|
|
#include "main.h"
|
|
|
|
#include "webserver.h"
|
|
#include "wlan_intf.h"
|
|
|
|
|
|
|
|
#include "cJSON.h"
|
|
|
|
|
|
|
|
#define CONFIG_READ_FLASH 1
|
|
|
|
|
|
#ifdef CONFIG_READ_FLASH
|
|
|
|
#ifndef CONFIG_PLATFORM_8195A
|
|
|
|
#include <flash/stm32_flash.h>
|
|
#if defined(STM32F2XX)
|
|
#include <stm32f2xx_flash.h>
|
|
#elif defined(STM32F4XX)
|
|
#include <stm32f4xx_flash.h>
|
|
#elif defined(STM32f1xx)
|
|
#include <stm32f10x_flash.h>
|
|
#endif
|
|
|
|
#else
|
|
#include "flash_api.h"
|
|
#define DATA_SECTOR (0x000FE000)
|
|
#define BACKUP_SECTOR (0x00008000)
|
|
|
|
#endif
|
|
#endif
|
|
/* ------------------------ Defines --------------------------------------- */
|
|
/* The size of the buffer in which the dynamic WEB page is created. */
|
|
#define webMAX_PAGE_SIZE ( 2800 ) /*FSL: buffer containing array*/
|
|
#define LOCAL_BUF_SIZE 800
|
|
#define AP_SETTING_ADDR 0x000FE000;
|
|
/* Standard GET response. */
|
|
#define webHTTP_OK "HTTP/1.0 200 OK\r\nContent-type: text/html\r\n\r\n"
|
|
|
|
/* The port on which we listen. */
|
|
#define webHTTP_PORT ( 80 )
|
|
|
|
/* Delay on close error. */
|
|
#define webSHORT_DELAY ( 10 )
|
|
|
|
|
|
/* Format of the dynamic page that is returned on each connection. */
|
|
#define webHTML_HEAD_START \
|
|
"<html>\
|
|
<head>\
|
|
<SCRIPT language=Javascript src=\"<% getLangInfo(\"lang\");%>\"></SCRIPT>\
|
|
"
|
|
/*
|
|
<meta http-equiv=\"Content-Type\" content=\"text/html;charset=gb2312>\
|
|
<meta http-equiv=\"Cache-Control\" CONTENT=\"no-cache\">\
|
|
<meta http-equiv=\"Expires\" CONTENT=\"0\">\
|
|
*/
|
|
|
|
#define webHTML_BODY_START \
|
|
"</head>\
|
|
<BODY onLoad=\"onChangeSecType()\">\
|
|
\r\n\r\n<form name=\"form\" method=\"post\" onsubmit=\"return onSubmitForm()\">\
|
|
<table width=\"500\">\
|
|
<tr>\
|
|
<td colspan=\"2\" style=\"background-color:#FFA500;text-align:center;\">\
|
|
<h2>Realtek SoftAP Configuration</h2>\
|
|
</td>\
|
|
</tr>"
|
|
|
|
#define webHTML_END \
|
|
"<tr>\
|
|
<td colspan=\"2\" style=\"background-color:#FFD700;text-align:center;height:40px\">\
|
|
<input type=\"submit\" value=\"Submit\"><br></td>\
|
|
</tr>\
|
|
<tr>\
|
|
<td colspan=\"2\" style=\"background-color:#FFA500;text-align:center;\">\
|
|
Copyright ?realtek.com</td>\
|
|
</tr>\
|
|
</table>\
|
|
\r\n</form>" \
|
|
"</BODY>\r\n" \
|
|
"</html>"
|
|
|
|
#define webWaitHTML_START \
|
|
"<html location.href='wait.html'>\
|
|
<head>\
|
|
"
|
|
#define webWaitHTML_END \
|
|
"</head>\
|
|
<BODY>\
|
|
<p>\
|
|
<h2>SoftAP is now restarting!</h2>\
|
|
<h2>Please wait a moment and reconnect!</h2>\
|
|
</p>"\
|
|
"</BODY>\r\n" \
|
|
"</html>"
|
|
|
|
#define onChangeSecType \
|
|
"<script>\
|
|
function onChangeSecType()\
|
|
{\
|
|
x=document.getElementById(\"sec\");\
|
|
y=document.getElementById(\"pwd_row\");\
|
|
if(x.value == \"open\"){\
|
|
y.style.display=\"none\";\
|
|
}else{\
|
|
y.style.display=\"block\";\
|
|
}\
|
|
}\
|
|
</script>"
|
|
|
|
#define onSubmitForm \
|
|
"<script>\
|
|
function onSubmitForm()\
|
|
{\
|
|
x=document.getElementById(\"Ssid\");\
|
|
y=document.getElementById(\"pwd_row\");\
|
|
z=document.getElementById(\"pwd\");\
|
|
if(x.value.length>32)\
|
|
{\
|
|
alert(\"SoftAP SSID is too long!(1-32)\");\
|
|
return false;\
|
|
}\
|
|
if(!(/^[A-Za-z0-9]+$/.test(x.value)))\
|
|
{\
|
|
alert(\"SoftAP SSID can only be [A-Za-z0-9]\");\
|
|
return false;\
|
|
}\
|
|
if(y.style.display == \"block\")\
|
|
{\
|
|
if((z.value.length < 8)||(z.value.length>32))\
|
|
{\
|
|
alert(\"Password length is between 8 to 32\");\
|
|
return false;\
|
|
}\
|
|
}\
|
|
}\
|
|
</script>"
|
|
|
|
/*
|
|
alert(\"Please enter your password!\");\
|
|
return false;\
|
|
}\
|
|
if(z.value.length < 8)\
|
|
{\
|
|
alert(\"Your password is too short!(8-32)\");\
|
|
return false;\
|
|
}\
|
|
if(z.value.length>32)\
|
|
{\
|
|
alert(\"Your password is too long!(8-32)\");\
|
|
*/
|
|
|
|
#define MAX_SOFTAP_SSID_LEN 32
|
|
#define MAX_PASSWORD_LEN 32
|
|
#define MAX_CHANNEL_NUM 13
|
|
|
|
#if INCLUDE_uxTaskGetStackHighWaterMark
|
|
static volatile unsigned portBASE_TYPE uxHighWaterMark_web = 0;
|
|
#endif
|
|
|
|
/* ------------------------ Prototypes ------------------------------------ */
|
|
static void vProcessConnection( struct netconn *pxNetCon );
|
|
|
|
/*------------------------------------------------------------------------------*/
|
|
/* GLOBALS */
|
|
/*------------------------------------------------------------------------------*/
|
|
rtw_wifi_setting_t wifi_setting = {RTW_MODE_NONE, {0}, 0, RTW_SECURITY_OPEN, {0}};
|
|
|
|
#ifndef WLAN0_NAME
|
|
#define WLAN0_NAME "wlan0"
|
|
#endif
|
|
|
|
#ifndef WLAN1_NAME
|
|
#define WLAN1_NAME "wlan1"
|
|
#endif
|
|
|
|
|
|
|
|
#define STRCMP(a,b) (strcmp(a,b) == 0)
|
|
|
|
|
|
|
|
static void LoadWifiSetting()
|
|
{
|
|
const char *ifname = WLAN0_NAME;
|
|
|
|
if(rltk_wlan_running(WLAN1_IDX))
|
|
{//STA_AP_MODE
|
|
ifname = WLAN1_NAME;
|
|
}
|
|
|
|
wifi_get_setting(ifname, &wifi_setting);
|
|
|
|
//printf("\r\nLoadWifiSetting(): wifi_setting.ssid=%s\n", wifi_setting.ssid);
|
|
//printf("\r\nLoadWifiSetting(): wifi_setting.channel=%d\n", wifi_setting.channel);
|
|
//printf("\r\nLoadWifiSetting(): wifi_setting.security_type=%d\n", wifi_setting.security_type);
|
|
//printf("\r\nLoadWifiSetting(): wifi_setting.password=%s\n", wifi_setting.password);
|
|
}
|
|
|
|
#if CONFIG_READ_FLASH
|
|
#ifndef CONFIG_PLATFORM_8195A
|
|
void LoadWifiConfig()
|
|
{
|
|
rtw_wifi_config_t local_config;
|
|
uint32_t address;
|
|
#ifdef STM32F10X_XL
|
|
address = 0x08080000; //bank2 domain
|
|
#else
|
|
uint16_t sector_nb = FLASH_Sector_11;
|
|
address = flash_SectorAddress(sector_nb);
|
|
#endif
|
|
printf("\r\nLoadWifiConfig(): Read from FLASH!\n");
|
|
flash_Read(address, (char *)&local_config, sizeof(local_config));
|
|
|
|
printf("\r\nLoadWifiConfig(): local_config.boot_mode=0x%x\n", local_config.boot_mode);
|
|
printf("\r\nLoadWifiConfig(): local_config.ssid=%s\n", local_config.ssid);
|
|
printf("\r\nLoadWifiConfig(): local_config.channel=%d\n", local_config.channel);
|
|
printf("\r\nLoadWifiConfig(): local_config.security_type=%d\n", local_config.security_type);
|
|
printf("\r\nLoadWifiConfig(): local_config.password=%s\n", local_config.password);
|
|
|
|
if(local_config.boot_mode == 0x77665502)
|
|
{
|
|
wifi_setting.mode = RTW_MODE_AP;
|
|
if(local_config.ssid_len > 32)
|
|
local_config.ssid_len = 32;
|
|
memcpy(wifi_setting.ssid, local_config.ssid, local_config.ssid_len);
|
|
wifi_setting.ssid[local_config.ssid_len] = '\0';
|
|
wifi_setting.channel = local_config.channel;
|
|
wifi_setting.security_type = local_config.security_type;
|
|
if(local_config.password_len > 32)
|
|
local_config.password_len = 32;
|
|
memcpy(wifi_setting.password, local_config.password, local_config.password_len);
|
|
wifi_setting.password[local_config.password_len] = '\0';
|
|
}
|
|
else
|
|
{
|
|
LoadWifiSetting();
|
|
}
|
|
}
|
|
|
|
int StoreApInfo()
|
|
{
|
|
rtw_wifi_config_t wifi_config;
|
|
uint32_t address;
|
|
#ifdef STM32F10X_XL
|
|
address = 0x08080000; //bank2 domain
|
|
#else
|
|
uint16_t sector_nb = FLASH_Sector_11;
|
|
address = flash_SectorAddress(sector_nb);
|
|
#endif
|
|
wifi_config.boot_mode = 0x77665502;
|
|
memcpy(wifi_config.ssid, wifi_setting.ssid, strlen((char*)wifi_setting.ssid));
|
|
wifi_config.ssid_len = strlen((char*)wifi_setting.ssid);
|
|
wifi_config.security_type = wifi_setting.security_type;
|
|
memcpy(wifi_config.password, wifi_setting.password, strlen((char*)wifi_setting.password));
|
|
wifi_config.password_len= strlen((char*)wifi_setting.password);
|
|
wifi_config.channel = wifi_setting.channel;
|
|
|
|
printf("\n\rWritting boot mode 0x77665502 and Wi-Fi setting to flash ...");
|
|
#ifdef STM32F10X_XL
|
|
FLASH_ErasePage(address);
|
|
#else
|
|
flash_EraseSector(sector_nb);
|
|
#endif
|
|
flash_Wrtie(address, (char *)&wifi_config, sizeof(rtw_wifi_config_t));
|
|
|
|
return 0;
|
|
}
|
|
|
|
|
|
#else
|
|
|
|
void LoadWifiConfig()
|
|
{
|
|
|
|
|
|
flash_t flash;
|
|
|
|
rtw_wifi_config_t local_config;
|
|
uint32_t address;
|
|
|
|
address = DATA_SECTOR;
|
|
|
|
|
|
//memset(&local_config,0,sizeof(rtw_wifi_config_t));
|
|
printf("\r\nLoadWifiConfig(): Read from FLASH!\n");
|
|
// flash_Read(address, &local_config, sizeof(local_config));
|
|
|
|
flash_stream_read(&flash, address, sizeof(rtw_wifi_config_t),(uint8_t *)(&local_config));
|
|
|
|
|
|
printf("\r\nLoadWifiConfig(): local_config.boot_mode=0x%x\n", local_config.boot_mode);
|
|
printf("\r\nLoadWifiConfig(): local_config.ssid=%s\n", local_config.ssid);
|
|
printf("\r\nLoadWifiConfig(): local_config.channel=%d\n", local_config.channel);
|
|
printf("\r\nLoadWifiConfig(): local_config.security_type=%d\n", local_config.security_type);
|
|
printf("\r\nLoadWifiConfig(): local_config.password=%s\n", local_config.password);
|
|
|
|
if(local_config.boot_mode == 0x77665502)
|
|
{
|
|
wifi_setting.mode = RTW_MODE_AP;
|
|
if(local_config.ssid_len > 32)
|
|
local_config.ssid_len = 32;
|
|
memcpy(wifi_setting.ssid, local_config.ssid, local_config.ssid_len);
|
|
wifi_setting.ssid[local_config.ssid_len] = '\0';
|
|
wifi_setting.channel = local_config.channel;
|
|
if(local_config.security_type == 1)
|
|
wifi_setting.security_type = RTW_SECURITY_WPA2_AES_PSK;
|
|
else
|
|
wifi_setting.security_type = RTW_SECURITY_OPEN;
|
|
if(local_config.password_len > 32)
|
|
local_config.password_len = 32;
|
|
memcpy(wifi_setting.password, local_config.password, local_config.password_len);
|
|
wifi_setting.password[local_config.password_len] = '\0';
|
|
}
|
|
else
|
|
{
|
|
LoadWifiSetting();
|
|
}
|
|
|
|
}
|
|
|
|
int StoreApInfo()
|
|
{
|
|
|
|
flash_t flash;
|
|
|
|
rtw_wifi_config_t wifi_config;
|
|
uint32_t address;
|
|
uint32_t data,i = 0;
|
|
|
|
|
|
address = DATA_SECTOR;
|
|
|
|
wifi_config.boot_mode = 0x77665502;
|
|
memcpy(wifi_config.ssid, wifi_setting.ssid, strlen((char*)wifi_setting.ssid));
|
|
wifi_config.ssid_len = strlen((char*)wifi_setting.ssid);
|
|
wifi_config.security_type = wifi_setting.security_type;
|
|
if(wifi_setting.security_type !=0)
|
|
wifi_config.security_type = 1;
|
|
else
|
|
wifi_config.security_type = 0;
|
|
memcpy(wifi_config.password, wifi_setting.password, strlen((char*)wifi_setting.password));
|
|
wifi_config.password_len= strlen((char*)wifi_setting.password);
|
|
wifi_config.channel = wifi_setting.channel;
|
|
printf("\n\rWritting boot mode 0x77665502 and Wi-Fi setting to flash ...");
|
|
//printf("\n\r &wifi_config = 0x%x",&wifi_config);
|
|
|
|
flash_read_word(&flash,address,&data);
|
|
|
|
|
|
if(data == ~0x0)
|
|
|
|
flash_stream_write(&flash, address,sizeof(rtw_wifi_config_t), (uint8_t *)&wifi_config);
|
|
|
|
else{
|
|
//flash_EraseSector(sector_nb);
|
|
|
|
|
|
flash_erase_sector(&flash,BACKUP_SECTOR);
|
|
for(i = 0; i < 0x1000; i+= 4){
|
|
flash_read_word(&flash, DATA_SECTOR + i, &data);
|
|
if(i < sizeof(rtw_wifi_config_t))
|
|
{
|
|
memcpy(&data,(char *)(&wifi_config) + i,4);
|
|
//printf("\n\r Wifi_config + %d = 0x%x",i,(void *)(&wifi_config + i));
|
|
//printf("\n\r Data = %d",data);
|
|
}
|
|
flash_write_word(&flash, BACKUP_SECTOR + i,data);
|
|
}
|
|
flash_read_word(&flash,BACKUP_SECTOR + 68,&data);
|
|
//printf("\n\r Base + BACKUP_SECTOR + 68 wifi channel = %d",data);
|
|
//erase system data
|
|
flash_erase_sector(&flash, DATA_SECTOR);
|
|
//write data back to system data
|
|
for(i = 0; i < 0x1000; i+= 4){
|
|
flash_read_word(&flash, BACKUP_SECTOR + i, &data);
|
|
flash_write_word(&flash, DATA_SECTOR + i,data);
|
|
}
|
|
//erase backup sector
|
|
flash_erase_sector(&flash, BACKUP_SECTOR);
|
|
}
|
|
|
|
//flash_Wrtie(address, (char *)&wifi_config, sizeof(rtw_wifi_config_t));
|
|
//flash_stream_write(&flash, address,sizeof(rtw_wifi_config_t), (uint8_t *)&wifi_config);
|
|
//flash_stream_read(&flash, address, sizeof(rtw_wifi_config_t),data);
|
|
//flash_stream_read(&flash, address, sizeof(rtw_wifi_config_t),data);
|
|
//printf("\n\r Base + 0x000FF000 +4 wifi config = %s",data[4]);
|
|
//printf("\n\r Base + 0x000FF000 +71 wifi channel = %d",data[71]);
|
|
|
|
return 0;
|
|
}
|
|
#endif
|
|
|
|
|
|
static void RestartSoftAP()
|
|
{
|
|
//printf("\r\nRestartAP: ssid=%s", wifi_setting.ssid);
|
|
//printf("\r\nRestartAP: ssid_len=%d", strlen((char*)wifi_setting.ssid));
|
|
//printf("\r\nRestartAP: security_type=%d", wifi_setting.security_type);
|
|
//printf("\r\nRestartAP: password=%s", wifi_setting.password);
|
|
//printf("\r\nRestartAP: password_len=%d", strlen((char*)wifi_setting.password));
|
|
//printf("\r\nRestartAP: channel=%d\n", wifi_setting.channel);
|
|
wifi_restart_ap(wifi_setting.ssid,
|
|
wifi_setting.security_type,
|
|
wifi_setting.password,
|
|
strlen((char*)wifi_setting.ssid),
|
|
strlen((char*)wifi_setting.password),
|
|
wifi_setting.channel);
|
|
}
|
|
#endif
|
|
|
|
|
|
u32 web_atoi(char* s)
|
|
{
|
|
int num=0,flag=0;
|
|
int i;
|
|
|
|
for(i=0;i<=strlen(s);i++)
|
|
{
|
|
if(s[i] >= '0' && s[i] <= '9')
|
|
num = num * 10 + s[i] -'0';
|
|
else if(s[0] == '-' && i==0)
|
|
flag =1;
|
|
else
|
|
break;
|
|
}
|
|
|
|
if(flag == 1)
|
|
num = num * -1;
|
|
|
|
return(num);
|
|
}
|
|
|
|
static void CreateSsidTableItem(char *pbuf, u8_t *ssid, u8_t ssid_len)
|
|
{
|
|
char local_ssid[MAX_SOFTAP_SSID_LEN+1];
|
|
|
|
if(ssid_len > MAX_SOFTAP_SSID_LEN)
|
|
ssid_len = MAX_SOFTAP_SSID_LEN;
|
|
memcpy(local_ssid, ssid, ssid_len);
|
|
local_ssid[ssid_len] = '\0';
|
|
sprintf(pbuf, "<tr>"
|
|
"<td style=\"background-color:#FFD700;width:100px;\">"
|
|
"<b>SoftAP SSID:</b><br>"
|
|
"</td>"
|
|
"<td style=\"background-color:#eeeeee;height:30px;width:400px;\">"
|
|
"<input type=\"text\" name=\"Ssid\" id=\"Ssid\" value=\"%s\"><br>"
|
|
"</td>"
|
|
"</tr>",
|
|
local_ssid);
|
|
//printf("\r\nstrlen(SsidTableItem)=%d\n", strlen(pbuf));
|
|
}
|
|
|
|
static void CreateSecTypeTableItem(char *pbuf, u32_t sectype)
|
|
{
|
|
u8_t flag[2] = {0, 0};
|
|
|
|
if(sectype == RTW_SECURITY_OPEN)
|
|
flag[0] = 1;
|
|
else if(sectype == RTW_SECURITY_WPA2_AES_PSK)
|
|
flag[1] = 1;
|
|
else
|
|
return;
|
|
|
|
sprintf(pbuf, "<tr>"
|
|
"<td style=\"background-color:#FFD700;width:100px;\">"
|
|
"<b>Security Type:</b><br>"
|
|
"</td>"
|
|
"<td style=\"background-color:#eeeeee;height:30px;\">"
|
|
"<select name=\"Security Type\" id=\"sec\" onChange=onChangeSecType()>"
|
|
"<option value=\"open\" %s>OPEN</option>"
|
|
"<option value=\"wpa2-aes\" %s>WPA2-AES</option>"
|
|
"</select>"
|
|
"</td>"
|
|
"</tr>",
|
|
flag[0]?"selected":"",
|
|
flag[1]?"selected":"");
|
|
//printf("\r\nstrlen(SecTypeTableItem)=%d\n", strlen(pbuf));
|
|
}
|
|
|
|
static void CreatePasswdTableItem(char *pbuf, u8_t *password, u8_t passwd_len)
|
|
{
|
|
char local_passwd[MAX_PASSWORD_LEN+1];
|
|
|
|
if(passwd_len > MAX_PASSWORD_LEN)
|
|
passwd_len = MAX_PASSWORD_LEN;
|
|
if(passwd_len > 0)
|
|
{
|
|
memcpy(local_passwd, password, passwd_len);
|
|
local_passwd[passwd_len] = '\0';
|
|
}
|
|
sprintf(pbuf, "<tr id=\"pwd_row\">"
|
|
"<td style=\"background-color:#FFD700;width:100px;\">"
|
|
"<b>Password:</b><br>"
|
|
"</td>"
|
|
"<td style=\"background-color:#eeeeee;height:30px;\">"
|
|
"<input type=\"text\" name=\"Password\" id=\"pwd\" value=\"%s\" ><br>"
|
|
"</td>"
|
|
"</tr>",
|
|
passwd_len?local_passwd:"");
|
|
//printf("\r\nstrlen(passwordTableItem)=%d\n", strlen(pbuf));
|
|
}
|
|
|
|
static void CreateChannelTableItem(char *pbuf, u8_t channel)
|
|
{
|
|
u8_t flag[MAX_CHANNEL_NUM+1] = {0};
|
|
|
|
if(channel > MAX_CHANNEL_NUM){
|
|
printf("Channel(%d) is out of range!\n", channel);
|
|
channel = 1;
|
|
}
|
|
flag[channel] = 1;
|
|
|
|
sprintf(pbuf, "<tr>"
|
|
"<td style=\"background-color:#FFD700;width:100px;\">"
|
|
"<b>Channel:</b><br>"
|
|
"</td>"
|
|
"<td style=\"background-color:#eeeeee;height:30px;\">"
|
|
"<select name=\"Channel\">"
|
|
"<option value=\"1\" %s>1</option>"
|
|
"<option value=\"2\" %s>2</option>"
|
|
"<option value=\"3\" %s>3</option>"
|
|
"<option value=\"4\" %s>4</option>"
|
|
"<option value=\"5\" %s>5</option>"
|
|
"<option value=\"6\" %s>6</option>"
|
|
"<option value=\"7\" %s>7</option>"
|
|
"<option value=\"8\" %s>8</option>"
|
|
"<option value=\"9\" %s>9</option>"
|
|
"<option value=\"10\" %s>10</option>"
|
|
"<option value=\"11\" %s>11</option>"
|
|
"</select>"
|
|
"</td>"
|
|
"</tr>",
|
|
flag[1]?"selected":"",
|
|
flag[2]?"selected":"",
|
|
flag[3]?"selected":"",
|
|
flag[4]?"selected":"",
|
|
flag[5]?"selected":"",
|
|
flag[6]?"selected":"",
|
|
flag[7]?"selected":"",
|
|
flag[8]?"selected":"",
|
|
flag[9]?"selected":"",
|
|
flag[10]?"selected":"",
|
|
flag[11]?"selected":"");
|
|
//printf("\r\nstrlen(ChannelTableItem)=%d\n", strlen(pbuf));
|
|
}
|
|
|
|
static void GenerateIndexHtmlPage(portCHAR* cDynamicPage, portCHAR *LocalBuf)
|
|
{
|
|
/* Generate the page index.html...
|
|
... First the page header. */
|
|
strcpy( cDynamicPage, webHTML_HEAD_START );
|
|
|
|
/* Add script */
|
|
strcat( cDynamicPage, onChangeSecType );
|
|
strcat( cDynamicPage, onSubmitForm);
|
|
|
|
/* Add Body start */
|
|
strcat( cDynamicPage, webHTML_BODY_START );
|
|
|
|
/* Add SSID */
|
|
CreateSsidTableItem(LocalBuf, wifi_setting.ssid, strlen((char*)wifi_setting.ssid));
|
|
strcat( cDynamicPage, LocalBuf );
|
|
|
|
/* Add SECURITY TYPE */
|
|
CreateSecTypeTableItem(LocalBuf, wifi_setting.security_type);
|
|
strcat( cDynamicPage, LocalBuf );
|
|
|
|
/* Add PASSWORD */
|
|
CreatePasswdTableItem(LocalBuf, wifi_setting.password, strlen((char*)wifi_setting.password));
|
|
strcat( cDynamicPage, LocalBuf );
|
|
|
|
/* Add CHANNEL */
|
|
CreateChannelTableItem(LocalBuf, wifi_setting.channel);
|
|
strcat( cDynamicPage, LocalBuf );
|
|
|
|
/* ... Finally the page footer. */
|
|
strcat( cDynamicPage, webHTML_END );
|
|
//printf("\r\nGenerateIndexHtmlPage(): %s\n", cDynamicPage);
|
|
printf("\r\nGenerateIndexHtmlPage Len: %d\n", strlen( cDynamicPage ));
|
|
}
|
|
|
|
static void GenerateWaitHtmlPage(portCHAR* cDynamicPage)
|
|
{
|
|
/* Generate the dynamic page...
|
|
... First the page header. */
|
|
strcpy( cDynamicPage, webWaitHTML_START );
|
|
|
|
/* ... Finally the page footer. */
|
|
strcat( cDynamicPage, webWaitHTML_END);
|
|
|
|
//printf("\r\nGenerateWaitHtmlPage(): %s\n", cDynamicPage);
|
|
//printf("\r\nGenerateWaitHtmlPage Len: %d\n", strlen( cDynamicPage ));
|
|
}
|
|
|
|
static u8_t ProcessPostMessage(struct netbuf *pxRxBuffer, portCHAR *LocalBuf)
|
|
{
|
|
struct pbuf *p;
|
|
portCHAR *pcRxString, *ptr;
|
|
unsigned portSHORT usLength;
|
|
u8_t bChanged = 0;
|
|
rtw_security_t secType;
|
|
u8_t channel;
|
|
u8_t len = 0;
|
|
|
|
pcRxString = LocalBuf;
|
|
p = pxRxBuffer->p;
|
|
usLength = p->tot_len;
|
|
//printf("\r\n !!!!!!!!!POST!p->tot_len =%d p->len=%d\n", p->tot_len, p->len);
|
|
while(p)
|
|
{
|
|
memcpy(pcRxString, p->payload, p->len);
|
|
pcRxString += p->len;
|
|
p = p->next;
|
|
}
|
|
pcRxString = LocalBuf;
|
|
pcRxString[usLength] = '\0';
|
|
//printf("\r\n usLength=%d pcRxString = %s\n", usLength, pcRxString);
|
|
|
|
ptr = (char*)strstr(pcRxString, "Ssid=");
|
|
if(ptr)
|
|
{
|
|
pcRxString = (char*)strstr(ptr, "&");
|
|
*pcRxString++ = '\0';
|
|
ptr += 5;
|
|
if(strcmp((char*)wifi_setting.ssid, ptr))
|
|
{
|
|
bChanged = 1;
|
|
len = strlen(ptr);
|
|
if(len > MAX_SOFTAP_SSID_LEN){
|
|
len = MAX_SOFTAP_SSID_LEN;
|
|
ptr[len] = '\0';
|
|
}
|
|
strcpy((char*)wifi_setting.ssid, ptr);
|
|
}
|
|
}
|
|
|
|
//printf("\r\n wifi_config.ssid = %s\n", wifi_setting.ssid);
|
|
ptr = (char*)strstr(pcRxString, "Security+Type=");
|
|
if(ptr)
|
|
{
|
|
pcRxString = (char*)strstr(ptr, "&");
|
|
*pcRxString++ = '\0';
|
|
ptr += 14;
|
|
if(!strcmp(ptr, "open"))
|
|
secType = RTW_SECURITY_OPEN;
|
|
else if(!strcmp(ptr, "wpa2-aes"))
|
|
secType = RTW_SECURITY_WPA2_AES_PSK;
|
|
else
|
|
secType = RTW_SECURITY_OPEN;
|
|
if(wifi_setting.security_type != secType)
|
|
{
|
|
bChanged = 1;
|
|
wifi_setting.security_type = secType;
|
|
}
|
|
}
|
|
|
|
//printf("\r\n wifi_config.security_type = %d\n", wifi_setting.security_type);
|
|
if(wifi_setting.security_type > RTW_SECURITY_OPEN)
|
|
{
|
|
ptr = (char*)strstr(pcRxString, "Password=");
|
|
if(ptr)
|
|
{
|
|
pcRxString = (char*)strstr(ptr, "&");
|
|
*pcRxString++ = '\0';
|
|
ptr += 9;
|
|
if(strcmp((char*)wifi_setting.password, ptr))
|
|
{
|
|
bChanged = 1;
|
|
len = strlen(ptr);
|
|
if(len > MAX_PASSWORD_LEN){
|
|
len = MAX_PASSWORD_LEN;
|
|
ptr[len] = '\0';
|
|
}
|
|
strcpy((char*)wifi_setting.password, ptr);
|
|
}
|
|
}
|
|
//printf("\r\n wifi_config.password = %s\n", wifi_setting.password);
|
|
}
|
|
ptr = (char*)strstr(pcRxString, "Channel=");
|
|
if(ptr)
|
|
{
|
|
ptr += 8;
|
|
channel = web_atoi(ptr);
|
|
if((channel>MAX_CHANNEL_NUM)||(channel < 1))
|
|
channel = 1;
|
|
if(wifi_setting.channel !=channel)
|
|
{
|
|
bChanged = 1;
|
|
wifi_setting.channel = channel;
|
|
}
|
|
}
|
|
//printf("\r\n wifi_config.channel = %d\n", wifi_setting.channel);
|
|
|
|
return bChanged;
|
|
}
|
|
|
|
struct netconn *pxHTTPListener = NULL;
|
|
static void vProcessConnection( struct netconn *pxNetCon )
|
|
{
|
|
static portCHAR cDynamicPage[webMAX_PAGE_SIZE];
|
|
struct netbuf *pxRxBuffer;
|
|
portCHAR *pcRxString;
|
|
unsigned portSHORT usLength;
|
|
static portCHAR LocalBuf[LOCAL_BUF_SIZE];
|
|
u8_t bChanged = 0;
|
|
int ret_recv = ERR_OK;
|
|
int ret_accept = ERR_OK;
|
|
|
|
/* Load WiFi Setting*/
|
|
LoadWifiSetting();
|
|
|
|
/* We expect to immediately get data. */
|
|
// Evan mopdified for adapt two version lwip api diff
|
|
port_netconn_recv( pxNetCon , pxRxBuffer, ret_recv);
|
|
|
|
if( pxRxBuffer != NULL && ret_recv == ERR_OK)
|
|
{
|
|
/* Where is the data? */
|
|
netbuf_data( pxRxBuffer, ( void * )&pcRxString, &usLength );
|
|
|
|
/* Is this a GET? We don't handle anything else. */
|
|
if( !strncmp( pcRxString, "GET", 3 ) )
|
|
{
|
|
//printf("\r\nusLength=%d pcRxString=%s \n", usLength, pcRxString);
|
|
pcRxString = cDynamicPage;
|
|
|
|
/* Write out the HTTP OK header. */
|
|
netconn_write( pxNetCon, webHTTP_OK, ( u16_t ) strlen( webHTTP_OK ), NETCONN_COPY );
|
|
|
|
/* Generate index.html page. */
|
|
GenerateIndexHtmlPage(cDynamicPage, LocalBuf);
|
|
|
|
/* Write out the dynamically generated page. */
|
|
netconn_write( pxNetCon, cDynamicPage, ( u16_t ) strlen( cDynamicPage ), NETCONN_COPY );
|
|
}
|
|
else if(!strncmp( pcRxString, "POST", 4 ) )
|
|
{
|
|
/* Write out the HTTP OK header. */
|
|
netconn_write( pxNetCon, webHTTP_OK, ( u16_t ) strlen( webHTTP_OK ), NETCONN_COPY );
|
|
bChanged = ProcessPostMessage(pxRxBuffer, LocalBuf);
|
|
if(bChanged)
|
|
{
|
|
GenerateWaitHtmlPage(cDynamicPage);
|
|
|
|
/* Write out the generated page. */
|
|
netconn_write( pxNetCon, cDynamicPage, ( u16_t ) strlen( cDynamicPage ), NETCONN_COPY );
|
|
|
|
#if CONFIG_READ_FLASH
|
|
StoreApInfo();
|
|
#endif
|
|
}
|
|
else
|
|
{
|
|
/* Generate index.html page. */
|
|
GenerateIndexHtmlPage(cDynamicPage, LocalBuf);
|
|
|
|
/* Write out the generated page. */
|
|
netconn_write( pxNetCon, cDynamicPage, ( u16_t ) strlen( cDynamicPage ), NETCONN_COPY );
|
|
}
|
|
}
|
|
netbuf_delete( pxRxBuffer );
|
|
}
|
|
netconn_close( pxNetCon );
|
|
|
|
if(bChanged)
|
|
{
|
|
struct netconn *pxNewConnection;
|
|
vTaskDelay(200/portTICK_RATE_MS);
|
|
//printf("\r\n%d:before restart ap\n", xTaskGetTickCount());
|
|
RestartSoftAP();
|
|
//printf("\r\n%d:after restart ap\n", xTaskGetTickCount());
|
|
pxHTTPListener->recv_timeout = 1;
|
|
// Evan mopdified for adapt two version lwip api diff
|
|
port_netconn_accept( pxHTTPListener , pxNewConnection, ret_accept);
|
|
if( pxNewConnection != NULL && ret_accept == ERR_OK)
|
|
{
|
|
//printf("\r\n%d: got a conn\n", xTaskGetTickCount());
|
|
netconn_close( pxNewConnection );
|
|
while( netconn_delete( pxNewConnection ) != ERR_OK )
|
|
{
|
|
vTaskDelay( webSHORT_DELAY );
|
|
}
|
|
}
|
|
//printf("\r\n%d:end\n", xTaskGetTickCount());
|
|
pxHTTPListener->recv_timeout = 0;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/***************************************************************
|
|
** PROSCEND implement
|
|
***************************************************************/
|
|
|
|
|
|
#define HTTP_OK_JSON "HTTP/1.0 200 OK\r\nContent-type: application/json\r\n\r\n"
|
|
#define STRNCMP(a,b,c) (strncmp(a,b,c) == 0)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
cJSON_Hooks memoryHook;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void rgb_mode_handle_off() {
|
|
|
|
Ai_WS2811_setColor(0, 0, 0);
|
|
sendLEDs();
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void rgb_mode_handle_on(int r, int g, int b) {
|
|
|
|
Ai_WS2811_setColor(r, g, b);
|
|
sendLEDs();
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void _handle_post_rgb_json(char *j) {
|
|
|
|
extern u16 Blink_ms;
|
|
extern u8 Config_r, Config_g, Config_b;
|
|
extern u8 IsBlink;
|
|
extern u8 IsMeteor;
|
|
|
|
cJSON *obj = cJSON_Parse(j);
|
|
if (obj) {
|
|
cJSON *R = cJSON_GetObjectItem(obj, "R");
|
|
cJSON *G = cJSON_GetObjectItem(obj, "G");
|
|
cJSON *B = cJSON_GetObjectItem(obj, "B");
|
|
|
|
cJSON *Mode = cJSON_GetObjectItem(obj, "Mode");
|
|
cJSON *Speed = cJSON_GetObjectItem(obj, "Speed");
|
|
|
|
printf("R: %d\n", R->valueint);
|
|
printf("G: %d\n", G->valueint);
|
|
printf("B: %d\n", B->valueint);
|
|
|
|
printf("Mode: %s\n", Mode->valuestring);
|
|
printf("Speed: %d\n", Speed->valueint);
|
|
|
|
Config_r = R->valueint;
|
|
Config_g = G->valueint;
|
|
Config_b = B->valueint;
|
|
|
|
if (Speed->valueint < 10) {
|
|
Blink_ms = 10;
|
|
} else {
|
|
Blink_ms = Speed->valueint;
|
|
}
|
|
|
|
if (STRCMP(Mode->valuestring, "OFF")) {
|
|
printf("rgb_mode_handle_off\n");
|
|
rgb_mode_handle_off();
|
|
}
|
|
|
|
if (STRCMP(Mode->valuestring, "ON")) {
|
|
printf("rgb_mode_handle_on\n");
|
|
rgb_mode_handle_on(R->valueint, G->valueint, B->valueint);
|
|
}
|
|
|
|
if (STRCMP(Mode->valuestring, "Blink")) {
|
|
printf("rgb_mode_handle_blink\n");
|
|
IsBlink = 1;
|
|
} else {
|
|
IsBlink = 0;
|
|
}
|
|
|
|
if (STRCMP(Mode->valuestring, "Meteor")) {
|
|
printf("rgb_mode_handle_meteor\n");
|
|
IsMeteor = 1;
|
|
} else {
|
|
IsMeteor = 0;
|
|
}
|
|
|
|
|
|
|
|
// wait for implementing
|
|
|
|
|
|
|
|
cJSON_Delete(obj);
|
|
}
|
|
}
|
|
|
|
|
|
|
|
void _handle_post_rgb(struct netbuf *netbuf, char *localbuf) {
|
|
struct pbuf *p;
|
|
portCHAR *pcRxString, *ptr;
|
|
unsigned portSHORT usLength;
|
|
u8_t bChanged = 0;
|
|
rtw_security_t secType;
|
|
u8_t channel;
|
|
u8_t len = 0;
|
|
|
|
pcRxString = localbuf;
|
|
p = netbuf->p;
|
|
usLength = p->tot_len;
|
|
|
|
while (p) {
|
|
memcpy(pcRxString, p->payload, p->len);
|
|
pcRxString += p->len;
|
|
p = p->next;
|
|
}
|
|
pcRxString = localbuf;
|
|
pcRxString[usLength] = '\0';
|
|
|
|
ptr = (char*)strstr(pcRxString, "\r\n\r\n");
|
|
if (ptr) {
|
|
ptr += 4;
|
|
_handle_post_rgb_json(ptr);
|
|
}
|
|
|
|
}
|
|
|
|
|
|
/*
|
|
** set the configuration about the smart lighting
|
|
** POST /rgb/ HTTP/1.1
|
|
**
|
|
** {
|
|
"R" : 0,
|
|
"G" : 255,
|
|
"B" : 27,
|
|
"Speed" : 50,
|
|
"Mode" : "ON"
|
|
}
|
|
**
|
|
** HTTP/1.1 200 OK
|
|
**
|
|
**
|
|
*/
|
|
static void _handle_post(struct netconn *netconn, const char *data, struct netbuf *netbuf) {
|
|
|
|
static char buf[LOCAL_BUF_SIZE];
|
|
|
|
netconn_write(netconn, HTTP_OK_JSON, strlen(HTTP_OK_JSON), NETCONN_COPY);
|
|
if (strstr(data, "/rgb")) {
|
|
printf("POST /rgb\n");
|
|
_handle_post_rgb(netbuf, buf);
|
|
} else {
|
|
printf("POST Unknown\n");
|
|
printf("pcRxString: %s\n", data);
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void restful_api_handler(struct netconn *netconn) {
|
|
struct netbuf *netbuf;
|
|
char *data;
|
|
u16_t len;
|
|
int ret = ERR_OK;
|
|
|
|
port_netconn_recv(netconn, netbuf, ret);
|
|
|
|
if (netbuf != NULL && ret == ERR_OK) {
|
|
netbuf_data(netbuf, (void *)&data, &len);
|
|
if (STRNCMP(data, "POST", 4)) _handle_post(netconn, data, netbuf);
|
|
netbuf_delete(netbuf);
|
|
}
|
|
|
|
netconn_close(netconn);
|
|
}
|
|
|
|
|
|
|
|
static void _cjson_init(void) {
|
|
memoryHook.malloc_fn = malloc;
|
|
memoryHook.free_fn = free;
|
|
cJSON_InitHooks(&memoryHook);
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/*------------------------------------------------------------*/
|
|
xTaskHandle webs_task = NULL;
|
|
xSemaphoreHandle webs_sema = NULL;
|
|
u8_t webs_terminate = 0;
|
|
void vBasicWEBServer( void *pvParameters )
|
|
{
|
|
struct netconn *pxNewConnection;
|
|
//struct ip_addr xIpAddr, xNetMast, xGateway;
|
|
extern err_t ethernetif_init( struct netif *netif );
|
|
int ret = ERR_OK;
|
|
/* Parameters are not used - suppress compiler error. */
|
|
( void )pvParameters;
|
|
|
|
/* Create a new tcp connection handle */
|
|
pxHTTPListener = netconn_new( NETCONN_TCP );
|
|
netconn_bind( pxHTTPListener, NULL, webHTTP_PORT );
|
|
netconn_listen( pxHTTPListener );
|
|
|
|
#if CONFIG_READ_FLASH
|
|
/* Load wifi_config */
|
|
LoadWifiConfig();
|
|
RestartSoftAP();
|
|
#endif
|
|
//printf("\r\n-0\n");
|
|
|
|
|
|
|
|
/* init once */
|
|
_cjson_init();
|
|
|
|
|
|
|
|
/* Loop forever */
|
|
for( ;; )
|
|
{
|
|
if(webs_terminate)
|
|
break;
|
|
|
|
//printf("\r\n%d:-1\n", xTaskGetTickCount());
|
|
/* Wait for connection. */
|
|
// Evan mopdified for adapt two version lwip api diff
|
|
port_netconn_accept( pxHTTPListener , pxNewConnection, ret);
|
|
//printf("\r\n%d:-2\n", xTaskGetTickCount());
|
|
|
|
if( pxNewConnection != NULL && ret == ERR_OK)
|
|
{
|
|
/* Service connection. */
|
|
|
|
#if 0
|
|
vProcessConnection( pxNewConnection );
|
|
#else // RESTful
|
|
restful_api_handler(pxNewConnection);
|
|
#endif
|
|
|
|
while( netconn_delete( pxNewConnection ) != ERR_OK )
|
|
{
|
|
vTaskDelay( webSHORT_DELAY );
|
|
}
|
|
}
|
|
//printf("\r\n%d:-3\n", xTaskGetTickCount());
|
|
}
|
|
//printf("\r\n-4\n");
|
|
if(pxHTTPListener)
|
|
{
|
|
netconn_close(pxHTTPListener);
|
|
netconn_delete(pxHTTPListener);
|
|
pxHTTPListener = NULL;
|
|
}
|
|
|
|
//printf("\r\nExit Web Server Thread!\n");
|
|
xSemaphoreGive(webs_sema);
|
|
}
|
|
|
|
#define STACKSIZE 512
|
|
void start_web_server()
|
|
{
|
|
printf("\r\nWEB:Enter start web server!\n");
|
|
webs_terminate = 0;
|
|
if(webs_task == NULL)
|
|
{
|
|
if(xTaskCreate(vBasicWEBServer, (const char *)"web_server", STACKSIZE, NULL, tskIDLE_PRIORITY + 1, &webs_task) != pdPASS)
|
|
printf("\n\rWEB: Create webserver task failed!\n");
|
|
}
|
|
if(webs_sema == NULL)
|
|
{
|
|
webs_sema = xSemaphoreCreateCounting(0xffffffff, 0); //Set max count 0xffffffff
|
|
}
|
|
//printf("\r\nWEB:Exit start web server!\n");
|
|
}
|
|
|
|
void stop_web_server()
|
|
{
|
|
//printf("\r\nWEB:Enter stop web server!\n");
|
|
webs_terminate = 1;
|
|
if(pxHTTPListener)
|
|
netconn_abort(pxHTTPListener);
|
|
if(webs_sema)
|
|
{
|
|
if(xSemaphoreTake(webs_sema, 15 * configTICK_RATE_HZ) != pdTRUE)
|
|
{
|
|
if(pxHTTPListener)
|
|
{
|
|
netconn_close(pxHTTPListener);
|
|
netconn_delete(pxHTTPListener);
|
|
pxHTTPListener = NULL;
|
|
}
|
|
printf("\r\nWEB: Take webs sema(%p) failed!!!!!!!!!!!\n", webs_sema);
|
|
}
|
|
vSemaphoreDelete(webs_sema);
|
|
webs_sema = NULL;
|
|
}
|
|
if(webs_task)
|
|
{
|
|
vTaskDelete(webs_task);
|
|
webs_task = NULL;
|
|
}
|
|
printf("\r\nWEB:Exit stop web server!\n");
|
|
}
|