moved from github

This commit is contained in:
Bogdan Pilyugin 2022-08-16 15:12:25 +02:00
parent 8a48dfad1a
commit b60d5f57c1
17 changed files with 3013 additions and 92 deletions

18
CMakeLists.txt Normal file
View File

@ -0,0 +1,18 @@
idf_component_register(
SRCS "src/SystemConfiguration.c"
"src/romfs.c"
"src/HTTPServer.c"
"src/HTTPPrintSystem.c"
"src/HTTPPostSystem.c"
"src/Helpers.c"
"src/NetTransport.c"
"src/WiFiTransport.c"
INCLUDE_DIRS "." "include" "src"
REQUIRES nvs_flash
libespfs
esp_http_server
mbedtls
lwip
mqtt
)

194
Kconfig Normal file
View File

@ -0,0 +1,194 @@
menu "WebGuiApp configuration"
config WEBGUIAPP_PROJECT_VER
string "WebGUIApp Project version"
default "0.0.0.0000"
help
Project version code
config WEBGUIAPP_HOSTNAME
string "Default host name"
default "DEVICE_HOSTNAME"
config WEBGUIAPP_USERNAME
string "Default user name"
default "user"
config WEBGUIAPP_USERPASS
string "Default user password"
default "password"
menu "SPI settings"
config WEBGUIAPP_SPI_ENABLE
bool "Enabled SPI interface"
default y
help
Set enabled SPI bus
if WEBGUIAPP_SPI_ENABLE
config SPI_HOST
int "SPI Host Number"
range 0 2
default 1
help
Set the SPI host used.
config SPI_SCLK_GPIO
int "SPI SCLK GPIO number"
range 0 33
default 18
help
Set the GPIO number used by SPI SCLK.
config SPI_MOSI_GPIO
int "SPI MOSI GPIO number"
range 0 33
default 23
help
Set the GPIO number used by SPI MOSI.
config SPI_MISO_GPIO
int "SPI MISO GPIO number"
range 0 33
default 19
help
Set the GPIO number used by SPI MISO.
endif
endmenu
menu "I2C settings"
config WEBGUIAPP_I2C_ENABLE
bool "Enabled I2C interface"
default y
help
Set enabled I2C bus
if WEBGUIAPP_I2C_ENABLE
config I2C_HOST
int "I2C Host Number"
range 0 1
default 0
help
Set the I2C host used.
config I2C_SCL_GPIO
int "I2C SCL GPIO number"
range 0 34
default 22
config I2C_SDA_GPIO
int "I2C SDA GPIO number"
range 0 34
default 21
config I2C_CLOCK
int "I2C clock"
range 400000 1000000
default 400000
endif
endmenu
menu "WiFi settings"
config WEBGUIAPP_WIFI_ENABLE
bool "Enabled WIFI interface"
default y
help
Set enabled WiFi
if WEBGUIAPP_WIFI_ENABLE
config WEBGUIAPP_WIFI_ON
bool "Default WiFi switched on"
default y
config WEBGUIAPP_WIFI_DHCP_ON
bool "Default WiFi DHCP switched on"
default y
config WEBGUIAPP_WIFI_SSID_AP
string "WiFi SSID AP"
default "YourAP"
help
SSID (network name) in AP mode.
config WEBGUIAPP_WIFI_KEY_AP
string "WiFi key AP"
default "123456789"
help
WiFi key (WPA or WPA2) in AP mode.
config WEBGUIAPP_WIFI_SSID_STA
string "WiFi SSID STA"
default "YourSTA"
help
SSID (network name) in client mode.
config WEBGUIAPP_WIFI_KEY_STA
string "WiFi key STA"
default "123456789"
help
WiFi key (WPA or WPA2) in client mode.
config WEBGUIAPP_WIFI_IP_AP
string "Default IP address in AP mode"
default "192.168.1.150"
config WEBGUIAPP_WIFI_IP_STA
string "Default IP address in STA mode"
default "192.168.1.150"
config WEBGUIAPP_WIFI_MASK_STA
string "Default network mask in STA mode"
default "255.255.255.0"
config WEBGUIAPP_WIFI_GATEWAY_STA
string "Default gateway in STA mode"
default "192.168.1.150"
endif
endmenu
menu "Ethernet settings"
config WEBGUIAPP_ETHERNET_ENABLE
bool "Enabled ETHERNET interface"
default n
help
Set enabled Ethernet adapter
if WEBGUIAPP_ETHERNET_ENABLE
config WEBGUIAPP_ETHERNET_ON
bool "Default Ethernet switched on"
default y
endif
endmenu
menu "GPRS settings"
config WEBGUIAPP_GPRS_ENABLE
bool "Enabled GPRS PPP interface"
default n
help
Set enabled GPRS adapter
if WEBGUIAPP_GPRS_ENABLE
config WEBGUIAPP_GPRS_ON
bool "Default GPRS switched on"
default n
endif
endmenu
endmenu

View File

