ameba_ws2812b/component/common/utilities/webserver.c
2015-11-17 10:30:14 +08:00

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");
}