/* 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 #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 #if defined(STM32F2XX) #include #elif defined(STM32F4XX) #include #elif defined(STM32f1xx) #include #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 \ "\ \ \ " /* \ \ \ */ #define webHTML_BODY_START \ "\ \ \r\n\r\n
\ \ \ \ " #define webHTML_END \ "\ \ \ \ \ \
\

Realtek SoftAP Configuration

\
\
\ Copyright ?realtek.com
\ \r\n
" \ "\r\n" \ "" #define webWaitHTML_START \ "\ \ " #define webWaitHTML_END \ "\ \

\

SoftAP is now restarting!

\

Please wait a moment and reconnect!

\

"\ "\r\n" \ "" #define onChangeSecType \ "" #define onSubmitForm \ "" /* 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, "" "" "SoftAP SSID:
" "" "" "
" "" "", 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, "" "" "Security Type:
" "" "" "" "" "", 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, "" "" "Password:
" "" "" "
" "" "", 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, "" "" "Channel:
" "" "" "" "" "", 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"); }