@ -1,92 +0,0 @@
# WebGUIAppComponent
## Getting started
To make it easy for you to get started with GitLab, here's a list of recommended next steps.
Already a pro? Just edit this README.md and make it your own. Want to make it easy? [Use the template at the bottom](#editing-this-readme)!
## Add your files
- [ ] [Create](https://docs.gitlab.com/ee/user/project/repository/web_editor.html#create-a-file) or [upload](https://docs.gitlab.com/ee/user/project/repository/web_editor.html#upload-a-file) files
- [ ] [Add files using the command line](https://docs.gitlab.com/ee/gitlab-basics/add-file.html#add-a-file-using-the-command-line) or push an existing Git repository with the following command:
```
cd existing_repo
git remote add origin https://gitlab.com/userbogd/WebGUIAppComponent.git
git branch -M main
git push -uf origin main
```
## Integrate with your tools
- [ ] [Set up project integrations](https://gitlab.com/userbogd/WebGUIAppComponent/-/settings/integrations)
## Collaborate with your team
- [ ] [Invite team members and collaborators](https://docs.gitlab.com/ee/user/project/members/)
- [ ] [Create a new merge request](https://docs.gitlab.com/ee/user/project/merge_requests/creating_merge_requests.html)
- [ ] [Automatically close issues from merge requests](https://docs.gitlab.com/ee/user/project/issues/managing_issues.html#closing-issues-automatically)
- [ ] [Enable merge request approvals](https://docs.gitlab.com/ee/user/project/merge_requests/approvals/)
- [ ] [Automatically merge when pipeline succeeds](https://docs.gitlab.com/ee/user/project/merge_requests/merge_when_pipeline_succeeds.html)
## Test and Deploy
Use the built-in continuous integration in GitLab.
- [ ] [Get started with GitLab CI/CD](https://docs.gitlab.com/ee/ci/quick_start/index.html)
- [ ] [Analyze your code for known vulnerabilities with Static Application Security Testing(SAST)](https://docs.gitlab.com/ee/user/application_security/sast/)
- [ ] [Deploy to Kubernetes, Amazon EC2, or Amazon ECS using Auto Deploy](https://docs.gitlab.com/ee/topics/autodevops/requirements.html)
- [ ] [Use pull-based deployments for improved Kubernetes management](https://docs.gitlab.com/ee/user/clusters/agent/)
- [ ] [Set up protected environments](https://docs.gitlab.com/ee/ci/environments/protected_environments.html)
***
# Editing this README
When you're ready to make this README your own, just edit this file and use the handy template below (or feel free to structure it however you want - this is just a starting point!). Thank you to [makeareadme.com](https://www.makeareadme.com/) for this template.
## Suggestions for a good README
Every project is different, so consider which of these sections apply to yours. The sections used in the template are suggestions for most open source projects. Also keep in mind that while a README can be too long and detailed, too long is better than too short. If you think your README is too long, consider utilizing another form of documentation rather than cutting out information.
## Name
Choose a self-explaining name for your project.
## Description
Let people know what your project can do specifically. Provide context and add a link to any reference visitors might be unfamiliar with. A list of Features or a Background subsection can also be added here. If there are alternatives to your project, this is a good place to list differentiating factors.
## Badges
On some READMEs, you may see small images that convey metadata, such as whether or not all the tests are passing for the project. You can use Shields to add some to your README. Many services also have instructions for adding a badge.
## Visuals
Depending on what you are making, it can be a good idea to include screenshots or even a video (you'll frequently see GIFs rather than actual videos). Tools like ttygif can help, but check out Asciinema for a more sophisticated method.
## Installation
Within a particular ecosystem, there may be a common way of installing things, such as using Yarn, NuGet, or Homebrew. However, consider the possibility that whoever is reading your README is a novice and would like more guidance. Listing specific steps helps remove ambiguity and gets people to using your project as quickly as possible. If it only runs in a specific context like a particular programming language version or operating system or has dependencies that have to be installed manually, also add a Requirements subsection.
## Usage
Use examples liberally, and show the expected output if you can. It's helpful to have inline the smallest example of usage that you can demonstrate, while providing links to more sophisticated examples if they are too long to reasonably include in the README.
## Support
Tell people where they can go to for help. It can be any combination of an issue tracker, a chat room, an email address, etc.
## Roadmap
If you have ideas for releases in the future, it is a good idea to list them in the README.
## Contributing
State if you are open to contributions and what your requirements are for accepting them.
For people who want to make changes to your project, it's helpful to have some documentation on how to get started. Perhaps there is a script that they should run or some environment variables that they need to set. Make these steps explicit. These instructions could also be useful to your future self.
You can also document commands to lint the code or run tests. These steps help to ensure high code quality and reduce the likelihood that the changes inadvertently break something. Having instructions for running tests is especially helpful if it requires external setup, such as starting a Selenium server for testing in a browser.
## Authors and acknowledgment
Show your appreciation to those who have contributed to the project.
## License
For open source projects, say how it is licensed.
## Project status
If you have run out of energy or time for your project, put a note at the top of the README saying that development has slowed down or stopped completely. Someone may choose to fork your project or volunteer to step in as a maintainer or owner, allowing your project to keep going. You can also make an explicit request for maintainers.

58
include/HTTPServer.h Normal file
View File

@ -0,0 +1,58 @@
/*! Copyright 2022 Bogdan Pilyugin
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* \file HTTPServer.h
* \version 1.0
* \date 2022-08-14
* \author Bogdan Pilyugin
* \brief
* \details
* \copyright Apache License, Version 2.0
*/
#ifndef COMPONENTS_WEB_GUI_APPLICATION_INCLUDE_HTTPSERVER_H_
#define COMPONENTS_WEB_GUI_APPLICATION_INCLUDE_HTTPSERVER_H_
#include "esp_err.h"
#include "esp_log.h"
#include "esp_vfs.h"
#include <esp_http_server.h>
#include <sys/param.h>
#include <sys/unistd.h>
#include <sys/stat.h>
#include "Helpers.h"
#include "SystemConfiguration.h"
#include "romfs.h"
#include "NetTransport.h"
#include <esp_event.h>
#include "esp_netif.h"
#include "esp_eth.h"
#include "mbedtls/base64.h"
typedef enum
{
HTTP_IO_DONE = 0u, // Finished with procedure
HTTP_IO_NEED_DATA, // More data needed to continue, call again later
HTTP_IO_WAITING, // Waiting for asynchronous process to complete, call again later
HTTP_IO_REDIRECT
} HTTP_IO_RESULT;
esp_err_t start_file_server(void);
HTTP_IO_RESULT HTTPPostApp(httpd_req_t *req, const char *filename, char *PostData);
int HTTPPrint(httpd_req_t *req, char* buf, char* var);
#endif /* COMPONENTS_WEB_GUI_APPLICATION_INCLUDE_HTTPSERVER_H_ */

36
include/Helpers.h Normal file
View File

@ -0,0 +1,36 @@
/* Copyright 2022 Bogdan Pilyugin
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* File name: Helpers.h
* Project: ChargePointMainboard
* Created on: 2022-07-21
* Author: Bogdan Pilyugin
* Description:
*/
#ifndef MAIN_INCLUDE_HELPERS_H_
#define MAIN_INCLUDE_HELPERS_H_
#include "common_types.h"
uint32_t crc32(uint32_t crc, uint8_t const *buf, uint32_t len);
void GetChipId(uint8_t *i);
uint32_t swap(uint32_t in);
void BytesToStr(unsigned char *StrIn, unsigned char *StrOut, uint8_t N);
bool StrToBytes(unsigned char *StrIn, unsigned char *StrOut);
bool StrToBytesLen(unsigned char *StrIn, unsigned char *StrOut, uint16_t InputSymbols);
void bin_to_hex_str(const uint8_t *buf, int len, char *hex);
void UnencodeURL(char* URL);
#endif /* MAIN_INCLUDE_HELPERS_H_ */

109
include/NetTransport.h Normal file
View File

@ -0,0 +1,109 @@
/* Copyright 2022 Bogdan Pilyugin
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* File name: NetTransport.h
* Project: ChargePointMainboard
* Created on: 2022-07-21
* Author: Bogdan Pilyugin
* Description:
*/
#ifndef MAIN_INCLUDE_NETTRANSPORT_H_
#define MAIN_INCLUDE_NETTRANSPORT_H_
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "freertos/semphr.h"
#include "freertos/queue.h"
#include "freertos/event_groups.h"
#include "mqtt_client.h"
#include "esp_netif.h"
//#include "esp_modem_api.h"
#include "esp_log.h"
typedef struct
{
char imei[32];
char imsi[32];
char oper[32];
char model[32];
} MODEM_INFO;
#define ETH_PRIO 100
#define STA_PRIO 50
#define PPP_PRIO 30
#define AP_PRIO 10
//#define DEFAULT_FALLBACK_DNS "8.8.8.8"
QueueHandle_t MQTT1MessagesQueueHandle;
QueueHandle_t MQTT2MessagesQueueHandle;
QueueHandle_t UARTMessagesQueueHandle;
EventGroupHandle_t transport_event_group;
void StartTimeGet(void);
void WiFiAPStart(void);
void WiFiSTAStart(void);
void EthStart(void);
void WiFiTransportTask(void *prm);
void LoRaWANInitJoinTask(void *pvParameter);
void LoRaWANStop(void);
void LoRaWANStart(void);
void PPPModemColdStart(void);
void PPPModemSoftRestart(void);
void PPPModemStart(void);
void MQTTRun(void);
MODEM_INFO* GetPPPModemInfo(void);
esp_mqtt_client_handle_t* GetMQTTHandle(void);
void MQTTStart(void);
void MQTTStop(void);
void MQTTReconnect(void);
esp_netif_t* GetPPPNetifAdapter(void);
esp_netif_t* GetSTANetifAdapter(void);
esp_netif_t* GetAPNetifAdapter(void);
esp_netif_t* GetETHNetifAdapter(void);
bool isWIFIConnected(void);
bool isETHConnected(void);
bool isPPPConnected(void);
bool isLORAConnected(void);
bool GetMQTT1Connected(void);
bool GetMQTT2Connected(void);
void SetDefaultNetIF(esp_netif_t *IF);
void NextDefaultNetIF(void);
void PrintDefaultNetIF(void);
void GetDefaultNetIFName(char *name);
void InitRS485(void);
void RS485Task(void *pvParameter);
void PrintNetifs(void);
void GotEthIF(void);
#endif /* MAIN_INCLUDE_NETTRANSPORT_H_ */

View File

@ -0,0 +1,247 @@
/*! Copyright 2022 Bogdan Pilyugin
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* \file SystemConfiguration.h
* \version 1.0
* \date 2022-08-13
* \author Bogdan Pilyugin
* \brief
* \details
* \copyright Apache License, Version 2.0
*/
#ifndef COMPONENTS_WEB_GUI_APPLICATION_INCLUDE_SYSTEMCONFIGURATION_H_
#define COMPONENTS_WEB_GUI_APPLICATION_INCLUDE_SYSTEMCONFIGURATION_H_
#include <stdint.h>
#include <stdbool.h>
#include "esp_netif.h"
#include <sdkconfig.h>
#define MQTT_CLIENTS_NUM 2
#define DEFAULT_HOST_NAME "DEVICE_HOSTNAME" ///<Default host name of device
#define SYSTEM_DEFAULT_USERNAME "user"
#define SYSTEM_DEFAULT_PASSWORD "password"
#define SYSTEM_DEFAULT_OTAURL "https://iotronic.cloud/firmware/HB75ControllerFirmware.bin"
#define DEFAULT_SNTP_SERVERNAME "ntp5.stratum2.ru"
#define DEFAULT_SNTP_TIMEZONE 2
#define DEFAULT_SNTP_ETH_IS_ENABLED false
#define DEFAULT_SNTP_WIFI_IS_ENABLED false
#define DEFAULT_SNTP_GLOBAL_ENABLED true
#define DEFAULT_MQTT_SERVERNAME "iotronic.cloud"
#define DEFAULT_MQTT_SERVERPORT 1883
#define DEFAULT_MQTT_CLIENTID "HB75_DISP1"
#define DEFAULT_MQTT_CLIENTID2 "HB75_DISP2"
#define DEFAULT_MQTT_USERNAME "hb75_username"
#define DEFAULT_MQTT_USERPASS "hb75_pass"
#define DEFAULT_MQTT_ROOTTOPIC "HB75_CONTROLLER"
#define DEFAULT_MQTT_GLOBAL_ENABLED true
//WIFI interface related constatnts
#define DEFAULT_WIFI_SSID_INF_NAME "wifiapname"
#define DEFAULT_WIFI_SSID_INF_KEY "wifikey"
#define DEFAULT_WIFI_SSID_AP_NAME "HB75"
#define DEFAULT_WIFI_SSID_AP_KEY "123456789"
#define DEFAULT_WIFI_IP_ADDR_INF "192.168.150.1"
#define DEFAULT_WIFI_MASK "255.255.255.0"
#define DEFAULT_WIFI_GATE "192.168.150.1"
#define DEFAULT_WIFI_IP_ADDR_AP "192.168.150.1"
#define DEFAULT_WIFI_FLAG_ISAP true
#define DEFAULT_WIFI_FLAG_DHCP_ENABLED true
#define DEFAULT_WIFI_FLAG_ISWIFI_ENABLED true
#define DEFAULT_ETH_IP_ADDR "192.168.150.2"
#define DEFAULT_ETH_MASK "255.255.255.0"
#define DEFAULT_ETH_GATE "192.168.150.1"
#define DEFAULT_ETH_FLAG_DHCP_ENABLED true
#define DEFAULT_ETH_FLAG_ISETH_ENABLED true
#define DEFAULT_DNS1 "8.8.8.8"
#define DEFAULT_DNS2 "4.4.8.8"
#define DEFAULT_DNS3 "1.1.1.1"
/*GSM DEFAULT SETTINGS*/
#define DEFAULT_GSM_GLOBAL_ENABLED true
//#define LOCK_RELAY_ON
// Application-dependent structure used to contain address information
/**
* @struct APP_CONFIG
* @brief The main configuration structure
* @details This structure saving to EEPROM and loading from EEPROM\n
* on device boot. On load the checksumm is calculate and compare to \n
* saved one. If find difference (due to eeprom memory distortions),\n
* the default values will be loaded.
*/
typedef struct
{
char NetBIOSName[32]; ///< NetBIOS name
char SysName[32]; ///< User Name
char SysPass[32]; ///< User Password
char OTAURL[64]; ///< OTA URL
uint8_t imei[4];
struct
{
char bIsOTAEnabled :1;
char bIsLedsEnabled :1; ///< Indication LEDs enable
char bIsLoRaConfirm :1; ///< Enable send back confirmation in LoRa channel
char bIsTCPConfirm :1; ///< Enable send back confirmation in TCP channel
char bit4 :1;
char bit5 :1;
char bit6 :1;
char bit7 :1;
} Flags1; // Flag structure
struct
{
int TimeZone;
uint8_t SntpServerAdr[33];
struct
{
char bIsWifiEnabled :1;
char bIsEthEnabled :1;
char b3 :1;
char b4 :1;
char b5 :1;
char b6 :1;
char b7 :1;
char bIsGlobalEnabled :1;
} Flags1;
} sntpClient;
struct
{
char ServerAddr[32];
uint16_t ServerPort;
char ClientID[32];
char RootTopic[32];
char UserName[32];
char UserPass[32];
struct
{
char b0 :1;
char b1 :1;
char b2 :1;
char b3 :1;
char b4 :1;
char b5 :1;
char b6 :1;
char bIsGlobalEnabled :1;
} Flags1;
} mqttStation[MQTT_CLIENTS_NUM];
struct
{
ip4_addr_t IPAddr; // IP address
ip4_addr_t Mask; // network mask
ip4_addr_t Gateway; // gateway
ip4_addr_t DNSAddr1; //
ip4_addr_t DNSAddr2; //
ip4_addr_t DNSAddr3; //
uint8_t MACAddr[6]; // MAC address
struct
{
char bIsDHCPEnabled :1;
char b1 :1;
char b2 :1;
char b3 :1;
char b4 :1;
char b5 :1;
char b6 :1;
char bIsETHEnabled :1;
} Flags1; // Flag structure
} ethSettings;
#ifdef CONFIG_WEBGUIAPP_WIFI_ENABLE
struct
{
ip4_addr_t InfIPAddr; // IP address in infrastructure(INF) mode
ip4_addr_t InfMask; // network mask in INF mode
ip4_addr_t InfGateway; // gateway IP in INF mode
ip4_addr_t ApIPAddr; // IP address in Access point(AP) mode
ip4_addr_t DNSAddr1; // DNS in station mode
ip4_addr_t DNSAddr2; // DNS in station mode
ip4_addr_t DNSAddr3; // DNS in station mode
char InfSSID[32]; // Wireless SSID in INF mode
char InfSecurityKey[32]; // Network key in INF mode
char ApSSID[32]; // Wireless SSID in AP mode
char ApSecurityKey[32]; // Wireless key in AP mode
char MACAddrInf[6]; // MAC address
char MACAddrAp[6]; // MAC address
struct
{
char bIsDHCPEnabled :1;
char bIsAP :1;
char b2 :1;
char b3 :1;
char b4 :1;
char b5 :1;
char b6 :1;
char bIsWiFiEnabled :1;
} Flags1; // Flag structure
} wifiSettings;
#endif
struct
{
ip4_addr_t IPAddr; // IP address
ip4_addr_t Mask; // network mask
ip4_addr_t Gateway; // gateway
ip4_addr_t DNSAddr1; //
ip4_addr_t DNSAddr2; //
ip4_addr_t DNSAddr3; //
uint8_t MACAddr[6]; // MAC address
struct
{
char b0 :1;
char b1 :1;
char b2 :1;
char b3 :1;
char b4 :1;
char b5 :1;
char b6 :1;
char bIsGSMEnabled :1;
} Flags1; // Flag structure
} gsmSettings;
} SYS_CONFIG;
esp_err_t ReadNVSSysConfig(SYS_CONFIG *SysConf);
esp_err_t WriteNVSSysConfig(SYS_CONFIG *SysConf);
esp_err_t InitSysConfig(void);
esp_err_t ResetInitSysConfig(void);
SYS_CONFIG* GetSysConf(void);
#endif /* COMPONENTS_WEB_GUI_APPLICATION_INCLUDE_SYSTEMCONFIGURATION_H_ */

142
include/common_types.h Normal file
View File

@ -0,0 +1,142 @@
/* Copyright 2022 Bogdan Pilyugin
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* File name: common_types.h
* Project: ChargePointMainboard
* Created on: 2022-07-21
* Author: Bogdan Pilyugin
* Description:
*/
#ifndef MAIN_INCLUDE_COMMON_TYPES_H_
#define MAIN_INCLUDE_COMMON_TYPES_H_
#include <stdint.h>
#include <stdbool.h>
#include <string.h>
typedef uint8_t BYTE;
typedef uint16_t WORD;
typedef uint32_t DWORD;
typedef unsigned long LONG;
typedef union
{
uint8_t Val;
struct __attribute__((packed))
{
uint8_t b0 :1;
uint8_t b1 :1;
uint8_t b2 :1;
uint8_t b3 :1;
uint8_t b4 :1;
uint8_t b5 :1;
uint8_t b6 :1;
uint8_t b7 :1;
} bits;
} TCPIP_UINT8_VAL, TCPIP_UINT8_BITS, UINT8_VAL;
typedef union
{
uint16_t Val;
uint8_t v[2];
struct __attribute__((packed))
{
uint8_t LB;
uint8_t HB;
} byte;
struct __attribute__((packed))
{
uint8_t b0 :1;
uint8_t b1 :1;
uint8_t b2 :1;
uint8_t b3 :1;
uint8_t b4 :1;
uint8_t b5 :1;
uint8_t b6 :1;
uint8_t b7 :1;
uint8_t b8 :1;
uint8_t b9 :1;
uint8_t b10 :1;
uint8_t b11 :1;
uint8_t b12 :1;
uint8_t b13 :1;
uint8_t b14 :1;
uint8_t b15 :1;
} bits;
} TCPIP_UINT16_VAL, TCPIP_UINT16_BITS, UINT16_VAL;
typedef union
{
uint32_t Val;
uint16_t w[2] __attribute__((packed));
uint8_t v[4];
struct __attribute__((packed))
{
uint16_t LW;
uint16_t HW;
} word;
struct __attribute__((packed))
{
uint8_t LB;
uint8_t HB;
uint8_t UB;
uint8_t MB;
} byte;
struct __attribute__((packed))
{
TCPIP_UINT16_VAL low;
TCPIP_UINT16_VAL high;
} wordUnion;
struct __attribute__((packed))
{
uint8_t b0 :1;
uint8_t b1 :1;
uint8_t b2 :1;
uint8_t b3 :1;
uint8_t b4 :1;
uint8_t b5 :1;
uint8_t b6 :1;
uint8_t b7 :1;
uint8_t b8 :1;
uint8_t b9 :1;
uint8_t b10 :1;
uint8_t b11 :1;
uint8_t b12 :1;
uint8_t b13 :1;
uint8_t b14 :1;
uint8_t b15 :1;
uint8_t b16 :1;
uint8_t b17 :1;
uint8_t b18 :1;
uint8_t b19 :1;
uint8_t b20 :1;
uint8_t b21 :1;
uint8_t b22 :1;
uint8_t b23 :1;
uint8_t b24 :1;
uint8_t b25 :1;
uint8_t b26 :1;
uint8_t b27 :1;
uint8_t b28 :1;
uint8_t b29 :1;
uint8_t b30 :1;
uint8_t b31 :1;
} bits;
} TCPIP_UINT32_VAL, UINT32_VAL;
#endif /* MAIN_INCLUDE_COMMON_TYPES_H_ */

34
include/romfs.h Normal file
View File

@ -0,0 +1,34 @@
/*! Copyright 2022 Bogdan Pilyugin
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* \file romfs.h
* \version 1.0
* \date 2022-08-14
* \author Bogdan Pilyugin
* \brief
* \details
* \copyright Apache License, Version 2.0
*/
#ifndef COMPONENTS_WEB_GUI_APPLICATION_INCLUDE_ROMFS_H_
#define COMPONENTS_WEB_GUI_APPLICATION_INCLUDE_ROMFS_H_
#include "libespfs/espfs.h"
#include "libespfs/espfs_format.h"
#include "libespfs/vfs.h"
espfs_fs_t *fs;
void init_rom_fs(const char *root);
#endif /* COMPONENTS_WEB_GUI_APPLICATION_INCLUDE_ROMFS_H_ */

579
src/HTTPPostSystem.c Normal file
View File

@ -0,0 +1,579 @@
/*! Copyright 2022 Bogdan Pilyugin
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* \file HTTPPostSystem.c
* \version 1.0
* \date 2022-08-14
* \author Bogdan Pilyugin
* \brief
* \details
* \copyright Apache License, Version 2.0
*/
#include "HTTPServer.h"
static const char *TAG = "HTTPServerPost";
#define FILE_PATH_MAX (ESP_VFS_PATH_MAX + CONFIG_SPIFFS_OBJ_NAME_LEN)
const char pg_11[] = "index.html";
const char pg_20[] = "index20.html";
const char pg_21[] = "index21.html";
const char pg_22[] = "index22.html";
const char pg_23[] = "index23.html";
const char pg_24[] = "index24.html";
const char pg_30[] = "index30.html";
const char pg_31[] = "index31.html";
const char pg_32[] = "index32.html";
const char pg_33[] = "index33.html";
const char pg_34[] = "index34.html";
const char pg_40[] = "index40.html";
const char pg_42[] = "index42.html";
const char pg_43[] = "index43.html";
const char pg_44[] = "index44.html";
const char pg_reboot[] = "reboot.html";
const char pg_db[] = "dbg.json";
const char pg_mm[] = "mem.json";
static HTTP_IO_RESULT AfterPostHandler(httpd_req_t *req, const char *filename, char *PostData);
static HTTP_IO_RESULT HTTPPostIndex(httpd_req_t *req, char *PostData);
static HTTP_IO_RESULT HTTPPostIndex21(httpd_req_t *req, char *PostData);
static HTTP_IO_RESULT HTTPPostIndex20(httpd_req_t *req, char *PostData);
static HTTP_IO_RESULT HTTPPostIndex22(httpd_req_t *req, char *PostData);
static HTTP_IO_RESULT HTTPPostIndex23(httpd_req_t *req, char *PostData);
static HTTP_IO_RESULT HTTPPostIndex24(httpd_req_t *req, char *PostData);
static HTTP_IO_RESULT HTTPPostIndex30(httpd_req_t *req, char *PostData);
static HTTP_IO_RESULT HTTPPostIndex31(httpd_req_t *req, char *PostData);
static HTTP_IO_RESULT HTTPPostIndex32(httpd_req_t *req, char *PostData);
static HTTP_IO_RESULT HTTPPostIndex33(httpd_req_t *req, char *PostData);
static HTTP_IO_RESULT HTTPPostIndex34(httpd_req_t *req, char *PostData);
static HTTP_IO_RESULT HTTPPostIndex40(httpd_req_t *req, char *PostData);
static HTTP_IO_RESULT HTTPPostIndex42(httpd_req_t *req, char *PostData);
static HTTP_IO_RESULT HTTPPostIndex43(httpd_req_t *req, char *PostData);
static HTTP_IO_RESULT HTTPPostIndex44(httpd_req_t *req, char *PostData);
static HTTP_IO_RESULT HTTPPostReboot(httpd_req_t *req, char *PostData);
static HTTP_IO_RESULT HTTPPostDebug(httpd_req_t *req, char *PostData);
static HTTP_IO_RESULT HTTPPostMemJson(httpd_req_t *req, char *PostData);
HTTP_IO_RESULT HTTPPostApp(httpd_req_t *req, const char *filename, char *PostData)
{
const char *pt = filename + 1;
#if HTTP_SERVER_DEBUG_LEVEL > 0
ESP_LOGI(TAG, "URI for POST processing:%s", req->uri);
ESP_LOGI(TAG, "Filename:%s", pt);
ESP_LOGI(TAG, "DATA for POST processing:%s", PostData);
#endif
HTTP_IO_RESULT res = AfterPostHandler(req, pt, PostData);
switch (res)
{
case HTTP_IO_DONE:
break;
case HTTP_IO_WAITING:
break;
case HTTP_IO_NEED_DATA:
break;
case HTTP_IO_REDIRECT:
strcpy(filename, PostData);
break;
}
return res;
}
static HTTP_IO_RESULT AfterPostHandler(httpd_req_t *req, const char *filename, char *PostData)
{
if (!memcmp(filename, pg_11, sizeof(pg_11)))
return HTTPPostIndex(req, PostData);
if (!memcmp(filename, pg_20, sizeof(pg_20)))
return HTTPPostIndex20(req, PostData);
if (!memcmp(filename, pg_21, sizeof(pg_21)))
return HTTPPostIndex21(req, PostData);
if (!memcmp(filename, pg_22, sizeof(pg_22)))
return HTTPPostIndex22(req, PostData);
if (!memcmp(filename, pg_23, sizeof(pg_23)))
return HTTPPostIndex23(req, PostData);
if (!memcmp(filename, pg_24, sizeof(pg_24)))
return HTTPPostIndex24(req, PostData);
if (!memcmp(filename, pg_30, sizeof(pg_30)))
return HTTPPostIndex30(req, PostData);
if (!memcmp(filename, pg_31, sizeof(pg_31)))
return HTTPPostIndex31(req, PostData);
if (!memcmp(filename, pg_32, sizeof(pg_32)))
return HTTPPostIndex32(req, PostData);
if (!memcmp(filename, pg_33, sizeof(pg_33)))
return HTTPPostIndex33(req, PostData);
if (!memcmp(filename, pg_34, sizeof(pg_34)))
return HTTPPostIndex34(req, PostData);
if (!memcmp(filename, pg_40, sizeof(pg_40)))
return HTTPPostIndex40(req, PostData);
if (!memcmp(filename, pg_42, sizeof(pg_42)))
return HTTPPostIndex42(req, PostData);
if (!memcmp(filename, pg_43, sizeof(pg_43)))
return HTTPPostIndex43(req, PostData);
if (!memcmp(filename, pg_44, sizeof(pg_44)))
return HTTPPostIndex44(req, PostData);
if (!memcmp(filename, pg_reboot, sizeof(pg_reboot)))
return HTTPPostReboot(req, PostData);
if (!memcmp(filename, pg_db, sizeof(pg_db)))
return HTTPPostDebug(req, PostData);
if (!memcmp(filename, pg_mm, sizeof(pg_mm)))
return HTTPPostMemJson(req, PostData);
return HTTP_IO_DONE;
}
static HTTP_IO_RESULT HTTPPostIndex(httpd_req_t *req, char *PostData)
{
return HTTP_IO_DONE;
}
static HTTP_IO_RESULT HTTPPostIndex20(httpd_req_t *req, char *PostData)
{
char tmp[32];
bool TempIsETHEnabled = false;
bool TempIsDHCPEnabled = false;
if (httpd_query_key_value(PostData, "ethen", tmp, sizeof(tmp)) == ESP_OK)
{
if (!strcmp((const char*) tmp, (const char*) "1"))
TempIsETHEnabled = true;
}
if (httpd_query_key_value(PostData, "dhcp", tmp, sizeof(tmp)) == ESP_OK)
{
if (!strcmp((const char*) tmp, (const char*) "1"))
TempIsDHCPEnabled = true;
}
if (httpd_query_key_value(PostData, "ipa", tmp, 15) == ESP_OK)
esp_netif_str_to_ip4(tmp, (esp_ip4_addr_t*) &GetSysConf()->ethSettings.IPAddr);
if (httpd_query_key_value(PostData, "mas", tmp, 15) == ESP_OK)
esp_netif_str_to_ip4(tmp, (esp_ip4_addr_t*) &GetSysConf()->ethSettings.Mask);
if (httpd_query_key_value(PostData, "gte", tmp, 15) == ESP_OK)
esp_netif_str_to_ip4(tmp, (esp_ip4_addr_t*) &GetSysConf()->ethSettings.Gateway);
if (httpd_query_key_value(PostData, "dns1", tmp, 15) == ESP_OK)
esp_netif_str_to_ip4(tmp, (esp_ip4_addr_t*) &GetSysConf()->ethSettings.DNSAddr1);
if (httpd_query_key_value(PostData, "dns2", tmp, 15) == ESP_OK)
esp_netif_str_to_ip4(tmp, (esp_ip4_addr_t*) &GetSysConf()->ethSettings.DNSAddr2);
if (httpd_query_key_value(PostData, "dns3", tmp, 15) == ESP_OK)
esp_netif_str_to_ip4(tmp, (esp_ip4_addr_t*) &GetSysConf()->ethSettings.DNSAddr3);
if (httpd_query_key_value(PostData, "sav", tmp, 4) == ESP_OK)
{
if (!strcmp(tmp, (const char*) "prs"))
{
GetSysConf()->ethSettings.Flags1.bIsETHEnabled = TempIsETHEnabled;
GetSysConf()->ethSettings.Flags1.bIsDHCPEnabled = TempIsDHCPEnabled;
WriteNVSSysConfig(GetSysConf());
memcpy(PostData, "/reboot.html", sizeof "/reboot.html");
return HTTP_IO_REDIRECT;
}
}
return HTTP_IO_DONE;
}
static HTTP_IO_RESULT HTTPPostIndex21(httpd_req_t *req, char *PostData)
{
#if CONFIG_WEBGUIAPP_WIFI_ENABLE
char tmp[32];
bool TempIsWiFiEnabled = false;
bool TempIsDHCPEnabled = false;
if (httpd_query_key_value(PostData, "wifien", tmp, sizeof(tmp)) == ESP_OK)
{
if (!strcmp((const char*) tmp, (const char*) "1"))
TempIsWiFiEnabled = true;
}
if (httpd_query_key_value(PostData, "netm", tmp, sizeof(tmp)) == ESP_OK)
{
if (!strcmp((const char*) tmp, (const char*) "1"))
GetSysConf()->wifiSettings.Flags1.bIsAP = true;
else if (!strcmp((const char*) tmp, (const char*) "2"))
GetSysConf()->wifiSettings.Flags1.bIsAP = false;
}
/*AP section*/
httpd_query_key_value(PostData, "wfiap", GetSysConf()->wifiSettings.ApSSID,
sizeof(GetSysConf()->wifiSettings.ApSSID));
if (httpd_query_key_value(PostData, "wfpap", tmp, sizeof(tmp)) == ESP_OK)
{
if (strcmp(tmp, (const char*) "********"))
strcpy(GetSysConf()->wifiSettings.ApSecurityKey, tmp);
}
if (httpd_query_key_value(PostData, "ipaap", tmp, sizeof(tmp)) == ESP_OK)
esp_netif_str_to_ip4(tmp, (esp_ip4_addr_t*) &GetSysConf()->wifiSettings.ApIPAddr);
httpd_query_key_value(PostData, "wfi", GetSysConf()->wifiSettings.InfSSID,
sizeof(GetSysConf()->wifiSettings.InfSSID));
if (httpd_query_key_value(PostData, "wfp", tmp, sizeof(tmp)) == ESP_OK)
{
if (strcmp(tmp, (const char*) "********"))
strcpy(GetSysConf()->wifiSettings.InfSecurityKey, tmp);
}
/*STATION section*/
if (httpd_query_key_value(PostData, "dhcp", tmp, sizeof(tmp)) == ESP_OK)
{
if (!strcmp((const char*) tmp, (const char*) "1"))
TempIsDHCPEnabled = true;
}
if (httpd_query_key_value(PostData, "ipa", tmp, 15) == ESP_OK)
esp_netif_str_to_ip4(tmp, (esp_ip4_addr_t*) &GetSysConf()->wifiSettings.InfIPAddr);
if (httpd_query_key_value(PostData, "mas", tmp, 15) == ESP_OK)
esp_netif_str_to_ip4(tmp, (esp_ip4_addr_t*) &GetSysConf()->wifiSettings.InfMask);
if (httpd_query_key_value(PostData, "gte", tmp, 15) == ESP_OK)
esp_netif_str_to_ip4(tmp, (esp_ip4_addr_t*) &GetSysConf()->wifiSettings.InfGateway);
if (httpd_query_key_value(PostData, "dns", tmp, 15) == ESP_OK)
esp_netif_str_to_ip4(tmp, (esp_ip4_addr_t*) &GetSysConf()->wifiSettings.DNSAddr1);
if (httpd_query_key_value(PostData, "dns2", tmp, 15) == ESP_OK)
esp_netif_str_to_ip4(tmp, (esp_ip4_addr_t*) &GetSysConf()->wifiSettings.DNSAddr2);
if (httpd_query_key_value(PostData, "dns3", tmp, 15) == ESP_OK)
esp_netif_str_to_ip4(tmp, (esp_ip4_addr_t*) &GetSysConf()->wifiSettings.DNSAddr3);
if (httpd_query_key_value(PostData, "sav", tmp, 4) == ESP_OK)
{
if (!strcmp(tmp, (const char*) "prs"))
{
GetSysConf()->wifiSettings.Flags1.bIsWiFiEnabled = TempIsWiFiEnabled;
GetSysConf()->wifiSettings.Flags1.bIsDHCPEnabled = TempIsDHCPEnabled;
WriteNVSSysConfig(GetSysConf());
memcpy(PostData, "/reboot.html", sizeof "/reboot.html");
return HTTP_IO_REDIRECT;
}
}
#endif
return HTTP_IO_DONE;
}
static HTTP_IO_RESULT HTTPPostIndex22(httpd_req_t *req, char *PostData)
{
char tmp[32];
bool TempIsGSMEnabled = false;
if (httpd_query_key_value(PostData, "gsmen", tmp, sizeof(tmp)) == ESP_OK)
{
if (!strcmp((const char*) tmp, (const char*) "1"))
TempIsGSMEnabled = true;
}
if (httpd_query_key_value(PostData, "sav", tmp, 4) == ESP_OK)
{
if (!strcmp(tmp, (const char*) "prs"))
{
GetSysConf()->gsmSettings.Flags1.bIsGSMEnabled = TempIsGSMEnabled;
WriteNVSSysConfig(GetSysConf());
memcpy(PostData, "/reboot.html", sizeof "/reboot.html");
return HTTP_IO_REDIRECT;
}
}
if (httpd_query_key_value(PostData, "restart", tmp, 4) == ESP_OK)
{
if (!strcmp(tmp, (const char*) "prs"))
{
//PPPModemSoftRestart();
}
}
if (httpd_query_key_value(PostData, "hdrst", tmp, 4) == ESP_OK)
{
if (!strcmp(tmp, (const char*) "prs"))
{
//PPPModemColdStart();
}
}
return HTTP_IO_DONE;
}
static HTTP_IO_RESULT HTTPPostIndex23(httpd_req_t *req, char *PostData)
{
return HTTP_IO_DONE;
}
static HTTP_IO_RESULT HTTPPostIndex24(httpd_req_t *req, char *PostData)
{
return HTTP_IO_DONE;
}
static HTTP_IO_RESULT HTTPPostIndex30(httpd_req_t *req, char *PostData)
{
return HTTP_IO_DONE;
}
static HTTP_IO_RESULT HTTPPostIndex32(httpd_req_t *req, char *PostData)
{
char tmp[64];
bool TempIsTCPConfirm = false;
bool TempIsLoRaConfirm = false;
bool TempIsOTAEnabled = false;
if (httpd_query_key_value(PostData, "nam", tmp, sizeof(tmp)) == ESP_OK)
{
UnencodeURL(tmp);
strcpy(GetSysConf()->NetBIOSName, tmp);
}
if (httpd_query_key_value(PostData, "otaurl", tmp, sizeof(tmp)) == ESP_OK)
{
UnencodeURL(tmp);
strcpy(GetSysConf()->OTAURL, tmp);
}
httpd_query_key_value(PostData, "lgn", GetSysConf()->SysName, sizeof(GetSysConf()->SysName));
if (httpd_query_key_value(PostData, "psn", tmp, sizeof(tmp)) == ESP_OK)
{
if (strcmp(tmp, (const char*) "******"))
strcpy(GetSysConf()->SysPass, tmp);
}
if (httpd_query_key_value(PostData, "lrdel", tmp, sizeof(tmp)) == ESP_OK)
{
if (!strcmp((const char*) tmp, (const char*) "1"))
TempIsLoRaConfirm = true;
}
if (httpd_query_key_value(PostData, "tcpdel", tmp, sizeof(tmp)) == ESP_OK)
{
if (!strcmp((const char*) tmp, (const char*) "1"))
TempIsTCPConfirm = true;
}
if (httpd_query_key_value(PostData, "ota", tmp, sizeof(tmp)) == ESP_OK)
{
if (!strcmp((const char*) tmp, (const char*) "1"))
TempIsOTAEnabled = true;
}
if (httpd_query_key_value(PostData, "upd", tmp, sizeof(tmp)) == ESP_OK)
{
if (!strcmp(tmp, (const char*) "prs"))
{
//StartOTA();
}
}
if (httpd_query_key_value(PostData, "rst", tmp, sizeof(tmp)) == ESP_OK)
{
if (!strcmp(tmp, (const char*) "prs"))
{
memcpy(PostData, "/reboot.html", sizeof "/reboot.html");
return HTTP_IO_REDIRECT;
}
}
if (httpd_query_key_value(PostData, "sav", tmp, sizeof(tmp)) == ESP_OK)
{
if (!strcmp(tmp, (const char*) "prs"))
{
GetSysConf()->Flags1.bIsTCPConfirm = TempIsTCPConfirm;
GetSysConf()->Flags1.bIsLoRaConfirm = TempIsLoRaConfirm;
GetSysConf()->Flags1.bIsOTAEnabled = TempIsOTAEnabled;
WriteNVSSysConfig(GetSysConf());
memcpy(PostData, "/reboot.html", sizeof "/reboot.html");
return HTTP_IO_REDIRECT;
}
}
return HTTP_IO_DONE;
}
static HTTP_IO_RESULT HTTPPostIndex31(httpd_req_t *req, char *PostData)
{
char tmp[33];
bool TempIsMQTT1Enabled = false;
bool TempIsMQTT2Enabled = false;
httpd_query_key_value(PostData, "cld1", GetSysConf()->mqttStation[0].ServerAddr,
sizeof(GetSysConf()->mqttStation[0].ServerAddr));
httpd_query_key_value(PostData, "idd1", GetSysConf()->mqttStation[0].ClientID,
sizeof(GetSysConf()->mqttStation[0].ClientID));
httpd_query_key_value(PostData, "top1", GetSysConf()->mqttStation[0].RootTopic,
sizeof(GetSysConf()->mqttStation[0].RootTopic));
httpd_query_key_value(PostData, "clnm1", GetSysConf()->mqttStation[0].UserName,
sizeof(GetSysConf()->mqttStation[0].UserName));
httpd_query_key_value(PostData, "cld2", GetSysConf()->mqttStation[1].ServerAddr,
sizeof(GetSysConf()->mqttStation[1].ServerAddr));
httpd_query_key_value(PostData, "idd2", GetSysConf()->mqttStation[1].ClientID,
sizeof(GetSysConf()->mqttStation[1].ClientID));
httpd_query_key_value(PostData, "top2", GetSysConf()->mqttStation[1].RootTopic,
sizeof(GetSysConf()->mqttStation[1].RootTopic));
httpd_query_key_value(PostData, "clnm2", GetSysConf()->mqttStation[1].UserName,
sizeof(GetSysConf()->mqttStation[1].UserName));
if (httpd_query_key_value(PostData, "mqttenb1", tmp, sizeof(tmp)) == ESP_OK)
{
if (!strcmp((const char*) tmp, (const char*) "1"))
TempIsMQTT1Enabled = true;
}
if (httpd_query_key_value(PostData, "mqttenb2", tmp, sizeof(tmp)) == ESP_OK)
{
if (!strcmp((const char*) tmp, (const char*) "1"))
TempIsMQTT2Enabled = true;
}
if (httpd_query_key_value(PostData, "mprt1", tmp, sizeof(tmp)) == ESP_OK)
if (httpd_query_key_value(PostData, "mprt1", tmp, sizeof(tmp)) == ESP_OK)
{
uint16_t tp = atoi((const char*) tmp);
if (tp < 65535 && tp >= 1000)
GetSysConf()->mqttStation[0].ServerPort = tp;
}
if (httpd_query_key_value(PostData, "mprt2", tmp, sizeof(tmp)) == ESP_OK)
if (httpd_query_key_value(PostData, "mprt2", tmp, sizeof(tmp)) == ESP_OK)
{
uint16_t tp = atoi((const char*) tmp);
if (tp < 65535 && tp >= 1000)
GetSysConf()->mqttStation[1].ServerPort = tp;
}
if (httpd_query_key_value(PostData, "clps1", tmp, sizeof(tmp)) == ESP_OK &&
strcmp(tmp, (const char*) "******"))
{
strcpy(GetSysConf()->mqttStation[0].UserPass, tmp);
}
if (httpd_query_key_value(PostData, "clps2", tmp, sizeof(tmp)) == ESP_OK &&
strcmp(tmp, (const char*) "******"))
{
strcpy(GetSysConf()->mqttStation[1].UserPass, tmp);
}
if (httpd_query_key_value(PostData, "sav", tmp, 4) == ESP_OK)
{
if (!strcmp(tmp, (const char*) "prs"))
{
GetSysConf()->mqttStation[0].Flags1.bIsGlobalEnabled = TempIsMQTT1Enabled;
GetSysConf()->mqttStation[1].Flags1.bIsGlobalEnabled = TempIsMQTT2Enabled;
WriteNVSSysConfig(GetSysConf());
memcpy(PostData, "/reboot.html", sizeof "/reboot.html");
return HTTP_IO_REDIRECT;
}
}
return HTTP_IO_DONE;
}
static HTTP_IO_RESULT HTTPPostIndex33(httpd_req_t *req, char *PostData)
{
return HTTP_IO_DONE;
}
static HTTP_IO_RESULT HTTPPostIndex34(httpd_req_t *req, char *PostData)
{
return HTTP_IO_DONE;
}
static HTTP_IO_RESULT HTTPPostIndex40(httpd_req_t *req, char *PostData)
{
char tmp[8];
if (httpd_query_key_value(PostData, "cmd", tmp, 4) == ESP_OK)
{
if (!strcmp(tmp, (const char*) "1"))
{
// SetCTRL_BAT(ON);
}
else if (!strcmp(tmp, (const char*) "2"))
{
// SetCTRL_BAT(OFF);
}
else if (!strcmp(tmp, (const char*) "3"))
{
//MQTTStart();
}
else if (!strcmp(tmp, (const char*) "4"))
{
// MQTTStop();
}
else if (!strcmp(tmp, (const char*) "5"))
{
}
else if (!strcmp(tmp, (const char*) "6"))
{
}
else if (!strcmp(tmp, (const char*) "7"))
{
//SetDefaultNetIF(GetETHNetifAdapter());
}
else if (!strcmp(tmp, (const char*) "8"))
{
//SetDefaultNetIF(GetSTANetifAdapter());
}
else if (!strcmp(tmp, (const char*) "9"))
{
//SetDefaultNetIF(GetPPPNetifAdapter());
}
else if (!strcmp(tmp, (const char*) "10"))
{
//NextDefaultNetIF();
}
else if (!strcmp(tmp, (const char*) "11"))
{
//PrintNetifs();
}
else if (!strcmp(tmp, (const char*) "12"))
{
// SendTestEvent();
}
}
return HTTP_IO_DONE;
}
static HTTP_IO_RESULT HTTPPostIndex42(httpd_req_t *req, char *PostData)
{
return HTTP_IO_DONE;
}
static HTTP_IO_RESULT HTTPPostIndex43(httpd_req_t *req, char *PostData)
{
return HTTP_IO_DONE;
}
static HTTP_IO_RESULT HTTPPostIndex44(httpd_req_t *req, char *PostData)
{
return HTTP_IO_DONE;
}
static HTTP_IO_RESULT HTTPPostReboot(httpd_req_t *req, char *PostData)
{
char tmp[33];
if (httpd_query_key_value(PostData, "rbt", tmp, sizeof(tmp)) == ESP_OK)
{
if (!strcmp(tmp, (const char*) "prs"))
{
//DelayedRestart();
}
}
return HTTP_IO_DONE;
}
static HTTP_IO_RESULT HTTPPostDebug(httpd_req_t *req, char *PostData)
{
return HTTP_IO_DONE;
}
static HTTP_IO_RESULT HTTPPostMemJson(httpd_req_t *req, char *PostData)
{
return HTTP_IO_DONE;
}

346
src/HTTPPrintSystem.c Normal file
View File

@ -0,0 +1,346 @@
/*! Copyright 2022 Bogdan Pilyugin
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* \file HTTPPrintSystem.c
* \version 1.0
* \date 2022-08-14
* \author Bogdan Pilyugin
* \brief
* \details
* \copyright Apache License, Version 2.0
*/
#include "HTTPServer.h"
#define MAX_DYNVAR_LENGTH 64
#define MAX_INCFILE_LENGTH 1024
// uint32_t UpTime;
static const char *TAG = "HTTPServerPrint";
typedef struct
{
const char tag[16];
const int taglen;
void (*HandlerRoutine)(char *VarData, void *arg);
} dyn_var_handler_t;
typedef enum
{
IP,
NETMASK,
GW
} IP_PRINT_TYPE;
static void PrintInterfaceState(char *VarData, void *arg, esp_netif_t *netif)
{
if (netif != NULL && esp_netif_is_netif_up(netif))
snprintf(VarData, MAX_DYNVAR_LENGTH, "CONNECTED");
else
snprintf(VarData, MAX_DYNVAR_LENGTH, "DISCONNECTED");
}
static void PrintIPFromInterface(char *VarData, void *arg, esp_netif_t *netif, IP_PRINT_TYPE tp)
{
char buf[16];
esp_netif_ip_info_t ip_info;
if (netif != NULL && esp_netif_get_ip_info(netif, &ip_info) == ESP_OK)
{
switch (tp)
{
case IP:
snprintf(VarData, MAX_DYNVAR_LENGTH, "%s", esp_ip4addr_ntoa(&ip_info.ip, buf, 16));
break;
case NETMASK:
snprintf(VarData, MAX_DYNVAR_LENGTH, "%s", esp_ip4addr_ntoa(&ip_info.netmask, buf, 16));
break;
case GW:
snprintf(VarData, MAX_DYNVAR_LENGTH, "%s", esp_ip4addr_ntoa(&ip_info.gw, buf, 16));
break;
}
}
else
snprintf(VarData, MAX_DYNVAR_LENGTH, "-");
}
static void PrintDNSFromInterface(char *VarData, void *arg, esp_netif_t *netif, esp_netif_dns_type_t type)
{
char buf[16];
esp_netif_dns_info_t dns_info;
if (netif != NULL && esp_netif_get_dns_info(netif, type, &dns_info) == ESP_OK)
{
snprintf(VarData, MAX_DYNVAR_LENGTH, "%s", esp_ip4addr_ntoa((esp_ip4_addr_t*) (&dns_info.ip), buf, 16));
}
else
snprintf(VarData, MAX_DYNVAR_LENGTH, "-");
}
static void PrintMACFromInterface(char *VarData, void *arg, esp_netif_t *netif)
{
uint8_t mac_addr[6] = { 0 };
esp_netif_get_mac(netif, mac_addr);
snprintf(VarData, MAX_DYNVAR_LENGTH, "%02x-%02x-%02x-%02x-%02x-%02x",
mac_addr[0],
mac_addr[1],
mac_addr[2],
mac_addr[3],
mac_addr[4],
mac_addr[5]);
}
static void PrintCheckbox(char *VarData, void *arg, bool checked)
{
if (checked)
snprintf(VarData, MAX_DYNVAR_LENGTH, "checked");
else
snprintf(VarData, MAX_DYNVAR_LENGTH, " ");
}
static void HTTPPrint_status_fail(char *VarData, void *arg)
{
snprintf(VarData, MAX_DYNVAR_LENGTH, "none");
}
static void HTTPPrint_dname(char *VarData, void *arg)
{
snprintf(VarData, MAX_DYNVAR_LENGTH, "%s", GetSysConf()->NetBIOSName);
}
static void HTTPPrint_login(char *VarData, void *arg)
{
snprintf(VarData, MAX_DYNVAR_LENGTH, "%s", GetSysConf()->SysName);
}
static void HTTPPrint_pass(char *VarData, void *arg)
{
snprintf(VarData, MAX_DYNVAR_LENGTH, "%s", "******");
}
//Default string if not found handler
static void HTTPPrint_DEF(char *VarData, void *arg)
{
snprintf(VarData, MAX_DYNVAR_LENGTH, "#DEF");
}
#if CONFIG_WEBGUIAPP_WIFI_ENABLE
static void HTTPPrint_wfen(char *VarData, void *arg)
{
PrintCheckbox(VarData, arg, GetSysConf()->wifiSettings.Flags1.bIsWiFiEnabled);
}
static void HTTPPrint_wfstat(char *VarData, void *arg)
{
if (GetSysConf()->wifiSettings.Flags1.bIsAP)
PrintInterfaceState(VarData, arg, GetAPNetifAdapter());
else
PrintInterfaceState(VarData, arg, GetSTANetifAdapter());
}
static void HTTPPrint_cln(char *VarData, void *arg)
{
PrintCheckbox(VarData, arg, !GetSysConf()->wifiSettings.Flags1.bIsAP);
}
static void HTTPPrint_apn(char *VarData, void *arg)
{
PrintCheckbox(VarData, arg, GetSysConf()->wifiSettings.Flags1.bIsAP);
}
static void HTTPPrint_ssidap(char *VarData, void *arg)
{
snprintf(VarData, MAX_DYNVAR_LENGTH, "%s", GetSysConf()->wifiSettings.ApSSID);
}
static void HTTPPrint_wkeyap(char *VarData, void *arg)
{
snprintf(VarData, MAX_DYNVAR_LENGTH, "%s", "********");
}
/*AP IP*/
static void HTTPPrint_ipap(char *VarData, void *arg)
{
if (GetAPNetifAdapter() && esp_netif_is_netif_up(GetAPNetifAdapter()))
PrintIPFromInterface(VarData, arg, GetAPNetifAdapter(), IP);
else
snprintf(VarData, MAX_DYNVAR_LENGTH, "%s", ip4addr_ntoa(&GetSysConf()->wifiSettings.ApIPAddr));
}
static void HTTPPrint_ssid(char *VarData, void *arg)
{
snprintf(VarData, MAX_DYNVAR_LENGTH, "%s", GetSysConf()->wifiSettings.InfSSID);
}
static void HTTPPrint_wkey(char *VarData, void *arg)
{
snprintf(VarData, MAX_DYNVAR_LENGTH, "%s", "********");
}
static void HTTPPrint_cbdh(char *VarData, void *arg)
{
PrintCheckbox(VarData, arg, GetSysConf()->wifiSettings.Flags1.bIsDHCPEnabled);
}
/*STA IP*/
static void HTTPPrint_ip(char *VarData, void *arg)
{
if (GetSTANetifAdapter() && esp_netif_is_netif_up(GetSTANetifAdapter()))
PrintIPFromInterface(VarData, arg, GetSTANetifAdapter(), IP);
else
snprintf(VarData, MAX_DYNVAR_LENGTH, "%s", ip4addr_ntoa(&GetSysConf()->wifiSettings.InfIPAddr));
}
/*STA NETMASK*/
static void HTTPPrint_msk(char *VarData, void *arg)
{
if (GetSTANetifAdapter() && esp_netif_is_netif_up(GetSTANetifAdapter()))
PrintIPFromInterface(VarData, arg, GetSTANetifAdapter(), NETMASK);
else
snprintf(VarData, MAX_DYNVAR_LENGTH, "%s", ip4addr_ntoa(&GetSysConf()->wifiSettings.InfMask));
}
/*STA GATEWAY*/
static void HTTPPrint_gate(char *VarData, void *arg)
{
if (GetSTANetifAdapter() && esp_netif_is_netif_up(GetSTANetifAdapter()))
PrintIPFromInterface(VarData, arg, GetSTANetifAdapter(), GW);
else
snprintf(VarData, MAX_DYNVAR_LENGTH, "%s", ip4addr_ntoa(&GetSysConf()->wifiSettings.InfGateway));
}
/*Current DNS*/
static void HTTPPrint_dns(char *VarData, void *arg)
{
if (GetSTANetifAdapter() && esp_netif_is_netif_up(GetSTANetifAdapter()))
PrintDNSFromInterface(VarData, arg, GetSTANetifAdapter(), ESP_NETIF_DNS_MAIN);
else
snprintf(VarData, MAX_DYNVAR_LENGTH, "%s", "0.0.0.0");
}
static void HTTPPrint_dns2(char *VarData, void *arg)
{
if (GetSTANetifAdapter() && esp_netif_is_netif_up(GetSTANetifAdapter()))
PrintDNSFromInterface(VarData, arg, GetSTANetifAdapter(), ESP_NETIF_DNS_BACKUP);
else
snprintf(VarData, MAX_DYNVAR_LENGTH, "%s", "0.0.0.0");
}
static void HTTPPrint_dns3(char *VarData, void *arg)
{
if (GetSTANetifAdapter() && esp_netif_is_netif_up(GetSTANetifAdapter()))
PrintDNSFromInterface(VarData, arg, GetSTANetifAdapter(), ESP_NETIF_DNS_FALLBACK);
else
snprintf(VarData, MAX_DYNVAR_LENGTH, "%s", "0.0.0.0");
}
static void HTTPPrint_macadr(char *VarData, void *arg)
{
PrintMACFromInterface(VarData, arg, GetSTANetifAdapter());
}
static void HTTPPrint_apmacadr(char *VarData, void *arg)
{
PrintMACFromInterface(VarData, arg, GetAPNetifAdapter());
}
#endif
dyn_var_handler_t HANDLERS_ARRAY[] = {
/*Ststem settings*/
{ "dname", sizeof("dname") - 1, &HTTPPrint_dname },
{ "login", sizeof("login") - 1, &HTTPPrint_login },
{ "pass", sizeof("pass") - 1, &HTTPPrint_pass },
#if CONFIG_WEBGUIAPP_WIFI_ENABLE
{ "wfen", sizeof("wfen") - 1, &HTTPPrint_wfen },
{ "wfstat", sizeof("wfstat") - 1, &HTTPPrint_wfstat },
{ "cln", sizeof("cln") - 1, &HTTPPrint_cln },
{ "apn", sizeof("apn") - 1, &HTTPPrint_apn },
{ "ssidap", sizeof("ssidap") - 1, &HTTPPrint_ssidap },
{ "wkeyap", sizeof("wkeyap") - 1, &HTTPPrint_wkeyap },
{ "ipap", sizeof("ipap") - 1, &HTTPPrint_ipap },
{ "ssid", sizeof("ssid") - 1, &HTTPPrint_ssid },
{ "wkey", sizeof("wkey") - 1, &HTTPPrint_wkey },
{ "cbdh", sizeof("cbdh") - 1, &HTTPPrint_cbdh },
{ "ip", sizeof("ip") - 1, &HTTPPrint_ip },
{ "msk", sizeof("msk") - 1, &HTTPPrint_msk },
{ "gate", sizeof("gate") - 1, &HTTPPrint_gate },
{ "dns", sizeof("dns") - 1, &HTTPPrint_dns },
{ "dns2", sizeof("dns2") - 1, &HTTPPrint_dns2 },
{ "dns3", sizeof("dns3") - 1, &HTTPPrint_dns3 },
{ "macadr", sizeof("macadr") - 1, &HTTPPrint_macadr },
{ "apmacadr", sizeof("apmacadr") - 1, &HTTPPrint_apmacadr },
#endif
/*ERROR report*/
{ "status_fail", sizeof("status_fail") - 1, &HTTPPrint_status_fail },
};
int HTTPPrint(httpd_req_t *req, char* buf, char* var)
{
char VarData[MAX_DYNVAR_LENGTH];
const char incPat[] = "inc:";
const int incPatLen = sizeof(incPat) - 1;
if (!memcmp(var, incPat, incPatLen))
{
const char rootFS[] = "/";
char filename[32];
filename[0] = 0x00;
var += incPatLen;
strcat(filename, rootFS);
strcat(filename, var);
espfs_file_t *file = espfs_fopen(fs, filename);
struct espfs_stat_t stat;
if (file)
{
espfs_fstat(file, &stat);
int readBytes = espfs_fread(file, buf, stat.size);
espfs_fclose(file);
return readBytes;
}
}
bool fnd = false;
char *p2 = var + strlen(var) - 1; //last var symbol
int arg = 0;
//searching for tag in handles array
for (int i = 0; i < (sizeof(HANDLERS_ARRAY) / sizeof(HANDLERS_ARRAY[0])); ++i)
{
if (*p2 == ')')
{ //found close brace
char *p1 = p2;
while ((*p1 != '(') && (p1 > var))
--p1;
if (*p1 == '(')
{ //found open brace
*p1 = 0x00; //trim variable to name part
++p1; //to begin of argument
*p2 = 0x00; //set end of argument
arg = atoi(p1);
}
}
if (strcmp(var, HANDLERS_ARRAY[i].tag) == 0
&& HANDLERS_ARRAY[i].HandlerRoutine != NULL)
{
HANDLERS_ARRAY[i].HandlerRoutine(VarData, (void*) &arg);
fnd = true;
break;
}
}
if (!fnd)
HTTPPrint_DEF(VarData, NULL);
int dLen = strlen(VarData);
memcpy(buf, VarData, dLen);
return dLen;
}

445
src/HTTPServer.c Normal file
View File

@ -0,0 +1,445 @@
/*! Copyright 2022 Bogdan Pilyugin
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* \file HTTPServer.c
* \version 1.0
* \date 2022-08-14
* \author Bogdan Pilyugin
* \brief
* \details
* \copyright Apache License, Version 2.0
*/
#include "HTTPServer.h"
#include "sdkconfig.h"
const char GZIP_SIGN[] = { 0x1f, 0x8b, 0x08 };
static esp_err_t GETHandler(httpd_req_t *req);
static esp_err_t CheckAuth(httpd_req_t *req);
/* Max length a file path can have on storage */
#define FILE_PATH_MAX (ESP_VFS_PATH_MAX + CONFIG_SPIFFS_OBJ_NAME_LEN)
/* Max size of an individual file. Make sure this
* value is same as that set in upload_script.html */
#define MAX_FILE_SIZE (200*1024) // 200 KB
#define MAX_FILE_SIZE_STR "200KB"
/* Scratch buffer size */
#define SCRATCH_BUFSIZE 8192
#define AUTH_DATA_MAX_LENGTH 16
struct file_server_data
{
/* Base path of file storage */
char base_path[ESP_VFS_PATH_MAX + 1];
/* Scratch buffer for temporary storage during file transfer */
char scratch[SCRATCH_BUFSIZE];
/* Pointer to external POST handler*/
};
struct file_server_data *server_data = NULL;
httpd_handle_t server = NULL;
static const char *TAG = "HTTPServer";
static esp_err_t CheckAuth(httpd_req_t *req)
{
unsigned char pass[18] = { 0 }; //max length of login:password decoded string
unsigned char inp[31]; //max length of login:password coded string plus Basic
const char keyword1[] = "Basic ";
const int keyword1len = sizeof(keyword1) - 1;
if (httpd_req_get_hdr_value_len(req, "Authorization") > 31)
{
httpd_resp_set_hdr(req, "Connection", "close");
httpd_resp_send_err(req, HTTPD_431_REQ_HDR_FIELDS_TOO_LARGE, "Authorization field value is too large");
return ESP_FAIL;
}
httpd_req_get_hdr_value_str(req, "Authorization", (char*) inp, 31);
unsigned char *pt = memmem(inp, sizeof(inp), keyword1, keyword1len);
if (pt)
{
pt += keyword1len;
#if HTTP_SERVER_DEBUG_LEVEL > 0
ESP_LOGI(TAG, "Authorization string is:%s", pt);
#endif
size_t l;
mbedtls_base64_decode(pass, (size_t) sizeof(pass), &l, pt, strlen((const char*) pt));
#if HTTP_SERVER_DEBUG_LEVEL > 0
ESP_LOGI(TAG, "Authorization decoded string is:%s", pass);
#endif
strcpy((char*) inp, GetSysConf()->SysName); //buffer inp reused for login:pass check
strcat((char*) inp, (char*) ":");
strcat((char*) inp, GetSysConf()->SysPass);
#if HTTP_SERVER_DEBUG_LEVEL > 0
ESP_LOGI(TAG, "Reference auth data is %s", inp);
#endif
}
if (pt == NULL || strcmp((const char*) inp, (char*) pass))
{
httpd_resp_set_hdr(req, "WWW-Authenticate", "Basic");
//httpd_resp_set_hdr(req, "Connection", "keep-alive");
httpd_resp_send_err(req, HTTPD_401_UNAUTHORIZED, "This page requires authorization");
return ESP_FAIL;
}
return ESP_OK;
}
#define IS_FILE_EXT(filename, ext) \
(strcasecmp(&filename[strlen(filename) - sizeof(ext) + 1], ext) == 0)
/* Set HTTP response content type according to file extension */
static esp_err_t set_content_type_from_file(httpd_req_t *req,
const char *filename)
{
if (IS_FILE_EXT(filename, ".pdf"))
{
return httpd_resp_set_type(req, "application/pdf");
}
else if (IS_FILE_EXT(filename, ".html"))
{
return httpd_resp_set_type(req, "text/html");
}
else if (IS_FILE_EXT(filename, ".jpeg"))
{
return httpd_resp_set_type(req, "image/jpeg");
}
else if (IS_FILE_EXT(filename, ".ico"))
{
return httpd_resp_set_type(req, "image/x-icon");
}
else if (IS_FILE_EXT(filename, ".css"))
{
return httpd_resp_set_type(req, "text/css");
}
/* This is a limited set only */
/* For any other type always set as plain text */
return httpd_resp_set_type(req, "text/plain");
}
/* Copies the full path into destination buffer and returns
* pointer to path (skipping the preceding base path) */
static const char* get_path_from_uri(char *dest, const char *base_path,
const char *uri,
size_t destsize)
{
const size_t base_pathlen = strlen(base_path);
size_t pathlen = strlen(uri);
const char *quest = strchr(uri, '?');
if (quest)
{
pathlen = MIN(pathlen, quest - uri);
}
const char *hash = strchr(uri, '#');
if (hash)
{
pathlen = MIN(pathlen, hash - uri);
}
if (base_pathlen + pathlen + 1 > destsize)
{
/* Full path string won't fit into destination buffer */
return NULL;
}
/* Construct full path (base + path) */
strcpy(dest, base_path);
strlcpy(dest + base_pathlen, uri, pathlen + 1);
/* Return pointer to path, skipping the base */
return dest + base_pathlen;
}
static esp_err_t POSTHandler(httpd_req_t *req)
{
#if HTTP_SERVER_DEBUG_LEVEL > 0
ESP_LOGI(TAG, "POST request handle");
#endif
char *buf = ((struct file_server_data*) req->user_ctx)->scratch;
int received;
int remaining = req->content_len;
buf[req->content_len] = 0x00;
while (remaining > 0)
{
#if HTTP_SERVER_DEBUG_LEVEL > 0
ESP_LOGI(TAG, "Remaining size : %d", remaining);
#endif
/* Receive the file part by part into a buffer */
if ((received = httpd_req_recv(req, buf,
MIN(remaining, SCRATCH_BUFSIZE))) <= 0)
{
if (received == HTTPD_SOCK_ERR_TIMEOUT)
{
/* Retry if timeout occurred */
continue;
}
/* In case of unrecoverable error*/
ESP_LOGE(TAG, "File reception failed!");
/* Respond with 500 Internal Server Error */
httpd_resp_send_err(req, HTTPD_500_INTERNAL_SERVER_ERROR,
"Failed to receive file");
return ESP_FAIL;
}
/* Write buffer content to file on storage */
if (received)
{
char filepath[FILE_PATH_MAX];
const char *filename = get_path_from_uri(filepath,
((struct file_server_data*) req->user_ctx)->base_path,
req->uri,
sizeof(filepath));
if (HTTPPostApp(req, filename, buf) == HTTP_IO_REDIRECT)
{
httpd_resp_set_status(req, "307 Temporary Redirect");
httpd_resp_set_hdr(req, "Location", filename);
httpd_resp_send(req, NULL, 0); // Response body can be empty
#if HTTP_SERVER_DEBUG_LEVEL > 0
ESP_LOGI(TAG, "Redirect request from POST");
#endif
return ESP_OK;
}
}
/* Keep track of remaining size of
* the file left to be uploaded */
remaining -= received;
}
return GETHandler(req);
}
static esp_err_t GETHandler(httpd_req_t *req)
{
#if HTTP_SERVER_DEBUG_LEVEL > 0
ESP_LOGI(TAG, "GET request handle");
#endif
char filepath[FILE_PATH_MAX];
espfs_file_t *file;
struct espfs_stat_t stat;
bool isCompressed = false;
const char *filename = get_path_from_uri(filepath,
((struct file_server_data*) req->user_ctx)->base_path,
req->uri,
sizeof(filepath));
if (!filename)
{
ESP_LOGE(TAG, "Filename is too long");
/* Respond with 500 Internal Server Error */
httpd_resp_send_err(req, HTTPD_500_INTERNAL_SERVER_ERROR,
"Filename too long");
return ESP_FAIL;
}
/* Redirect request to /index.html */
if (filename[strlen(filename) - 1] == '/')
{
httpd_resp_set_status(req, "307 Temporary Redirect");
httpd_resp_set_hdr(req, "Location", "/index.html");
httpd_resp_send(req, NULL, 0); // Response body can be empty
#if HTTP_SERVER_DEBUG_LEVEL > 0
ESP_LOGI(TAG, "Redirect request to /index.html");
#endif
return ESP_OK;
}
//check auth for all files except status.json
if (strcmp(filename, "/status.json"))
{
if (CheckAuth(req) != ESP_OK)
{
return ESP_FAIL;
}
}
//open file
file = espfs_fopen(fs, filepath);
if (!file)
{
ESP_LOGE(TAG, "Failed to read existing file : %s", filepath);
/* Respond with 500 Internal Server Error */
httpd_resp_send_err(req, HTTPD_500_INTERNAL_SERVER_ERROR,
"Failed to read existing file");
return ESP_FAIL;
}
//get file info
espfs_stat(fs, filepath, &stat);
#if HTTP_SERVER_DEBUG_LEVEL > 0
ESP_LOGI(TAG, "Sending file : %s (%d bytes)...", filename,
stat.size);
#endif
//OutputDisplay((char*) filepath);
set_content_type_from_file(req, filename);
/* Retrieve the pointer to scratch buffer for temporary storage */
char *chunk = ((struct file_server_data*) req->user_ctx)->scratch;
uint32_t readBytes, fileSize;
fileSize = stat.size;
char *buf = (char*) malloc(fileSize);
if (buf)
{
readBytes = espfs_fread(file, buf, fileSize);
}
else
{
ESP_LOGE(TAG, "Failed to allocate memory");
/* Respond with 500 Internal Server Error */
httpd_resp_send_err(req, HTTPD_500_INTERNAL_SERVER_ERROR,
"Out of memory");
espfs_fclose(file);
return ESP_FAIL;
}
if (memmem(buf, 3, GZIP_SIGN, 3))
{
httpd_resp_set_hdr(req, "Content-Encoding", "gzip");
httpd_resp_set_hdr(req, "Cache-Control", "max-age=600");
isCompressed = true;
}
int pt = 0;
do
{
readBytes = 0;
while (pt < fileSize && readBytes < (SCRATCH_BUFSIZE - 64))
{
if (buf[pt] == '~' && !isCompressed)
{
int k = 0;
char DynVarName[16];
while (pt < fileSize && k < 16 && (buf[++pt] != '~'))
DynVarName[k++] = buf[pt];
if (buf[pt] == '~')
{ //got valid dynamic variable name
DynVarName[k] = 0x00;
readBytes += HTTPPrint(req, &chunk[readBytes], DynVarName);
pt++;
}
}
else
chunk[readBytes++] = buf[pt++];
}
if (readBytes != 0)
{
/* Send the buffer contents as HTTP response chunk */
#if HTTP_SERVER_DEBUG_LEVEL > 0
ESP_LOGI(TAG, "Write to HTTPserv resp %d", readBytes);
#endif
if (httpd_resp_send_chunk(req, chunk, readBytes) != ESP_OK)
{
ESP_LOGE(TAG, "File sending failed!");
/* Abort sending file */
httpd_resp_sendstr_chunk(req, NULL);
/* Respond with 500 Internal Server Error */
httpd_resp_send_err(req, HTTPD_500_INTERNAL_SERVER_ERROR,
"Failed to send file");
free(buf);
espfs_fclose(file);
return ESP_FAIL;
}
}
/* Keep looping till the whole file is sent */
}
while (readBytes != 0);
/* Close file after sending complete */
espfs_fclose(file);
#if HTTP_SERVER_DEBUG_LEVEL > 0
ESP_LOGI(TAG, "File sending complete");
#endif
/* Respond with an empty chunk to signal HTTP response completion */
httpd_resp_send_chunk(req, NULL, 0);
free(buf);
return ESP_OK;
}
static httpd_handle_t start_webserver(void)
{
httpd_handle_t server = NULL;
httpd_config_t config = HTTPD_DEFAULT_CONFIG();
config.lru_purge_enable = true;
config.uri_match_fn = httpd_uri_match_wildcard;
config.max_open_sockets = 3;
// Start the httpd server
ESP_LOGI(TAG, "Starting server on port: '%d'", config.server_port);
if (httpd_start(&server, &config) == ESP_OK)
{
// Set URI handlers
ESP_LOGI(TAG, "Registering URI handlers");
/* URI handler for GET request */
httpd_uri_t get = { .uri = "/*",
.method = HTTP_GET,
.handler = GETHandler,
.user_ctx = server_data // Pass server data as context
};
httpd_register_uri_handler(server, &get);
/* URI handler for POST request */
httpd_uri_t post = { .uri = "/*",
.method = HTTP_POST,
.handler = POSTHandler,
.user_ctx = server_data // Pass server data as context
};
httpd_register_uri_handler(server, &post);
return server;
}
ESP_LOGI(TAG, "Error starting server!");
return NULL;
}
static void stop_webserver(httpd_handle_t server)
{
// Stop the httpd server
httpd_stop(server);
}
static void reconnect_handler(void *arg, esp_event_base_t event_base,
int32_t event_id,
void *event_data)
{
httpd_handle_t *server = (httpd_handle_t*) arg;
if (*server)
{
ESP_LOGI(TAG, "Any adapter got new IP. Restart web server.");
stop_webserver(*server);
*server = start_webserver();
}
}
/* Function to start the file server */
esp_err_t start_file_server(void)
{
if (server_data)
{
ESP_LOGE(TAG, "File server already started");
return ESP_ERR_INVALID_STATE;
}
ESP_ERROR_CHECK(esp_event_handler_register(IP_EVENT, IP_EVENT_STA_GOT_IP, &reconnect_handler, &server));
ESP_ERROR_CHECK(esp_event_handler_register(IP_EVENT, IP_EVENT_ETH_GOT_IP, &reconnect_handler, &server));
/* Allocate memory for server data */
server_data = calloc(1, sizeof(struct file_server_data));
if (!server_data)
{
ESP_LOGE(TAG, "Failed to allocate memory for server data");
return ESP_ERR_NO_MEM;
}
strlcpy(server_data->base_path, "/", sizeof("/"));
server = start_webserver();
return ESP_OK;
}

178
src/Helpers.c Normal file
View File

@ -0,0 +1,178 @@
/* Copyright 2022 Bogdan Pilyugin
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* File name: Helpers.c
* Project: ChargePointMainboard
* Created on: 2022-07-21
* Author: Bogdan Pilyugin
* Description:
*/
#include "Helpers.h"
#include "esp_mac.h"
#include "esp_rom_crc.h"
uint32_t crc32(uint32_t crc, uint8_t const *buf, uint32_t len)
{
return esp_rom_crc32_le(crc, buf, len);
}
void GetChipId(uint8_t *i)
{
uint8_t mac[6];
//esp_base_mac_addr_get(mac);
esp_efuse_mac_get_default(mac);
memcpy(i,&mac[2],4);
}
char val_to_hex_digit(int val)
{
return "0123456789ABCDEF"[val];
}
void bin_to_hex_str(const uint8_t *buf, int len, char *hex)
{
for (int i = 0; i < len; i++)
{
uint8_t b = buf[i];
*hex = val_to_hex_digit((b & 0xf0) >> 4);
hex++;
*hex = val_to_hex_digit(b & 0x0f);
hex++;
}
}
void BytesToStr(unsigned char *StrIn, unsigned char *StrOut, uint8_t N)
{
uint8_t it, tmp;
for (it = 0; it < N; ++it)
{
tmp = *StrIn;
tmp >>= 4;
tmp &= 0x0F;
if (tmp <= 0x09)
*StrOut = tmp + 0x30;
else
*StrOut = tmp + 0x37;
++StrOut;
tmp = *StrIn;
tmp &= 0x0F;
if (tmp <= 0x09)
*StrOut = tmp + 0x30;
else
*StrOut = tmp + 0x37;
++StrOut;
*StrOut = 0x00;
++StrIn;
}
}
static char char2int(char input)
{
if (input >= '0' && input <= '9')
return input - '0';
if (input >= 'A' && input <= 'F')
return input - 'A' + 10;
if (input >= 'a' && input <= 'f')
return input - 'a' + 10;
return 0x00;
}
bool StrToBytes(unsigned char *StrIn, unsigned char *StrOut)
{
if ((strlen((const char*) StrIn) % 2))
return false;
while (*StrIn && StrIn[1])
{
*(StrOut++) = char2int(*StrIn) * 16 + char2int(StrIn[1]);
StrIn += 2;
}
return true;
}
bool StrToBytesLen(unsigned char *StrIn, unsigned char *StrOut, uint16_t InputSymbols)
{
if (InputSymbols % 2)
return false;
for (int i = 0; i < InputSymbols; i+=2)
{
*(StrOut++) = char2int(*StrIn) * 16 + char2int(StrIn[1]);
StrIn += 2;
}
return true;
}
uint32_t swap(uint32_t in)
{
in = ((in & 0xff000000) >> 24) | ((in & 0x00FF0000) >> 8) | ((in & 0x0000FF00) << 8) | ((in & 0xFF) << 24);
//in = (in >> 16) | (in << 16);
return in;
}
char btohexa_low(char b)
{
b &= 0x0F;
return (b > 9u) ? b + 'A' - 10 : b + '0';
}
BYTE hexatob(TCPIP_UINT16_VAL AsciiChars)
{
// Convert lowercase to uppercase
if (AsciiChars.v[1] > 'F')
AsciiChars.v[1] -= 'a' - 'A';
if (AsciiChars.v[0] > 'F')
AsciiChars.v[0] -= 'a' - 'A';
// Convert 0-9, A-F to 0x0-0xF
if (AsciiChars.v[1] > '9')
AsciiChars.v[1] -= 'A' - 10;
else
AsciiChars.v[1] -= '0';
if (AsciiChars.v[0] > '9')
AsciiChars.v[0] -= 'A' - 10;
else
AsciiChars.v[0] -= '0';
// Concatenate
return (BYTE) ((AsciiChars.v[1] << 4) | AsciiChars.v[0]);
}
void UnencodeURL(char* URL)
{
char *Right, *Copy;
UINT16_VAL Number;
while ((Right = strchr((const char*) URL, '%')))
{
// Make sure the string is long enough
if (Right[1] == '\0')
break;
if (Right[2] == '\0')
break;
// Update the string in place
Number.v[0] = Right[2];
Number.v[1] = Right[1];
*Right++ = hexatob(Number);
URL = Right;
// Remove two blank spots by shifting all remaining characters right two
Copy = Right + 2;
while ((*Right++ = *Copy++));
}
}

148
src/NetTransport.c Normal file
View File

@ -0,0 +1,148 @@
/* Copyright 2022 Bogdan Pilyugin
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* File name: NetTransport.c
* Project: ChargePointMainboard
* Created on: 2022-07-21
* Author: Bogdan Pilyugin
* Description:
*/
#include "NetTransport.h"
#include "SystemConfiguration.h"
#include "sdkconfig.h"
#include "lwip/netif.h"
#define TAG "NET_TRANSPORT"
extern struct netif *netif_default;
esp_netif_t* GetNetifByName(char *name)
{
return esp_netif_get_handle_from_ifkey(name);
}
void SetDefaultNetIF(esp_netif_t *IF)
{
for (struct netif *pri = netif_list; pri != NULL; pri = pri->next)
{
char ifname[4];
esp_netif_get_netif_impl_name(IF, ifname);
if ((pri->name[0] == ifname[0]) && (pri->name[1] == ifname[1]))
{
ESP_LOGI(TAG, "Interface priority set to %s", ifname);
netif_set_default(pri);
}
}
}
void PrintDefaultNetIF(void)
{
char ifname[3];
ifname[0] = netif_default->name[0];
ifname[1] = netif_default->name[1];
ifname[2] = 0x00;
ESP_LOGI(TAG, "Default IF is:%s", ifname);
}
void GetDefaultNetIFName(char *name)
{
name[0] = netif_default->name[0];
name[1] = netif_default->name[1];
name[2] = 0x00;
}
void NextDefaultNetIF(void)
{
for (struct netif *netif = netif_list; netif != NULL; netif = netif->next)
{
if ((netif->name[0] == netif_default->name[0]) && (netif->name[1] == netif_default->name[1]))
{
netif = netif->next;
if (!netif || ((netif->name[0] == 'l') && (netif->name[1] == 'o')))
{
netif = netif_list;
}
if (netif)
{
netif_set_default(netif);
PrintDefaultNetIF();
return;
}
}
}
}
void PrintNetifs(void)
{
// Create an esp_netif pointer to store current interface
esp_netif_t *interface = esp_netif_next(NULL);
// Stores the unique interface descriptor, such as "PP1", etc
char ifdesc[7];
ifdesc[6] = 0; // Ensure null terminated string
ESP_LOGI(TAG, "***************************************");
while (interface != NULL)
{
esp_netif_get_netif_impl_name(interface, ifdesc);
ESP_LOGI(TAG, "IF NAME:%s", ifdesc);
ESP_LOGI(TAG, "IF KEY:%s", esp_netif_get_ifkey(interface));
ESP_LOGI(TAG, "IF DESCR:%s", esp_netif_get_desc(interface));
ESP_LOGI(TAG, "IF ROUTE PRIO:%d", esp_netif_get_route_prio(interface));
if (esp_netif_is_netif_up(interface))
ESP_LOGI(TAG, "IF STATE:UP");
else
ESP_LOGI(TAG, "IF STATE:DOWN");
uint8_t mac_addr[6] = { 0 };
esp_netif_ip_info_t ip_info;
if (esp_netif_get_ip_info(interface, &ip_info) == ESP_OK)
{
char buf[16];
ESP_LOGI(TAG, "IP:%s", esp_ip4addr_ntoa(&ip_info.ip, buf, 16));
ESP_LOGI(TAG, "GW:%s", esp_ip4addr_ntoa(&ip_info.gw, buf, 16));
ESP_LOGI(TAG, "MASK:%s", esp_ip4addr_ntoa(&ip_info.netmask, buf, 16));
}
esp_netif_dns_info_t dns_info;
if (esp_netif_get_dns_info(interface, ESP_NETIF_DNS_MAIN, &dns_info) == ESP_OK)
{
char buf[16];
ESP_LOGI(TAG, "DNS MAIN:%s", esp_ip4addr_ntoa((esp_ip4_addr_t* ) &dns_info.ip, buf, 16));
}
if (esp_netif_get_dns_info(interface, ESP_NETIF_DNS_BACKUP, &dns_info) == ESP_OK)
{
char buf[16];
ESP_LOGI(TAG, "DNS BACKUP:%s", esp_ip4addr_ntoa((esp_ip4_addr_t* ) &dns_info.ip, buf, 16));
}
if (esp_netif_get_mac(interface, mac_addr) == ESP_OK)
{
ESP_LOGI(TAG, "MAC:%02x-%02x-%02x-%02x-%02x-%02x",
mac_addr[0],
mac_addr[1],
mac_addr[2],
mac_addr[3],
mac_addr[4],
mac_addr[5]);
}
ESP_LOGI(TAG, "-----------------------");
// Get the next interface
interface = esp_netif_next(interface);
}
ESP_LOGI(TAG, "***************************************");
}

129
src/SystemConfiguration.c Normal file
View File

@ -0,0 +1,129 @@
/*! Copyright 2022 Bogdan Pilyugin
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* \file SystemConfiguration.c
* \version 1.0
* \date 2022-08-13
* \author Bogdan Pilyugin
* \brief
* \details
* \copyright Apache License, Version 2.0
*/
#include "SystemConfiguration.h"
#include "stdlib.h"
#include "string.h"
#include "nvs_flash.h"
#include "nvs.h"
#include "esp_log.h"
#define STORAGE_NAMESPACE "storage"
#define TAG "SystemConfiguration"
static SYS_CONFIG SysConfig;
static void ResetSysConfig(SYS_CONFIG *Conf)
{
#if CONFIG_WEBGUIAPP_WIFI_ENABLE
Conf->wifiSettings.Flags1.bIsWiFiEnabled = CONFIG_WEBGUIAPP_WIFI_ON;
esp_netif_str_to_ip4(CONFIG_WEBGUIAPP_WIFI_IP_STA, (esp_ip4_addr_t*)&Conf->wifiSettings.InfIPAddr);
esp_netif_str_to_ip4(CONFIG_WEBGUIAPP_WIFI_MASK_STA, (esp_ip4_addr_t*)&Conf->wifiSettings.InfMask);
esp_netif_str_to_ip4(CONFIG_WEBGUIAPP_WIFI_GATEWAY_STA, (esp_ip4_addr_t*)&Conf->wifiSettings.InfGateway);
esp_netif_str_to_ip4(CONFIG_WEBGUIAPP_WIFI_IP_AP, (esp_ip4_addr_t*)&Conf->wifiSettings.ApIPAddr);
Conf->wifiSettings.Flags1.bIsAP = true;
memcpy(Conf->wifiSettings.ApSecurityKey, CONFIG_WEBGUIAPP_WIFI_KEY_AP, sizeof(CONFIG_WEBGUIAPP_WIFI_KEY_AP));
memcpy(Conf->wifiSettings.InfSSID, CONFIG_WEBGUIAPP_WIFI_SSID_STA, sizeof(CONFIG_WEBGUIAPP_WIFI_SSID_STA));
memcpy(Conf->wifiSettings.InfSecurityKey, CONFIG_WEBGUIAPP_WIFI_KEY_STA, sizeof(CONFIG_WEBGUIAPP_WIFI_KEY_STA));
Conf->wifiSettings.Flags1.bIsDHCPEnabled = CONFIG_WEBGUIAPP_WIFI_DHCP_ON;
#endif
}
esp_err_t ReadNVSSysConfig(SYS_CONFIG *SysConf)
{
nvs_handle_t my_handle;
esp_err_t err;
err = nvs_open(STORAGE_NAMESPACE, NVS_READWRITE, &my_handle);
if (err != ESP_OK)
return err;
// obtain required memory space to store blob being read from NVS
size_t L = (size_t) sizeof(SYS_CONFIG);
ESP_LOGI(TAG, "Size of structure to read is %d", L);
err = nvs_get_blob(my_handle, "sys_conf", SysConf, &L);
if (err != ESP_OK)
return err;
nvs_close(my_handle);
return ESP_OK;
}
esp_err_t WriteNVSSysConfig(SYS_CONFIG *SysConf)
{
nvs_handle_t my_handle;
esp_err_t err;
// Open
err = nvs_open(STORAGE_NAMESPACE, NVS_READWRITE, &my_handle);
if (err != ESP_OK)
return err;
size_t L = (size_t) sizeof(SYS_CONFIG);
ESP_LOGI(TAG, "Size of structure to write is %d", L);
err = nvs_set_blob(my_handle, "sys_conf", SysConf, L);
if (err != ESP_OK)
return err;
// Commit
err = nvs_commit(my_handle);
if (err != ESP_OK)
return err;
// Close
nvs_close(my_handle);
return ESP_OK;
}
SYS_CONFIG* GetSysConf(void)
{
return &SysConfig;
}
esp_err_t InitSysConfig(void)
{
esp_err_t err;
err = ReadNVSSysConfig(&SysConfig);
if (err != ESP_ERR_NVS_NOT_FOUND)
{
if (err == ESP_OK)
{
ESP_LOGI(TAG, "Read system configuration OK");
}
return err;
}
else
{
ESP_LOGI(TAG, "Reset and write default system configuration");
ResetSysConfig(&SysConfig);
err = WriteNVSSysConfig(&SysConfig);
}
return err;
}
esp_err_t ResetInitSysConfig(void)
{
ESP_LOGI(TAG, "Reset and write default system configuration");
ResetSysConfig(&SysConfig);
return WriteNVSSysConfig(&SysConfig);
}

307
src/WiFiTransport.c Normal file
View File

@ -0,0 +1,307 @@
/* Copyright 2022 Bogdan Pilyugin
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* File name: WiFiTransport.c
* Project: ChargePointMainboard
* Created on: 2022-07-21
* Author: Bogdan Pilyugin
* Description:
*/
#include "SystemConfiguration.h"
#include "esp_log.h"
#include "Helpers.h"
#include "esp_system.h"
#include "esp_wifi.h"
#include "esp_event.h"
#include "esp_log.h"
#include "nvs_flash.h"
#include "lwip/err.h"
#include "lwip/sys.h"
#include "NetTransport.h"
esp_netif_t *sta_netif;
esp_netif_t *ap_netif;
static const char *TAG = "WiFiTransport";
#define EXAMPLE_ESP_MAXIMUM_RETRY 5
#define EXAMPLE_ESP_WIFI_CHANNEL 6
#define EXAMPLE_MAX_STA_CONN 10
static EventGroupHandle_t s_wifi_event_group;
#define WIFI_CONNECTED_BIT BIT0
#define WIFI_FAIL_BIT BIT1
static int s_retry_num = 0;
static bool isWiFiGotIp = false;
esp_netif_t* GetSTANetifAdapter(void)
{
return sta_netif;
}
esp_netif_t* GetAPNetifAdapter(void)
{
return ap_netif;
}
bool isWIFIConnected(void)
{
return isWiFiGotIp;
}
static void event_handler(void *arg, esp_event_base_t event_base,
int32_t event_id,
void *event_data)
{
if (event_base == WIFI_EVENT && event_id == WIFI_EVENT_STA_START)
{
esp_wifi_connect();
}
else if (event_base == WIFI_EVENT && event_id == WIFI_EVENT_STA_DISCONNECTED)
{
if (s_retry_num < EXAMPLE_ESP_MAXIMUM_RETRY)
{
esp_wifi_connect();
s_retry_num++;
ESP_LOGI(TAG, "retry to connect to the AP");
}
else
{
xEventGroupSetBits(s_wifi_event_group, WIFI_FAIL_BIT);
}
isWiFiGotIp = false;
ESP_LOGI(TAG, "connect to the AP fail");
}
else if (event_base == IP_EVENT && event_id == IP_EVENT_STA_GOT_IP)
{
ip_event_got_ip_t *event = (ip_event_got_ip_t*) event_data;
ESP_LOGI(TAG, "got ip:" IPSTR, IP2STR(&event->ip_info.ip));
s_retry_num = 0;
memcpy(&GetSysConf()->wifiSettings.InfIPAddr, &event->ip_info.ip, sizeof(event->ip_info.ip));
memcpy(&GetSysConf()->wifiSettings.InfMask, &event->ip_info.netmask, sizeof(event->ip_info.netmask));
memcpy(&GetSysConf()->wifiSettings.InfGateway, &event->ip_info.gw, sizeof(event->ip_info.gw));
isWiFiGotIp = true;
xEventGroupSetBits(s_wifi_event_group, WIFI_CONNECTED_BIT);
}
if (event_id == WIFI_EVENT_AP_STACONNECTED)
{
wifi_event_ap_staconnected_t *event = (wifi_event_ap_staconnected_t*) event_data;
ESP_LOGI(TAG, "station "MACSTR" join, AID=%d",
MAC2STR(event->mac),
event->aid);
}
else if (event_id == WIFI_EVENT_AP_STADISCONNECTED)
{
wifi_event_ap_stadisconnected_t *event = (wifi_event_ap_stadisconnected_t*) event_data;
ESP_LOGI(TAG, "station "MACSTR" leave, AID=%d",
MAC2STR(event->mac),
event->aid);
}
}
static void wifi_init_softap(void *pvParameter)
{
char if_key_str[24];
esp_netif_inherent_config_t esp_netif_conf = ESP_NETIF_INHERENT_DEFAULT_WIFI_AP()
;
strcpy(if_key_str, "WIFI_AP_USER");
esp_netif_conf.if_key = if_key_str;
esp_netif_conf.route_prio = AP_PRIO;
esp_netif_config_t cfg_netif = {
.base = &esp_netif_conf,
.stack = ESP_NETIF_NETSTACK_DEFAULT_WIFI_AP
};
ap_netif = esp_netif_new(&cfg_netif);
assert(ap_netif);
esp_netif_ip_info_t ip_info;
memcpy(&ip_info.ip, &GetSysConf()->wifiSettings.ApIPAddr, 4);
memcpy(&ip_info.gw, &GetSysConf()->wifiSettings.InfGateway, 4);
memcpy(&ip_info.netmask, &GetSysConf()->wifiSettings.InfMask, 4);
esp_netif_dhcps_stop(ap_netif);
esp_netif_set_ip_info(ap_netif, &ip_info);
esp_netif_dhcps_start(ap_netif);
esp_netif_attach_wifi_ap(ap_netif);
esp_wifi_set_default_wifi_ap_handlers();
wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT()
;
ESP_ERROR_CHECK(esp_wifi_init(&cfg));
ESP_ERROR_CHECK(esp_event_handler_instance_register(WIFI_EVENT,
ESP_EVENT_ANY_ID,
&event_handler,
NULL,
NULL));
wifi_config_t wifi_config = {
.ap = {
.channel = EXAMPLE_ESP_WIFI_CHANNEL,
.max_connection = EXAMPLE_MAX_STA_CONN,
.authmode = WIFI_AUTH_WPA_WPA2_PSK
},
};
if (strlen(DEFAULT_WIFI_SSID_AP_KEY) == 0)
{
wifi_config.ap.authmode = WIFI_AUTH_OPEN;
}
memcpy(wifi_config.ap.ssid, GetSysConf()->wifiSettings.ApSSID, strlen(GetSysConf()->wifiSettings.ApSSID));
memcpy(wifi_config.ap.password, GetSysConf()->wifiSettings.ApSecurityKey,
strlen(GetSysConf()->wifiSettings.ApSecurityKey));
wifi_config.ap.ssid_len = strlen(GetSysConf()->wifiSettings.ApSSID);
ESP_ERROR_CHECK(esp_wifi_set_mode(WIFI_MODE_AP));
ESP_ERROR_CHECK(esp_wifi_set_config(WIFI_IF_AP, &wifi_config));
ESP_ERROR_CHECK(esp_wifi_start());
ESP_LOGI(TAG, "wifi_init_softap finished");
vTaskDelete(NULL);
}
static void wifi_init_sta(void *pvParameter)
{
s_wifi_event_group = xEventGroupCreate();
//sta_netif = esp_netif_create_default_wifi_sta();
char if_key_str[24];
esp_netif_inherent_config_t esp_netif_conf = ESP_NETIF_INHERENT_DEFAULT_WIFI_STA();
strcpy(if_key_str, "WIFI_STA_USER");
esp_netif_conf.if_key = if_key_str;
esp_netif_conf.route_prio = STA_PRIO;
esp_netif_config_t cfg_netif = {
.base = &esp_netif_conf,
.stack = ESP_NETIF_NETSTACK_DEFAULT_WIFI_STA
};
sta_netif = esp_netif_new(&cfg_netif);
assert(sta_netif);
esp_netif_ip_info_t ip_info;
memcpy(&ip_info.ip, &GetSysConf()->wifiSettings.InfIPAddr, 4);
memcpy(&ip_info.gw, &GetSysConf()->wifiSettings.InfGateway, 4);
memcpy(&ip_info.netmask, &GetSysConf()->wifiSettings.InfMask, 4);
esp_netif_dns_info_t dns_info;
memcpy(&dns_info, &GetSysConf()->wifiSettings.DNSAddr1, 4);
esp_netif_dhcpc_stop(sta_netif);
esp_netif_set_ip_info(sta_netif, &ip_info);
esp_netif_set_dns_info(sta_netif, ESP_NETIF_DNS_MAIN, &dns_info);
//esp_netif_str_to_ip4(&GetSysConf()->wifiSettings.DNSAddr3, (esp_ip4_addr_t*)(&dns_info.ip));
memcpy(&dns_info.ip, &GetSysConf()->wifiSettings.DNSAddr3, sizeof(esp_ip4_addr_t));
esp_netif_set_dns_info(sta_netif, ESP_NETIF_DNS_FALLBACK, &dns_info);
if (GetSysConf()->wifiSettings.Flags1.bIsDHCPEnabled)
esp_netif_dhcpc_start(sta_netif);
esp_netif_attach_wifi_station(sta_netif);
esp_wifi_set_default_wifi_sta_handlers();
wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT()
;
ESP_ERROR_CHECK(esp_wifi_init(&cfg));
esp_event_handler_instance_t instance_any_id;
esp_event_handler_instance_t instance_got_ip;
ESP_ERROR_CHECK(esp_event_handler_instance_register(WIFI_EVENT,
ESP_EVENT_ANY_ID,
&event_handler,
NULL,
&instance_any_id));
ESP_ERROR_CHECK(esp_event_handler_instance_register(IP_EVENT,
IP_EVENT_STA_GOT_IP,
&event_handler,
NULL,
&instance_got_ip));
wifi_config_t wifi_config = {
.sta = {
/* Setting a password implies station will connect to all security modes including WEP/WPA.
* However these modes are deprecated and not advisable to be used. Incase your Access point
* doesn't support WPA2, these mode can be enabled by commenting below line */
.threshold.authmode = WIFI_AUTH_WPA2_PSK,
.pmf_cfg = {
.capable = true,
.required = false
},
},
};
memcpy(wifi_config.sta.ssid, GetSysConf()->wifiSettings.InfSSID, strlen(GetSysConf()->wifiSettings.InfSSID));
memcpy(wifi_config.sta.password, GetSysConf()->wifiSettings.InfSecurityKey,
strlen(GetSysConf()->wifiSettings.InfSecurityKey));
ESP_ERROR_CHECK(esp_wifi_set_mode(WIFI_MODE_STA));
ESP_ERROR_CHECK(esp_wifi_set_config(WIFI_IF_STA, &wifi_config));
ESP_ERROR_CHECK(esp_wifi_start());
ESP_LOGI(TAG, "wifi_init_sta finished.");
/* Waiting until either the connection is established (WIFI_CONNECTED_BIT) or connection failed for the maximum
* number of re-tries (WIFI_FAIL_BIT). The bits are set by event_handler() (see above) */
EventBits_t bits = xEventGroupWaitBits(s_wifi_event_group,
WIFI_CONNECTED_BIT | WIFI_FAIL_BIT,
pdFALSE,
pdFALSE,
portMAX_DELAY);
/* xEventGroupWaitBits() returns the bits before the call returned, hence we can test which event actually
* happened. */
if (bits & WIFI_CONNECTED_BIT)
{
ESP_LOGI(TAG, "connected to ap SSID:%s password:%s",
GetSysConf()->wifiSettings.InfSSID,
GetSysConf()->wifiSettings.InfSecurityKey);
}
else if (bits & WIFI_FAIL_BIT)
{
ESP_LOGI(TAG, "Failed to connect to SSID:%s, password:%s",
GetSysConf()->wifiSettings.InfSSID,
GetSysConf()->wifiSettings.InfSecurityKey);
}
else
{
ESP_LOGE(TAG, "UNEXPECTED EVENT");
}
/* The event will not be processed after unregister */
// ESP_ERROR_CHECK(esp_event_handler_instance_unregister(IP_EVENT, IP_EVENT_STA_GOT_IP, instance_got_ip));
// ESP_ERROR_CHECK(esp_event_handler_instance_unregister( WIFI_EVENT, ESP_EVENT_ANY_ID, instance_any_id));
// vEventGroupDelete(s_wifi_event_group);
vTaskDelete(NULL);
}
void WiFiAPStart(void)
{
xTaskCreate(wifi_init_softap, "InitSoftAPTask", 1024 * 4, (void*) 0, 3, NULL);
}
void WiFiSTAStart(void)
{
xTaskCreate(wifi_init_sta, "InitStationTask", 1024 * 4, (void*) 0, 3, NULL);
}

43
src/romfs.c Normal file
View File

@ -0,0 +1,43 @@
/*! Copyright 2022 Bogdan Pilyugin
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* \file romfs.c
* \version 1.0
* \date 2022-08-14
* \author Bogdan Pilyugin
* \brief
* \details
* \copyright Apache License, Version 2.0
*/
#include "romfs.h"
extern const uint8_t espfs_bin[];
espfs_fs_t *fs;
espfs_config_t espfs_config = {
.addr = espfs_bin,
};
void init_rom_fs(const char *root)
{
fs = espfs_init(&espfs_config);
assert(fs != NULL);
/*
esp_vfs_espfs_conf_t vfs_espfs_conf = {
.base_path = root,
.fs = fs,
.max_files = 5, };
esp_vfs_espfs_register(&vfs_espfs_conf);
*/
}